Commit 3475187dd814be9b27c4632b59c1e3c76d966d63

Authored by bellard
1 parent 8979b227

sparc64 marge (Blue Swirl)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1462 c046a42c-6fe2-441c-8c8c-71466251a162
Changelog
@@ -4,6 +4,7 @@ version 0.7.1: @@ -4,6 +4,7 @@ version 0.7.1:
4 - Windows 2000 install disk full hack (original idea from Vladimir 4 - Windows 2000 install disk full hack (original idea from Vladimir
5 N. Oleynik) 5 N. Oleynik)
6 - VMDK disk image creation (Filip Navara) 6 - VMDK disk image creation (Filip Navara)
  7 + - SPARC64 progress (Blue Swirl)
7 8
8 version 0.7.0: 9 version 0.7.0:
9 10
Makefile.target
@@ -349,7 +349,11 @@ VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o @@ -349,7 +349,11 @@ VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o
349 VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o mixeng.o 349 VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o mixeng.o
350 endif 350 endif
351 ifeq ($(TARGET_BASE_ARCH), sparc) 351 ifeq ($(TARGET_BASE_ARCH), sparc)
352 -VL_OBJS+= sun4m.o tcx.o lance.o iommu.o m48t08.o magic-load.o slavio_intctl.o slavio_timer.o slavio_serial.o fdc.o esp.o 352 +ifeq ($(TARGET_ARCH), sparc64)
  353 +VL_OBJS+= sun4u.o m48t08.o magic-load.o slavio_serial.o
  354 +else
  355 +VL_OBJS+= sun4m.o tcx.o lance.o iommu.o m48t08.o magic-load.o slavio_intctl.o slavio_timer.o slavio_serial.o slavio_misc.o fdc.o esp.o
  356 +endif
353 endif 357 endif
354 ifdef CONFIG_GDBSTUB 358 ifdef CONFIG_GDBSTUB
355 VL_OBJS+=gdbstub.o 359 VL_OBJS+=gdbstub.o
@@ -442,7 +446,8 @@ op.o: op.c op_template.h @@ -442,7 +446,8 @@ op.o: op.c op_template.h
442 endif 446 endif
443 447
444 ifeq ($(TARGET_BASE_ARCH), sparc) 448 ifeq ($(TARGET_BASE_ARCH), sparc)
445 -op.o: op.c op_template.h op_mem.h 449 +op.o: op.c op_template.h op_mem.h fop_template.h fbranch_template.h
  450 +magic_load.o: elf_op.h
446 endif 451 endif
447 452
448 ifeq ($(TARGET_ARCH), ppc) 453 ifeq ($(TARGET_ARCH), ppc)
cpu-exec.c
@@ -47,6 +47,9 @@ void cpu_loop_exit(void) @@ -47,6 +47,9 @@ void cpu_loop_exit(void)
47 longjmp(env->jmp_env, 1); 47 longjmp(env->jmp_env, 1);
48 } 48 }
49 #endif 49 #endif
  50 +#ifndef TARGET_SPARC
  51 +#define reg_T2
  52 +#endif
50 53
51 /* exit the current TB from a signal handler. The host registers are 54 /* exit the current TB from a signal handler. The host registers are
52 restored in a state compatible with the CPU emulator 55 restored in a state compatible with the CPU emulator
@@ -74,8 +77,12 @@ void cpu_resume_from_signal(CPUState *env1, void *puc) @@ -74,8 +77,12 @@ void cpu_resume_from_signal(CPUState *env1, void *puc)
74 77
75 int cpu_exec(CPUState *env1) 78 int cpu_exec(CPUState *env1)
76 { 79 {
77 - int saved_T0, saved_T1, saved_T2; 80 + int saved_T0, saved_T1;
  81 +#if defined(reg_T2)
  82 + int saved_T2;
  83 +#endif
78 CPUState *saved_env; 84 CPUState *saved_env;
  85 +#if defined(TARGET_I386)
79 #ifdef reg_EAX 86 #ifdef reg_EAX
80 int saved_EAX; 87 int saved_EAX;
81 #endif 88 #endif
@@ -100,6 +107,11 @@ int cpu_exec(CPUState *env1) @@ -100,6 +107,11 @@ int cpu_exec(CPUState *env1)
100 #ifdef reg_EDI 107 #ifdef reg_EDI
101 int saved_EDI; 108 int saved_EDI;
102 #endif 109 #endif
  110 +#elif defined(TARGET_SPARC)
  111 +#if defined(reg_REGWPTR)
  112 + uint32_t *saved_regwptr;
  113 +#endif
  114 +#endif
103 #ifdef __sparc__ 115 #ifdef __sparc__
104 int saved_i7, tmp_T0; 116 int saved_i7, tmp_T0;
105 #endif 117 #endif
@@ -115,7 +127,9 @@ int cpu_exec(CPUState *env1) @@ -115,7 +127,9 @@ int cpu_exec(CPUState *env1)
115 env = env1; 127 env = env1;
116 saved_T0 = T0; 128 saved_T0 = T0;
117 saved_T1 = T1; 129 saved_T1 = T1;
  130 +#if defined(reg_T2)
118 saved_T2 = T2; 131 saved_T2 = T2;
  132 +#endif
119 #ifdef __sparc__ 133 #ifdef __sparc__
120 /* we also save i7 because longjmp may not restore it */ 134 /* we also save i7 because longjmp may not restore it */
121 asm volatile ("mov %%i7, %0" : "=r" (saved_i7)); 135 asm volatile ("mov %%i7, %0" : "=r" (saved_i7));
@@ -164,6 +178,9 @@ int cpu_exec(CPUState *env1) @@ -164,6 +178,9 @@ int cpu_exec(CPUState *env1)
164 env->cpsr = psr & ~CACHED_CPSR_BITS; 178 env->cpsr = psr & ~CACHED_CPSR_BITS;
165 } 179 }
166 #elif defined(TARGET_SPARC) 180 #elif defined(TARGET_SPARC)
  181 +#if defined(reg_REGWPTR)
  182 + saved_regwptr = REGWPTR;
  183 +#endif
167 #elif defined(TARGET_PPC) 184 #elif defined(TARGET_PPC)
168 #else 185 #else
169 #error unsupported target CPU 186 #error unsupported target CPU
@@ -354,7 +371,9 @@ int cpu_exec(CPUState *env1) @@ -354,7 +371,9 @@ int cpu_exec(CPUState *env1)
354 cpu_dump_state(env, logfile, fprintf, 0); 371 cpu_dump_state(env, logfile, fprintf, 0);
355 env->cpsr &= ~CACHED_CPSR_BITS; 372 env->cpsr &= ~CACHED_CPSR_BITS;
356 #elif defined(TARGET_SPARC) 373 #elif defined(TARGET_SPARC)
357 - cpu_dump_state (env, logfile, fprintf, 0); 374 + REGWPTR = env->regbase + (env->cwp * 16);
  375 + env->regwptr = REGWPTR;
  376 + cpu_dump_state(env, logfile, fprintf, 0);
358 #elif defined(TARGET_PPC) 377 #elif defined(TARGET_PPC)
359 cpu_dump_state(env, logfile, fprintf, 0); 378 cpu_dump_state(env, logfile, fprintf, 0);
360 #else 379 #else
@@ -376,7 +395,11 @@ int cpu_exec(CPUState *env1) @@ -376,7 +395,11 @@ int cpu_exec(CPUState *env1)
376 cs_base = 0; 395 cs_base = 0;
377 pc = env->regs[15]; 396 pc = env->regs[15];
378 #elif defined(TARGET_SPARC) 397 #elif defined(TARGET_SPARC)
379 - flags = 0; 398 +#ifdef TARGET_SPARC64
  399 + flags = (env->pstate << 2) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);
  400 +#else
  401 + flags = env->psrs | ((env->mmuregs[0] & (MMU_E | MMU_NF)) << 1);
  402 +#endif
380 cs_base = env->npc; 403 cs_base = env->npc;
381 pc = env->pc; 404 pc = env->pc;
382 #elif defined(TARGET_PPC) 405 #elif defined(TARGET_PPC)
@@ -657,6 +680,9 @@ int cpu_exec(CPUState *env1) @@ -657,6 +680,9 @@ int cpu_exec(CPUState *env1)
657 env->cpsr = compute_cpsr(); 680 env->cpsr = compute_cpsr();
658 /* XXX: Save/restore host fpu exception state?. */ 681 /* XXX: Save/restore host fpu exception state?. */
659 #elif defined(TARGET_SPARC) 682 #elif defined(TARGET_SPARC)
  683 +#if defined(reg_REGWPTR)
  684 + REGWPTR = saved_regwptr;
  685 +#endif
660 #elif defined(TARGET_PPC) 686 #elif defined(TARGET_PPC)
661 #else 687 #else
662 #error unsupported target CPU 688 #error unsupported target CPU
@@ -666,7 +692,9 @@ int cpu_exec(CPUState *env1) @@ -666,7 +692,9 @@ int cpu_exec(CPUState *env1)
666 #endif 692 #endif
667 T0 = saved_T0; 693 T0 = saved_T0;
668 T1 = saved_T1; 694 T1 = saved_T1;
  695 +#if defined(reg_T2)
669 T2 = saved_T2; 696 T2 = saved_T2;
  697 +#endif
670 env = saved_env; 698 env = saved_env;
671 return ret; 699 return ret;
672 } 700 }
@@ -155,6 +155,9 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags) @@ -155,6 +155,9 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
155 print_insn = print_insn_arm; 155 print_insn = print_insn_arm;
156 #elif defined(TARGET_SPARC) 156 #elif defined(TARGET_SPARC)
157 print_insn = print_insn_sparc; 157 print_insn = print_insn_sparc;
  158 +#ifdef TARGET_SPARC64
  159 + disasm_info.mach = bfd_mach_sparc_v9b;
  160 +#endif
158 #elif defined(TARGET_PPC) 161 #elif defined(TARGET_PPC)
159 if (cpu_single_env->msr[MSR_LE]) 162 if (cpu_single_env->msr[MSR_LE])
160 disasm_info.endian = BFD_ENDIAN_LITTLE; 163 disasm_info.endian = BFD_ENDIAN_LITTLE;
gdbstub.c
1 /* 1 /*
2 * gdb server stub 2 * gdb server stub
3 * 3 *
4 - * Copyright (c) 2003 Fabrice Bellard 4 + * Copyright (c) 2003-2005 Fabrice Bellard
5 * 5 *
6 * This library is free software; you can redistribute it and/or 6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public 7 * modify it under the terms of the GNU Lesser General Public
@@ -293,7 +293,7 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) @@ -293,7 +293,7 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
293 #elif defined (TARGET_SPARC) 293 #elif defined (TARGET_SPARC)
294 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) 294 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
295 { 295 {
296 - uint32_t *registers = (uint32_t *)mem_buf, tmp; 296 + target_ulong *registers = (target_ulong *)mem_buf;
297 int i; 297 int i;
298 298
299 /* fill in g0..g7 */ 299 /* fill in g0..g7 */
@@ -308,10 +308,15 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) @@ -308,10 +308,15 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
308 for (i = 0; i < 32; i++) { 308 for (i = 0; i < 32; i++) {
309 registers[i + 32] = tswapl(*((uint32_t *)&env->fpr[i])); 309 registers[i + 32] = tswapl(*((uint32_t *)&env->fpr[i]));
310 } 310 }
  311 +#ifndef TARGET_SPARC64
311 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ 312 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
312 registers[64] = tswapl(env->y); 313 registers[64] = tswapl(env->y);
313 - tmp = GET_PSR(env);  
314 - registers[65] = tswapl(tmp); 314 + {
  315 + target_ulong tmp;
  316 +
  317 + tmp = GET_PSR(env);
  318 + registers[65] = tswapl(tmp);
  319 + }
315 registers[66] = tswapl(env->wim); 320 registers[66] = tswapl(env->wim);
316 registers[67] = tswapl(env->tbr); 321 registers[67] = tswapl(env->tbr);
317 registers[68] = tswapl(env->pc); 322 registers[68] = tswapl(env->pc);
@@ -319,13 +324,24 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) @@ -319,13 +324,24 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
319 registers[70] = tswapl(env->fsr); 324 registers[70] = tswapl(env->fsr);
320 registers[71] = 0; /* csr */ 325 registers[71] = 0; /* csr */
321 registers[72] = 0; 326 registers[72] = 0;
322 -  
323 - return 73 * 4; 327 + return 73 * sizeof(target_ulong);
  328 +#else
  329 + for (i = 0; i < 32; i += 2) {
  330 + registers[i/2 + 64] = tswapl(*((uint64_t *)&env->fpr[i]));
  331 + }
  332 + registers[81] = tswapl(env->pc);
  333 + registers[82] = tswapl(env->npc);
  334 + registers[83] = tswapl(env->tstate[env->tl]);
  335 + registers[84] = tswapl(env->fsr);
  336 + registers[85] = tswapl(env->fprs);
  337 + registers[86] = tswapl(env->y);
  338 + return 87 * sizeof(target_ulong);
  339 +#endif
324 } 340 }
325 341
326 static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) 342 static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
327 { 343 {
328 - uint32_t *registers = (uint32_t *)mem_buf; 344 + target_ulong *registers = (target_ulong *)mem_buf;
329 int i; 345 int i;
330 346
331 /* fill in g0..g7 */ 347 /* fill in g0..g7 */
@@ -334,12 +350,13 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) @@ -334,12 +350,13 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
334 } 350 }
335 /* fill in register window */ 351 /* fill in register window */
336 for(i = 0; i < 24; i++) { 352 for(i = 0; i < 24; i++) {
337 - env->regwptr[i] = tswapl(registers[i]); 353 + env->regwptr[i] = tswapl(registers[i + 8]);
338 } 354 }
339 /* fill in fprs */ 355 /* fill in fprs */
340 for (i = 0; i < 32; i++) { 356 for (i = 0; i < 32; i++) {
341 *((uint32_t *)&env->fpr[i]) = tswapl(registers[i + 32]); 357 *((uint32_t *)&env->fpr[i]) = tswapl(registers[i + 32]);
342 } 358 }
  359 +#ifndef TARGET_SPARC64
343 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ 360 /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
344 env->y = tswapl(registers[64]); 361 env->y = tswapl(registers[64]);
345 PUT_PSR(env, tswapl(registers[65])); 362 PUT_PSR(env, tswapl(registers[65]));
@@ -348,6 +365,20 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) @@ -348,6 +365,20 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
348 env->pc = tswapl(registers[68]); 365 env->pc = tswapl(registers[68]);
349 env->npc = tswapl(registers[69]); 366 env->npc = tswapl(registers[69]);
350 env->fsr = tswapl(registers[70]); 367 env->fsr = tswapl(registers[70]);
  368 +#else
  369 + for (i = 0; i < 32; i += 2) {
  370 + uint64_t tmp;
  371 + tmp = tswapl(registers[i/2 + 64]) << 32;
  372 + tmp |= tswapl(registers[i/2 + 64 + 1]);
  373 + *((uint64_t *)&env->fpr[i]) = tmp;
  374 + }
  375 + env->pc = tswapl(registers[81]);
  376 + env->npc = tswapl(registers[82]);
  377 + env->tstate[env->tl] = tswapl(registers[83]);
  378 + env->fsr = tswapl(registers[84]);
  379 + env->fprs = tswapl(registers[85]);
  380 + env->y = tswapl(registers[86]);
  381 +#endif
351 } 382 }
352 #elif defined (TARGET_ARM) 383 #elif defined (TARGET_ARM)
353 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) 384 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
hw/elf_ops.h 0 โ†’ 100644
  1 +#ifdef BSWAP_NEEDED
  2 +static void glue(bswap_ehdr, SZ)(struct elfhdr *ehdr)
  3 +{
  4 + bswap16s(&ehdr->e_type); /* Object file type */
  5 + bswap16s(&ehdr->e_machine); /* Architecture */
  6 + bswap32s(&ehdr->e_version); /* Object file version */
  7 + bswapSZs(&ehdr->e_entry); /* Entry point virtual address */
  8 + bswapSZs(&ehdr->e_phoff); /* Program header table file offset */
  9 + bswapSZs(&ehdr->e_shoff); /* Section header table file offset */
  10 + bswap32s(&ehdr->e_flags); /* Processor-specific flags */
  11 + bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */
  12 + bswap16s(&ehdr->e_phentsize); /* Program header table entry size */
  13 + bswap16s(&ehdr->e_phnum); /* Program header table entry count */
  14 + bswap16s(&ehdr->e_shentsize); /* Section header table entry size */
  15 + bswap16s(&ehdr->e_shnum); /* Section header table entry count */
  16 + bswap16s(&ehdr->e_shstrndx); /* Section header string table index */
  17 +}
  18 +
  19 +static void glue(bswap_phdr, SZ)(struct elf_phdr *phdr)
  20 +{
  21 + bswap32s(&phdr->p_type); /* Segment type */
  22 + bswapSZs(&phdr->p_offset); /* Segment file offset */
  23 + bswapSZs(&phdr->p_vaddr); /* Segment virtual address */
  24 + bswapSZs(&phdr->p_paddr); /* Segment physical address */
  25 + bswapSZs(&phdr->p_filesz); /* Segment size in file */
  26 + bswapSZs(&phdr->p_memsz); /* Segment size in memory */
  27 + bswap32s(&phdr->p_flags); /* Segment flags */
  28 + bswapSZs(&phdr->p_align); /* Segment alignment */
  29 +}
  30 +
  31 +static void glue(bswap_shdr, SZ)(struct elf_shdr *shdr)
  32 +{
  33 + bswap32s(&shdr->sh_name);
  34 + bswap32s(&shdr->sh_type);
  35 + bswapSZs(&shdr->sh_flags);
  36 + bswapSZs(&shdr->sh_addr);
  37 + bswapSZs(&shdr->sh_offset);
  38 + bswapSZs(&shdr->sh_size);
  39 + bswap32s(&shdr->sh_link);
  40 + bswap32s(&shdr->sh_info);
  41 + bswapSZs(&shdr->sh_addralign);
  42 + bswapSZs(&shdr->sh_entsize);
  43 +}
  44 +
  45 +static void glue(bswap_sym, SZ)(struct elf_sym *sym)
  46 +{
  47 + bswap32s(&sym->st_name);
  48 + bswapSZs(&sym->st_value);
  49 + bswapSZs(&sym->st_size);
  50 + bswap16s(&sym->st_shndx);
  51 +}
  52 +#endif
  53 +
  54 +static int glue(find_phdr, SZ)(struct elfhdr *ehdr, int fd, struct elf_phdr *phdr, elf_word type)
  55 +{
  56 + int i, retval;
  57 +
  58 + retval = lseek(fd, ehdr->e_phoff, SEEK_SET);
  59 + if (retval < 0)
  60 + return -1;
  61 +
  62 + for (i = 0; i < ehdr->e_phnum; i++) {
  63 + retval = read(fd, phdr, sizeof(*phdr));
  64 + if (retval < 0)
  65 + return -1;
  66 + glue(bswap_phdr, SZ)(phdr);
  67 + if (phdr->p_type == type)
  68 + return 0;
  69 + }
  70 + return -1;
  71 +}
  72 +
  73 +static void * glue(find_shdr, SZ)(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, elf_word type)
  74 +{
  75 + int i, retval;
  76 +
  77 + retval = lseek(fd, ehdr->e_shoff, SEEK_SET);
  78 + if (retval < 0)
  79 + return NULL;
  80 +
  81 + for (i = 0; i < ehdr->e_shnum; i++) {
  82 + retval = read(fd, shdr, sizeof(*shdr));
  83 + if (retval < 0)
  84 + return NULL;
  85 + glue(bswap_shdr, SZ)(shdr);
  86 + if (shdr->sh_type == type)
  87 + return qemu_malloc(shdr->sh_size);
  88 + }
  89 + return NULL;
  90 +}
  91 +
  92 +static void * glue(find_strtab, SZ)(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab)
  93 +{
  94 + int retval;
  95 +
  96 + retval = lseek(fd, ehdr->e_shoff + sizeof(struct elf_shdr) * symtab->sh_link, SEEK_SET);
  97 + if (retval < 0)
  98 + return NULL;
  99 +
  100 + retval = read(fd, shdr, sizeof(*shdr));
  101 + if (retval < 0)
  102 + return NULL;
  103 + glue(bswap_shdr, SZ)(shdr);
  104 + if (shdr->sh_type == SHT_STRTAB)
  105 + return qemu_malloc(shdr->sh_size);;
  106 + return NULL;
  107 +}
  108 +
  109 +static int glue(read_program, SZ)(int fd, struct elf_phdr *phdr, void *dst, elf_word entry)
  110 +{
  111 + int retval;
  112 + retval = lseek(fd, phdr->p_offset + entry - phdr->p_vaddr, SEEK_SET);
  113 + if (retval < 0)
  114 + return -1;
  115 + return read(fd, dst, phdr->p_filesz);
  116 +}
  117 +
  118 +static int glue(read_section, SZ)(int fd, struct elf_shdr *s, void *dst)
  119 +{
  120 + int retval;
  121 +
  122 + retval = lseek(fd, s->sh_offset, SEEK_SET);
  123 + if (retval < 0)
  124 + return -1;
  125 + retval = read(fd, dst, s->sh_size);
  126 + if (retval < 0)
  127 + return -1;
  128 + return 0;
  129 +}
  130 +
  131 +static void * glue(process_section, SZ)(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, elf_word type)
  132 +{
  133 + void *dst;
  134 +
  135 + dst = glue(find_shdr, SZ)(ehdr, fd, shdr, type);
  136 + if (!dst)
  137 + goto error;
  138 +
  139 + if (glue(read_section, SZ)(fd, shdr, dst))
  140 + goto error;
  141 + return dst;
  142 + error:
  143 + qemu_free(dst);
  144 + return NULL;
  145 +}
  146 +
  147 +static void * glue(process_strtab, SZ)(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab)
  148 +{
  149 + void *dst;
  150 +
  151 + dst = glue(find_strtab, SZ)(ehdr, fd, shdr, symtab);
  152 + if (!dst)
  153 + goto error;
  154 +
  155 + if (glue(read_section, SZ)(fd, shdr, dst))
  156 + goto error;
  157 + return dst;
  158 + error:
  159 + qemu_free(dst);
  160 + return NULL;
  161 +}
  162 +
  163 +static void glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd)
  164 +{
  165 + struct elf_shdr symtab, strtab;
  166 + struct elf_sym *syms;
  167 +#if (SZ == 64)
  168 + struct elf32_sym *syms32;
  169 +#endif
  170 + struct syminfo *s;
  171 + int nsyms, i;
  172 + char *str;
  173 +
  174 + /* Symbol table */
  175 + syms = glue(process_section, SZ)(ehdr, fd, &symtab, SHT_SYMTAB);
  176 + if (!syms)
  177 + return;
  178 +
  179 + nsyms = symtab.sh_size / sizeof(struct elf_sym);
  180 +#if (SZ == 64)
  181 + syms32 = qemu_mallocz(nsyms * sizeof(struct elf32_sym));
  182 +#endif
  183 + for (i = 0; i < nsyms; i++) {
  184 + glue(bswap_sym, SZ)(&syms[i]);
  185 +#if (SZ == 64)
  186 + syms32[i].st_name = syms[i].st_name;
  187 + syms32[i].st_info = syms[i].st_info;
  188 + syms32[i].st_other = syms[i].st_other;
  189 + syms32[i].st_shndx = syms[i].st_shndx;
  190 + syms32[i].st_value = syms[i].st_value & 0xffffffff;
  191 + syms32[i].st_size = syms[i].st_size & 0xffffffff;
  192 +#endif
  193 + }
  194 + /* String table */
  195 + str = glue(process_strtab, SZ)(ehdr, fd, &strtab, &symtab);
  196 + if (!str)
  197 + goto error_freesyms;
  198 +
  199 + /* Commit */
  200 + s = qemu_mallocz(sizeof(*s));
  201 +#if (SZ == 64)
  202 + s->disas_symtab = syms32;
  203 + qemu_free(syms);
  204 +#else
  205 + s->disas_symtab = syms;
  206 +#endif
  207 + s->disas_num_syms = nsyms;
  208 + s->disas_strtab = str;
  209 + s->next = syminfos;
  210 + syminfos = s;
  211 + return;
  212 + error_freesyms:
  213 +#if (SZ == 64)
  214 + qemu_free(syms32);
  215 +#endif
  216 + qemu_free(syms);
  217 + return;
  218 +}
hw/magic-load.c
@@ -56,213 +56,49 @@ static void bswap_ahdr(struct exec *e) @@ -56,213 +56,49 @@ static void bswap_ahdr(struct exec *e)
56 56
57 #include "elf.h" 57 #include "elf.h"
58 58
59 -#ifdef BSWAP_NEEDED  
60 -static void bswap_ehdr(Elf32_Ehdr *ehdr)  
61 -{  
62 - bswap16s(&ehdr->e_type); /* Object file type */  
63 - bswap16s(&ehdr->e_machine); /* Architecture */  
64 - bswap32s(&ehdr->e_version); /* Object file version */  
65 - bswap32s(&ehdr->e_entry); /* Entry point virtual address */  
66 - bswap32s(&ehdr->e_phoff); /* Program header table file offset */  
67 - bswap32s(&ehdr->e_shoff); /* Section header table file offset */  
68 - bswap32s(&ehdr->e_flags); /* Processor-specific flags */  
69 - bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */  
70 - bswap16s(&ehdr->e_phentsize); /* Program header table entry size */  
71 - bswap16s(&ehdr->e_phnum); /* Program header table entry count */  
72 - bswap16s(&ehdr->e_shentsize); /* Section header table entry size */  
73 - bswap16s(&ehdr->e_shnum); /* Section header table entry count */  
74 - bswap16s(&ehdr->e_shstrndx); /* Section header string table index */  
75 -}  
76 -  
77 -static void bswap_phdr(Elf32_Phdr *phdr)  
78 -{  
79 - bswap32s(&phdr->p_type); /* Segment type */  
80 - bswap32s(&phdr->p_offset); /* Segment file offset */  
81 - bswap32s(&phdr->p_vaddr); /* Segment virtual address */  
82 - bswap32s(&phdr->p_paddr); /* Segment physical address */  
83 - bswap32s(&phdr->p_filesz); /* Segment size in file */  
84 - bswap32s(&phdr->p_memsz); /* Segment size in memory */  
85 - bswap32s(&phdr->p_flags); /* Segment flags */  
86 - bswap32s(&phdr->p_align); /* Segment alignment */  
87 -}  
88 -  
89 -static void bswap_shdr(Elf32_Shdr *shdr)  
90 -{  
91 - bswap32s(&shdr->sh_name);  
92 - bswap32s(&shdr->sh_type);  
93 - bswap32s(&shdr->sh_flags);  
94 - bswap32s(&shdr->sh_addr);  
95 - bswap32s(&shdr->sh_offset);  
96 - bswap32s(&shdr->sh_size);  
97 - bswap32s(&shdr->sh_link);  
98 - bswap32s(&shdr->sh_info);  
99 - bswap32s(&shdr->sh_addralign);  
100 - bswap32s(&shdr->sh_entsize);  
101 -}  
102 -  
103 -static void bswap_sym(Elf32_Sym *sym)  
104 -{  
105 - bswap32s(&sym->st_name);  
106 - bswap32s(&sym->st_value);  
107 - bswap32s(&sym->st_size);  
108 - bswap16s(&sym->st_shndx);  
109 -}  
110 -#else  
111 -#define bswap_ehdr(e) do { } while (0)  
112 -#define bswap_phdr(e) do { } while (0)  
113 -#define bswap_shdr(e) do { } while (0)  
114 -#define bswap_sym(e) do { } while (0) 59 +#ifndef BSWAP_NEEDED
  60 +#define bswap_ehdr32(e) do { } while (0)
  61 +#define bswap_phdr32(e) do { } while (0)
  62 +#define bswap_shdr32(e) do { } while (0)
  63 +#define bswap_sym32(e) do { } while (0)
  64 +#ifdef TARGET_SPARC64
  65 +#define bswap_ehdr64(e) do { } while (0)
  66 +#define bswap_phdr64(e) do { } while (0)
  67 +#define bswap_shdr64(e) do { } while (0)
  68 +#define bswap_sym64(e) do { } while (0)
  69 +#endif
115 #endif 70 #endif
116 71
117 -static int find_phdr(struct elfhdr *ehdr, int fd, struct elf_phdr *phdr, uint32_t type)  
118 -{  
119 - int i, retval;  
120 -  
121 - retval = lseek(fd, ehdr->e_phoff, SEEK_SET);  
122 - if (retval < 0)  
123 - return -1;  
124 -  
125 - for (i = 0; i < ehdr->e_phnum; i++) {  
126 - retval = read(fd, phdr, sizeof(*phdr));  
127 - if (retval < 0)  
128 - return -1;  
129 - bswap_phdr(phdr);  
130 - if (phdr->p_type == type)  
131 - return 0;  
132 - }  
133 - return -1;  
134 -}  
135 -  
136 -static void *find_shdr(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, uint32_t type)  
137 -{  
138 - int i, retval;  
139 -  
140 - retval = lseek(fd, ehdr->e_shoff, SEEK_SET);  
141 - if (retval < 0)  
142 - return NULL;  
143 -  
144 - for (i = 0; i < ehdr->e_shnum; i++) {  
145 - retval = read(fd, shdr, sizeof(*shdr));  
146 - if (retval < 0)  
147 - return NULL;  
148 - bswap_shdr(shdr);  
149 - if (shdr->sh_type == type)  
150 - return qemu_malloc(shdr->sh_size);  
151 - }  
152 - return NULL;  
153 -}  
154 -  
155 -static void *find_strtab(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab)  
156 -{  
157 - int retval;  
158 -  
159 - retval = lseek(fd, ehdr->e_shoff + sizeof(struct elf_shdr) * symtab->sh_link, SEEK_SET);  
160 - if (retval < 0)  
161 - return NULL;  
162 -  
163 - retval = read(fd, shdr, sizeof(*shdr));  
164 - if (retval < 0)  
165 - return NULL;  
166 - bswap_shdr(shdr);  
167 - if (shdr->sh_type == SHT_STRTAB)  
168 - return qemu_malloc(shdr->sh_size);;  
169 - return NULL;  
170 -}  
171 -  
172 -static int read_program(int fd, struct elf_phdr *phdr, void *dst, uint32_t entry)  
173 -{  
174 - int retval;  
175 - retval = lseek(fd, phdr->p_offset + entry - phdr->p_vaddr, SEEK_SET);  
176 - if (retval < 0)  
177 - return -1;  
178 - return read(fd, dst, phdr->p_filesz);  
179 -}  
180 -  
181 -static int read_section(int fd, struct elf_shdr *s, void *dst)  
182 -{  
183 - int retval;  
184 -  
185 - retval = lseek(fd, s->sh_offset, SEEK_SET);  
186 - if (retval < 0)  
187 - return -1;  
188 - retval = read(fd, dst, s->sh_size);  
189 - if (retval < 0)  
190 - return -1;  
191 - return 0;  
192 -}  
193 -  
194 -static void *process_section(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, uint32_t type)  
195 -{  
196 - void *dst;  
197 -  
198 - dst = find_shdr(ehdr, fd, shdr, type);  
199 - if (!dst)  
200 - goto error;  
201 -  
202 - if (read_section(fd, shdr, dst))  
203 - goto error;  
204 - return dst;  
205 - error:  
206 - qemu_free(dst);  
207 - return NULL;  
208 -}  
209 -  
210 -static void *process_strtab(struct elfhdr *ehdr, int fd, struct elf_shdr *shdr, struct elf_shdr *symtab)  
211 -{  
212 - void *dst;  
213 -  
214 - dst = find_strtab(ehdr, fd, shdr, symtab);  
215 - if (!dst)  
216 - goto error;  
217 -  
218 - if (read_section(fd, shdr, dst))  
219 - goto error;  
220 - return dst;  
221 - error:  
222 - qemu_free(dst);  
223 - return NULL;  
224 -}  
225 -  
226 -static void load_symbols(struct elfhdr *ehdr, int fd)  
227 -{  
228 - struct elf_shdr symtab, strtab;  
229 - struct elf_sym *syms;  
230 - struct syminfo *s;  
231 - int nsyms, i;  
232 - char *str;  
233 -  
234 - /* Symbol table */  
235 - syms = process_section(ehdr, fd, &symtab, SHT_SYMTAB);  
236 - if (!syms)  
237 - return;  
238 -  
239 - nsyms = symtab.sh_size / sizeof(struct elf_sym);  
240 - for (i = 0; i < nsyms; i++)  
241 - bswap_sym(&syms[i]);  
242 -  
243 - /* String table */  
244 - str = process_strtab(ehdr, fd, &strtab, &symtab);  
245 - if (!str)  
246 - goto error_freesyms;  
247 -  
248 - /* Commit */  
249 - s = qemu_mallocz(sizeof(*s));  
250 - s->disas_symtab = syms;  
251 - s->disas_num_syms = nsyms;  
252 - s->disas_strtab = str;  
253 - s->next = syminfos;  
254 - syminfos = s;  
255 - return;  
256 - error_freesyms:  
257 - qemu_free(syms);  
258 - return;  
259 -} 72 +#define SZ 32
  73 +#define elf_word uint32_t
  74 +#define bswapSZs bswap32s
  75 +#include "elf_ops.h"
  76 +
  77 +#ifdef TARGET_SPARC64
  78 +#undef elfhdr
  79 +#undef elf_phdr
  80 +#undef elf_shdr
  81 +#undef elf_sym
  82 +#undef elf_note
  83 +#undef elf_word
  84 +#undef bswapSZs
  85 +#undef SZ
  86 +#define elfhdr elf64_hdr
  87 +#define elf_phdr elf64_phdr
  88 +#define elf_note elf64_note
  89 +#define elf_shdr elf64_shdr
  90 +#define elf_sym elf64_sym
  91 +#define elf_word uint64_t
  92 +#define bswapSZs bswap64s
  93 +#define SZ 64
  94 +#include "elf_ops.h"
  95 +#endif
260 96
261 int load_elf(const char *filename, uint8_t *addr) 97 int load_elf(const char *filename, uint8_t *addr)
262 { 98 {
263 - struct elfhdr ehdr;  
264 - struct elf_phdr phdr; 99 + struct elf32_hdr ehdr;
265 int retval, fd; 100 int retval, fd;
  101 + Elf32_Half machine;
266 102
267 fd = open(filename, O_RDONLY | O_BINARY); 103 fd = open(filename, O_RDONLY | O_BINARY);
268 if (fd < 0) 104 if (fd < 0)
@@ -272,21 +108,43 @@ int load_elf(const char *filename, uint8_t *addr) @@ -272,21 +108,43 @@ int load_elf(const char *filename, uint8_t *addr)
272 if (retval < 0) 108 if (retval < 0)
273 goto error; 109 goto error;
274 110
275 - bswap_ehdr(&ehdr);  
276 -  
277 if (ehdr.e_ident[0] != 0x7f || ehdr.e_ident[1] != 'E' 111 if (ehdr.e_ident[0] != 0x7f || ehdr.e_ident[1] != 'E'
278 - || ehdr.e_ident[2] != 'L' || ehdr.e_ident[3] != 'F'  
279 - || (ehdr.e_machine != EM_SPARC  
280 - && ehdr.e_machine != EM_SPARC32PLUS)) 112 + || ehdr.e_ident[2] != 'L' || ehdr.e_ident[3] != 'F')
281 goto error; 113 goto error;
  114 + machine = tswap16(ehdr.e_machine);
  115 + if (machine == EM_SPARC || machine == EM_SPARC32PLUS) {
  116 + struct elf32_phdr phdr;
282 117
283 - if (find_phdr(&ehdr, fd, &phdr, PT_LOAD))  
284 - goto error;  
285 - retval = read_program(fd, &phdr, addr, ehdr.e_entry);  
286 - if (retval < 0)  
287 - goto error; 118 + bswap_ehdr32(&ehdr);
288 119
289 - load_symbols(&ehdr, fd); 120 + if (find_phdr32(&ehdr, fd, &phdr, PT_LOAD))
  121 + goto error;
  122 + retval = read_program32(fd, &phdr, addr, ehdr.e_entry);
  123 + if (retval < 0)
  124 + goto error;
  125 + load_symbols32(&ehdr, fd);
  126 + }
  127 +#ifdef TARGET_SPARC64
  128 + else if (machine == EM_SPARCV9) {
  129 + struct elf64_hdr ehdr64;
  130 + struct elf64_phdr phdr;
  131 +
  132 + lseek(fd, 0, SEEK_SET);
  133 +
  134 + retval = read(fd, &ehdr64, sizeof(ehdr64));
  135 + if (retval < 0)
  136 + goto error;
  137 +
  138 + bswap_ehdr64(&ehdr64);
  139 +
  140 + if (find_phdr64(&ehdr64, fd, &phdr, PT_LOAD))
  141 + goto error;
  142 + retval = read_program64(fd, &phdr, addr, ehdr64.e_entry);
  143 + if (retval < 0)
  144 + goto error;
  145 + load_symbols64(&ehdr64, fd);
  146 + }
  147 +#endif
290 148
291 close(fd); 149 close(fd);
292 return retval; 150 return retval;
hw/slavio_intctl.c
@@ -144,14 +144,14 @@ static void slavio_intctlm_mem_writel(void *opaque, target_phys_addr_t addr, uin @@ -144,14 +144,14 @@ static void slavio_intctlm_mem_writel(void *opaque, target_phys_addr_t addr, uin
144 switch (saddr) { 144 switch (saddr) {
145 case 2: // clear (enable) 145 case 2: // clear (enable)
146 // Force clear unused bits 146 // Force clear unused bits
147 - val &= ~0x7fb2007f; 147 + val &= ~0x4fb2007f;
148 s->intregm_disabled &= ~val; 148 s->intregm_disabled &= ~val;
149 DPRINTF("Enabled master irq mask %x, curmask %x\n", val, s->intregm_disabled); 149 DPRINTF("Enabled master irq mask %x, curmask %x\n", val, s->intregm_disabled);
150 slavio_check_interrupts(s); 150 slavio_check_interrupts(s);
151 break; 151 break;
152 case 3: // set (disable, clear pending) 152 case 3: // set (disable, clear pending)
153 // Force clear unused bits 153 // Force clear unused bits
154 - val &= ~0x7fb2007f; 154 + val &= ~0x4fb2007f;
155 s->intregm_disabled |= val; 155 s->intregm_disabled |= val;
156 s->intregm_pending &= ~val; 156 s->intregm_pending &= ~val;
157 DPRINTF("Disabled master irq mask %x, curmask %x\n", val, s->intregm_disabled); 157 DPRINTF("Disabled master irq mask %x, curmask %x\n", val, s->intregm_disabled);
@@ -208,7 +208,7 @@ void slavio_irq_info(void *opaque) @@ -208,7 +208,7 @@ void slavio_irq_info(void *opaque)
208 208
209 static const uint32_t intbit_to_level[32] = { 209 static const uint32_t intbit_to_level[32] = {
210 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12, 210 2, 3, 5, 7, 9, 11, 0, 14, 3, 5, 7, 9, 11, 13, 12, 12,
211 - 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 0, 0, 211 + 6, 0, 4, 10, 8, 0, 11, 0, 0, 0, 0, 0, 15, 0, 15, 0,
212 }; 212 };
213 213
214 static void slavio_check_interrupts(void *opaque) 214 static void slavio_check_interrupts(void *opaque)
hw/slavio_misc.c 0 โ†’ 100644
  1 +/*
  2 + * QEMU Sparc SLAVIO aux io port emulation
  3 + *
  4 + * Copyright (c) 2005 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#include "vl.h"
  25 +/* debug misc */
  26 +//#define DEBUG_MISC
  27 +
  28 +/*
  29 + * This is the auxio port, chip control and system control part of
  30 + * chip STP2001 (Slave I/O), also produced as NCR89C105. See
  31 + * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
  32 + *
  33 + * This also includes the PMC CPU idle controller.
  34 + */
  35 +
  36 +#ifdef DEBUG_MISC
  37 +#define MISC_DPRINTF(fmt, args...) \
  38 +do { printf("MISC: " fmt , ##args); } while (0)
  39 +#else
  40 +#define MISC_DPRINTF(fmt, args...)
  41 +#endif
  42 +
  43 +typedef struct MiscState {
  44 + int irq;
  45 + uint8_t config;
  46 + uint8_t aux1, aux2;
  47 + uint8_t diag, mctrl;
  48 +} MiscState;
  49 +
  50 +#define MISC_MAXADDR 1
  51 +
  52 +static void slavio_misc_update_irq(void *opaque)
  53 +{
  54 + MiscState *s = opaque;
  55 +
  56 + if ((s->aux2 & 0x4) && (s->config & 0x8)) {
  57 + pic_set_irq(s->irq, 1);
  58 + } else {
  59 + pic_set_irq(s->irq, 0);
  60 + }
  61 +}
  62 +
  63 +static void slavio_misc_reset(void *opaque)
  64 +{
  65 + MiscState *s = opaque;
  66 +
  67 + // Diagnostic register not cleared in reset
  68 + s->config = s->aux1 = s->aux2 = s->mctrl = 0;
  69 +}
  70 +
  71 +void slavio_set_power_fail(void *opaque, int power_failing)
  72 +{
  73 + MiscState *s = opaque;
  74 +
  75 + MISC_DPRINTF("Power fail: %d, config: %d\n", power_failing, s->config);
  76 + if (power_failing && (s->config & 0x8)) {
  77 + s->aux2 |= 0x4;
  78 + } else {
  79 + s->aux2 &= ~0x4;
  80 + }
  81 + slavio_misc_update_irq(s);
  82 +}
  83 +
  84 +static void slavio_misc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
  85 +{
  86 + MiscState *s = opaque;
  87 +
  88 + switch (addr & 0xfff0000) {
  89 + case 0x1800000:
  90 + MISC_DPRINTF("Write config %2.2x\n", val & 0xff);
  91 + s->config = val & 0xff;
  92 + slavio_misc_update_irq(s);
  93 + break;
  94 + case 0x1900000:
  95 + MISC_DPRINTF("Write aux1 %2.2x\n", val & 0xff);
  96 + s->aux1 = val & 0xff;
  97 + break;
  98 + case 0x1910000:
  99 + val &= 0x3;
  100 + MISC_DPRINTF("Write aux2 %2.2x\n", val);
  101 + val |= s->aux2 & 0x4;
  102 + if (val & 0x2) // Clear Power Fail int
  103 + val &= 0x1;
  104 + s->aux2 = val;
  105 + if (val & 1)
  106 + qemu_system_shutdown_request();
  107 + slavio_misc_update_irq(s);
  108 + break;
  109 + case 0x1a00000:
  110 + MISC_DPRINTF("Write diag %2.2x\n", val & 0xff);
  111 + s->diag = val & 0xff;
  112 + break;
  113 + case 0x1b00000:
  114 + MISC_DPRINTF("Write modem control %2.2x\n", val & 0xff);
  115 + s->mctrl = val & 0xff;
  116 + break;
  117 + case 0x1f00000:
  118 + MISC_DPRINTF("Write system control %2.2x\n", val & 0xff);
  119 + if (val & 1)
  120 + qemu_system_reset_request();
  121 + break;
  122 + case 0xa000000:
  123 + MISC_DPRINTF("Write power management %2.2x\n", val & 0xff);
  124 +#if 0
  125 + // XXX: halting CPU does not work
  126 + raise_exception(EXCP_HLT);
  127 + cpu_loop_exit();
  128 +#endif
  129 + break;
  130 + }
  131 +}
  132 +
  133 +static uint32_t slavio_misc_mem_readb(void *opaque, target_phys_addr_t addr)
  134 +{
  135 + MiscState *s = opaque;
  136 + uint32_t ret = 0;
  137 +
  138 + switch (addr & 0xfff0000) {
  139 + case 0x1800000:
  140 + ret = s->config;
  141 + MISC_DPRINTF("Read config %2.2x\n", ret);
  142 + break;
  143 + case 0x1900000:
  144 + ret = s->aux1;
  145 + MISC_DPRINTF("Read aux1 %2.2x\n", ret);
  146 + break;
  147 + case 0x1910000:
  148 + ret = s->aux2;
  149 + MISC_DPRINTF("Read aux2 %2.2x\n", ret);
  150 + break;
  151 + case 0x1a00000:
  152 + ret = s->diag;
  153 + MISC_DPRINTF("Read diag %2.2x\n", ret);
  154 + break;
  155 + case 0x1b00000:
  156 + ret = s->mctrl;
  157 + MISC_DPRINTF("Read modem control %2.2x\n", ret);
  158 + break;
  159 + case 0x1f00000:
  160 + MISC_DPRINTF("Read system control %2.2x\n", ret);
  161 + break;
  162 + case 0xa000000:
  163 + MISC_DPRINTF("Read power management %2.2x\n", ret);
  164 + break;
  165 + }
  166 + return ret;
  167 +}
  168 +
  169 +static CPUReadMemoryFunc *slavio_misc_mem_read[3] = {
  170 + slavio_misc_mem_readb,
  171 + slavio_misc_mem_readb,
  172 + slavio_misc_mem_readb,
  173 +};
  174 +
  175 +static CPUWriteMemoryFunc *slavio_misc_mem_write[3] = {
  176 + slavio_misc_mem_writeb,
  177 + slavio_misc_mem_writeb,
  178 + slavio_misc_mem_writeb,
  179 +};
  180 +
  181 +static void slavio_misc_save(QEMUFile *f, void *opaque)
  182 +{
  183 + MiscState *s = opaque;
  184 +
  185 + qemu_put_be32s(f, &s->irq);
  186 + qemu_put_8s(f, &s->config);
  187 + qemu_put_8s(f, &s->aux1);
  188 + qemu_put_8s(f, &s->aux2);
  189 + qemu_put_8s(f, &s->diag);
  190 + qemu_put_8s(f, &s->mctrl);
  191 +}
  192 +
  193 +static int slavio_misc_load(QEMUFile *f, void *opaque, int version_id)
  194 +{
  195 + MiscState *s = opaque;
  196 +
  197 + if (version_id != 1)
  198 + return -EINVAL;
  199 +
  200 + qemu_get_be32s(f, &s->irq);
  201 + qemu_get_8s(f, &s->config);
  202 + qemu_get_8s(f, &s->aux1);
  203 + qemu_get_8s(f, &s->aux2);
  204 + qemu_get_8s(f, &s->diag);
  205 + qemu_get_8s(f, &s->mctrl);
  206 + return 0;
  207 +}
  208 +
  209 +void *slavio_misc_init(uint32_t base, int irq)
  210 +{
  211 + int slavio_misc_io_memory;
  212 + MiscState *s;
  213 +
  214 + s = qemu_mallocz(sizeof(MiscState));
  215 + if (!s)
  216 + return NULL;
  217 +
  218 + slavio_misc_io_memory = cpu_register_io_memory(0, slavio_misc_mem_read, slavio_misc_mem_write, s);
  219 + // Slavio control
  220 + cpu_register_physical_memory(base + 0x1800000, MISC_MAXADDR, slavio_misc_io_memory);
  221 + // AUX 1
  222 + cpu_register_physical_memory(base + 0x1900000, MISC_MAXADDR, slavio_misc_io_memory);
  223 + // AUX 2
  224 + cpu_register_physical_memory(base + 0x1910000, MISC_MAXADDR, slavio_misc_io_memory);
  225 + // Diagnostics
  226 + cpu_register_physical_memory(base + 0x1a00000, MISC_MAXADDR, slavio_misc_io_memory);
  227 + // Modem control
  228 + cpu_register_physical_memory(base + 0x1b00000, MISC_MAXADDR, slavio_misc_io_memory);
  229 + // System control
  230 + cpu_register_physical_memory(base + 0x1f00000, MISC_MAXADDR, slavio_misc_io_memory);
  231 + // Power management
  232 + cpu_register_physical_memory(base + 0xa000000, MISC_MAXADDR, slavio_misc_io_memory);
  233 +
  234 + s->irq = irq;
  235 +
  236 + register_savevm("slavio_misc", base, 1, slavio_misc_save, slavio_misc_load, s);
  237 + qemu_register_reset(slavio_misc_reset, s);
  238 + slavio_misc_reset(s);
  239 + return s;
  240 +}
hw/sun4m.c
@@ -37,6 +37,7 @@ @@ -37,6 +37,7 @@
37 // bits 37 // bits
38 #define PHYS_JJ_IOMMU 0x10000000 /* I/O MMU */ 38 #define PHYS_JJ_IOMMU 0x10000000 /* I/O MMU */
39 #define PHYS_JJ_TCX_FB 0x50000000 /* TCX frame buffer */ 39 #define PHYS_JJ_TCX_FB 0x50000000 /* TCX frame buffer */
  40 +#define PHYS_JJ_SLAVIO 0x70000000 /* Slavio base */
40 #define PHYS_JJ_ESPDMA 0x78400000 /* ESP DMA controller */ 41 #define PHYS_JJ_ESPDMA 0x78400000 /* ESP DMA controller */
41 #define PHYS_JJ_ESP 0x78800000 /* ESP SCSI */ 42 #define PHYS_JJ_ESP 0x78800000 /* ESP SCSI */
42 #define PHYS_JJ_ESP_IRQ 18 43 #define PHYS_JJ_ESP_IRQ 18
@@ -55,6 +56,7 @@ @@ -55,6 +56,7 @@
55 #define PHYS_JJ_SER_IRQ 15 56 #define PHYS_JJ_SER_IRQ 15
56 #define PHYS_JJ_FDC 0x71400000 /* Floppy */ 57 #define PHYS_JJ_FDC 0x71400000 /* Floppy */
57 #define PHYS_JJ_FLOPPY_IRQ 22 58 #define PHYS_JJ_FLOPPY_IRQ 22
  59 +#define PHYS_JJ_ME_IRQ 30 /* Module error, power fail */
58 60
59 /* TSC handling */ 61 /* TSC handling */
60 62
@@ -202,6 +204,13 @@ uint32_t iommu_translate(uint32_t addr) @@ -202,6 +204,13 @@ uint32_t iommu_translate(uint32_t addr)
202 return iommu_translate_local(iommu, addr); 204 return iommu_translate_local(iommu, addr);
203 } 205 }
204 206
  207 +static void *slavio_misc;
  208 +
  209 +void qemu_system_powerdown(void)
  210 +{
  211 + slavio_set_power_fail(slavio_misc, 1);
  212 +}
  213 +
205 /* Sun4m hardware initialisation */ 214 /* Sun4m hardware initialisation */
206 static void sun4m_init(int ram_size, int vga_ram_size, int boot_device, 215 static void sun4m_init(int ram_size, int vga_ram_size, int boot_device,
207 DisplayState *ds, const char **fd_filename, int snapshot, 216 DisplayState *ds, const char **fd_filename, int snapshot,
@@ -230,6 +239,7 @@ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device, @@ -230,6 +239,7 @@ static void sun4m_init(int ram_size, int vga_ram_size, int boot_device,
230 slavio_serial_init(PHYS_JJ_SER, PHYS_JJ_SER_IRQ, serial_hds[1], serial_hds[0]); 239 slavio_serial_init(PHYS_JJ_SER, PHYS_JJ_SER_IRQ, serial_hds[1], serial_hds[0]);
231 fdctrl_init(PHYS_JJ_FLOPPY_IRQ, 0, 1, PHYS_JJ_FDC, fd_table); 240 fdctrl_init(PHYS_JJ_FLOPPY_IRQ, 0, 1, PHYS_JJ_FDC, fd_table);
232 esp_init(bs_table, PHYS_JJ_ESP_IRQ, PHYS_JJ_ESP, PHYS_JJ_ESPDMA); 241 esp_init(bs_table, PHYS_JJ_ESP_IRQ, PHYS_JJ_ESP, PHYS_JJ_ESPDMA);
  242 + slavio_misc = slavio_misc_init(PHYS_JJ_SLAVIO, PHYS_JJ_ME_IRQ);
233 243
234 prom_offset = ram_size + vram_size; 244 prom_offset = ram_size + vram_size;
235 245
hw/sun4u.c 0 โ†’ 100644
  1 +/*
  2 + * QEMU Sun4u System Emulator
  3 + *
  4 + * Copyright (c) 2005 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#include "vl.h"
  25 +#include "m48t08.h"
  26 +
  27 +#define KERNEL_LOAD_ADDR 0x00004000
  28 +#define CMDLINE_ADDR 0x007ff000
  29 +#define INITRD_LOAD_ADDR 0x00800000
  30 +#define PROM_ADDR 0xffd00000
  31 +#define PROM_FILENAMEB "proll-sparc64.bin"
  32 +#define PROM_FILENAMEE "proll-sparc64.elf"
  33 +#define PHYS_JJ_EEPROM 0x71200000 /* m48t08 */
  34 +#define PHYS_JJ_IDPROM_OFF 0x1FD8
  35 +#define PHYS_JJ_EEPROM_SIZE 0x2000
  36 +// IRQs are not PIL ones, but master interrupt controller register
  37 +// bits
  38 +#define PHYS_JJ_MS_KBD 0x71000000 /* Mouse and keyboard */
  39 +#define PHYS_JJ_MS_KBD_IRQ 14
  40 +#define PHYS_JJ_SER 0x71100000 /* Serial */
  41 +#define PHYS_JJ_SER_IRQ 15
  42 +
  43 +/* TSC handling */
  44 +
  45 +uint64_t cpu_get_tsc()
  46 +{
  47 + return qemu_get_clock(vm_clock);
  48 +}
  49 +
  50 +int DMA_get_channel_mode (int nchan)
  51 +{
  52 + return 0;
  53 +}
  54 +int DMA_read_memory (int nchan, void *buf, int pos, int size)
  55 +{
  56 + return 0;
  57 +}
  58 +int DMA_write_memory (int nchan, void *buf, int pos, int size)
  59 +{
  60 + return 0;
  61 +}
  62 +void DMA_hold_DREQ (int nchan) {}
  63 +void DMA_release_DREQ (int nchan) {}
  64 +void DMA_schedule(int nchan) {}
  65 +void DMA_run (void) {}
  66 +void DMA_init (int high_page_enable) {}
  67 +void DMA_register_channel (int nchan,
  68 + DMA_transfer_handler transfer_handler,
  69 + void *opaque)
  70 +{
  71 +}
  72 +
  73 +static void nvram_set_word (m48t08_t *nvram, uint32_t addr, uint16_t value)
  74 +{
  75 + m48t08_write(nvram, addr++, (value >> 8) & 0xff);
  76 + m48t08_write(nvram, addr++, value & 0xff);
  77 +}
  78 +
  79 +static void nvram_set_lword (m48t08_t *nvram, uint32_t addr, uint32_t value)
  80 +{
  81 + m48t08_write(nvram, addr++, value >> 24);
  82 + m48t08_write(nvram, addr++, (value >> 16) & 0xff);
  83 + m48t08_write(nvram, addr++, (value >> 8) & 0xff);
  84 + m48t08_write(nvram, addr++, value & 0xff);
  85 +}
  86 +
  87 +static void nvram_set_string (m48t08_t *nvram, uint32_t addr,
  88 + const unsigned char *str, uint32_t max)
  89 +{
  90 + unsigned int i;
  91 +
  92 + for (i = 0; i < max && str[i] != '\0'; i++) {
  93 + m48t08_write(nvram, addr + i, str[i]);
  94 + }
  95 + m48t08_write(nvram, addr + max - 1, '\0');
  96 +}
  97 +
  98 +static m48t08_t *nvram;
  99 +
  100 +extern int nographic;
  101 +
  102 +static void nvram_init(m48t08_t *nvram, uint8_t *macaddr, const char *cmdline,
  103 + int boot_device, uint32_t RAM_size,
  104 + uint32_t kernel_size,
  105 + int width, int height, int depth)
  106 +{
  107 + unsigned char tmp = 0;
  108 + int i, j;
  109 +
  110 + // Try to match PPC NVRAM
  111 + nvram_set_string(nvram, 0x00, "QEMU_BIOS", 16);
  112 + nvram_set_lword(nvram, 0x10, 0x00000001); /* structure v1 */
  113 + // NVRAM_size, arch not applicable
  114 + m48t08_write(nvram, 0x2F, nographic & 0xff);
  115 + nvram_set_lword(nvram, 0x30, RAM_size);
  116 + m48t08_write(nvram, 0x34, boot_device & 0xff);
  117 + nvram_set_lword(nvram, 0x38, KERNEL_LOAD_ADDR);
  118 + nvram_set_lword(nvram, 0x3C, kernel_size);
  119 + if (cmdline) {
  120 + strcpy(phys_ram_base + CMDLINE_ADDR, cmdline);
  121 + nvram_set_lword(nvram, 0x40, CMDLINE_ADDR);
  122 + nvram_set_lword(nvram, 0x44, strlen(cmdline));
  123 + }
  124 + // initrd_image, initrd_size passed differently
  125 + nvram_set_word(nvram, 0x54, width);
  126 + nvram_set_word(nvram, 0x56, height);
  127 + nvram_set_word(nvram, 0x58, depth);
  128 +
  129 + // Sun4m specific use
  130 + i = 0x1fd8;
  131 + m48t08_write(nvram, i++, 0x01);
  132 + m48t08_write(nvram, i++, 0x80); /* Sun4m OBP */
  133 + j = 0;
  134 + m48t08_write(nvram, i++, macaddr[j++]);
  135 + m48t08_write(nvram, i++, macaddr[j++]);
  136 + m48t08_write(nvram, i++, macaddr[j++]);
  137 + m48t08_write(nvram, i++, macaddr[j++]);
  138 + m48t08_write(nvram, i++, macaddr[j++]);
  139 + m48t08_write(nvram, i, macaddr[j]);
  140 +
  141 + /* Calculate checksum */
  142 + for (i = 0x1fd8; i < 0x1fe7; i++) {
  143 + tmp ^= m48t08_read(nvram, i);
  144 + }
  145 + m48t08_write(nvram, 0x1fe7, tmp);
  146 +}
  147 +
  148 +void pic_info()
  149 +{
  150 +}
  151 +
  152 +void irq_info()
  153 +{
  154 +}
  155 +
  156 +void pic_set_irq(int irq, int level)
  157 +{
  158 +}
  159 +
  160 +void vga_update_display()
  161 +{
  162 +}
  163 +
  164 +void vga_invalidate_display()
  165 +{
  166 +}
  167 +
  168 +void vga_screen_dump(const char *filename)
  169 +{
  170 +}
  171 +
  172 +void qemu_system_powerdown(void)
  173 +{
  174 +}
  175 +
  176 +/* Sun4u hardware initialisation */
  177 +static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
  178 + DisplayState *ds, const char **fd_filename, int snapshot,
  179 + const char *kernel_filename, const char *kernel_cmdline,
  180 + const char *initrd_filename)
  181 +{
  182 + char buf[1024];
  183 + int ret, linux_boot;
  184 + unsigned int i;
  185 + long vram_size = 0x100000, prom_offset, initrd_size, kernel_size;
  186 +
  187 + linux_boot = (kernel_filename != NULL);
  188 +
  189 + /* allocate RAM */
  190 + cpu_register_physical_memory(0, ram_size, 0);
  191 +
  192 + nvram = m48t08_init(PHYS_JJ_EEPROM, PHYS_JJ_EEPROM_SIZE);
  193 + // Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
  194 + // Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
  195 + slavio_serial_init(PHYS_JJ_SER, PHYS_JJ_SER_IRQ, serial_hds[1], serial_hds[0]);
  196 +
  197 + prom_offset = ram_size + vram_size;
  198 +
  199 + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEE);
  200 + ret = load_elf(buf, phys_ram_base + prom_offset);
  201 + if (ret < 0) {
  202 + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, PROM_FILENAMEB);
  203 + ret = load_image(buf, phys_ram_base + prom_offset);
  204 + }
  205 + if (ret < 0) {
  206 + fprintf(stderr, "qemu: could not load prom '%s'\n",
  207 + buf);
  208 + exit(1);
  209 + }
  210 + cpu_register_physical_memory(PROM_ADDR, (ret + TARGET_PAGE_SIZE) & TARGET_PAGE_MASK,
  211 + prom_offset | IO_MEM_ROM);
  212 +
  213 + kernel_size = 0;
  214 + if (linux_boot) {
  215 + kernel_size = load_elf(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
  216 + if (kernel_size < 0)
  217 + kernel_size = load_aout(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
  218 + if (kernel_size < 0)
  219 + kernel_size = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
  220 + if (kernel_size < 0) {
  221 + fprintf(stderr, "qemu: could not load kernel '%s'\n",
  222 + kernel_filename);
  223 + exit(1);
  224 + }
  225 +
  226 + /* load initrd */
  227 + initrd_size = 0;
  228 + if (initrd_filename) {
  229 + initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
  230 + if (initrd_size < 0) {
  231 + fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
  232 + initrd_filename);
  233 + exit(1);
  234 + }
  235 + }
  236 + if (initrd_size > 0) {
  237 + for (i = 0; i < 64 * TARGET_PAGE_SIZE; i += TARGET_PAGE_SIZE) {
  238 + if (ldl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i)
  239 + == 0x48647253) { // HdrS
  240 + stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 16, INITRD_LOAD_ADDR);
  241 + stl_raw(phys_ram_base + KERNEL_LOAD_ADDR + i + 20, initrd_size);
  242 + break;
  243 + }
  244 + }
  245 + }
  246 + }
  247 + nvram_init(nvram, (uint8_t *)&nd_table[0].macaddr, kernel_cmdline, boot_device, ram_size, kernel_size, graphic_width, graphic_height, graphic_depth);
  248 +}
  249 +
  250 +QEMUMachine sun4u_machine = {
  251 + "sun4u",
  252 + "Sun4u platform",
  253 + sun4u_init,
  254 +};
linux-user/main.c
@@ -552,6 +552,7 @@ void cpu_loop (CPUSPARCState *env) @@ -552,6 +552,7 @@ void cpu_loop (CPUSPARCState *env)
552 env->pc = env->npc; 552 env->pc = env->npc;
553 env->npc = env->npc + 4; 553 env->npc = env->npc + 4;
554 break; 554 break;
  555 +#ifndef TARGET_SPARC64
555 case TT_WIN_OVF: /* window overflow */ 556 case TT_WIN_OVF: /* window overflow */
556 save_window(env); 557 save_window(env);
557 break; 558 break;
@@ -569,6 +570,9 @@ void cpu_loop (CPUSPARCState *env) @@ -569,6 +570,9 @@ void cpu_loop (CPUSPARCState *env)
569 queue_signal(info.si_signo, &info); 570 queue_signal(info.si_signo, &info);
570 } 571 }
571 break; 572 break;
  573 +#else
  574 + // XXX
  575 +#endif
572 case 0x100: // XXX, why do we get these? 576 case 0x100: // XXX, why do we get these?
573 break; 577 break;
574 case EXCP_DEBUG: 578 case EXCP_DEBUG:
monitor.c
@@ -767,6 +767,11 @@ static void do_system_reset(void) @@ -767,6 +767,11 @@ static void do_system_reset(void)
767 qemu_system_reset_request(); 767 qemu_system_reset_request();
768 } 768 }
769 769
  770 +static void do_system_powerdown(void)
  771 +{
  772 + qemu_system_powerdown_request();
  773 +}
  774 +
770 #if defined(TARGET_I386) 775 #if defined(TARGET_I386)
771 static void print_pte(uint32_t addr, uint32_t pte, uint32_t mask) 776 static void print_pte(uint32_t addr, uint32_t pte, uint32_t mask)
772 { 777 {
@@ -922,6 +927,8 @@ static term_cmd_t term_cmds[] = { @@ -922,6 +927,8 @@ static term_cmd_t term_cmds[] = {
922 "keys", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1')" }, 927 "keys", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1')" },
923 { "system_reset", "", do_system_reset, 928 { "system_reset", "", do_system_reset,
924 "", "reset the system" }, 929 "", "reset the system" },
  930 + { "system_powerdown", "", do_system_powerdown,
  931 + "", "send system power down event" },
925 { "sum", "ii", do_sum, 932 { "sum", "ii", do_sum,
926 "addr size", "compute the checksum of a memory region" }, 933 "addr size", "compute the checksum of a memory region" },
927 { NULL, NULL, }, 934 { NULL, NULL, },
qemu-doc.texi
@@ -42,10 +42,11 @@ For system emulation, the following hardware targets are supported: @@ -42,10 +42,11 @@ For system emulation, the following hardware targets are supported:
42 @item PC (x86 processor) 42 @item PC (x86 processor)
43 @item PREP (PowerPC processor) 43 @item PREP (PowerPC processor)
44 @item PowerMac (PowerPC processor, in progress) 44 @item PowerMac (PowerPC processor, in progress)
45 -@item Sun4m (Sparc processor, in progress) 45 +@item Sun4m (32-bit Sparc processor)
  46 +@item Sun4u (64-bit Sparc processor, in progress)
46 @end itemize 47 @end itemize
47 48
48 -For user emulation, x86, PowerPC, ARM, and SPARC CPUs are supported. 49 +For user emulation, x86, PowerPC, ARM, and Sparc32/64 CPUs are supported.
49 50
50 @chapter Installation 51 @chapter Installation
51 52
@@ -999,15 +1000,15 @@ Set the initial VGA graphic mode. The default is 800x600x15. @@ -999,15 +1000,15 @@ Set the initial VGA graphic mode. The default is 800x600x15.
999 More information is available at 1000 More information is available at
1000 @url{http://jocelyn.mayer.free.fr/qemu-ppc/}. 1001 @url{http://jocelyn.mayer.free.fr/qemu-ppc/}.
1001 1002
1002 -@chapter Sparc System emulator invocation 1003 +@chapter Sparc32 System emulator invocation
1003 1004
1004 Use the executable @file{qemu-system-sparc} to simulate a JavaStation 1005 Use the executable @file{qemu-system-sparc} to simulate a JavaStation
1005 -(sun4m architecture). The emulation is far from complete. 1006 +(sun4m architecture). The emulation is somewhat complete.
1006 1007
1007 QEMU emulates the following sun4m peripherals: 1008 QEMU emulates the following sun4m peripherals:
1008 1009
1009 @itemize @minus 1010 @itemize @minus
1010 -@item 1011 +@item
1011 IOMMU 1012 IOMMU
1012 @item 1013 @item
1013 TCX Frame buffer 1014 TCX Frame buffer
@@ -1016,14 +1017,42 @@ Lance (Am7990) Ethernet @@ -1016,14 +1017,42 @@ Lance (Am7990) Ethernet
1016 @item 1017 @item
1017 Non Volatile RAM M48T08 1018 Non Volatile RAM M48T08
1018 @item 1019 @item
1019 -Slave I/O: timers, interrupt controllers, Zilog serial ports 1020 +Slave I/O: timers, interrupt controllers, Zilog serial ports, keyboard
  1021 +and power/reset logic
  1022 +@item
  1023 +ESP SCSI controller with hard disk and CD-ROM support
  1024 +@item
  1025 +Floppy drive
1020 @end itemize 1026 @end itemize
1021 1027
  1028 +The number of peripherals is fixed in the architecture.
  1029 +
1022 QEMU uses the Proll, a PROM replacement available at 1030 QEMU uses the Proll, a PROM replacement available at
1023 -@url{http://people.redhat.com/zaitcev/linux/}. 1031 +@url{http://people.redhat.com/zaitcev/linux/}. The required
  1032 +QEMU-specific patches are included with the sources.
  1033 +
  1034 +A sample Linux 2.6 series kernel and ram disk image are available on
  1035 +the QEMU web site. Please note that currently neither Linux 2.4
  1036 +series, NetBSD, nor OpenBSD kernels work.
  1037 +
  1038 +@c man begin OPTIONS
  1039 +
  1040 +The following options are specific to the Sparc emulation:
  1041 +
  1042 +@table @option
  1043 +
  1044 +@item -g WxH
  1045 +
  1046 +Set the initial TCX graphic mode. The default is 1024x768.
  1047 +
  1048 +@end table
  1049 +
  1050 +@c man end
  1051 +
  1052 +@chapter Sparc64 System emulator invocation
1024 1053
1025 -A sample Linux kernel and ram disk image are available on the QEMU web  
1026 -site. 1054 +Use the executable @file{qemu-system-sparc64} to simulate a Sun4u machine.
  1055 +The emulator is not usable for anything yet.
1027 1056
1028 @chapter QEMU User space emulator invocation 1057 @chapter QEMU User space emulator invocation
1029 1058
qemu-tech.texi
@@ -138,9 +138,32 @@ FPU and MMU. @@ -138,9 +138,32 @@ FPU and MMU.
138 @itemize 138 @itemize
139 139
140 @item Somewhat complete SPARC V8 emulation, including privileged 140 @item Somewhat complete SPARC V8 emulation, including privileged
141 -instructions, FPU and MMU. 141 +instructions, FPU and MMU. SPARC V9 emulation includes most privileged
  142 +instructions, FPU and I/D MMU, but misses VIS instructions.
142 143
143 -@item Can run some SPARC Linux binaries. 144 +@item Can run some 32-bit SPARC Linux binaries.
  145 +
  146 +@end itemize
  147 +
  148 +Current QEMU limitations:
  149 +
  150 +@itemize
  151 +
  152 +@item Tagged add/subtract instructions are not supported, but they are
  153 +probably not used.
  154 +
  155 +@item IPC syscalls are missing.
  156 +
  157 +@item 128-bit floating point operations are not supported, though none of the
  158 +real CPUs implement them either. FCMPE[SD] are not correctly
  159 +implemented. Floating point exception support is untested.
  160 +
  161 +@item Alignment is not enforced at all.
  162 +
  163 +@item Atomic instructions are not correctly implemented.
  164 +
  165 +@item Sparc64 emulators are not usable for anything yet.
  166 +Address space is limited to first 4 gigabytes.
144 167
145 @end itemize 168 @end itemize
146 169
target-sparc/cpu.h
@@ -6,12 +6,11 @@ @@ -6,12 +6,11 @@
6 #if !defined(TARGET_SPARC64) 6 #if !defined(TARGET_SPARC64)
7 #define TARGET_LONG_BITS 32 7 #define TARGET_LONG_BITS 32
8 #define TARGET_FPREGS 32 8 #define TARGET_FPREGS 32
9 -#define TARGET_FPREG_T float  
10 #else 9 #else
11 #define TARGET_LONG_BITS 64 10 #define TARGET_LONG_BITS 64
12 #define TARGET_FPREGS 64 11 #define TARGET_FPREGS 64
13 -#define TARGET_FPREG_T double  
14 #endif 12 #endif
  13 +#define TARGET_FPREG_T float
15 14
16 #include "cpu-defs.h" 15 #include "cpu-defs.h"
17 16
@@ -22,6 +21,7 @@ @@ -22,6 +21,7 @@
22 /*#define EXCP_INTERRUPT 0x100*/ 21 /*#define EXCP_INTERRUPT 0x100*/
23 22
24 /* trap definitions */ 23 /* trap definitions */
  24 +#ifndef TARGET_SPARC64
25 #define TT_TFAULT 0x01 25 #define TT_TFAULT 0x01
26 #define TT_ILL_INSN 0x02 26 #define TT_ILL_INSN 0x02
27 #define TT_PRIV_INSN 0x03 27 #define TT_PRIV_INSN 0x03
@@ -33,6 +33,21 @@ @@ -33,6 +33,21 @@
33 #define TT_EXTINT 0x10 33 #define TT_EXTINT 0x10
34 #define TT_DIV_ZERO 0x2a 34 #define TT_DIV_ZERO 0x2a
35 #define TT_TRAP 0x80 35 #define TT_TRAP 0x80
  36 +#else
  37 +#define TT_TFAULT 0x08
  38 +#define TT_ILL_INSN 0x10
  39 +#define TT_PRIV_INSN 0x11
  40 +#define TT_NFPU_INSN 0x20
  41 +#define TT_FP_EXCP 0x21
  42 +#define TT_CLRWIN 0x24
  43 +#define TT_DIV_ZERO 0x28
  44 +#define TT_DFAULT 0x30
  45 +#define TT_EXTINT 0x40
  46 +#define TT_SPILL 0x80
  47 +#define TT_FILL 0xc0
  48 +#define TT_WOTHER 0x10
  49 +#define TT_TRAP 0x100
  50 +#endif
36 51
37 #define PSR_NEG (1<<23) 52 #define PSR_NEG (1<<23)
38 #define PSR_ZERO (1<<22) 53 #define PSR_ZERO (1<<22)
@@ -49,6 +64,13 @@ @@ -49,6 +64,13 @@
49 /* Trap base register */ 64 /* Trap base register */
50 #define TBR_BASE_MASK 0xfffff000 65 #define TBR_BASE_MASK 0xfffff000
51 66
  67 +#if defined(TARGET_SPARC64)
  68 +#define PS_PEF (1<<4)
  69 +#define PS_AM (1<<3)
  70 +#define PS_PRIV (1<<2)
  71 +#define PS_IE (1<<1)
  72 +#endif
  73 +
52 /* Fcc */ 74 /* Fcc */
53 #define FSR_RD1 (1<<31) 75 #define FSR_RD1 (1<<31)
54 #define FSR_RD0 (1<<30) 76 #define FSR_RD0 (1<<30)
@@ -119,15 +141,15 @@ typedef struct CPUSPARCState { @@ -119,15 +141,15 @@ typedef struct CPUSPARCState {
119 target_ulong npc; /* next program counter */ 141 target_ulong npc; /* next program counter */
120 target_ulong y; /* multiply/divide register */ 142 target_ulong y; /* multiply/divide register */
121 uint32_t psr; /* processor state register */ 143 uint32_t psr; /* processor state register */
122 - uint32_t fsr; /* FPU state register */ 144 + target_ulong fsr; /* FPU state register */
123 uint32_t cwp; /* index of current register window (extracted 145 uint32_t cwp; /* index of current register window (extracted
124 from PSR) */ 146 from PSR) */
125 uint32_t wim; /* window invalid mask */ 147 uint32_t wim; /* window invalid mask */
126 - uint32_t tbr; /* trap base register */ 148 + target_ulong tbr; /* trap base register */
127 int psrs; /* supervisor mode (extracted from PSR) */ 149 int psrs; /* supervisor mode (extracted from PSR) */
128 int psrps; /* previous supervisor mode */ 150 int psrps; /* previous supervisor mode */
129 int psret; /* enable traps */ 151 int psret; /* enable traps */
130 - int psrpil; /* interrupt level */ 152 + uint32_t psrpil; /* interrupt level */
131 int psref; /* enable fpu */ 153 int psref; /* enable fpu */
132 jmp_buf jmp_env; 154 jmp_buf jmp_env;
133 int user_mode_only; 155 int user_mode_only;
@@ -150,13 +172,43 @@ typedef struct CPUSPARCState { @@ -150,13 +172,43 @@ typedef struct CPUSPARCState {
150 CPUTLBEntry tlb_read[2][CPU_TLB_SIZE]; 172 CPUTLBEntry tlb_read[2][CPU_TLB_SIZE];
151 CPUTLBEntry tlb_write[2][CPU_TLB_SIZE]; 173 CPUTLBEntry tlb_write[2][CPU_TLB_SIZE];
152 /* MMU regs */ 174 /* MMU regs */
  175 +#if defined(TARGET_SPARC64)
  176 + uint64_t lsu;
  177 +#define DMMU_E 0x8
  178 +#define IMMU_E 0x4
  179 + uint64_t immuregs[16];
  180 + uint64_t dmmuregs[16];
  181 + uint64_t itlb_tag[64];
  182 + uint64_t itlb_tte[64];
  183 + uint64_t dtlb_tag[64];
  184 + uint64_t dtlb_tte[64];
  185 +#else
153 uint32_t mmuregs[16]; 186 uint32_t mmuregs[16];
  187 +#endif
154 /* temporary float registers */ 188 /* temporary float registers */
155 - float ft0, ft1, ft2;  
156 - double dt0, dt1, dt2; 189 + float ft0, ft1;
  190 + double dt0, dt1;
157 float_status fp_status; 191 float_status fp_status;
158 #if defined(TARGET_SPARC64) 192 #if defined(TARGET_SPARC64)
159 - target_ulong t0, t1, t2; 193 +#define MAXTL 4
  194 + uint64_t t0, t1, t2;
  195 + uint64_t tpc[MAXTL];
  196 + uint64_t tnpc[MAXTL];
  197 + uint64_t tstate[MAXTL];
  198 + uint32_t tt[MAXTL];
  199 + uint32_t xcc; /* Extended integer condition codes */
  200 + uint32_t asi;
  201 + uint32_t pstate;
  202 + uint32_t tl;
  203 + uint32_t cansave, canrestore, otherwin, wstate, cleanwin;
  204 + target_ulong agregs[8]; /* alternate general registers */
  205 + target_ulong igregs[8]; /* interrupt general registers */
  206 + target_ulong mgregs[8]; /* mmu general registers */
  207 + uint64_t version;
  208 + uint64_t fprs;
  209 +#endif
  210 +#if !defined(TARGET_SPARC64) && !defined(reg_T2)
  211 + target_ulong t2;
160 #endif 212 #endif
161 213
162 /* ice debug support */ 214 /* ice debug support */
@@ -165,6 +217,24 @@ typedef struct CPUSPARCState { @@ -165,6 +217,24 @@ typedef struct CPUSPARCState {
165 int singlestep_enabled; /* XXX: should use CPU single step mode instead */ 217 int singlestep_enabled; /* XXX: should use CPU single step mode instead */
166 218
167 } CPUSPARCState; 219 } CPUSPARCState;
  220 +#if defined(TARGET_SPARC64)
  221 +#define GET_FSR32(env) (env->fsr & 0xcfc1ffff)
  222 +#define PUT_FSR32(env, val) do { uint32_t _tmp = val; \
  223 + env->fsr = (_tmp & 0xcfc1c3ff) | (env->fsr & 0x3f00000000ULL); \
  224 + } while (0)
  225 +#define GET_FSR64(env) (env->fsr & 0x3fcfc1ffffULL)
  226 +#define PUT_FSR64(env, val) do { uint64_t _tmp = val; \
  227 + env->fsr = _tmp & 0x3fcfc1c3ffULL; \
  228 + } while (0)
  229 +// Manuf 0x17, version 0x11, mask 0 (UltraSparc-II)
  230 +#define GET_VER(env) ((0x17ULL << 48) | (0x11ULL << 32) | \
  231 + (0 << 24) | (MAXTL << 8) | (NWINDOWS - 1))
  232 +#else
  233 +#define GET_FSR32(env) (env->fsr)
  234 +#define PUT_FSR32(env, val) do { uint32_t _tmp = val; \
  235 + env->fsr = _tmp & 0xcfc1ffff; \
  236 + } while (0)
  237 +#endif
168 238
169 CPUSPARCState *cpu_sparc_init(void); 239 CPUSPARCState *cpu_sparc_init(void);
170 int cpu_sparc_exec(CPUSPARCState *s); 240 int cpu_sparc_exec(CPUSPARCState *s);
@@ -194,6 +264,14 @@ void cpu_set_cwp(CPUSPARCState *env1, int new_cwp); @@ -194,6 +264,14 @@ void cpu_set_cwp(CPUSPARCState *env1, int new_cwp);
194 cpu_set_cwp(env, _tmp & PSR_CWP & (NWINDOWS - 1)); \ 264 cpu_set_cwp(env, _tmp & PSR_CWP & (NWINDOWS - 1)); \
195 } while (0) 265 } while (0)
196 266
  267 +#ifdef TARGET_SPARC64
  268 +#define GET_CCR(env) ((env->xcc << 4) | (env->psr & PSR_ICC))
  269 +#define PUT_CCR(env, val) do { int _tmp = val; \
  270 + env->xcc = _tmp >> 4; \
  271 + env->psr = (_tmp & 0xf) << 20; \
  272 + } while (0)
  273 +#endif
  274 +
197 struct siginfo; 275 struct siginfo;
198 int cpu_sparc_signal_handler(int hostsignum, struct siginfo *info, void *puc); 276 int cpu_sparc_signal_handler(int hostsignum, struct siginfo *info, void *puc);
199 277
target-sparc/exec.h
1 #ifndef EXEC_SPARC_H 1 #ifndef EXEC_SPARC_H
2 #define EXEC_SPARC_H 1 2 #define EXEC_SPARC_H 1
3 #include "dyngen-exec.h" 3 #include "dyngen-exec.h"
  4 +#include "config.h"
4 5
5 register struct CPUSPARCState *env asm(AREG0); 6 register struct CPUSPARCState *env asm(AREG0);
6 #ifdef TARGET_SPARC64 7 #ifdef TARGET_SPARC64
7 #define T0 (env->t0) 8 #define T0 (env->t0)
8 #define T1 (env->t1) 9 #define T1 (env->t1)
9 #define T2 (env->t2) 10 #define T2 (env->t2)
  11 +#define REGWPTR env->regwptr
10 #else 12 #else
11 register uint32_t T0 asm(AREG1); 13 register uint32_t T0 asm(AREG1);
12 register uint32_t T1 asm(AREG2); 14 register uint32_t T1 asm(AREG2);
  15 +
  16 +#undef REG_REGWPTR // Broken
  17 +#ifdef REG_REGWPTR
  18 +register uint32_t *REGWPTR asm(AREG3);
  19 +#define reg_REGWPTR
  20 +
  21 +#ifdef AREG4
  22 +register uint32_t T2 asm(AREG4);
  23 +#define reg_T2
  24 +#else
  25 +#define T2 (env->t2)
  26 +#endif
  27 +
  28 +#else
  29 +#define REGWPTR env->regwptr
13 register uint32_t T2 asm(AREG3); 30 register uint32_t T2 asm(AREG3);
  31 +#define reg_T2
  32 +#endif
14 #endif 33 #endif
  34 +
15 #define FT0 (env->ft0) 35 #define FT0 (env->ft0)
16 #define FT1 (env->ft1) 36 #define FT1 (env->ft1)
17 -#define FT2 (env->ft2)  
18 #define DT0 (env->dt0) 37 #define DT0 (env->dt0)
19 #define DT1 (env->dt1) 38 #define DT1 (env->dt1)
20 -#define DT2 (env->dt2)  
21 39
22 #include "cpu.h" 40 #include "cpu.h"
23 #include "exec-all.h" 41 #include "exec-all.h"
@@ -38,6 +56,16 @@ void do_fsqrts(void); @@ -38,6 +56,16 @@ void do_fsqrts(void);
38 void do_fsqrtd(void); 56 void do_fsqrtd(void);
39 void do_fcmps(void); 57 void do_fcmps(void);
40 void do_fcmpd(void); 58 void do_fcmpd(void);
  59 +#ifdef TARGET_SPARC64
  60 +void do_fabsd(void);
  61 +void do_fcmps_fcc1(void);
  62 +void do_fcmpd_fcc1(void);
  63 +void do_fcmps_fcc2(void);
  64 +void do_fcmpd_fcc2(void);
  65 +void do_fcmps_fcc3(void);
  66 +void do_fcmpd_fcc3(void);
  67 +void do_popc();
  68 +#endif
41 void do_ldd_kernel(target_ulong addr); 69 void do_ldd_kernel(target_ulong addr);
42 void do_ldd_user(target_ulong addr); 70 void do_ldd_user(target_ulong addr);
43 void do_ldd_raw(target_ulong addr); 71 void do_ldd_raw(target_ulong addr);
target-sparc/fbranch_template.h 0 โ†’ 100644
  1 +/* FCC1:FCC0: 0 =, 1 <, 2 >, 3 u */
  2 +
  3 +void OPPROTO glue(op_eval_fbne, FCC)(void)
  4 +{
  5 +// !0
  6 + T2 = FFLAG_SET(FSR_FCC0) | FFLAG_SET(FSR_FCC1); /* L or G or U */
  7 +}
  8 +
  9 +void OPPROTO glue(op_eval_fblg, FCC)(void)
  10 +{
  11 +// 1 or 2
  12 + T2 = FFLAG_SET(FSR_FCC0) ^ FFLAG_SET(FSR_FCC1);
  13 +}
  14 +
  15 +void OPPROTO glue(op_eval_fbul, FCC)(void)
  16 +{
  17 +// 1 or 3
  18 + T2 = FFLAG_SET(FSR_FCC0);
  19 +}
  20 +
  21 +void OPPROTO glue(op_eval_fbl, FCC)(void)
  22 +{
  23 +// 1
  24 + T2 = FFLAG_SET(FSR_FCC0) & !FFLAG_SET(FSR_FCC1);
  25 +}
  26 +
  27 +void OPPROTO glue(op_eval_fbug, FCC)(void)
  28 +{
  29 +// 2 or 3
  30 + T2 = FFLAG_SET(FSR_FCC1);
  31 +}
  32 +
  33 +void OPPROTO glue(op_eval_fbg, FCC)(void)
  34 +{
  35 +// 2
  36 + T2 = !FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1);
  37 +}
  38 +
  39 +void OPPROTO glue(op_eval_fbu, FCC)(void)
  40 +{
  41 +// 3
  42 + T2 = FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1);
  43 +}
  44 +
  45 +void OPPROTO glue(op_eval_fbe, FCC)(void)
  46 +{
  47 +// 0
  48 + T2 = !FFLAG_SET(FSR_FCC0) & !FFLAG_SET(FSR_FCC1);
  49 +}
  50 +
  51 +void OPPROTO glue(op_eval_fbue, FCC)(void)
  52 +{
  53 +// 0 or 3
  54 + T2 = !(FFLAG_SET(FSR_FCC1) ^ FFLAG_SET(FSR_FCC0));
  55 + FORCE_RET();
  56 +}
  57 +
  58 +void OPPROTO glue(op_eval_fbge, FCC)(void)
  59 +{
  60 +// 0 or 2
  61 + T2 = !FFLAG_SET(FSR_FCC0);
  62 +}
  63 +
  64 +void OPPROTO glue(op_eval_fbuge, FCC)(void)
  65 +{
  66 +// !1
  67 + T2 = !(FFLAG_SET(FSR_FCC0) & !FFLAG_SET(FSR_FCC1));
  68 +}
  69 +
  70 +void OPPROTO glue(op_eval_fble, FCC)(void)
  71 +{
  72 +// 0 or 1
  73 + T2 = !FFLAG_SET(FSR_FCC1);
  74 +}
  75 +
  76 +void OPPROTO glue(op_eval_fbule, FCC)(void)
  77 +{
  78 +// !2
  79 + T2 = !(!FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1));
  80 +}
  81 +
  82 +void OPPROTO glue(op_eval_fbo, FCC)(void)
  83 +{
  84 +// !3
  85 + T2 = !(FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1));
  86 +}
  87 +
  88 +#undef FCC
  89 +#undef FFLAG_SET
target-sparc/fop_template.h
@@ -40,16 +40,6 @@ void OPPROTO glue(op_store_FT1_fpr_fpr, REGNAME)(void) @@ -40,16 +40,6 @@ void OPPROTO glue(op_store_FT1_fpr_fpr, REGNAME)(void)
40 REG = FT1; 40 REG = FT1;
41 } 41 }
42 42
43 -void OPPROTO glue(op_load_fpr_FT2_fpr, REGNAME)(void)  
44 -{  
45 - FT2 = REG;  
46 -}  
47 -  
48 -void OPPROTO glue(op_store_FT2_fpr_fpr, REGNAME)(void)  
49 -{  
50 - REG = FT2;  
51 -}  
52 -  
53 /* double floating point registers moves */ 43 /* double floating point registers moves */
54 void OPPROTO glue(op_load_fpr_DT0_fpr, REGNAME)(void) 44 void OPPROTO glue(op_load_fpr_DT0_fpr, REGNAME)(void)
55 { 45 {
@@ -87,23 +77,5 @@ void OPPROTO glue(op_store_DT1_fpr_fpr, REGNAME)(void) @@ -87,23 +77,5 @@ void OPPROTO glue(op_store_DT1_fpr_fpr, REGNAME)(void)
87 *p = u.l.upper; 77 *p = u.l.upper;
88 } 78 }
89 79
90 -void OPPROTO glue(op_load_fpr_DT2_fpr, REGNAME)(void)  
91 -{  
92 - CPU_DoubleU u;  
93 - uint32_t *p = (uint32_t *)&REG;  
94 - u.l.lower = *(p +1);  
95 - u.l.upper = *p;  
96 - DT2 = u.d;  
97 -}  
98 -  
99 -void OPPROTO glue(op_store_DT2_fpr_fpr, REGNAME)(void)  
100 -{  
101 - CPU_DoubleU u;  
102 - uint32_t *p = (uint32_t *)&REG;  
103 - u.d = DT2;  
104 - *(p +1) = u.l.lower;  
105 - *p = u.l.upper;  
106 -}  
107 -  
108 #undef REG 80 #undef REG
109 #undef REGNAME 81 #undef REGNAME
target-sparc/helper.c
@@ -43,7 +43,6 @@ void cpu_unlock(void) @@ -43,7 +43,6 @@ void cpu_unlock(void)
43 int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw, 43 int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
44 int is_user, int is_softmmu) 44 int is_user, int is_softmmu)
45 { 45 {
46 - env->mmuregs[4] = address;  
47 if (rw & 2) 46 if (rw & 2)
48 env->exception_index = TT_TFAULT; 47 env->exception_index = TT_TFAULT;
49 else 48 else
@@ -102,6 +101,7 @@ void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr) @@ -102,6 +101,7 @@ void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
102 env = saved_env; 101 env = saved_env;
103 } 102 }
104 103
  104 +#ifndef TARGET_SPARC64
105 static const int access_table[8][8] = { 105 static const int access_table[8][8] = {
106 { 0, 0, 0, 0, 2, 0, 3, 3 }, 106 { 0, 0, 0, 0, 2, 0, 3, 3 },
107 { 0, 0, 0, 0, 2, 0, 0, 0 }, 107 { 0, 0, 0, 0, 2, 0, 0, 0 },
@@ -268,6 +268,136 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, @@ -268,6 +268,136 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
268 return 1; 268 return 1;
269 } 269 }
270 } 270 }
  271 +#else
  272 +static int get_physical_address_data(CPUState *env, target_phys_addr_t *physical, int *prot,
  273 + int *access_index, target_ulong address, int rw,
  274 + int is_user)
  275 +{
  276 + target_ulong mask;
  277 + unsigned int i;
  278 +
  279 + if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
  280 + *physical = address & 0xffffffff;
  281 + *prot = PAGE_READ | PAGE_WRITE;
  282 + return 0;
  283 + }
  284 +
  285 + for (i = 0; i < 64; i++) {
  286 + if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0) {
  287 + switch (env->dtlb_tte[i] >> 60) {
  288 + default:
  289 + case 0x4: // 8k
  290 + mask = 0xffffffffffffe000ULL;
  291 + break;
  292 + case 0x5: // 64k
  293 + mask = 0xffffffffffff0000ULL;
  294 + break;
  295 + case 0x6: // 512k
  296 + mask = 0xfffffffffff80000ULL;
  297 + break;
  298 + case 0x7: // 4M
  299 + mask = 0xffffffffffc00000ULL;
  300 + break;
  301 + }
  302 + // ctx match, vaddr match?
  303 + if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&
  304 + (address & mask) == (env->dtlb_tag[i] & ~0x1fffULL)) {
  305 + // access ok?
  306 + if (((env->dtlb_tte[i] & 0x4) && !(env->pstate & PS_PRIV)) ||
  307 + (!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {
  308 + env->exception_index = TT_DFAULT;
  309 + return 1;
  310 + }
  311 + *physical = env->dtlb_tte[i] & 0xffffe000;
  312 + *prot = PAGE_READ;
  313 + if (env->dtlb_tte[i] & 0x2)
  314 + *prot |= PAGE_WRITE;
  315 + return 0;
  316 + }
  317 + }
  318 + }
  319 + env->exception_index = TT_DFAULT;
  320 + return 1;
  321 +}
  322 +
  323 +static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical, int *prot,
  324 + int *access_index, target_ulong address, int rw,
  325 + int is_user)
  326 +{
  327 + target_ulong mask;
  328 + unsigned int i;
  329 +
  330 + if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */
  331 + *physical = address & 0xffffffff;
  332 + *prot = PAGE_READ;
  333 + return 0;
  334 + }
  335 + for (i = 0; i < 64; i++) {
  336 + if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) {
  337 + switch (env->itlb_tte[i] >> 60) {
  338 + default:
  339 + case 0x4: // 8k
  340 + mask = 0xffffffffffffe000ULL;
  341 + break;
  342 + case 0x5: // 64k
  343 + mask = 0xffffffffffff0000ULL;
  344 + break;
  345 + case 0x6: // 512k
  346 + mask = 0xfffffffffff80000ULL;
  347 + break;
  348 + case 0x7: // 4M
  349 + mask = 0xffffffffffc00000ULL;
  350 + break;
  351 + }
  352 + // ctx match, vaddr match?
  353 + if (env->immuregs[1] == (env->itlb_tag[i] & 0x1fff) &&
  354 + (address & mask) == (env->itlb_tag[i] & ~0x1fffULL)) {
  355 + // access ok?
  356 + if ((env->itlb_tte[i] & 0x4) && !(env->pstate & PS_PRIV)) {
  357 + env->exception_index = TT_TFAULT;
  358 + return 1;
  359 + }
  360 + *physical = env->itlb_tte[i] & 0xffffe000;
  361 + *prot = PAGE_READ;
  362 + return 0;
  363 + }
  364 + }
  365 + }
  366 + env->exception_index = TT_TFAULT;
  367 + return 1;
  368 +}
  369 +
  370 +int get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot,
  371 + int *access_index, target_ulong address, int rw,
  372 + int is_user)
  373 +{
  374 + if (rw == 2)
  375 + return get_physical_address_code(env, physical, prot, access_index, address, rw, is_user);
  376 + else
  377 + return get_physical_address_data(env, physical, prot, access_index, address, rw, is_user);
  378 +}
  379 +
  380 +/* Perform address translation */
  381 +int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
  382 + int is_user, int is_softmmu)
  383 +{
  384 + target_ulong virt_addr;
  385 + target_phys_addr_t paddr;
  386 + unsigned long vaddr;
  387 + int error_code = 0, prot, ret = 0, access_index;
  388 +
  389 + error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
  390 + if (error_code == 0) {
  391 + virt_addr = address & TARGET_PAGE_MASK;
  392 + vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));
  393 + ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu);
  394 + return ret;
  395 + }
  396 + // XXX
  397 + return 1;
  398 +}
  399 +
  400 +#endif
271 #endif 401 #endif
272 402
273 void memcpy32(target_ulong *dst, const target_ulong *src) 403 void memcpy32(target_ulong *dst, const target_ulong *src)
@@ -292,17 +422,73 @@ void set_cwp(int new_cwp) @@ -292,17 +422,73 @@ void set_cwp(int new_cwp)
292 if (new_cwp == (NWINDOWS - 1)) 422 if (new_cwp == (NWINDOWS - 1))
293 memcpy32(env->regbase + NWINDOWS * 16, env->regbase); 423 memcpy32(env->regbase + NWINDOWS * 16, env->regbase);
294 env->regwptr = env->regbase + (new_cwp * 16); 424 env->regwptr = env->regbase + (new_cwp * 16);
  425 + REGWPTR = env->regwptr;
295 } 426 }
296 427
297 void cpu_set_cwp(CPUState *env1, int new_cwp) 428 void cpu_set_cwp(CPUState *env1, int new_cwp)
298 { 429 {
299 CPUState *saved_env; 430 CPUState *saved_env;
  431 +#ifdef reg_REGWPTR
  432 + target_ulong *saved_regwptr;
  433 +#endif
  434 +
300 saved_env = env; 435 saved_env = env;
  436 +#ifdef reg_REGWPTR
  437 + saved_regwptr = REGWPTR;
  438 +#endif
301 env = env1; 439 env = env1;
302 set_cwp(new_cwp); 440 set_cwp(new_cwp);
303 env = saved_env; 441 env = saved_env;
  442 +#ifdef reg_REGWPTR
  443 + REGWPTR = saved_regwptr;
  444 +#endif
304 } 445 }
305 446
  447 +#ifdef TARGET_SPARC64
  448 +void do_interrupt(int intno)
  449 +{
  450 +#ifdef DEBUG_PCALL
  451 + if (loglevel & CPU_LOG_INT) {
  452 + static int count;
  453 + fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
  454 + count, intno,
  455 + env->pc,
  456 + env->npc, env->regwptr[6]);
  457 + cpu_dump_state(env, logfile, fprintf, 0);
  458 +#if 0
  459 + {
  460 + int i;
  461 + uint8_t *ptr;
  462 +
  463 + fprintf(logfile, " code=");
  464 + ptr = (uint8_t *)env->pc;
  465 + for(i = 0; i < 16; i++) {
  466 + fprintf(logfile, " %02x", ldub(ptr + i));
  467 + }
  468 + fprintf(logfile, "\n");
  469 + }
  470 +#endif
  471 + count++;
  472 + }
  473 +#endif
  474 +#if !defined(CONFIG_USER_ONLY)
  475 + if (env->pstate & PS_IE) {
  476 + cpu_abort(cpu_single_env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
  477 + return;
  478 + }
  479 +#endif
  480 + env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) |
  481 + ((env->pstate & 0xfff) << 8) | (env->cwp & 0xff);
  482 + env->tpc[env->tl] = env->pc;
  483 + env->tnpc[env->tl] = env->npc;
  484 + env->tt[env->tl] = intno;
  485 + env->tbr = env->tbr | (env->tl > 1) ? 1 << 14 : 0 | (intno << 4);
  486 + env->tl++;
  487 + env->pc = env->tbr;
  488 + env->npc = env->pc + 4;
  489 + env->exception_index = 0;
  490 +}
  491 +#else
306 void do_interrupt(int intno) 492 void do_interrupt(int intno)
307 { 493 {
308 int cwp; 494 int cwp;
@@ -448,3 +634,4 @@ void dump_mmu(void) @@ -448,3 +634,4 @@ void dump_mmu(void)
448 printf("MMU dump ends\n"); 634 printf("MMU dump ends\n");
449 } 635 }
450 #endif 636 #endif
  637 +#endif
target-sparc/op.c
@@ -46,76 +46,76 @@ @@ -46,76 +46,76 @@
46 #define REG (env->gregs[7]) 46 #define REG (env->gregs[7])
47 #include "op_template.h" 47 #include "op_template.h"
48 #define REGNAME i0 48 #define REGNAME i0
49 -#define REG (env->regwptr[16]) 49 +#define REG (REGWPTR[16])
50 #include "op_template.h" 50 #include "op_template.h"
51 #define REGNAME i1 51 #define REGNAME i1
52 -#define REG (env->regwptr[17]) 52 +#define REG (REGWPTR[17])
53 #include "op_template.h" 53 #include "op_template.h"
54 #define REGNAME i2 54 #define REGNAME i2
55 -#define REG (env->regwptr[18]) 55 +#define REG (REGWPTR[18])
56 #include "op_template.h" 56 #include "op_template.h"
57 #define REGNAME i3 57 #define REGNAME i3
58 -#define REG (env->regwptr[19]) 58 +#define REG (REGWPTR[19])
59 #include "op_template.h" 59 #include "op_template.h"
60 #define REGNAME i4 60 #define REGNAME i4
61 -#define REG (env->regwptr[20]) 61 +#define REG (REGWPTR[20])
62 #include "op_template.h" 62 #include "op_template.h"
63 #define REGNAME i5 63 #define REGNAME i5
64 -#define REG (env->regwptr[21]) 64 +#define REG (REGWPTR[21])
65 #include "op_template.h" 65 #include "op_template.h"
66 #define REGNAME i6 66 #define REGNAME i6
67 -#define REG (env->regwptr[22]) 67 +#define REG (REGWPTR[22])
68 #include "op_template.h" 68 #include "op_template.h"
69 #define REGNAME i7 69 #define REGNAME i7
70 -#define REG (env->regwptr[23]) 70 +#define REG (REGWPTR[23])
71 #include "op_template.h" 71 #include "op_template.h"
72 #define REGNAME l0 72 #define REGNAME l0
73 -#define REG (env->regwptr[8]) 73 +#define REG (REGWPTR[8])
74 #include "op_template.h" 74 #include "op_template.h"
75 #define REGNAME l1 75 #define REGNAME l1
76 -#define REG (env->regwptr[9]) 76 +#define REG (REGWPTR[9])
77 #include "op_template.h" 77 #include "op_template.h"
78 #define REGNAME l2 78 #define REGNAME l2
79 -#define REG (env->regwptr[10]) 79 +#define REG (REGWPTR[10])
80 #include "op_template.h" 80 #include "op_template.h"
81 #define REGNAME l3 81 #define REGNAME l3
82 -#define REG (env->regwptr[11]) 82 +#define REG (REGWPTR[11])
83 #include "op_template.h" 83 #include "op_template.h"
84 #define REGNAME l4 84 #define REGNAME l4
85 -#define REG (env->regwptr[12]) 85 +#define REG (REGWPTR[12])
86 #include "op_template.h" 86 #include "op_template.h"
87 #define REGNAME l5 87 #define REGNAME l5
88 -#define REG (env->regwptr[13]) 88 +#define REG (REGWPTR[13])
89 #include "op_template.h" 89 #include "op_template.h"
90 #define REGNAME l6 90 #define REGNAME l6
91 -#define REG (env->regwptr[14]) 91 +#define REG (REGWPTR[14])
92 #include "op_template.h" 92 #include "op_template.h"
93 #define REGNAME l7 93 #define REGNAME l7
94 -#define REG (env->regwptr[15]) 94 +#define REG (REGWPTR[15])
95 #include "op_template.h" 95 #include "op_template.h"
96 #define REGNAME o0 96 #define REGNAME o0
97 -#define REG (env->regwptr[0]) 97 +#define REG (REGWPTR[0])
98 #include "op_template.h" 98 #include "op_template.h"
99 #define REGNAME o1 99 #define REGNAME o1
100 -#define REG (env->regwptr[1]) 100 +#define REG (REGWPTR[1])
101 #include "op_template.h" 101 #include "op_template.h"
102 #define REGNAME o2 102 #define REGNAME o2
103 -#define REG (env->regwptr[2]) 103 +#define REG (REGWPTR[2])
104 #include "op_template.h" 104 #include "op_template.h"
105 #define REGNAME o3 105 #define REGNAME o3
106 -#define REG (env->regwptr[3]) 106 +#define REG (REGWPTR[3])
107 #include "op_template.h" 107 #include "op_template.h"
108 #define REGNAME o4 108 #define REGNAME o4
109 -#define REG (env->regwptr[4]) 109 +#define REG (REGWPTR[4])
110 #include "op_template.h" 110 #include "op_template.h"
111 #define REGNAME o5 111 #define REGNAME o5
112 -#define REG (env->regwptr[5]) 112 +#define REG (REGWPTR[5])
113 #include "op_template.h" 113 #include "op_template.h"
114 #define REGNAME o6 114 #define REGNAME o6
115 -#define REG (env->regwptr[6]) 115 +#define REG (REGWPTR[6])
116 #include "op_template.h" 116 #include "op_template.h"
117 #define REGNAME o7 117 #define REGNAME o7
118 -#define REG (env->regwptr[7]) 118 +#define REG (REGWPTR[7])
119 #include "op_template.h" 119 #include "op_template.h"
120 120
121 #define REGNAME f0 121 #define REGNAME f0
@@ -215,10 +215,106 @@ @@ -215,10 +215,106 @@
215 #define REG (env->fpr[31]) 215 #define REG (env->fpr[31])
216 #include "fop_template.h" 216 #include "fop_template.h"
217 217
  218 +#ifdef TARGET_SPARC64
  219 +#define REGNAME f32
  220 +#define REG (env->fpr[32])
  221 +#include "fop_template.h"
  222 +#define REGNAME f34
  223 +#define REG (env->fpr[34])
  224 +#include "fop_template.h"
  225 +#define REGNAME f36
  226 +#define REG (env->fpr[36])
  227 +#include "fop_template.h"
  228 +#define REGNAME f38
  229 +#define REG (env->fpr[38])
  230 +#include "fop_template.h"
  231 +#define REGNAME f40
  232 +#define REG (env->fpr[40])
  233 +#include "fop_template.h"
  234 +#define REGNAME f42
  235 +#define REG (env->fpr[42])
  236 +#include "fop_template.h"
  237 +#define REGNAME f44
  238 +#define REG (env->fpr[44])
  239 +#include "fop_template.h"
  240 +#define REGNAME f46
  241 +#define REG (env->fpr[46])
  242 +#include "fop_template.h"
  243 +#define REGNAME f48
  244 +#define REG (env->fpr[47])
  245 +#include "fop_template.h"
  246 +#define REGNAME f50
  247 +#define REG (env->fpr[50])
  248 +#include "fop_template.h"
  249 +#define REGNAME f52
  250 +#define REG (env->fpr[52])
  251 +#include "fop_template.h"
  252 +#define REGNAME f54
  253 +#define REG (env->fpr[54])
  254 +#include "fop_template.h"
  255 +#define REGNAME f56
  256 +#define REG (env->fpr[56])
  257 +#include "fop_template.h"
  258 +#define REGNAME f58
  259 +#define REG (env->fpr[58])
  260 +#include "fop_template.h"
  261 +#define REGNAME f60
  262 +#define REG (env->fpr[60])
  263 +#include "fop_template.h"
  264 +#define REGNAME f62
  265 +#define REG (env->fpr[62])
  266 +#include "fop_template.h"
  267 +#endif
  268 +
  269 +#ifdef TARGET_SPARC64
  270 +#undef JUMP_TB
  271 +#define JUMP_TB(opname, tbparam, n, eip) \
  272 + do { \
  273 + GOTO_TB(opname, tbparam, n); \
  274 + T0 = (long)(tbparam) + (n); \
  275 + env->pc = (eip) & 0xffffffff; \
  276 + EXIT_TB(); \
  277 + } while (0)
  278 +
  279 +#ifdef WORDS_BIGENDIAN
  280 +typedef union UREG64 {
  281 + struct { uint16_t v3, v2, v1, v0; } w;
  282 + struct { uint32_t v1, v0; } l;
  283 + uint64_t q;
  284 +} UREG64;
  285 +#else
  286 +typedef union UREG64 {
  287 + struct { uint16_t v0, v1, v2, v3; } w;
  288 + struct { uint32_t v0, v1; } l;
  289 + uint64_t q;
  290 +} UREG64;
  291 +#endif
  292 +
  293 +#define PARAMQ1 \
  294 +({\
  295 + UREG64 __p;\
  296 + __p.l.v1 = PARAM1;\
  297 + __p.l.v0 = PARAM2;\
  298 + __p.q;\
  299 +})
  300 +
  301 +void OPPROTO op_movq_T0_im64(void)
  302 +{
  303 + T0 = PARAMQ1;
  304 +}
  305 +
  306 +void OPPROTO op_movq_T1_im64(void)
  307 +{
  308 + T1 = PARAMQ1;
  309 +}
  310 +
  311 +#define XFLAG_SET(x) ((env->xcc&x)?1:0)
  312 +
  313 +#else
218 #define EIP (env->pc) 314 #define EIP (env->pc)
  315 +#endif
219 316
220 #define FLAG_SET(x) ((env->psr&x)?1:0) 317 #define FLAG_SET(x) ((env->psr&x)?1:0)
221 -#define FFLAG_SET(x) ((env->fsr&x)?1:0)  
222 318
223 void OPPROTO op_movl_T0_0(void) 319 void OPPROTO op_movl_T0_0(void)
224 { 320 {
@@ -227,17 +323,52 @@ void OPPROTO op_movl_T0_0(void) @@ -227,17 +323,52 @@ void OPPROTO op_movl_T0_0(void)
227 323
228 void OPPROTO op_movl_T0_im(void) 324 void OPPROTO op_movl_T0_im(void)
229 { 325 {
230 - T0 = PARAM1; 326 + T0 = (uint32_t)PARAM1;
231 } 327 }
232 328
233 void OPPROTO op_movl_T1_im(void) 329 void OPPROTO op_movl_T1_im(void)
234 { 330 {
235 - T1 = PARAM1; 331 + T1 = (uint32_t)PARAM1;
236 } 332 }
237 333
238 void OPPROTO op_movl_T2_im(void) 334 void OPPROTO op_movl_T2_im(void)
239 { 335 {
240 - T2 = PARAM1; 336 + T2 = (uint32_t)PARAM1;
  337 +}
  338 +
  339 +void OPPROTO op_movl_T0_sim(void)
  340 +{
  341 + T0 = (int32_t)PARAM1;
  342 +}
  343 +
  344 +void OPPROTO op_movl_T1_sim(void)
  345 +{
  346 + T1 = (int32_t)PARAM1;
  347 +}
  348 +
  349 +void OPPROTO op_movl_T2_sim(void)
  350 +{
  351 + T2 = (int32_t)PARAM1;
  352 +}
  353 +
  354 +void OPPROTO op_movl_T0_env(void)
  355 +{
  356 + T0 = *(uint32_t *)((char *)env + PARAM1);
  357 +}
  358 +
  359 +void OPPROTO op_movl_env_T0(void)
  360 +{
  361 + *(uint32_t *)((char *)env + PARAM1) = T0;
  362 +}
  363 +
  364 +void OPPROTO op_movtl_T0_env(void)
  365 +{
  366 + T0 = *(target_ulong *)((char *)env + PARAM1);
  367 +}
  368 +
  369 +void OPPROTO op_movtl_env_T0(void)
  370 +{
  371 + *(target_ulong *)((char *)env + PARAM1) = T0;
241 } 372 }
242 373
243 void OPPROTO op_add_T1_T0(void) 374 void OPPROTO op_add_T1_T0(void)
@@ -252,6 +383,27 @@ void OPPROTO op_add_T1_T0_cc(void) @@ -252,6 +383,27 @@ void OPPROTO op_add_T1_T0_cc(void)
252 src1 = T0; 383 src1 = T0;
253 T0 += T1; 384 T0 += T1;
254 env->psr = 0; 385 env->psr = 0;
  386 +#ifdef TARGET_SPARC64
  387 + if (!(T0 & 0xffffffff))
  388 + env->psr |= PSR_ZERO;
  389 + if ((int32_t) T0 < 0)
  390 + env->psr |= PSR_NEG;
  391 + if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
  392 + env->psr |= PSR_CARRY;
  393 + if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
  394 + ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
  395 + env->psr |= PSR_OVF;
  396 +
  397 + env->xcc = 0;
  398 + if (!T0)
  399 + env->xcc |= PSR_ZERO;
  400 + if ((int64_t) T0 < 0)
  401 + env->xcc |= PSR_NEG;
  402 + if (T0 < src1)
  403 + env->xcc |= PSR_CARRY;
  404 + if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
  405 + env->xcc |= PSR_OVF;
  406 +#else
255 if (!T0) 407 if (!T0)
256 env->psr |= PSR_ZERO; 408 env->psr |= PSR_ZERO;
257 if ((int32_t) T0 < 0) 409 if ((int32_t) T0 < 0)
@@ -260,7 +412,7 @@ void OPPROTO op_add_T1_T0_cc(void) @@ -260,7 +412,7 @@ void OPPROTO op_add_T1_T0_cc(void)
260 env->psr |= PSR_CARRY; 412 env->psr |= PSR_CARRY;
261 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31)) 413 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
262 env->psr |= PSR_OVF; 414 env->psr |= PSR_OVF;
263 - /* V9 xcc */ 415 +#endif
264 FORCE_RET(); 416 FORCE_RET();
265 } 417 }
266 418
@@ -276,6 +428,27 @@ void OPPROTO op_addx_T1_T0_cc(void) @@ -276,6 +428,27 @@ void OPPROTO op_addx_T1_T0_cc(void)
276 src1 = T0; 428 src1 = T0;
277 T0 += T1 + FLAG_SET(PSR_CARRY); 429 T0 += T1 + FLAG_SET(PSR_CARRY);
278 env->psr = 0; 430 env->psr = 0;
  431 +#ifdef TARGET_SPARC64
  432 + if (!(T0 & 0xffffffff))
  433 + env->psr |= PSR_ZERO;
  434 + if ((int32_t) T0 < 0)
  435 + env->psr |= PSR_NEG;
  436 + if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
  437 + env->psr |= PSR_CARRY;
  438 + if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff) ^ -1) &
  439 + ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
  440 + env->psr |= PSR_OVF;
  441 +
  442 + env->xcc = 0;
  443 + if (!T0)
  444 + env->xcc |= PSR_ZERO;
  445 + if ((int64_t) T0 < 0)
  446 + env->xcc |= PSR_NEG;
  447 + if (T0 < src1)
  448 + env->xcc |= PSR_CARRY;
  449 + if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1ULL << 63))
  450 + env->xcc |= PSR_OVF;
  451 +#else
279 if (!T0) 452 if (!T0)
280 env->psr |= PSR_ZERO; 453 env->psr |= PSR_ZERO;
281 if ((int32_t) T0 < 0) 454 if ((int32_t) T0 < 0)
@@ -284,7 +457,7 @@ void OPPROTO op_addx_T1_T0_cc(void) @@ -284,7 +457,7 @@ void OPPROTO op_addx_T1_T0_cc(void)
284 env->psr |= PSR_CARRY; 457 env->psr |= PSR_CARRY;
285 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31)) 458 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
286 env->psr |= PSR_OVF; 459 env->psr |= PSR_OVF;
287 - /* V9 xcc */ 460 +#endif
288 FORCE_RET(); 461 FORCE_RET();
289 } 462 }
290 463
@@ -300,6 +473,27 @@ void OPPROTO op_sub_T1_T0_cc(void) @@ -300,6 +473,27 @@ void OPPROTO op_sub_T1_T0_cc(void)
300 src1 = T0; 473 src1 = T0;
301 T0 -= T1; 474 T0 -= T1;
302 env->psr = 0; 475 env->psr = 0;
  476 +#ifdef TARGET_SPARC64
  477 + if (!(T0 & 0xffffffff))
  478 + env->psr |= PSR_ZERO;
  479 + if ((int32_t) T0 < 0)
  480 + env->psr |= PSR_NEG;
  481 + if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
  482 + env->psr |= PSR_CARRY;
  483 + if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
  484 + ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
  485 + env->psr |= PSR_OVF;
  486 +
  487 + env->xcc = 0;
  488 + if (!T0)
  489 + env->xcc |= PSR_ZERO;
  490 + if ((int64_t) T0 < 0)
  491 + env->xcc |= PSR_NEG;
  492 + if (T0 < src1)
  493 + env->xcc |= PSR_CARRY;
  494 + if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
  495 + env->xcc |= PSR_OVF;
  496 +#else
303 if (!T0) 497 if (!T0)
304 env->psr |= PSR_ZERO; 498 env->psr |= PSR_ZERO;
305 if ((int32_t) T0 < 0) 499 if ((int32_t) T0 < 0)
@@ -308,7 +502,7 @@ void OPPROTO op_sub_T1_T0_cc(void) @@ -308,7 +502,7 @@ void OPPROTO op_sub_T1_T0_cc(void)
308 env->psr |= PSR_CARRY; 502 env->psr |= PSR_CARRY;
309 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31)) 503 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
310 env->psr |= PSR_OVF; 504 env->psr |= PSR_OVF;
311 - /* V9 xcc */ 505 +#endif
312 FORCE_RET(); 506 FORCE_RET();
313 } 507 }
314 508
@@ -324,6 +518,27 @@ void OPPROTO op_subx_T1_T0_cc(void) @@ -324,6 +518,27 @@ void OPPROTO op_subx_T1_T0_cc(void)
324 src1 = T0; 518 src1 = T0;
325 T0 -= T1 + FLAG_SET(PSR_CARRY); 519 T0 -= T1 + FLAG_SET(PSR_CARRY);
326 env->psr = 0; 520 env->psr = 0;
  521 +#ifdef TARGET_SPARC64
  522 + if (!(T0 & 0xffffffff))
  523 + env->psr |= PSR_ZERO;
  524 + if ((int32_t) T0 < 0)
  525 + env->psr |= PSR_NEG;
  526 + if ((T0 & 0xffffffff) < (src1 & 0xffffffff))
  527 + env->psr |= PSR_CARRY;
  528 + if ((((src1 & 0xffffffff) ^ (T1 & 0xffffffff)) &
  529 + ((src1 & 0xffffffff) ^ (T0 & 0xffffffff))) & (1 << 31))
  530 + env->psr |= PSR_OVF;
  531 +
  532 + env->xcc = 0;
  533 + if (!T0)
  534 + env->xcc |= PSR_ZERO;
  535 + if ((int64_t) T0 < 0)
  536 + env->xcc |= PSR_NEG;
  537 + if (T0 < src1)
  538 + env->xcc |= PSR_CARRY;
  539 + if (((src1 ^ T1) & (src1 ^ T0)) & (1ULL << 63))
  540 + env->xcc |= PSR_OVF;
  541 +#else
327 if (!T0) 542 if (!T0)
328 env->psr |= PSR_ZERO; 543 env->psr |= PSR_ZERO;
329 if ((int32_t) T0 < 0) 544 if ((int32_t) T0 < 0)
@@ -332,7 +547,7 @@ void OPPROTO op_subx_T1_T0_cc(void) @@ -332,7 +547,7 @@ void OPPROTO op_subx_T1_T0_cc(void)
332 env->psr |= PSR_CARRY; 547 env->psr |= PSR_CARRY;
333 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31)) 548 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
334 env->psr |= PSR_OVF; 549 env->psr |= PSR_OVF;
335 - /* V9 xcc */ 550 +#endif
336 FORCE_RET(); 551 FORCE_RET();
337 } 552 }
338 553
@@ -449,24 +664,73 @@ void OPPROTO op_sdiv_T1_T0(void) @@ -449,24 +664,73 @@ void OPPROTO op_sdiv_T1_T0(void)
449 void OPPROTO op_div_cc(void) 664 void OPPROTO op_div_cc(void)
450 { 665 {
451 env->psr = 0; 666 env->psr = 0;
  667 +#ifdef TARGET_SPARC64
  668 + if (!T0)
  669 + env->psr |= PSR_ZERO;
  670 + if ((int32_t) T0 < 0)
  671 + env->psr |= PSR_NEG;
  672 + if (T1)
  673 + env->psr |= PSR_OVF;
  674 +
  675 + env->xcc = 0;
  676 + if (!T0)
  677 + env->xcc |= PSR_ZERO;
  678 + if ((int64_t) T0 < 0)
  679 + env->xcc |= PSR_NEG;
  680 +#else
452 if (!T0) 681 if (!T0)
453 env->psr |= PSR_ZERO; 682 env->psr |= PSR_ZERO;
454 if ((int32_t) T0 < 0) 683 if ((int32_t) T0 < 0)
455 env->psr |= PSR_NEG; 684 env->psr |= PSR_NEG;
456 if (T1) 685 if (T1)
457 env->psr |= PSR_OVF; 686 env->psr |= PSR_OVF;
458 - /* V9 xcc */ 687 +#endif
459 FORCE_RET(); 688 FORCE_RET();
460 } 689 }
461 690
  691 +#ifdef TARGET_SPARC64
  692 +void OPPROTO op_mulx_T1_T0(void)
  693 +{
  694 + T0 *= T1;
  695 + FORCE_RET();
  696 +}
  697 +
  698 +void OPPROTO op_udivx_T1_T0(void)
  699 +{
  700 + T0 /= T1;
  701 + FORCE_RET();
  702 +}
  703 +
  704 +void OPPROTO op_sdivx_T1_T0(void)
  705 +{
  706 + if (T0 == INT64_MIN && T1 == -1)
  707 + T0 = INT64_MIN;
  708 + else
  709 + T0 /= (target_long) T1;
  710 + FORCE_RET();
  711 +}
  712 +#endif
  713 +
462 void OPPROTO op_logic_T0_cc(void) 714 void OPPROTO op_logic_T0_cc(void)
463 { 715 {
464 env->psr = 0; 716 env->psr = 0;
  717 +#ifdef TARGET_SPARC64
  718 + if (!(T0 & 0xffffffff))
  719 + env->psr |= PSR_ZERO;
  720 + if ((int32_t) T0 < 0)
  721 + env->psr |= PSR_NEG;
  722 +
  723 + env->xcc = 0;
  724 + if (!T0)
  725 + env->xcc |= PSR_ZERO;
  726 + if ((int64_t) T0 < 0)
  727 + env->xcc |= PSR_NEG;
  728 +#else
465 if (!T0) 729 if (!T0)
466 env->psr |= PSR_ZERO; 730 env->psr |= PSR_ZERO;
467 if ((int32_t) T0 < 0) 731 if ((int32_t) T0 < 0)
468 env->psr |= PSR_NEG; 732 env->psr |= PSR_NEG;
469 - /* V9 xcc */ 733 +#endif
470 FORCE_RET(); 734 FORCE_RET();
471 } 735 }
472 736
@@ -475,6 +739,27 @@ void OPPROTO op_sll(void) @@ -475,6 +739,27 @@ void OPPROTO op_sll(void)
475 T0 <<= T1; 739 T0 <<= T1;
476 } 740 }
477 741
  742 +#ifdef TARGET_SPARC64
  743 +void OPPROTO op_srl(void)
  744 +{
  745 + T0 = (T0 & 0xffffffff) >> T1;
  746 +}
  747 +
  748 +void OPPROTO op_srlx(void)
  749 +{
  750 + T0 >>= T1;
  751 +}
  752 +
  753 +void OPPROTO op_sra(void)
  754 +{
  755 + T0 = ((int32_t) (T0 & 0xffffffff)) >> T1;
  756 +}
  757 +
  758 +void OPPROTO op_srax(void)
  759 +{
  760 + T0 = ((int64_t) T0) >> T1;
  761 +}
  762 +#else
478 void OPPROTO op_srl(void) 763 void OPPROTO op_srl(void)
479 { 764 {
480 T0 >>= T1; 765 T0 >>= T1;
@@ -484,6 +769,7 @@ void OPPROTO op_sra(void) @@ -484,6 +769,7 @@ void OPPROTO op_sra(void)
484 { 769 {
485 T0 = ((int32_t) T0) >> T1; 770 T0 = ((int32_t) T0) >> T1;
486 } 771 }
  772 +#endif
487 773
488 /* Load and store */ 774 /* Load and store */
489 #define MEMSUFFIX _raw 775 #define MEMSUFFIX _raw
@@ -498,62 +784,137 @@ void OPPROTO op_sra(void) @@ -498,62 +784,137 @@ void OPPROTO op_sra(void)
498 784
499 void OPPROTO op_ldfsr(void) 785 void OPPROTO op_ldfsr(void)
500 { 786 {
501 - env->fsr = *((uint32_t *) &FT0); 787 + PUT_FSR32(env, *((uint32_t *) &FT0));
502 helper_ldfsr(); 788 helper_ldfsr();
503 } 789 }
504 790
505 void OPPROTO op_stfsr(void) 791 void OPPROTO op_stfsr(void)
506 { 792 {
507 - *((uint32_t *) &FT0) = env->fsr; 793 + *((uint32_t *) &FT0) = GET_FSR32(env);
508 } 794 }
509 795
510 -void OPPROTO op_wry(void) 796 +#ifndef TARGET_SPARC64
  797 +void OPPROTO op_rdpsr(void)
511 { 798 {
512 - env->y = T0; 799 + do_rdpsr();
513 } 800 }
514 801
515 -void OPPROTO op_rdy(void) 802 +void OPPROTO op_wrpsr(void)
516 { 803 {
517 - T0 = env->y; 804 + do_wrpsr();
  805 + FORCE_RET();
518 } 806 }
519 807
520 -void OPPROTO op_rdwim(void) 808 +void OPPROTO op_rett(void)
521 { 809 {
522 - T0 = env->wim; 810 + helper_rett();
  811 + FORCE_RET();
523 } 812 }
524 813
525 -void OPPROTO op_wrwim(void) 814 +/* XXX: use another pointer for %iN registers to avoid slow wrapping
  815 + handling ? */
  816 +void OPPROTO op_save(void)
526 { 817 {
527 - env->wim = T0; 818 + uint32_t cwp;
  819 + cwp = (env->cwp - 1) & (NWINDOWS - 1);
  820 + if (env->wim & (1 << cwp)) {
  821 + raise_exception(TT_WIN_OVF);
  822 + }
  823 + set_cwp(cwp);
528 FORCE_RET(); 824 FORCE_RET();
529 } 825 }
530 826
531 -void OPPROTO op_rdpsr(void) 827 +void OPPROTO op_restore(void)
532 { 828 {
533 - do_rdpsr(); 829 + uint32_t cwp;
  830 + cwp = (env->cwp + 1) & (NWINDOWS - 1);
  831 + if (env->wim & (1 << cwp)) {
  832 + raise_exception(TT_WIN_UNF);
  833 + }
  834 + set_cwp(cwp);
  835 + FORCE_RET();
  836 +}
  837 +#else
  838 +void OPPROTO op_rdccr(void)
  839 +{
  840 + T0 = GET_CCR(env);
534 } 841 }
535 842
536 -void OPPROTO op_wrpsr(void) 843 +void OPPROTO op_wrccr(void)
537 { 844 {
538 - do_wrpsr();  
539 - FORCE_RET(); 845 + PUT_CCR(env, T0);
540 } 846 }
541 847
542 -void OPPROTO op_rdtbr(void) 848 +void OPPROTO op_rdtick(void)
543 { 849 {
544 - T0 = env->tbr; 850 + T0 = 0; // XXX read cycle counter and bit 31
545 } 851 }
546 852
547 -void OPPROTO op_wrtbr(void) 853 +void OPPROTO op_wrtick(void)
548 { 854 {
549 - env->tbr = T0;  
550 - FORCE_RET(); 855 + // XXX write cycle counter and bit 31
551 } 856 }
552 857
553 -void OPPROTO op_rett(void) 858 +void OPPROTO op_rdtpc(void)
554 { 859 {
555 - helper_rett();  
556 - FORCE_RET(); 860 + T0 = env->tpc[env->tl];
  861 +}
  862 +
  863 +void OPPROTO op_wrtpc(void)
  864 +{
  865 + env->tpc[env->tl] = T0;
  866 +}
  867 +
  868 +void OPPROTO op_rdtnpc(void)
  869 +{
  870 + T0 = env->tnpc[env->tl];
  871 +}
  872 +
  873 +void OPPROTO op_wrtnpc(void)
  874 +{
  875 + env->tnpc[env->tl] = T0;
  876 +}
  877 +
  878 +void OPPROTO op_rdtstate(void)
  879 +{
  880 + T0 = env->tstate[env->tl];
  881 +}
  882 +
  883 +void OPPROTO op_wrtstate(void)
  884 +{
  885 + env->tstate[env->tl] = T0;
  886 +}
  887 +
  888 +void OPPROTO op_rdtt(void)
  889 +{
  890 + T0 = env->tt[env->tl];
  891 +}
  892 +
  893 +void OPPROTO op_wrtt(void)
  894 +{
  895 + env->tt[env->tl] = T0;
  896 +}
  897 +
  898 +void OPPROTO op_rdpstate(void)
  899 +{
  900 + T0 = env->pstate;
  901 +}
  902 +
  903 +void OPPROTO op_wrpstate(void)
  904 +{
  905 + env->pstate = T0 & 0x1f;
  906 +}
  907 +
  908 +// CWP handling is reversed in V9, but we still use the V8 register
  909 +// order.
  910 +void OPPROTO op_rdcwp(void)
  911 +{
  912 + T0 = NWINDOWS - 1 - env->cwp;
  913 +}
  914 +
  915 +void OPPROTO op_wrcwp(void)
  916 +{
  917 + env->cwp = NWINDOWS - 1 - T0;
557 } 918 }
558 919
559 /* XXX: use another pointer for %iN registers to avoid slow wrapping 920 /* XXX: use another pointer for %iN registers to avoid slow wrapping
@@ -562,10 +923,20 @@ void OPPROTO op_save(void) @@ -562,10 +923,20 @@ void OPPROTO op_save(void)
562 { 923 {
563 uint32_t cwp; 924 uint32_t cwp;
564 cwp = (env->cwp - 1) & (NWINDOWS - 1); 925 cwp = (env->cwp - 1) & (NWINDOWS - 1);
565 - if (env->wim & (1 << cwp)) {  
566 - raise_exception(TT_WIN_OVF); 926 + if (env->cansave == 0) {
  927 + raise_exception(TT_SPILL | (env->otherwin != 0 ?
  928 + (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
  929 + ((env->wstate & 0x7) << 2)));
  930 + } else {
  931 + if (env->cleanwin - env->canrestore == 0) {
  932 + // XXX Clean windows without trap
  933 + raise_exception(TT_CLRWIN);
  934 + } else {
  935 + env->cansave--;
  936 + env->canrestore++;
  937 + set_cwp(cwp);
  938 + }
567 } 939 }
568 - set_cwp(cwp);  
569 FORCE_RET(); 940 FORCE_RET();
570 } 941 }
571 942
@@ -573,12 +944,18 @@ void OPPROTO op_restore(void) @@ -573,12 +944,18 @@ void OPPROTO op_restore(void)
573 { 944 {
574 uint32_t cwp; 945 uint32_t cwp;
575 cwp = (env->cwp + 1) & (NWINDOWS - 1); 946 cwp = (env->cwp + 1) & (NWINDOWS - 1);
576 - if (env->wim & (1 << cwp)) {  
577 - raise_exception(TT_WIN_UNF); 947 + if (env->canrestore == 0) {
  948 + raise_exception(TT_FILL | (env->otherwin != 0 ?
  949 + (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
  950 + ((env->wstate & 0x7) << 2)));
  951 + } else {
  952 + env->cansave++;
  953 + env->canrestore--;
  954 + set_cwp(cwp);
578 } 955 }
579 - set_cwp(cwp);  
580 FORCE_RET(); 956 FORCE_RET();
581 } 957 }
  958 +#endif
582 959
583 void OPPROTO op_exception(void) 960 void OPPROTO op_exception(void)
584 { 961 {
@@ -629,6 +1006,11 @@ void OPPROTO op_exit_tb(void) @@ -629,6 +1006,11 @@ void OPPROTO op_exit_tb(void)
629 EXIT_TB(); 1006 EXIT_TB();
630 } 1007 }
631 1008
  1009 +void OPPROTO op_eval_ba(void)
  1010 +{
  1011 + T2 = 1;
  1012 +}
  1013 +
632 void OPPROTO op_eval_be(void) 1014 void OPPROTO op_eval_be(void)
633 { 1015 {
634 T2 = FLAG_SET(PSR_ZERO); 1016 T2 = FLAG_SET(PSR_ZERO);
@@ -665,6 +1047,11 @@ void OPPROTO op_eval_bvs(void) @@ -665,6 +1047,11 @@ void OPPROTO op_eval_bvs(void)
665 T2 = FLAG_SET(PSR_OVF); 1047 T2 = FLAG_SET(PSR_OVF);
666 } 1048 }
667 1049
  1050 +void OPPROTO op_eval_bn(void)
  1051 +{
  1052 + T2 = 0;
  1053 +}
  1054 +
668 void OPPROTO op_eval_bneg(void) 1055 void OPPROTO op_eval_bneg(void)
669 { 1056 {
670 T2 = FLAG_SET(PSR_NEG); 1057 T2 = FLAG_SET(PSR_NEG);
@@ -711,101 +1098,156 @@ void OPPROTO op_eval_bvc(void) @@ -711,101 +1098,156 @@ void OPPROTO op_eval_bvc(void)
711 T2 = !FLAG_SET(PSR_OVF); 1098 T2 = !FLAG_SET(PSR_OVF);
712 } 1099 }
713 1100
714 -/* FCC1:FCC0: 0 =, 1 <, 2 >, 3 u */ 1101 +#ifdef TARGET_SPARC64
  1102 +void OPPROTO op_eval_xbe(void)
  1103 +{
  1104 + T2 = XFLAG_SET(PSR_ZERO);
  1105 +}
715 1106
716 -void OPPROTO op_eval_fbne(void) 1107 +void OPPROTO op_eval_xble(void)
717 { 1108 {
718 -// !0  
719 - T2 = (env->fsr & (FSR_FCC1 | FSR_FCC0)); /* L or G or U */ 1109 + target_ulong Z = XFLAG_SET(PSR_ZERO), N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
  1110 +
  1111 + T2 = Z | (N ^ V);
720 } 1112 }
721 1113
722 -void OPPROTO op_eval_fblg(void) 1114 +void OPPROTO op_eval_xbl(void)
723 { 1115 {
724 -// 1 or 2  
725 - T2 = FFLAG_SET(FSR_FCC0) ^ FFLAG_SET(FSR_FCC1); 1116 + target_ulong N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
  1117 +
  1118 + T2 = N ^ V;
726 } 1119 }
727 1120
728 -void OPPROTO op_eval_fbul(void) 1121 +void OPPROTO op_eval_xbleu(void)
729 { 1122 {
730 -// 1 or 3  
731 - T2 = FFLAG_SET(FSR_FCC0); 1123 + target_ulong Z = XFLAG_SET(PSR_ZERO), C = XFLAG_SET(PSR_CARRY);
  1124 +
  1125 + T2 = C | Z;
732 } 1126 }
733 1127
734 -void OPPROTO op_eval_fbl(void) 1128 +void OPPROTO op_eval_xbcs(void)
735 { 1129 {
736 -// 1  
737 - T2 = FFLAG_SET(FSR_FCC0) & !FFLAG_SET(FSR_FCC1); 1130 + T2 = XFLAG_SET(PSR_CARRY);
738 } 1131 }
739 1132
740 -void OPPROTO op_eval_fbug(void) 1133 +void OPPROTO op_eval_xbvs(void)
741 { 1134 {
742 -// 2 or 3  
743 - T2 = FFLAG_SET(FSR_FCC1); 1135 + T2 = XFLAG_SET(PSR_OVF);
744 } 1136 }
745 1137
746 -void OPPROTO op_eval_fbg(void) 1138 +void OPPROTO op_eval_xbneg(void)
747 { 1139 {
748 -// 2  
749 - T2 = !FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1); 1140 + T2 = XFLAG_SET(PSR_NEG);
750 } 1141 }
751 1142
752 -void OPPROTO op_eval_fbu(void) 1143 +void OPPROTO op_eval_xbne(void)
753 { 1144 {
754 -// 3  
755 - T2 = FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1); 1145 + T2 = !XFLAG_SET(PSR_ZERO);
756 } 1146 }
757 1147
758 -void OPPROTO op_eval_fbe(void) 1148 +void OPPROTO op_eval_xbg(void)
759 { 1149 {
760 -// 0  
761 - T2 = !FFLAG_SET(FSR_FCC0) & !FFLAG_SET(FSR_FCC1); 1150 + target_ulong Z = XFLAG_SET(PSR_ZERO), N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
  1151 +
  1152 + T2 = !(Z | (N ^ V));
762 } 1153 }
763 1154
764 -void OPPROTO op_eval_fbue(void) 1155 +void OPPROTO op_eval_xbge(void)
765 { 1156 {
766 -// 0 or 3  
767 - T2 = !(FFLAG_SET(FSR_FCC1) ^ FFLAG_SET(FSR_FCC0));  
768 - FORCE_RET(); 1157 + target_ulong N = XFLAG_SET(PSR_NEG), V = XFLAG_SET(PSR_OVF);
  1158 +
  1159 + T2 = !(N ^ V);
  1160 +}
  1161 +
  1162 +void OPPROTO op_eval_xbgu(void)
  1163 +{
  1164 + target_ulong Z = XFLAG_SET(PSR_ZERO), C = XFLAG_SET(PSR_CARRY);
  1165 +
  1166 + T2 = !(C | Z);
  1167 +}
  1168 +
  1169 +void OPPROTO op_eval_xbcc(void)
  1170 +{
  1171 + T2 = !XFLAG_SET(PSR_CARRY);
  1172 +}
  1173 +
  1174 +void OPPROTO op_eval_xbpos(void)
  1175 +{
  1176 + T2 = !XFLAG_SET(PSR_NEG);
  1177 +}
  1178 +
  1179 +void OPPROTO op_eval_xbvc(void)
  1180 +{
  1181 + T2 = !XFLAG_SET(PSR_OVF);
  1182 +}
  1183 +#endif
  1184 +
  1185 +#define FCC
  1186 +#define FFLAG_SET(x) (env->fsr & x? 1: 0)
  1187 +#include "fbranch_template.h"
  1188 +
  1189 +#ifdef TARGET_SPARC64
  1190 +#define FCC _fcc1
  1191 +#define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 32))? 1: 0)
  1192 +#include "fbranch_template.h"
  1193 +#define FCC _fcc2
  1194 +#define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 34))? 1: 0)
  1195 +#include "fbranch_template.h"
  1196 +#define FCC _fcc3
  1197 +#define FFLAG_SET(x) ((env->fsr & ((uint64_t)x >> 36))? 1: 0)
  1198 +#include "fbranch_template.h"
  1199 +#endif
  1200 +
  1201 +#ifdef TARGET_SPARC64
  1202 +void OPPROTO op_eval_brz(void)
  1203 +{
  1204 + T2 = T0;
769 } 1205 }
770 1206
771 -void OPPROTO op_eval_fbge(void) 1207 +void OPPROTO op_eval_brnz(void)
772 { 1208 {
773 -// 0 or 2  
774 - T2 = !FFLAG_SET(FSR_FCC0); 1209 + T2 = !T0;
775 } 1210 }
776 1211
777 -void OPPROTO op_eval_fbuge(void) 1212 +void OPPROTO op_eval_brlz(void)
778 { 1213 {
779 -// !1  
780 - T2 = !(FFLAG_SET(FSR_FCC0) & !FFLAG_SET(FSR_FCC1)); 1214 + T2 = ((int64_t)T0 < 0);
781 } 1215 }
782 1216
783 -void OPPROTO op_eval_fble(void) 1217 +void OPPROTO op_eval_brlez(void)
784 { 1218 {
785 -// 0 or 1  
786 - T2 = !FFLAG_SET(FSR_FCC1); 1219 + T2 = ((int64_t)T0 <= 0);
787 } 1220 }
788 1221
789 -void OPPROTO op_eval_fbule(void) 1222 +void OPPROTO op_eval_brgz(void)
790 { 1223 {
791 -// !2  
792 - T2 = !(!FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1)); 1224 + T2 = ((int64_t)T0 > 0);
793 } 1225 }
794 1226
795 -void OPPROTO op_eval_fbo(void) 1227 +void OPPROTO op_eval_brgez(void)
796 { 1228 {
797 -// !3  
798 - T2 = !(FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1)); 1229 + T2 = ((int64_t)T0 >= 0);
799 } 1230 }
800 1231
  1232 +void OPPROTO op_jmp_im64(void)
  1233 +{
  1234 + env->pc = PARAMQ1;
  1235 +}
  1236 +
  1237 +void OPPROTO op_movq_npc_im64(void)
  1238 +{
  1239 + env->npc = PARAMQ1;
  1240 +}
  1241 +#endif
  1242 +
801 void OPPROTO op_jmp_im(void) 1243 void OPPROTO op_jmp_im(void)
802 { 1244 {
803 - env->pc = PARAM1; 1245 + env->pc = (uint32_t)PARAM1;
804 } 1246 }
805 1247
806 void OPPROTO op_movl_npc_im(void) 1248 void OPPROTO op_movl_npc_im(void)
807 { 1249 {
808 - env->npc = PARAM1; 1250 + env->npc = (uint32_t)PARAM1;
809 } 1251 }
810 1252
811 void OPPROTO op_movl_npc_T0(void) 1253 void OPPROTO op_movl_npc_T0(void)
@@ -826,17 +1268,17 @@ void OPPROTO op_next_insn(void) @@ -826,17 +1268,17 @@ void OPPROTO op_next_insn(void)
826 1268
827 void OPPROTO op_branch(void) 1269 void OPPROTO op_branch(void)
828 { 1270 {
829 - env->npc = PARAM3; /* XXX: optimize */ 1271 + env->npc = (uint32_t)PARAM3; /* XXX: optimize */
830 JUMP_TB(op_branch, PARAM1, 0, PARAM2); 1272 JUMP_TB(op_branch, PARAM1, 0, PARAM2);
831 } 1273 }
832 1274
833 void OPPROTO op_branch2(void) 1275 void OPPROTO op_branch2(void)
834 { 1276 {
835 if (T2) { 1277 if (T2) {
836 - env->npc = PARAM2 + 4; 1278 + env->npc = (uint32_t)PARAM2 + 4;
837 JUMP_TB(op_branch2, PARAM1, 0, PARAM2); 1279 JUMP_TB(op_branch2, PARAM1, 0, PARAM2);
838 } else { 1280 } else {
839 - env->npc = PARAM3 + 4; 1281 + env->npc = (uint32_t)PARAM3 + 4;
840 JUMP_TB(op_branch2, PARAM1, 1, PARAM3); 1282 JUMP_TB(op_branch2, PARAM1, 1, PARAM3);
841 } 1283 }
842 FORCE_RET(); 1284 FORCE_RET();
@@ -845,10 +1287,10 @@ void OPPROTO op_branch2(void) @@ -845,10 +1287,10 @@ void OPPROTO op_branch2(void)
845 void OPPROTO op_branch_a(void) 1287 void OPPROTO op_branch_a(void)
846 { 1288 {
847 if (T2) { 1289 if (T2) {
848 - env->npc = PARAM2; /* XXX: optimize */ 1290 + env->npc = (uint32_t)PARAM2; /* XXX: optimize */
849 JUMP_TB(op_branch_a, PARAM1, 0, PARAM3); 1291 JUMP_TB(op_branch_a, PARAM1, 0, PARAM3);
850 } else { 1292 } else {
851 - env->npc = PARAM3 + 8; /* XXX: optimize */ 1293 + env->npc = (uint32_t)PARAM3 + 8; /* XXX: optimize */
852 JUMP_TB(op_branch_a, PARAM1, 1, PARAM3 + 4); 1294 JUMP_TB(op_branch_a, PARAM1, 1, PARAM3 + 4);
853 } 1295 }
854 FORCE_RET(); 1296 FORCE_RET();
@@ -857,9 +1299,9 @@ void OPPROTO op_branch_a(void) @@ -857,9 +1299,9 @@ void OPPROTO op_branch_a(void)
857 void OPPROTO op_generic_branch(void) 1299 void OPPROTO op_generic_branch(void)
858 { 1300 {
859 if (T2) { 1301 if (T2) {
860 - env->npc = PARAM1; 1302 + env->npc = (uint32_t)PARAM1;
861 } else { 1303 } else {
862 - env->npc = PARAM2; 1304 + env->npc = (uint32_t)PARAM2;
863 } 1305 }
864 FORCE_RET(); 1306 FORCE_RET();
865 } 1307 }
@@ -879,6 +1321,18 @@ void OPPROTO op_fabss(void) @@ -879,6 +1321,18 @@ void OPPROTO op_fabss(void)
879 do_fabss(); 1321 do_fabss();
880 } 1322 }
881 1323
  1324 +#ifdef TARGET_SPARC64
  1325 +void OPPROTO op_fnegd(void)
  1326 +{
  1327 + DT0 = -DT1;
  1328 +}
  1329 +
  1330 +void OPPROTO op_fabsd(void)
  1331 +{
  1332 + do_fabsd();
  1333 +}
  1334 +#endif
  1335 +
882 void OPPROTO op_fsqrts(void) 1336 void OPPROTO op_fsqrts(void)
883 { 1337 {
884 do_fsqrts(); 1338 do_fsqrts();
@@ -944,6 +1398,38 @@ void OPPROTO op_fcmpd(void) @@ -944,6 +1398,38 @@ void OPPROTO op_fcmpd(void)
944 do_fcmpd(); 1398 do_fcmpd();
945 } 1399 }
946 1400
  1401 +#ifdef TARGET_SPARC64
  1402 +void OPPROTO op_fcmps_fcc1(void)
  1403 +{
  1404 + do_fcmps_fcc1();
  1405 +}
  1406 +
  1407 +void OPPROTO op_fcmpd_fcc1(void)
  1408 +{
  1409 + do_fcmpd_fcc1();
  1410 +}
  1411 +
  1412 +void OPPROTO op_fcmps_fcc2(void)
  1413 +{
  1414 + do_fcmps_fcc2();
  1415 +}
  1416 +
  1417 +void OPPROTO op_fcmpd_fcc2(void)
  1418 +{
  1419 + do_fcmpd_fcc2();
  1420 +}
  1421 +
  1422 +void OPPROTO op_fcmps_fcc3(void)
  1423 +{
  1424 + do_fcmps_fcc3();
  1425 +}
  1426 +
  1427 +void OPPROTO op_fcmpd_fcc3(void)
  1428 +{
  1429 + do_fcmpd_fcc3();
  1430 +}
  1431 +#endif
  1432 +
947 #ifdef USE_INT_TO_FLOAT_HELPERS 1433 #ifdef USE_INT_TO_FLOAT_HELPERS
948 void OPPROTO op_fitos(void) 1434 void OPPROTO op_fitos(void)
949 { 1435 {
@@ -964,6 +1450,18 @@ void OPPROTO op_fitod(void) @@ -964,6 +1450,18 @@ void OPPROTO op_fitod(void)
964 { 1450 {
965 DT0 = (double) *((int32_t *)&FT1); 1451 DT0 = (double) *((int32_t *)&FT1);
966 } 1452 }
  1453 +
  1454 +#ifdef TARGET_SPARC64
  1455 +void OPPROTO op_fxtos(void)
  1456 +{
  1457 + FT0 = (float) *((int64_t *)&DT1);
  1458 +}
  1459 +
  1460 +void OPPROTO op_fxtod(void)
  1461 +{
  1462 + DT0 = (double) *((int64_t *)&DT1);
  1463 +}
  1464 +#endif
967 #endif 1465 #endif
968 1466
969 void OPPROTO op_fdtos(void) 1467 void OPPROTO op_fdtos(void)
@@ -986,6 +1484,102 @@ void OPPROTO op_fdtoi(void) @@ -986,6 +1484,102 @@ void OPPROTO op_fdtoi(void)
986 *((int32_t *)&FT0) = (int32_t) DT1; 1484 *((int32_t *)&FT0) = (int32_t) DT1;
987 } 1485 }
988 1486
  1487 +#ifdef TARGET_SPARC64
  1488 +void OPPROTO op_fstox(void)
  1489 +{
  1490 + *((int64_t *)&DT0) = (int64_t) FT1;
  1491 +}
  1492 +
  1493 +void OPPROTO op_fdtox(void)
  1494 +{
  1495 + *((int64_t *)&DT0) = (int64_t) DT1;
  1496 +}
  1497 +
  1498 +void OPPROTO op_fmovs_cc(void)
  1499 +{
  1500 + if (T2)
  1501 + FT0 = FT1;
  1502 +}
  1503 +
  1504 +void OPPROTO op_fmovd_cc(void)
  1505 +{
  1506 + if (T2)
  1507 + DT0 = DT1;
  1508 +}
  1509 +
  1510 +void OPPROTO op_mov_cc(void)
  1511 +{
  1512 + if (T2)
  1513 + T0 = T1;
  1514 +}
  1515 +
  1516 +void OPPROTO op_flushw(void)
  1517 +{
  1518 + if (env->cansave != NWINDOWS - 2) {
  1519 + raise_exception(TT_SPILL | (env->otherwin != 0 ?
  1520 + (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
  1521 + ((env->wstate & 0x7) << 2)));
  1522 + }
  1523 +}
  1524 +
  1525 +void OPPROTO op_saved(void)
  1526 +{
  1527 + env->cansave++;
  1528 + if (env->otherwin == 0)
  1529 + env->canrestore--;
  1530 +}
  1531 +
  1532 +void OPPROTO op_restored(void)
  1533 +{
  1534 + env->canrestore++;
  1535 + if (env->cleanwin < NWINDOWS - 1)
  1536 + env->cleanwin++;
  1537 + if (env->otherwin == 0)
  1538 + env->cansave--;
  1539 + else
  1540 + env->otherwin--;
  1541 +}
  1542 +
  1543 +void OPPROTO op_popc(void)
  1544 +{
  1545 + do_popc();
  1546 +}
  1547 +
  1548 +void OPPROTO op_done(void)
  1549 +{
  1550 + env->pc = env->tnpc[env->tl];
  1551 + env->npc = env->tnpc[env->tl] + 4;
  1552 + env->pstate = env->tstate[env->tl];
  1553 + env->tl--;
  1554 +}
  1555 +
  1556 +void OPPROTO op_retry(void)
  1557 +{
  1558 + env->pc = env->tpc[env->tl];
  1559 + env->npc = env->tnpc[env->tl];
  1560 + env->pstate = env->tstate[env->tl];
  1561 + env->tl--;
  1562 +}
  1563 +
  1564 +void OPPROTO op_sir(void)
  1565 +{
  1566 + // XXX
  1567 +
  1568 +}
  1569 +
  1570 +void OPPROTO op_ld_asi_reg()
  1571 +{
  1572 + T0 += PARAM1;
  1573 + helper_ld_asi(env->asi, PARAM2, PARAM3);
  1574 +}
  1575 +
  1576 +void OPPROTO op_st_asi_reg()
  1577 +{
  1578 + T0 += PARAM1;
  1579 + helper_st_asi(env->asi, PARAM2, PARAM3);
  1580 +}
  1581 +#endif
  1582 +
989 void OPPROTO op_ld_asi() 1583 void OPPROTO op_ld_asi()
990 { 1584 {
991 helper_ld_asi(PARAM1, PARAM2, PARAM3); 1585 helper_ld_asi(PARAM1, PARAM2, PARAM3);
target-sparc/op_helper.c
@@ -25,6 +25,13 @@ void do_fabss(void) @@ -25,6 +25,13 @@ void do_fabss(void)
25 FT0 = float32_abs(FT1); 25 FT0 = float32_abs(FT1);
26 } 26 }
27 27
  28 +#ifdef TARGET_SPARC64
  29 +void do_fabsd(void)
  30 +{
  31 + DT0 = float64_abs(DT1);
  32 +}
  33 +#endif
  34 +
28 void do_fsqrts(void) 35 void do_fsqrts(void)
29 { 36 {
30 FT0 = float32_sqrt(FT1, &env->fp_status); 37 FT0 = float32_sqrt(FT1, &env->fp_status);
@@ -35,48 +42,185 @@ void do_fsqrtd(void) @@ -35,48 +42,185 @@ void do_fsqrtd(void)
35 DT0 = float64_sqrt(DT1, &env->fp_status); 42 DT0 = float64_sqrt(DT1, &env->fp_status);
36 } 43 }
37 44
  45 +#define FS 0
38 void do_fcmps (void) 46 void do_fcmps (void)
39 { 47 {
  48 + env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
40 if (isnan(FT0) || isnan(FT1)) { 49 if (isnan(FT0) || isnan(FT1)) {
41 - T0 = FSR_FCC1 | FSR_FCC0;  
42 - env->fsr &= ~(FSR_FCC1 | FSR_FCC0);  
43 - env->fsr |= T0; 50 + T0 = (FSR_FCC1 | FSR_FCC0) << FS;
44 if (env->fsr & FSR_NVM) { 51 if (env->fsr & FSR_NVM) {
  52 + env->fsr |= T0;
45 raise_exception(TT_FP_EXCP); 53 raise_exception(TT_FP_EXCP);
46 } else { 54 } else {
47 env->fsr |= FSR_NVA; 55 env->fsr |= FSR_NVA;
48 } 56 }
49 } else if (FT0 < FT1) { 57 } else if (FT0 < FT1) {
50 - T0 = FSR_FCC0; 58 + T0 = FSR_FCC0 << FS;
51 } else if (FT0 > FT1) { 59 } else if (FT0 > FT1) {
52 - T0 = FSR_FCC1; 60 + T0 = FSR_FCC1 << FS;
53 } else { 61 } else {
54 T0 = 0; 62 T0 = 0;
55 } 63 }
56 - env->fsr = T0; 64 + env->fsr |= T0;
57 } 65 }
58 66
59 void do_fcmpd (void) 67 void do_fcmpd (void)
60 { 68 {
  69 + env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
  70 + if (isnan(DT0) || isnan(DT1)) {
  71 + T0 = (FSR_FCC1 | FSR_FCC0) << FS;
  72 + if (env->fsr & FSR_NVM) {
  73 + env->fsr |= T0;
  74 + raise_exception(TT_FP_EXCP);
  75 + } else {
  76 + env->fsr |= FSR_NVA;
  77 + }
  78 + } else if (DT0 < DT1) {
  79 + T0 = FSR_FCC0 << FS;
  80 + } else if (DT0 > DT1) {
  81 + T0 = FSR_FCC1 << FS;
  82 + } else {
  83 + T0 = 0;
  84 + }
  85 + env->fsr |= T0;
  86 +}
  87 +
  88 +#ifdef TARGET_SPARC64
  89 +#undef FS
  90 +#define FS 22
  91 +void do_fcmps_fcc1 (void)
  92 +{
  93 + env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
  94 + if (isnan(FT0) || isnan(FT1)) {
  95 + T0 = (FSR_FCC1 | FSR_FCC0) << FS;
  96 + if (env->fsr & FSR_NVM) {
  97 + env->fsr |= T0;
  98 + raise_exception(TT_FP_EXCP);
  99 + } else {
  100 + env->fsr |= FSR_NVA;
  101 + }
  102 + } else if (FT0 < FT1) {
  103 + T0 = FSR_FCC0 << FS;
  104 + } else if (FT0 > FT1) {
  105 + T0 = FSR_FCC1 << FS;
  106 + } else {
  107 + T0 = 0;
  108 + }
  109 + env->fsr |= T0;
  110 +}
  111 +
  112 +void do_fcmpd_fcc1 (void)
  113 +{
  114 + env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
  115 + if (isnan(DT0) || isnan(DT1)) {
  116 + T0 = (FSR_FCC1 | FSR_FCC0) << FS;
  117 + if (env->fsr & FSR_NVM) {
  118 + env->fsr |= T0;
  119 + raise_exception(TT_FP_EXCP);
  120 + } else {
  121 + env->fsr |= FSR_NVA;
  122 + }
  123 + } else if (DT0 < DT1) {
  124 + T0 = FSR_FCC0 << FS;
  125 + } else if (DT0 > DT1) {
  126 + T0 = FSR_FCC1 << FS;
  127 + } else {
  128 + T0 = 0;
  129 + }
  130 + env->fsr |= T0;
  131 +}
  132 +
  133 +#undef FS
  134 +#define FS 24
  135 +void do_fcmps_fcc2 (void)
  136 +{
  137 + env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
  138 + if (isnan(FT0) || isnan(FT1)) {
  139 + T0 = (FSR_FCC1 | FSR_FCC0) << FS;
  140 + if (env->fsr & FSR_NVM) {
  141 + env->fsr |= T0;
  142 + raise_exception(TT_FP_EXCP);
  143 + } else {
  144 + env->fsr |= FSR_NVA;
  145 + }
  146 + } else if (FT0 < FT1) {
  147 + T0 = FSR_FCC0 << FS;
  148 + } else if (FT0 > FT1) {
  149 + T0 = FSR_FCC1 << FS;
  150 + } else {
  151 + T0 = 0;
  152 + }
  153 + env->fsr |= T0;
  154 +}
  155 +
  156 +void do_fcmpd_fcc2 (void)
  157 +{
  158 + env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
61 if (isnan(DT0) || isnan(DT1)) { 159 if (isnan(DT0) || isnan(DT1)) {
62 - T0 = FSR_FCC1 | FSR_FCC0;  
63 - env->fsr &= ~(FSR_FCC1 | FSR_FCC0);  
64 - env->fsr |= T0; 160 + T0 = (FSR_FCC1 | FSR_FCC0) << FS;
65 if (env->fsr & FSR_NVM) { 161 if (env->fsr & FSR_NVM) {
  162 + env->fsr |= T0;
66 raise_exception(TT_FP_EXCP); 163 raise_exception(TT_FP_EXCP);
67 } else { 164 } else {
68 env->fsr |= FSR_NVA; 165 env->fsr |= FSR_NVA;
69 } 166 }
70 } else if (DT0 < DT1) { 167 } else if (DT0 < DT1) {
71 - T0 = FSR_FCC0; 168 + T0 = FSR_FCC0 << FS;
72 } else if (DT0 > DT1) { 169 } else if (DT0 > DT1) {
73 - T0 = FSR_FCC1; 170 + T0 = FSR_FCC1 << FS;
  171 + } else {
  172 + T0 = 0;
  173 + }
  174 + env->fsr |= T0;
  175 +}
  176 +
  177 +#undef FS
  178 +#define FS 26
  179 +void do_fcmps_fcc3 (void)
  180 +{
  181 + env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
  182 + if (isnan(FT0) || isnan(FT1)) {
  183 + T0 = (FSR_FCC1 | FSR_FCC0) << FS;
  184 + if (env->fsr & FSR_NVM) {
  185 + env->fsr |= T0;
  186 + raise_exception(TT_FP_EXCP);
  187 + } else {
  188 + env->fsr |= FSR_NVA;
  189 + }
  190 + } else if (FT0 < FT1) {
  191 + T0 = FSR_FCC0 << FS;
  192 + } else if (FT0 > FT1) {
  193 + T0 = FSR_FCC1 << FS;
74 } else { 194 } else {
75 T0 = 0; 195 T0 = 0;
76 } 196 }
77 - env->fsr = T0; 197 + env->fsr |= T0;
78 } 198 }
79 199
  200 +void do_fcmpd_fcc3 (void)
  201 +{
  202 + env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);
  203 + if (isnan(DT0) || isnan(DT1)) {
  204 + T0 = (FSR_FCC1 | FSR_FCC0) << FS;
  205 + if (env->fsr & FSR_NVM) {
  206 + env->fsr |= T0;
  207 + raise_exception(TT_FP_EXCP);
  208 + } else {
  209 + env->fsr |= FSR_NVA;
  210 + }
  211 + } else if (DT0 < DT1) {
  212 + T0 = FSR_FCC0 << FS;
  213 + } else if (DT0 > DT1) {
  214 + T0 = FSR_FCC1 << FS;
  215 + } else {
  216 + T0 = 0;
  217 + }
  218 + env->fsr |= T0;
  219 +}
  220 +#undef FS
  221 +#endif
  222 +
  223 +#ifndef TARGET_SPARC64
80 void helper_ld_asi(int asi, int size, int sign) 224 void helper_ld_asi(int asi, int size, int sign)
81 { 225 {
82 uint32_t ret; 226 uint32_t ret;
@@ -235,6 +379,255 @@ void helper_st_asi(int asi, int size, int sign) @@ -235,6 +379,255 @@ void helper_st_asi(int asi, int size, int sign)
235 } 379 }
236 } 380 }
237 381
  382 +#else
  383 +
  384 +void helper_ld_asi(int asi, int size, int sign)
  385 +{
  386 + uint64_t ret;
  387 +
  388 + if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
  389 + raise_exception(TT_PRIV_INSN);
  390 +
  391 + switch (asi) {
  392 + case 0x14: // Bypass
  393 + case 0x15: // Bypass, non-cacheable
  394 + {
  395 + cpu_physical_memory_read(T0, (void *) &ret, size);
  396 + if (size == 8)
  397 + tswap64s(&ret);
  398 + if (size == 4)
  399 + tswap32s((uint32_t *)&ret);
  400 + else if (size == 2)
  401 + tswap16s((uint16_t *)&ret);
  402 + break;
  403 + }
  404 + case 0x1c: // Bypass LE
  405 + case 0x1d: // Bypass, non-cacheable LE
  406 + // XXX
  407 + break;
  408 + case 0x45: // LSU
  409 + ret = env->lsu;
  410 + break;
  411 + case 0x50: // I-MMU regs
  412 + {
  413 + int reg = (T0 >> 3) & 0xf;
  414 +
  415 + ret = env->immuregs[reg];
  416 + break;
  417 + }
  418 + case 0x51: // I-MMU 8k TSB pointer
  419 + case 0x52: // I-MMU 64k TSB pointer
  420 + case 0x55: // I-MMU data access
  421 + case 0x56: // I-MMU tag read
  422 + break;
  423 + case 0x58: // D-MMU regs
  424 + {
  425 + int reg = (T0 >> 3) & 0xf;
  426 +
  427 + ret = env->dmmuregs[reg];
  428 + break;
  429 + }
  430 + case 0x59: // D-MMU 8k TSB pointer
  431 + case 0x5a: // D-MMU 64k TSB pointer
  432 + case 0x5b: // D-MMU data pointer
  433 + case 0x5d: // D-MMU data access
  434 + case 0x5e: // D-MMU tag read
  435 + break;
  436 + case 0x54: // I-MMU data in, WO
  437 + case 0x57: // I-MMU demap, WO
  438 + case 0x5c: // D-MMU data in, WO
  439 + case 0x5f: // D-MMU demap, WO
  440 + default:
  441 + ret = 0;
  442 + break;
  443 + }
  444 + T1 = ret;
  445 +}
  446 +
  447 +void helper_st_asi(int asi, int size, int sign)
  448 +{
  449 + if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
  450 + raise_exception(TT_PRIV_INSN);
  451 +
  452 + switch(asi) {
  453 + case 0x14: // Bypass
  454 + case 0x15: // Bypass, non-cacheable
  455 + {
  456 + target_ulong temp = T1;
  457 + if (size == 8)
  458 + tswap64s(&temp);
  459 + else if (size == 4)
  460 + tswap32s((uint32_t *)&temp);
  461 + else if (size == 2)
  462 + tswap16s((uint16_t *)&temp);
  463 + cpu_physical_memory_write(T0, (void *) &temp, size);
  464 + }
  465 + return;
  466 + case 0x1c: // Bypass LE
  467 + case 0x1d: // Bypass, non-cacheable LE
  468 + // XXX
  469 + return;
  470 + case 0x45: // LSU
  471 + {
  472 + uint64_t oldreg;
  473 +
  474 + oldreg = env->lsu;
  475 + env->lsu = T1 & (DMMU_E | IMMU_E);
  476 + // Mappings generated during D/I MMU disabled mode are
  477 + // invalid in normal mode
  478 + if (oldreg != env->lsu)
  479 + tlb_flush(env, 1);
  480 + return;
  481 + }
  482 + case 0x50: // I-MMU regs
  483 + {
  484 + int reg = (T0 >> 3) & 0xf;
  485 + uint64_t oldreg;
  486 +
  487 + oldreg = env->immuregs[reg];
  488 + switch(reg) {
  489 + case 0: // RO
  490 + case 4:
  491 + return;
  492 + case 1: // Not in I-MMU
  493 + case 2:
  494 + case 7:
  495 + case 8:
  496 + return;
  497 + case 3: // SFSR
  498 + if ((T1 & 1) == 0)
  499 + T1 = 0; // Clear SFSR
  500 + break;
  501 + case 5: // TSB access
  502 + case 6: // Tag access
  503 + default:
  504 + break;
  505 + }
  506 + env->immuregs[reg] = T1;
  507 +#ifdef DEBUG_MMU
  508 + if (oldreg != env->immuregs[reg]) {
  509 + printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->immuregs[reg]);
  510 + }
  511 + dump_mmu();
  512 +#endif
  513 + return;
  514 + }
  515 + case 0x54: // I-MMU data in
  516 + {
  517 + unsigned int i;
  518 +
  519 + // Try finding an invalid entry
  520 + for (i = 0; i < 64; i++) {
  521 + if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0) {
  522 + env->itlb_tag[i] = env->immuregs[6];
  523 + env->itlb_tte[i] = T1;
  524 + return;
  525 + }
  526 + }
  527 + // Try finding an unlocked entry
  528 + for (i = 0; i < 64; i++) {
  529 + if ((env->itlb_tte[i] & 0x40) == 0) {
  530 + env->itlb_tag[i] = env->immuregs[6];
  531 + env->itlb_tte[i] = T1;
  532 + return;
  533 + }
  534 + }
  535 + // error state?
  536 + return;
  537 + }
  538 + case 0x55: // I-MMU data access
  539 + {
  540 + unsigned int i = (T0 >> 3) & 0x3f;
  541 +
  542 + env->itlb_tag[i] = env->immuregs[6];
  543 + env->itlb_tte[i] = T1;
  544 + return;
  545 + }
  546 + case 0x57: // I-MMU demap
  547 + return;
  548 + case 0x58: // D-MMU regs
  549 + {
  550 + int reg = (T0 >> 3) & 0xf;
  551 + uint64_t oldreg;
  552 +
  553 + oldreg = env->dmmuregs[reg];
  554 + switch(reg) {
  555 + case 0: // RO
  556 + case 4:
  557 + return;
  558 + case 3: // SFSR
  559 + if ((T1 & 1) == 0) {
  560 + T1 = 0; // Clear SFSR, Fault address
  561 + env->dmmuregs[4] = 0;
  562 + }
  563 + env->dmmuregs[reg] = T1;
  564 + break;
  565 + case 1: // Primary context
  566 + case 2: // Secondary context
  567 + case 5: // TSB access
  568 + case 6: // Tag access
  569 + case 7: // Virtual Watchpoint
  570 + case 8: // Physical Watchpoint
  571 + default:
  572 + break;
  573 + }
  574 + env->dmmuregs[reg] = T1;
  575 +#ifdef DEBUG_MMU
  576 + if (oldreg != env->dmmuregs[reg]) {
  577 + printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->dmmuregs[reg]);
  578 + }
  579 + dump_mmu();
  580 +#endif
  581 + return;
  582 + }
  583 + case 0x5c: // D-MMU data in
  584 + {
  585 + unsigned int i;
  586 +
  587 + // Try finding an invalid entry
  588 + for (i = 0; i < 64; i++) {
  589 + if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0) {
  590 + env->dtlb_tag[i] = env->dmmuregs[6];
  591 + env->dtlb_tte[i] = T1;
  592 + return;
  593 + }
  594 + }
  595 + // Try finding an unlocked entry
  596 + for (i = 0; i < 64; i++) {
  597 + if ((env->dtlb_tte[i] & 0x40) == 0) {
  598 + env->dtlb_tag[i] = env->dmmuregs[6];
  599 + env->dtlb_tte[i] = T1;
  600 + return;
  601 + }
  602 + }
  603 + // error state?
  604 + return;
  605 + }
  606 + case 0x5d: // D-MMU data access
  607 + {
  608 + unsigned int i = (T0 >> 3) & 0x3f;
  609 +
  610 + env->dtlb_tag[i] = env->dmmuregs[6];
  611 + env->dtlb_tte[i] = T1;
  612 + return;
  613 + }
  614 + case 0x5f: // D-MMU demap
  615 + return;
  616 + case 0x51: // I-MMU 8k TSB pointer, RO
  617 + case 0x52: // I-MMU 64k TSB pointer, RO
  618 + case 0x56: // I-MMU tag read, RO
  619 + case 0x59: // D-MMU 8k TSB pointer, RO
  620 + case 0x5a: // D-MMU 64k TSB pointer, RO
  621 + case 0x5b: // D-MMU data pointer, RO
  622 + case 0x5e: // D-MMU tag read, RO
  623 + default:
  624 + return;
  625 + }
  626 +}
  627 +
  628 +#endif
  629 +
  630 +#ifndef TARGET_SPARC64
238 void helper_rett() 631 void helper_rett()
239 { 632 {
240 unsigned int cwp; 633 unsigned int cwp;
@@ -247,6 +640,7 @@ void helper_rett() @@ -247,6 +640,7 @@ void helper_rett()
247 set_cwp(cwp); 640 set_cwp(cwp);
248 env->psrs = env->psrps; 641 env->psrs = env->psrps;
249 } 642 }
  643 +#endif
250 644
251 void helper_ldfsr(void) 645 void helper_ldfsr(void)
252 { 646 {
@@ -288,6 +682,7 @@ void helper_debug() @@ -288,6 +682,7 @@ void helper_debug()
288 cpu_loop_exit(); 682 cpu_loop_exit();
289 } 683 }
290 684
  685 +#ifndef TARGET_SPARC64
291 void do_wrpsr() 686 void do_wrpsr()
292 { 687 {
293 PUT_PSR(env, T0); 688 PUT_PSR(env, T0);
@@ -297,3 +692,16 @@ void do_rdpsr() @@ -297,3 +692,16 @@ void do_rdpsr()
297 { 692 {
298 T0 = GET_PSR(env); 693 T0 = GET_PSR(env);
299 } 694 }
  695 +
  696 +#else
  697 +
  698 +void do_popc()
  699 +{
  700 + T0 = (T1 & 0x5555555555555555ULL) + ((T1 >> 1) & 0x5555555555555555ULL);
  701 + T0 = (T0 & 0x3333333333333333ULL) + ((T0 >> 2) & 0x3333333333333333ULL);
  702 + T0 = (T0 & 0x0f0f0f0f0f0f0f0fULL) + ((T0 >> 4) & 0x0f0f0f0f0f0f0f0fULL);
  703 + T0 = (T0 & 0x00ff00ff00ff00ffULL) + ((T0 >> 8) & 0x00ff00ff00ff00ffULL);
  704 + T0 = (T0 & 0x0000ffff0000ffffULL) + ((T0 >> 16) & 0x0000ffff0000ffffULL);
  705 + T0 = (T0 & 0x00000000ffffffffULL) + ((T0 >> 32) & 0x00000000ffffffffULL);
  706 +}
  707 +#endif
target-sparc/op_mem.h
@@ -2,9 +2,15 @@ @@ -2,9 +2,15 @@
2 #define SPARC_LD_OP(name, qp) \ 2 #define SPARC_LD_OP(name, qp) \
3 void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \ 3 void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
4 { \ 4 { \
5 - T1 = glue(qp, MEMSUFFIX)(T0); \ 5 + T1 = (target_ulong)glue(qp, MEMSUFFIX)(T0); \
6 } 6 }
7 7
  8 +#define SPARC_LD_OP_S(name, qp) \
  9 + void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
  10 + { \
  11 + T1 = (target_long)glue(qp, MEMSUFFIX)(T0); \
  12 + }
  13 +
8 #define SPARC_ST_OP(name, op) \ 14 #define SPARC_ST_OP(name, op) \
9 void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \ 15 void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
10 { \ 16 { \
@@ -14,8 +20,8 @@ void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \ @@ -14,8 +20,8 @@ void OPPROTO glue(glue(op_, name), MEMSUFFIX)(void) \
14 SPARC_LD_OP(ld, ldl); 20 SPARC_LD_OP(ld, ldl);
15 SPARC_LD_OP(ldub, ldub); 21 SPARC_LD_OP(ldub, ldub);
16 SPARC_LD_OP(lduh, lduw); 22 SPARC_LD_OP(lduh, lduw);
17 -SPARC_LD_OP(ldsb, ldsb);  
18 -SPARC_LD_OP(ldsh, ldsw); 23 +SPARC_LD_OP_S(ldsb, ldsb);
  24 +SPARC_LD_OP_S(ldsh, ldsw);
19 25
20 /*** Integer store ***/ 26 /*** Integer store ***/
21 SPARC_ST_OP(st, stl); 27 SPARC_ST_OP(st, stl);
@@ -68,4 +74,51 @@ void OPPROTO glue(op_lddf, MEMSUFFIX) (void) @@ -68,4 +74,51 @@ void OPPROTO glue(op_lddf, MEMSUFFIX) (void)
68 { 74 {
69 DT0 = glue(ldfq, MEMSUFFIX)(T0); 75 DT0 = glue(ldfq, MEMSUFFIX)(T0);
70 } 76 }
  77 +
  78 +#ifdef TARGET_SPARC64
  79 +/* XXX: Should be Atomically */
  80 +/* XXX: There are no cas[x] instructions, only cas[x]a */
  81 +void OPPROTO glue(op_cas, MEMSUFFIX)(void)
  82 +{
  83 + uint32_t tmp;
  84 +
  85 + tmp = glue(ldl, MEMSUFFIX)(T0);
  86 + T2 &= 0xffffffffULL;
  87 + if (tmp == (T1 & 0xffffffffULL)) {
  88 + glue(stl, MEMSUFFIX)(T0, T2);
  89 + }
  90 + T2 = tmp;
  91 +}
  92 +
  93 +void OPPROTO glue(op_casx, MEMSUFFIX)(void)
  94 +{
  95 + uint64_t tmp;
  96 +
  97 + // XXX
  98 + tmp = (uint64_t)glue(ldl, MEMSUFFIX)(T0) << 32;
  99 + tmp |= glue(ldl, MEMSUFFIX)(T0);
  100 + if (tmp == T1) {
  101 + glue(stq, MEMSUFFIX)(T0, T2);
  102 + }
  103 + T2 = tmp;
  104 +}
  105 +
  106 +void OPPROTO glue(op_ldsw, MEMSUFFIX)(void)
  107 +{
  108 + T1 = (int64_t)glue(ldl, MEMSUFFIX)(T0);
  109 +}
  110 +
  111 +void OPPROTO glue(op_ldx, MEMSUFFIX)(void)
  112 +{
  113 + // XXX
  114 + T1 = (uint64_t)glue(ldl, MEMSUFFIX)(T0) << 32;
  115 + T1 |= glue(ldl, MEMSUFFIX)(T0);
  116 +}
  117 +
  118 +void OPPROTO glue(op_stx, MEMSUFFIX)(void)
  119 +{
  120 + glue(stl, MEMSUFFIX)(T0, T1 >> 32);
  121 + glue(stl, MEMSUFFIX)(T0, T1 & 0xffffffff);
  122 +}
  123 +#endif
71 #undef MEMSUFFIX 124 #undef MEMSUFFIX
target-sparc/translate.c
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 SPARC translation 2 SPARC translation
3 3
4 Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at> 4 Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
5 - Copyright (C) 2003 Fabrice Bellard 5 + Copyright (C) 2003-2005 Fabrice Bellard
6 6
7 This library is free software; you can redistribute it and/or 7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public 8 modify it under the terms of the GNU Lesser General Public
@@ -22,12 +22,12 @@ @@ -22,12 +22,12 @@
22 /* 22 /*
23 TODO-list: 23 TODO-list:
24 24
  25 + Rest of V9 instructions, VIS instructions
25 NPC/PC static optimisations (use JUMP_TB when possible) 26 NPC/PC static optimisations (use JUMP_TB when possible)
26 - FPU-Instructions  
27 - Privileged instructions  
28 - Coprocessor-Instructions  
29 Optimize synthetic instructions 27 Optimize synthetic instructions
30 - Optional alignment and privileged instruction check 28 + Optional alignment check
  29 + 128-bit float
  30 + Tagged add/sub
31 */ 31 */
32 32
33 #include <stdarg.h> 33 #include <stdarg.h>
@@ -69,9 +69,29 @@ enum { @@ -69,9 +69,29 @@ enum {
69 69
70 #include "gen-op.h" 70 #include "gen-op.h"
71 71
  72 +// This function uses non-native bit order
72 #define GET_FIELD(X, FROM, TO) \ 73 #define GET_FIELD(X, FROM, TO) \
73 ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1)) 74 ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
74 75
  76 +// This function uses the order in the manuals, i.e. bit 0 is 2^0
  77 +#define GET_FIELD_SP(X, FROM, TO) \
  78 + GET_FIELD(X, 31 - (TO), 31 - (FROM))
  79 +
  80 +#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
  81 +#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), 32 - ((b) - (a) + 1))
  82 +
  83 +#ifdef TARGET_SPARC64
  84 +#define DFPREG(r) (((r & 1) << 6) | (r & 0x1e))
  85 +#else
  86 +#define DFPREG(r) (r)
  87 +#endif
  88 +
  89 +static int sign_extend(int x, int len)
  90 +{
  91 + len = 32 - len;
  92 + return (x << len) >> len;
  93 +}
  94 +
75 #define IS_IMM (insn & (1<<13)) 95 #define IS_IMM (insn & (1<<13))
76 96
77 static void disas_sparc_insn(DisasContext * dc); 97 static void disas_sparc_insn(DisasContext * dc);
@@ -258,6 +278,34 @@ static GenOpFunc1 *gen_op_movl_TN_im[3] = { @@ -258,6 +278,34 @@ static GenOpFunc1 *gen_op_movl_TN_im[3] = {
258 gen_op_movl_T2_im 278 gen_op_movl_T2_im
259 }; 279 };
260 280
  281 +// Sign extending version
  282 +static GenOpFunc1 * const gen_op_movl_TN_sim[3] = {
  283 + gen_op_movl_T0_sim,
  284 + gen_op_movl_T1_sim,
  285 + gen_op_movl_T2_sim
  286 +};
  287 +
  288 +#ifdef TARGET_SPARC64
  289 +#define GEN32(func, NAME) \
  290 +static GenOpFunc *NAME ## _table [64] = { \
  291 +NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \
  292 +NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \
  293 +NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11, \
  294 +NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15, \
  295 +NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19, \
  296 +NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23, \
  297 +NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27, \
  298 +NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31, \
  299 +NAME ## 32, 0, NAME ## 34, 0, NAME ## 36, 0, NAME ## 38, 0, \
  300 +NAME ## 40, 0, NAME ## 42, 0, NAME ## 44, 0, NAME ## 46, 0, \
  301 +NAME ## 48, 0, NAME ## 50, 0, NAME ## 52, 0, NAME ## 54, 0, \
  302 +NAME ## 56, 0, NAME ## 58, 0, NAME ## 60, 0, NAME ## 62, 0, \
  303 +}; \
  304 +static inline void func(int n) \
  305 +{ \
  306 + NAME ## _table[n](); \
  307 +}
  308 +#else
261 #define GEN32(func, NAME) \ 309 #define GEN32(func, NAME) \
262 static GenOpFunc *NAME ## _table [32] = { \ 310 static GenOpFunc *NAME ## _table [32] = { \
263 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \ 311 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \
@@ -273,22 +321,77 @@ static inline void func(int n) \ @@ -273,22 +321,77 @@ static inline void func(int n) \
273 { \ 321 { \
274 NAME ## _table[n](); \ 322 NAME ## _table[n](); \
275 } 323 }
  324 +#endif
276 325
277 /* floating point registers moves */ 326 /* floating point registers moves */
278 GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fprf); 327 GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fprf);
279 GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fprf); 328 GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fprf);
280 -GEN32(gen_op_load_fpr_FT2, gen_op_load_fpr_FT2_fprf);  
281 GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fprf); 329 GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fprf);
282 GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fprf); 330 GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fprf);
283 -GEN32(gen_op_store_FT2_fpr, gen_op_store_FT2_fpr_fprf);  
284 331
285 GEN32(gen_op_load_fpr_DT0, gen_op_load_fpr_DT0_fprf); 332 GEN32(gen_op_load_fpr_DT0, gen_op_load_fpr_DT0_fprf);
286 GEN32(gen_op_load_fpr_DT1, gen_op_load_fpr_DT1_fprf); 333 GEN32(gen_op_load_fpr_DT1, gen_op_load_fpr_DT1_fprf);
287 -GEN32(gen_op_load_fpr_DT2, gen_op_load_fpr_DT2_fprf);  
288 GEN32(gen_op_store_DT0_fpr, gen_op_store_DT0_fpr_fprf); 334 GEN32(gen_op_store_DT0_fpr, gen_op_store_DT0_fpr_fprf);
289 GEN32(gen_op_store_DT1_fpr, gen_op_store_DT1_fpr_fprf); 335 GEN32(gen_op_store_DT1_fpr, gen_op_store_DT1_fpr_fprf);
290 -GEN32(gen_op_store_DT2_fpr, gen_op_store_DT2_fpr_fprf);  
291 336
  337 +#ifdef TARGET_SPARC64
  338 +// 'a' versions allowed to user depending on asi
  339 +#if defined(CONFIG_USER_ONLY)
  340 +#define supervisor(dc) 0
  341 +#define gen_op_ldst(name) gen_op_##name##_raw()
  342 +#define OP_LD_TABLE(width) \
  343 + static void gen_op_##width##a(int insn, int is_ld, int size, int sign) \
  344 + { \
  345 + int asi, offset; \
  346 + \
  347 + if (IS_IMM) { \
  348 + offset = GET_FIELD(insn, 25, 31); \
  349 + if (is_ld) \
  350 + gen_op_ld_asi_reg(offset, size, sign); \
  351 + else \
  352 + gen_op_st_asi_reg(offset, size, sign); \
  353 + return; \
  354 + } \
  355 + asi = GET_FIELD(insn, 19, 26); \
  356 + switch (asi) { \
  357 + case 0x80: /* Primary address space */ \
  358 + gen_op_##width##_raw(); \
  359 + break; \
  360 + default: \
  361 + break; \
  362 + } \
  363 + }
  364 +
  365 +#else
  366 +#define gen_op_ldst(name) (*gen_op_##name[dc->mem_idx])()
  367 +#define OP_LD_TABLE(width) \
  368 + static GenOpFunc *gen_op_##width[] = { \
  369 + &gen_op_##width##_user, \
  370 + &gen_op_##width##_kernel, \
  371 + }; \
  372 + \
  373 + static void gen_op_##width##a(int insn, int is_ld, int size, int sign) \
  374 + { \
  375 + int asi, offset; \
  376 + \
  377 + if (IS_IMM) { \
  378 + offset = GET_FIELD(insn, 25, 31); \
  379 + if (is_ld) \
  380 + gen_op_ld_asi_reg(offset, size, sign); \
  381 + else \
  382 + gen_op_st_asi_reg(offset, size, sign); \
  383 + return; \
  384 + } \
  385 + asi = GET_FIELD(insn, 19, 26); \
  386 + if (is_ld) \
  387 + gen_op_ld_asi(asi, size, sign); \
  388 + else \
  389 + gen_op_st_asi(asi, size, sign); \
  390 + }
  391 +
  392 +#define supervisor(dc) (dc->mem_idx == 1)
  393 +#endif
  394 +#else
292 #if defined(CONFIG_USER_ONLY) 395 #if defined(CONFIG_USER_ONLY)
293 #define gen_op_ldst(name) gen_op_##name##_raw() 396 #define gen_op_ldst(name) gen_op_##name##_raw()
294 #define OP_LD_TABLE(width) 397 #define OP_LD_TABLE(width)
@@ -330,6 +433,7 @@ static void gen_op_##width##a(int insn, int is_ld, int size, int sign) \ @@ -330,6 +433,7 @@ static void gen_op_##width##a(int insn, int is_ld, int size, int sign) \
330 433
331 #define supervisor(dc) (dc->mem_idx == 1) 434 #define supervisor(dc) (dc->mem_idx == 1)
332 #endif 435 #endif
  436 +#endif
333 437
334 OP_LD_TABLE(ld); 438 OP_LD_TABLE(ld);
335 OP_LD_TABLE(st); 439 OP_LD_TABLE(st);
@@ -348,21 +452,44 @@ OP_LD_TABLE(stdf); @@ -348,21 +452,44 @@ OP_LD_TABLE(stdf);
348 OP_LD_TABLE(ldf); 452 OP_LD_TABLE(ldf);
349 OP_LD_TABLE(lddf); 453 OP_LD_TABLE(lddf);
350 454
351 -static inline void gen_movl_imm_TN(int reg, int imm) 455 +#ifdef TARGET_SPARC64
  456 +OP_LD_TABLE(ldsw);
  457 +OP_LD_TABLE(ldx);
  458 +OP_LD_TABLE(stx);
  459 +OP_LD_TABLE(cas);
  460 +OP_LD_TABLE(casx);
  461 +#endif
  462 +
  463 +static inline void gen_movl_imm_TN(int reg, uint32_t imm)
352 { 464 {
353 gen_op_movl_TN_im[reg] (imm); 465 gen_op_movl_TN_im[reg] (imm);
354 } 466 }
355 467
356 -static inline void gen_movl_imm_T1(int val) 468 +static inline void gen_movl_imm_T1(uint32_t val)
357 { 469 {
358 gen_movl_imm_TN(1, val); 470 gen_movl_imm_TN(1, val);
359 } 471 }
360 472
361 -static inline void gen_movl_imm_T0(int val) 473 +static inline void gen_movl_imm_T0(uint32_t val)
362 { 474 {
363 gen_movl_imm_TN(0, val); 475 gen_movl_imm_TN(0, val);
364 } 476 }
365 477
  478 +static inline void gen_movl_simm_TN(int reg, int32_t imm)
  479 +{
  480 + gen_op_movl_TN_sim[reg](imm);
  481 +}
  482 +
  483 +static inline void gen_movl_simm_T1(int32_t val)
  484 +{
  485 + gen_movl_simm_TN(1, val);
  486 +}
  487 +
  488 +static inline void gen_movl_simm_T0(int32_t val)
  489 +{
  490 + gen_movl_simm_TN(0, val);
  491 +}
  492 +
366 static inline void gen_movl_reg_TN(int reg, int t) 493 static inline void gen_movl_reg_TN(int reg, int t)
367 { 494 {
368 if (reg) 495 if (reg)
@@ -411,19 +538,45 @@ static inline void flush_T2(DisasContext * dc) @@ -411,19 +538,45 @@ static inline void flush_T2(DisasContext * dc)
411 } 538 }
412 } 539 }
413 540
  541 +static inline void gen_jmp_im(target_ulong pc)
  542 +{
  543 +#ifdef TARGET_SPARC64
  544 + if (pc == (uint32_t)pc) {
  545 + gen_op_jmp_im(pc);
  546 + } else {
  547 + gen_op_jmp_im64(pc >> 32, pc);
  548 + }
  549 +#else
  550 + gen_op_jmp_im(pc);
  551 +#endif
  552 +}
  553 +
  554 +static inline void gen_movl_npc_im(target_ulong npc)
  555 +{
  556 +#ifdef TARGET_SPARC64
  557 + if (npc == (uint32_t)npc) {
  558 + gen_op_movl_npc_im(npc);
  559 + } else {
  560 + gen_op_movq_npc_im64(npc >> 32, npc);
  561 + }
  562 +#else
  563 + gen_op_movl_npc_im(npc);
  564 +#endif
  565 +}
  566 +
414 static inline void save_npc(DisasContext * dc) 567 static inline void save_npc(DisasContext * dc)
415 { 568 {
416 if (dc->npc == JUMP_PC) { 569 if (dc->npc == JUMP_PC) {
417 gen_op_generic_branch(dc->jump_pc[0], dc->jump_pc[1]); 570 gen_op_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
418 dc->npc = DYNAMIC_PC; 571 dc->npc = DYNAMIC_PC;
419 } else if (dc->npc != DYNAMIC_PC) { 572 } else if (dc->npc != DYNAMIC_PC) {
420 - gen_op_movl_npc_im(dc->npc); 573 + gen_movl_npc_im(dc->npc);
421 } 574 }
422 } 575 }
423 576
424 static inline void save_state(DisasContext * dc) 577 static inline void save_state(DisasContext * dc)
425 { 578 {
426 - gen_op_jmp_im(dc->pc); 579 + gen_jmp_im(dc->pc);
427 save_npc(dc); 580 save_npc(dc);
428 } 581 }
429 582
@@ -441,110 +594,159 @@ static inline void gen_mov_pc_npc(DisasContext * dc) @@ -441,110 +594,159 @@ static inline void gen_mov_pc_npc(DisasContext * dc)
441 } 594 }
442 } 595 }
443 596
444 -static void gen_cond(int cond)  
445 -{  
446 - switch (cond) {  
447 - case 0x1:  
448 - gen_op_eval_be();  
449 - break;  
450 - case 0x2:  
451 - gen_op_eval_ble();  
452 - break;  
453 - case 0x3:  
454 - gen_op_eval_bl();  
455 - break;  
456 - case 0x4:  
457 - gen_op_eval_bleu();  
458 - break;  
459 - case 0x5:  
460 - gen_op_eval_bcs();  
461 - break;  
462 - case 0x6:  
463 - gen_op_eval_bneg();  
464 - break;  
465 - case 0x7:  
466 - gen_op_eval_bvs();  
467 - break;  
468 - case 0x9:  
469 - gen_op_eval_bne();  
470 - break;  
471 - case 0xa:  
472 - gen_op_eval_bg();  
473 - break;  
474 - case 0xb:  
475 - gen_op_eval_bge();  
476 - break;  
477 - case 0xc:  
478 - gen_op_eval_bgu();  
479 - break;  
480 - case 0xd:  
481 - gen_op_eval_bcc();  
482 - break;  
483 - case 0xe:  
484 - gen_op_eval_bpos();  
485 - break;  
486 - default:  
487 - case 0xf:  
488 - gen_op_eval_bvc();  
489 - break;  
490 - }  
491 -} 597 +static GenOpFunc * const gen_cond[2][16] = {
  598 + {
  599 + gen_op_eval_ba,
  600 + gen_op_eval_be,
  601 + gen_op_eval_ble,
  602 + gen_op_eval_bl,
  603 + gen_op_eval_bleu,
  604 + gen_op_eval_bcs,
  605 + gen_op_eval_bneg,
  606 + gen_op_eval_bvs,
  607 + gen_op_eval_bn,
  608 + gen_op_eval_bne,
  609 + gen_op_eval_bg,
  610 + gen_op_eval_bge,
  611 + gen_op_eval_bgu,
  612 + gen_op_eval_bcc,
  613 + gen_op_eval_bpos,
  614 + gen_op_eval_bvc,
  615 + },
  616 + {
  617 +#ifdef TARGET_SPARC64
  618 + gen_op_eval_ba,
  619 + gen_op_eval_xbe,
  620 + gen_op_eval_xble,
  621 + gen_op_eval_xbl,
  622 + gen_op_eval_xbleu,
  623 + gen_op_eval_xbcs,
  624 + gen_op_eval_xbneg,
  625 + gen_op_eval_xbvs,
  626 + gen_op_eval_bn,
  627 + gen_op_eval_xbne,
  628 + gen_op_eval_xbg,
  629 + gen_op_eval_xbge,
  630 + gen_op_eval_xbgu,
  631 + gen_op_eval_xbcc,
  632 + gen_op_eval_xbpos,
  633 + gen_op_eval_xbvc,
  634 +#endif
  635 + },
  636 +};
  637 +
  638 +static GenOpFunc * const gen_fcond[4][16] = {
  639 + {
  640 + gen_op_eval_ba,
  641 + gen_op_eval_fbne,
  642 + gen_op_eval_fblg,
  643 + gen_op_eval_fbul,
  644 + gen_op_eval_fbl,
  645 + gen_op_eval_fbug,
  646 + gen_op_eval_fbg,
  647 + gen_op_eval_fbu,
  648 + gen_op_eval_bn,
  649 + gen_op_eval_fbe,
  650 + gen_op_eval_fbue,
  651 + gen_op_eval_fbge,
  652 + gen_op_eval_fbuge,
  653 + gen_op_eval_fble,
  654 + gen_op_eval_fbule,
  655 + gen_op_eval_fbo,
  656 + },
  657 +#ifdef TARGET_SPARC64
  658 + {
  659 + gen_op_eval_ba,
  660 + gen_op_eval_fbne_fcc1,
  661 + gen_op_eval_fblg_fcc1,
  662 + gen_op_eval_fbul_fcc1,
  663 + gen_op_eval_fbl_fcc1,
  664 + gen_op_eval_fbug_fcc1,
  665 + gen_op_eval_fbg_fcc1,
  666 + gen_op_eval_fbu_fcc1,
  667 + gen_op_eval_bn,
  668 + gen_op_eval_fbe_fcc1,
  669 + gen_op_eval_fbue_fcc1,
  670 + gen_op_eval_fbge_fcc1,
  671 + gen_op_eval_fbuge_fcc1,
  672 + gen_op_eval_fble_fcc1,
  673 + gen_op_eval_fbule_fcc1,
  674 + gen_op_eval_fbo_fcc1,
  675 + },
  676 + {
  677 + gen_op_eval_ba,
  678 + gen_op_eval_fbne_fcc2,
  679 + gen_op_eval_fblg_fcc2,
  680 + gen_op_eval_fbul_fcc2,
  681 + gen_op_eval_fbl_fcc2,
  682 + gen_op_eval_fbug_fcc2,
  683 + gen_op_eval_fbg_fcc2,
  684 + gen_op_eval_fbu_fcc2,
  685 + gen_op_eval_bn,
  686 + gen_op_eval_fbe_fcc2,
  687 + gen_op_eval_fbue_fcc2,
  688 + gen_op_eval_fbge_fcc2,
  689 + gen_op_eval_fbuge_fcc2,
  690 + gen_op_eval_fble_fcc2,
  691 + gen_op_eval_fbule_fcc2,
  692 + gen_op_eval_fbo_fcc2,
  693 + },
  694 + {
  695 + gen_op_eval_ba,
  696 + gen_op_eval_fbne_fcc3,
  697 + gen_op_eval_fblg_fcc3,
  698 + gen_op_eval_fbul_fcc3,
  699 + gen_op_eval_fbl_fcc3,
  700 + gen_op_eval_fbug_fcc3,
  701 + gen_op_eval_fbg_fcc3,
  702 + gen_op_eval_fbu_fcc3,
  703 + gen_op_eval_bn,
  704 + gen_op_eval_fbe_fcc3,
  705 + gen_op_eval_fbue_fcc3,
  706 + gen_op_eval_fbge_fcc3,
  707 + gen_op_eval_fbuge_fcc3,
  708 + gen_op_eval_fble_fcc3,
  709 + gen_op_eval_fbule_fcc3,
  710 + gen_op_eval_fbo_fcc3,
  711 + },
  712 +#else
  713 + {}, {}, {},
  714 +#endif
  715 +};
492 716
493 -static void gen_fcond(int cond) 717 +#ifdef TARGET_SPARC64
  718 +static void gen_cond_reg(int cond)
494 { 719 {
495 switch (cond) { 720 switch (cond) {
496 case 0x1: 721 case 0x1:
497 - gen_op_eval_fbne(); 722 + gen_op_eval_brz();
498 break; 723 break;
499 case 0x2: 724 case 0x2:
500 - gen_op_eval_fblg(); 725 + gen_op_eval_brlez();
501 break; 726 break;
502 case 0x3: 727 case 0x3:
503 - gen_op_eval_fbul();  
504 - break;  
505 - case 0x4:  
506 - gen_op_eval_fbl(); 728 + gen_op_eval_brlz();
507 break; 729 break;
508 case 0x5: 730 case 0x5:
509 - gen_op_eval_fbug(); 731 + gen_op_eval_brnz();
510 break; 732 break;
511 case 0x6: 733 case 0x6:
512 - gen_op_eval_fbg();  
513 - break;  
514 - case 0x7:  
515 - gen_op_eval_fbu();  
516 - break;  
517 - case 0x9:  
518 - gen_op_eval_fbe();  
519 - break;  
520 - case 0xa:  
521 - gen_op_eval_fbue();  
522 - break;  
523 - case 0xb:  
524 - gen_op_eval_fbge();  
525 - break;  
526 - case 0xc:  
527 - gen_op_eval_fbuge();  
528 - break;  
529 - case 0xd:  
530 - gen_op_eval_fble();  
531 - break;  
532 - case 0xe:  
533 - gen_op_eval_fbule(); 734 + gen_op_eval_brgz();
534 break; 735 break;
535 default: 736 default:
536 - case 0xf:  
537 - gen_op_eval_fbo(); 737 + case 0x7:
  738 + gen_op_eval_brgez();
538 break; 739 break;
539 } 740 }
540 } 741 }
  742 +#endif
541 743
542 /* XXX: potentially incorrect if dynamic npc */ 744 /* XXX: potentially incorrect if dynamic npc */
543 -static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn) 745 +static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
544 { 746 {
545 unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29)); 747 unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
546 target_ulong target = dc->pc + offset; 748 target_ulong target = dc->pc + offset;
547 - 749 +
548 if (cond == 0x0) { 750 if (cond == 0x0) {
549 /* unconditional not taken */ 751 /* unconditional not taken */
550 if (a) { 752 if (a) {
@@ -565,7 +767,7 @@ static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn) @@ -565,7 +767,7 @@ static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn)
565 } 767 }
566 } else { 768 } else {
567 flush_T2(dc); 769 flush_T2(dc);
568 - gen_cond(cond); 770 + gen_cond[cc][cond]();
569 if (a) { 771 if (a) {
570 gen_op_branch_a((long)dc->tb, target, dc->npc); 772 gen_op_branch_a((long)dc->tb, target, dc->npc);
571 dc->is_br = 1; 773 dc->is_br = 1;
@@ -579,7 +781,7 @@ static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn) @@ -579,7 +781,7 @@ static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn)
579 } 781 }
580 782
581 /* XXX: potentially incorrect if dynamic npc */ 783 /* XXX: potentially incorrect if dynamic npc */
582 -static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn) 784 +static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
583 { 785 {
584 unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29)); 786 unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
585 target_ulong target = dc->pc + offset; 787 target_ulong target = dc->pc + offset;
@@ -604,7 +806,7 @@ static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn) @@ -604,7 +806,7 @@ static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn)
604 } 806 }
605 } else { 807 } else {
606 flush_T2(dc); 808 flush_T2(dc);
607 - gen_fcond(cond); 809 + gen_fcond[cc][cond]();
608 if (a) { 810 if (a) {
609 gen_op_branch_a((long)dc->tb, target, dc->npc); 811 gen_op_branch_a((long)dc->tb, target, dc->npc);
610 dc->is_br = 1; 812 dc->is_br = 1;
@@ -617,14 +819,41 @@ static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn) @@ -617,14 +819,41 @@ static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn)
617 } 819 }
618 } 820 }
619 821
620 -#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)  
621 -  
622 -static int sign_extend(int x, int len) 822 +#ifdef TARGET_SPARC64
  823 +/* XXX: potentially incorrect if dynamic npc */
  824 +static void do_branch_reg(DisasContext * dc, int32_t offset, uint32_t insn)
623 { 825 {
624 - len = 32 - len;  
625 - return (x << len) >> len; 826 + unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
  827 + target_ulong target = dc->pc + offset;
  828 +
  829 + flush_T2(dc);
  830 + gen_cond_reg(cond);
  831 + if (a) {
  832 + gen_op_branch_a((long)dc->tb, target, dc->npc);
  833 + dc->is_br = 1;
  834 + } else {
  835 + dc->pc = dc->npc;
  836 + dc->jump_pc[0] = target;
  837 + dc->jump_pc[1] = dc->npc + 4;
  838 + dc->npc = JUMP_PC;
  839 + }
626 } 840 }
627 841
  842 +static GenOpFunc * const gen_fcmps[4] = {
  843 + gen_op_fcmps,
  844 + gen_op_fcmps_fcc1,
  845 + gen_op_fcmps_fcc2,
  846 + gen_op_fcmps_fcc3,
  847 +};
  848 +
  849 +static GenOpFunc * const gen_fcmpd[4] = {
  850 + gen_op_fcmpd,
  851 + gen_op_fcmpd_fcc1,
  852 + gen_op_fcmpd_fcc2,
  853 + gen_op_fcmpd_fcc3,
  854 +};
  855 +#endif
  856 +
628 /* before an instruction, dc->pc must be static */ 857 /* before an instruction, dc->pc must be static */
629 static void disas_sparc_insn(DisasContext * dc) 858 static void disas_sparc_insn(DisasContext * dc)
630 { 859 {
@@ -639,19 +868,54 @@ static void disas_sparc_insn(DisasContext * dc) @@ -639,19 +868,54 @@ static void disas_sparc_insn(DisasContext * dc)
639 { 868 {
640 unsigned int xop = GET_FIELD(insn, 7, 9); 869 unsigned int xop = GET_FIELD(insn, 7, 9);
641 int32_t target; 870 int32_t target;
642 - target = GET_FIELD(insn, 10, 31);  
643 switch (xop) { 871 switch (xop) {
644 - case 0x0: /* UNIMPL */ 872 +#ifdef TARGET_SPARC64
645 case 0x1: /* V9 BPcc */ 873 case 0x1: /* V9 BPcc */
  874 + {
  875 + int cc;
  876 +
  877 + target = GET_FIELD_SP(insn, 0, 18);
  878 + target <<= 2;
  879 + target = sign_extend(target, 18);
  880 + cc = GET_FIELD_SP(insn, 20, 21);
  881 + if (cc == 0)
  882 + do_branch(dc, target, insn, 0);
  883 + else if (cc == 2)
  884 + do_branch(dc, target, insn, 1);
  885 + else
  886 + goto illegal_insn;
  887 + goto jmp_insn;
  888 + }
646 case 0x3: /* V9 BPr */ 889 case 0x3: /* V9 BPr */
  890 + {
  891 + target = GET_FIELD_SP(insn, 0, 13) |
  892 + (GET_FIELD_SP(insn, 20, 21) >> 7);
  893 + target <<= 2;
  894 + target = sign_extend(target, 16);
  895 + rs1 = GET_FIELD(insn, 13, 17);
  896 + gen_movl_T0_reg(rs1);
  897 + do_branch_reg(dc, target, insn);
  898 + goto jmp_insn;
  899 + }
647 case 0x5: /* V9 FBPcc */ 900 case 0x5: /* V9 FBPcc */
648 - default:  
649 - goto illegal_insn; 901 + {
  902 + int cc = GET_FIELD_SP(insn, 20, 21);
  903 +#if !defined(CONFIG_USER_ONLY)
  904 + gen_op_trap_ifnofpu();
  905 +#endif
  906 + target = GET_FIELD_SP(insn, 0, 18);
  907 + target <<= 2;
  908 + target = sign_extend(target, 19);
  909 + do_fbranch(dc, target, insn, cc);
  910 + goto jmp_insn;
  911 + }
  912 +#endif
650 case 0x2: /* BN+x */ 913 case 0x2: /* BN+x */
651 { 914 {
  915 + target = GET_FIELD(insn, 10, 31);
652 target <<= 2; 916 target <<= 2;
653 target = sign_extend(target, 22); 917 target = sign_extend(target, 22);
654 - do_branch(dc, target, insn); 918 + do_branch(dc, target, insn, 0);
655 goto jmp_insn; 919 goto jmp_insn;
656 } 920 }
657 case 0x6: /* FBN+x */ 921 case 0x6: /* FBN+x */
@@ -659,9 +923,10 @@ static void disas_sparc_insn(DisasContext * dc) @@ -659,9 +923,10 @@ static void disas_sparc_insn(DisasContext * dc)
659 #if !defined(CONFIG_USER_ONLY) 923 #if !defined(CONFIG_USER_ONLY)
660 gen_op_trap_ifnofpu(); 924 gen_op_trap_ifnofpu();
661 #endif 925 #endif
  926 + target = GET_FIELD(insn, 10, 31);
662 target <<= 2; 927 target <<= 2;
663 target = sign_extend(target, 22); 928 target = sign_extend(target, 22);
664 - do_fbranch(dc, target, insn); 929 + do_fbranch(dc, target, insn, 0);
665 goto jmp_insn; 930 goto jmp_insn;
666 } 931 }
667 case 0x4: /* SETHI */ 932 case 0x4: /* SETHI */
@@ -669,12 +934,16 @@ static void disas_sparc_insn(DisasContext * dc) @@ -669,12 +934,16 @@ static void disas_sparc_insn(DisasContext * dc)
669 #if defined(OPTIM) 934 #if defined(OPTIM)
670 if (rd) { // nop 935 if (rd) { // nop
671 #endif 936 #endif
672 - gen_movl_imm_T0(target << 10); 937 + uint32_t value = GET_FIELD(insn, 10, 31);
  938 + gen_movl_imm_T0(value << 10);
673 gen_movl_T0_reg(rd); 939 gen_movl_T0_reg(rd);
674 #if defined(OPTIM) 940 #if defined(OPTIM)
675 } 941 }
676 #endif 942 #endif
677 break; 943 break;
  944 + case 0x0: /* UNIMPL */
  945 + default:
  946 + goto illegal_insn;
678 } 947 }
679 break; 948 break;
680 } 949 }
@@ -695,6 +964,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -695,6 +964,7 @@ static void disas_sparc_insn(DisasContext * dc)
695 unsigned int xop = GET_FIELD(insn, 7, 12); 964 unsigned int xop = GET_FIELD(insn, 7, 12);
696 if (xop == 0x3a) { /* generate trap */ 965 if (xop == 0x3a) { /* generate trap */
697 int cond; 966 int cond;
  967 +
698 rs1 = GET_FIELD(insn, 13, 17); 968 rs1 = GET_FIELD(insn, 13, 17);
699 gen_movl_reg_T0(rs1); 969 gen_movl_reg_T0(rs1);
700 if (IS_IMM) { 970 if (IS_IMM) {
@@ -702,7 +972,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -702,7 +972,7 @@ static void disas_sparc_insn(DisasContext * dc)
702 #if defined(OPTIM) 972 #if defined(OPTIM)
703 if (rs2 != 0) { 973 if (rs2 != 0) {
704 #endif 974 #endif
705 - gen_movl_imm_T1(rs2); 975 + gen_movl_simm_T1(rs2);
706 gen_op_add_T1_T0(); 976 gen_op_add_T1_T0();
707 #if defined(OPTIM) 977 #if defined(OPTIM)
708 } 978 }
@@ -719,51 +989,141 @@ static void disas_sparc_insn(DisasContext * dc) @@ -719,51 +989,141 @@ static void disas_sparc_insn(DisasContext * dc)
719 #endif 989 #endif
720 } 990 }
721 save_state(dc); 991 save_state(dc);
722 - /* V9 icc/xcc */  
723 cond = GET_FIELD(insn, 3, 6); 992 cond = GET_FIELD(insn, 3, 6);
724 if (cond == 0x8) { 993 if (cond == 0x8) {
725 gen_op_trap_T0(); 994 gen_op_trap_T0();
726 dc->is_br = 1; 995 dc->is_br = 1;
727 goto jmp_insn; 996 goto jmp_insn;
728 } else if (cond != 0) { 997 } else if (cond != 0) {
729 - gen_cond(cond); 998 +#ifdef TARGET_SPARC64
  999 + /* V9 icc/xcc */
  1000 + int cc = GET_FIELD_SP(insn, 11, 12);
  1001 + if (cc == 0)
  1002 + gen_cond[0][cond]();
  1003 + else if (cc == 2)
  1004 + gen_cond[1][cond]();
  1005 + else
  1006 + goto illegal_insn;
  1007 +#else
  1008 + gen_cond[0][cond]();
  1009 +#endif
730 gen_op_trapcc_T0(); 1010 gen_op_trapcc_T0();
731 } 1011 }
732 } else if (xop == 0x28) { 1012 } else if (xop == 0x28) {
733 rs1 = GET_FIELD(insn, 13, 17); 1013 rs1 = GET_FIELD(insn, 13, 17);
734 switch(rs1) { 1014 switch(rs1) {
735 case 0: /* rdy */ 1015 case 0: /* rdy */
736 - gen_op_rdy(); 1016 + gen_op_movtl_T0_env(offsetof(CPUSPARCState, y));
737 gen_movl_T0_reg(rd); 1017 gen_movl_T0_reg(rd);
738 break; 1018 break;
739 case 15: /* stbar / V9 membar */ 1019 case 15: /* stbar / V9 membar */
740 break; /* no effect? */ 1020 break; /* no effect? */
741 - default: 1021 +#ifdef TARGET_SPARC64
742 case 0x2: /* V9 rdccr */ 1022 case 0x2: /* V9 rdccr */
  1023 + gen_op_rdccr();
  1024 + gen_movl_T0_reg(rd);
  1025 + break;
743 case 0x3: /* V9 rdasi */ 1026 case 0x3: /* V9 rdasi */
  1027 + gen_op_movl_T0_env(offsetof(CPUSPARCState, asi));
  1028 + gen_movl_T0_reg(rd);
  1029 + break;
744 case 0x4: /* V9 rdtick */ 1030 case 0x4: /* V9 rdtick */
  1031 + gen_op_rdtick();
  1032 + gen_movl_T0_reg(rd);
  1033 + break;
745 case 0x5: /* V9 rdpc */ 1034 case 0x5: /* V9 rdpc */
  1035 + gen_op_movl_T0_im(dc->pc);
  1036 + gen_movl_T0_reg(rd);
  1037 + break;
746 case 0x6: /* V9 rdfprs */ 1038 case 0x6: /* V9 rdfprs */
  1039 + gen_op_movl_T0_env(offsetof(CPUSPARCState, fprs));
  1040 + gen_movl_T0_reg(rd);
  1041 + break;
  1042 +#endif
  1043 + default:
747 goto illegal_insn; 1044 goto illegal_insn;
748 } 1045 }
749 #if !defined(CONFIG_USER_ONLY) 1046 #if !defined(CONFIG_USER_ONLY)
750 - } else if (xop == 0x29) { 1047 +#ifndef TARGET_SPARC64
  1048 + } else if (xop == 0x29) { /* rdpsr / V9 unimp */
751 if (!supervisor(dc)) 1049 if (!supervisor(dc))
752 goto priv_insn; 1050 goto priv_insn;
753 gen_op_rdpsr(); 1051 gen_op_rdpsr();
754 gen_movl_T0_reg(rd); 1052 gen_movl_T0_reg(rd);
755 break; 1053 break;
756 - } else if (xop == 0x2a) { 1054 +#endif
  1055 + } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
757 if (!supervisor(dc)) 1056 if (!supervisor(dc))
758 goto priv_insn; 1057 goto priv_insn;
759 - gen_op_rdwim(); 1058 +#ifdef TARGET_SPARC64
  1059 + rs1 = GET_FIELD(insn, 13, 17);
  1060 + switch (rs1) {
  1061 + case 0: // tpc
  1062 + gen_op_rdtpc();
  1063 + break;
  1064 + case 1: // tnpc
  1065 + gen_op_rdtnpc();
  1066 + break;
  1067 + case 2: // tstate
  1068 + gen_op_rdtstate();
  1069 + break;
  1070 + case 3: // tt
  1071 + gen_op_rdtt();
  1072 + break;
  1073 + case 4: // tick
  1074 + gen_op_rdtick();
  1075 + break;
  1076 + case 5: // tba
  1077 + gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
  1078 + break;
  1079 + case 6: // pstate
  1080 + gen_op_rdpstate();
  1081 + break;
  1082 + case 7: // tl
  1083 + gen_op_movl_T0_env(offsetof(CPUSPARCState, tl));
  1084 + break;
  1085 + case 8: // pil
  1086 + gen_op_movl_T0_env(offsetof(CPUSPARCState, psrpil));
  1087 + break;
  1088 + case 9: // cwp
  1089 + gen_op_rdcwp();
  1090 + break;
  1091 + case 10: // cansave
  1092 + gen_op_movl_T0_env(offsetof(CPUSPARCState, cansave));
  1093 + break;
  1094 + case 11: // canrestore
  1095 + gen_op_movl_T0_env(offsetof(CPUSPARCState, canrestore));
  1096 + break;
  1097 + case 12: // cleanwin
  1098 + gen_op_movl_T0_env(offsetof(CPUSPARCState, cleanwin));
  1099 + break;
  1100 + case 13: // otherwin
  1101 + gen_op_movl_T0_env(offsetof(CPUSPARCState, otherwin));
  1102 + break;
  1103 + case 14: // wstate
  1104 + gen_op_movl_T0_env(offsetof(CPUSPARCState, wstate));
  1105 + break;
  1106 + case 31: // ver
  1107 + gen_op_movtl_T0_env(offsetof(CPUSPARCState, version));
  1108 + break;
  1109 + case 15: // fq
  1110 + default:
  1111 + goto illegal_insn;
  1112 + }
  1113 +#else
  1114 + gen_op_movl_T0_env(offsetof(CPUSPARCState, wim));
  1115 +#endif
760 gen_movl_T0_reg(rd); 1116 gen_movl_T0_reg(rd);
761 break; 1117 break;
762 - } else if (xop == 0x2b) { 1118 + } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
  1119 +#ifdef TARGET_SPARC64
  1120 + gen_op_flushw();
  1121 +#else
763 if (!supervisor(dc)) 1122 if (!supervisor(dc))
764 goto priv_insn; 1123 goto priv_insn;
765 - gen_op_rdtbr(); 1124 + gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
766 gen_movl_T0_reg(rd); 1125 gen_movl_T0_reg(rd);
  1126 +#endif
767 break; 1127 break;
768 #endif 1128 #endif
769 } else if (xop == 0x34) { /* FPU Operations */ 1129 } else if (xop == 0x34) { /* FPU Operations */
@@ -794,9 +1154,9 @@ static void disas_sparc_insn(DisasContext * dc) @@ -794,9 +1154,9 @@ static void disas_sparc_insn(DisasContext * dc)
794 gen_op_store_FT0_fpr(rd); 1154 gen_op_store_FT0_fpr(rd);
795 break; 1155 break;
796 case 0x2a: /* fsqrtd */ 1156 case 0x2a: /* fsqrtd */
797 - gen_op_load_fpr_DT1(rs2); 1157 + gen_op_load_fpr_DT1(DFPREG(rs2));
798 gen_op_fsqrtd(); 1158 gen_op_fsqrtd();
799 - gen_op_store_DT0_fpr(rd); 1159 + gen_op_store_DT0_fpr(DFPREG(rd));
800 break; 1160 break;
801 case 0x2b: /* fsqrtq */ 1161 case 0x2b: /* fsqrtq */
802 goto nfpu_insn; 1162 goto nfpu_insn;
@@ -807,10 +1167,10 @@ static void disas_sparc_insn(DisasContext * dc) @@ -807,10 +1167,10 @@ static void disas_sparc_insn(DisasContext * dc)
807 gen_op_store_FT0_fpr(rd); 1167 gen_op_store_FT0_fpr(rd);
808 break; 1168 break;
809 case 0x42: 1169 case 0x42:
810 - gen_op_load_fpr_DT0(rs1);  
811 - gen_op_load_fpr_DT1(rs2); 1170 + gen_op_load_fpr_DT0(DFPREG(rs1));
  1171 + gen_op_load_fpr_DT1(DFPREG(rs2));
812 gen_op_faddd(); 1172 gen_op_faddd();
813 - gen_op_store_DT0_fpr(rd); 1173 + gen_op_store_DT0_fpr(DFPREG(rd));
814 break; 1174 break;
815 case 0x43: /* faddq */ 1175 case 0x43: /* faddq */
816 goto nfpu_insn; 1176 goto nfpu_insn;
@@ -821,10 +1181,10 @@ static void disas_sparc_insn(DisasContext * dc) @@ -821,10 +1181,10 @@ static void disas_sparc_insn(DisasContext * dc)
821 gen_op_store_FT0_fpr(rd); 1181 gen_op_store_FT0_fpr(rd);
822 break; 1182 break;
823 case 0x46: 1183 case 0x46:
824 - gen_op_load_fpr_DT0(rs1);  
825 - gen_op_load_fpr_DT1(rs2); 1184 + gen_op_load_fpr_DT0(DFPREG(rs1));
  1185 + gen_op_load_fpr_DT1(DFPREG(rs2));
826 gen_op_fsubd(); 1186 gen_op_fsubd();
827 - gen_op_store_DT0_fpr(rd); 1187 + gen_op_store_DT0_fpr(DFPREG(rd));
828 break; 1188 break;
829 case 0x47: /* fsubq */ 1189 case 0x47: /* fsubq */
830 goto nfpu_insn; 1190 goto nfpu_insn;
@@ -835,8 +1195,8 @@ static void disas_sparc_insn(DisasContext * dc) @@ -835,8 +1195,8 @@ static void disas_sparc_insn(DisasContext * dc)
835 gen_op_store_FT0_fpr(rd); 1195 gen_op_store_FT0_fpr(rd);
836 break; 1196 break;
837 case 0x4a: 1197 case 0x4a:
838 - gen_op_load_fpr_DT0(rs1);  
839 - gen_op_load_fpr_DT1(rs2); 1198 + gen_op_load_fpr_DT0(DFPREG(rs1));
  1199 + gen_op_load_fpr_DT1(DFPREG(rs2));
840 gen_op_fmuld(); 1200 gen_op_fmuld();
841 gen_op_store_DT0_fpr(rd); 1201 gen_op_store_DT0_fpr(rd);
842 break; 1202 break;
@@ -849,10 +1209,10 @@ static void disas_sparc_insn(DisasContext * dc) @@ -849,10 +1209,10 @@ static void disas_sparc_insn(DisasContext * dc)
849 gen_op_store_FT0_fpr(rd); 1209 gen_op_store_FT0_fpr(rd);
850 break; 1210 break;
851 case 0x4e: 1211 case 0x4e:
852 - gen_op_load_fpr_DT0(rs1);  
853 - gen_op_load_fpr_DT1(rs2); 1212 + gen_op_load_fpr_DT0(DFPREG(rs1));
  1213 + gen_op_load_fpr_DT1(DFPREG(rs2));
854 gen_op_fdivd(); 1214 gen_op_fdivd();
855 - gen_op_store_DT0_fpr(rd); 1215 + gen_op_store_DT0_fpr(DFPREG(rd));
856 break; 1216 break;
857 case 0x4f: /* fdivq */ 1217 case 0x4f: /* fdivq */
858 goto nfpu_insn; 1218 goto nfpu_insn;
@@ -860,7 +1220,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -860,7 +1220,7 @@ static void disas_sparc_insn(DisasContext * dc)
860 gen_op_load_fpr_FT0(rs1); 1220 gen_op_load_fpr_FT0(rs1);
861 gen_op_load_fpr_FT1(rs2); 1221 gen_op_load_fpr_FT1(rs2);
862 gen_op_fsmuld(); 1222 gen_op_fsmuld();
863 - gen_op_store_DT0_fpr(rd); 1223 + gen_op_store_DT0_fpr(DFPREG(rd));
864 break; 1224 break;
865 case 0x6e: /* fdmulq */ 1225 case 0x6e: /* fdmulq */
866 goto nfpu_insn; 1226 goto nfpu_insn;
@@ -870,7 +1230,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -870,7 +1230,7 @@ static void disas_sparc_insn(DisasContext * dc)
870 gen_op_store_FT0_fpr(rd); 1230 gen_op_store_FT0_fpr(rd);
871 break; 1231 break;
872 case 0xc6: 1232 case 0xc6:
873 - gen_op_load_fpr_DT1(rs2); 1233 + gen_op_load_fpr_DT1(DFPREG(rs2));
874 gen_op_fdtos(); 1234 gen_op_fdtos();
875 gen_op_store_FT0_fpr(rd); 1235 gen_op_store_FT0_fpr(rd);
876 break; 1236 break;
@@ -879,12 +1239,12 @@ static void disas_sparc_insn(DisasContext * dc) @@ -879,12 +1239,12 @@ static void disas_sparc_insn(DisasContext * dc)
879 case 0xc8: 1239 case 0xc8:
880 gen_op_load_fpr_FT1(rs2); 1240 gen_op_load_fpr_FT1(rs2);
881 gen_op_fitod(); 1241 gen_op_fitod();
882 - gen_op_store_DT0_fpr(rd); 1242 + gen_op_store_DT0_fpr(DFPREG(rd));
883 break; 1243 break;
884 case 0xc9: 1244 case 0xc9:
885 gen_op_load_fpr_FT1(rs2); 1245 gen_op_load_fpr_FT1(rs2);
886 gen_op_fstod(); 1246 gen_op_fstod();
887 - gen_op_store_DT0_fpr(rd); 1247 + gen_op_store_DT0_fpr(DFPREG(rd));
888 break; 1248 break;
889 case 0xcb: /* fqtod */ 1249 case 0xcb: /* fqtod */
890 goto nfpu_insn; 1250 goto nfpu_insn;
@@ -906,55 +1266,248 @@ static void disas_sparc_insn(DisasContext * dc) @@ -906,55 +1266,248 @@ static void disas_sparc_insn(DisasContext * dc)
906 break; 1266 break;
907 case 0xd3: /* fqtoi */ 1267 case 0xd3: /* fqtoi */
908 goto nfpu_insn; 1268 goto nfpu_insn;
909 - default: 1269 +#ifdef TARGET_SPARC64
910 case 0x2: /* V9 fmovd */ 1270 case 0x2: /* V9 fmovd */
  1271 + gen_op_load_fpr_DT0(DFPREG(rs2));
  1272 + gen_op_store_DT0_fpr(DFPREG(rd));
  1273 + break;
911 case 0x6: /* V9 fnegd */ 1274 case 0x6: /* V9 fnegd */
  1275 + gen_op_load_fpr_DT1(DFPREG(rs2));
  1276 + gen_op_fnegd();
  1277 + gen_op_store_DT0_fpr(DFPREG(rd));
  1278 + break;
912 case 0xa: /* V9 fabsd */ 1279 case 0xa: /* V9 fabsd */
  1280 + gen_op_load_fpr_DT1(DFPREG(rs2));
  1281 + gen_op_fabsd();
  1282 + gen_op_store_DT0_fpr(DFPREG(rd));
  1283 + break;
913 case 0x81: /* V9 fstox */ 1284 case 0x81: /* V9 fstox */
  1285 + gen_op_load_fpr_FT1(rs2);
  1286 + gen_op_fstox();
  1287 + gen_op_store_DT0_fpr(DFPREG(rd));
  1288 + break;
914 case 0x82: /* V9 fdtox */ 1289 case 0x82: /* V9 fdtox */
  1290 + gen_op_load_fpr_DT1(DFPREG(rs2));
  1291 + gen_op_fdtox();
  1292 + gen_op_store_DT0_fpr(DFPREG(rd));
  1293 + break;
915 case 0x84: /* V9 fxtos */ 1294 case 0x84: /* V9 fxtos */
  1295 + gen_op_load_fpr_DT1(DFPREG(rs2));
  1296 + gen_op_fxtos();
  1297 + gen_op_store_FT0_fpr(rd);
  1298 + break;
916 case 0x88: /* V9 fxtod */ 1299 case 0x88: /* V9 fxtod */
917 - 1300 + gen_op_load_fpr_DT1(DFPREG(rs2));
  1301 + gen_op_fxtod();
  1302 + gen_op_store_DT0_fpr(DFPREG(rd));
  1303 + break;
918 case 0x3: /* V9 fmovq */ 1304 case 0x3: /* V9 fmovq */
919 case 0x7: /* V9 fnegq */ 1305 case 0x7: /* V9 fnegq */
920 case 0xb: /* V9 fabsq */ 1306 case 0xb: /* V9 fabsq */
921 case 0x83: /* V9 fqtox */ 1307 case 0x83: /* V9 fqtox */
922 case 0x8c: /* V9 fxtoq */ 1308 case 0x8c: /* V9 fxtoq */
  1309 + goto nfpu_insn;
  1310 +#endif
  1311 + default:
923 goto illegal_insn; 1312 goto illegal_insn;
924 } 1313 }
925 } else if (xop == 0x35) { /* FPU Operations */ 1314 } else if (xop == 0x35) { /* FPU Operations */
  1315 +#ifdef TARGET_SPARC64
  1316 + int cond;
  1317 +#endif
926 #if !defined(CONFIG_USER_ONLY) 1318 #if !defined(CONFIG_USER_ONLY)
927 gen_op_trap_ifnofpu(); 1319 gen_op_trap_ifnofpu();
928 #endif 1320 #endif
929 rs1 = GET_FIELD(insn, 13, 17); 1321 rs1 = GET_FIELD(insn, 13, 17);
930 rs2 = GET_FIELD(insn, 27, 31); 1322 rs2 = GET_FIELD(insn, 27, 31);
931 xop = GET_FIELD(insn, 18, 26); 1323 xop = GET_FIELD(insn, 18, 26);
932 - /* V9 fmovscc: x5, cond = x >> 1 */  
933 - /* V9 fmovdcc: x6, cond = x >> 1 */  
934 -  
935 - /* V9 fmovqcc: x7, cond = x >> 1 */ 1324 +#ifdef TARGET_SPARC64
  1325 + if ((xop & 0x11f) == 0x005) { // V9 fmovsr
  1326 + cond = GET_FIELD_SP(insn, 14, 17);
  1327 + gen_op_load_fpr_FT0(rd);
  1328 + gen_op_load_fpr_FT1(rs2);
  1329 + rs1 = GET_FIELD(insn, 13, 17);
  1330 + gen_movl_reg_T0(rs1);
  1331 + flush_T2(dc);
  1332 + gen_cond_reg(cond);
  1333 + gen_op_fmovs_cc();
  1334 + gen_op_store_FT0_fpr(rd);
  1335 + break;
  1336 + } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
  1337 + cond = GET_FIELD_SP(insn, 14, 17);
  1338 + gen_op_load_fpr_DT0(rd);
  1339 + gen_op_load_fpr_DT1(rs2);
  1340 + flush_T2(dc);
  1341 + rs1 = GET_FIELD(insn, 13, 17);
  1342 + gen_movl_reg_T0(rs1);
  1343 + gen_cond_reg(cond);
  1344 + gen_op_fmovs_cc();
  1345 + gen_op_store_DT0_fpr(rd);
  1346 + break;
  1347 + } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
  1348 + goto nfpu_insn;
  1349 + }
  1350 +#endif
936 switch (xop) { 1351 switch (xop) {
937 - case 0x51: 1352 +#ifdef TARGET_SPARC64
  1353 + case 0x001: /* V9 fmovscc %fcc0 */
  1354 + cond = GET_FIELD_SP(insn, 14, 17);
  1355 + gen_op_load_fpr_FT0(rd);
  1356 + gen_op_load_fpr_FT1(rs2);
  1357 + flush_T2(dc);
  1358 + gen_fcond[0][cond]();
  1359 + gen_op_fmovs_cc();
  1360 + gen_op_store_FT0_fpr(rd);
  1361 + break;
  1362 + case 0x002: /* V9 fmovdcc %fcc0 */
  1363 + cond = GET_FIELD_SP(insn, 14, 17);
  1364 + gen_op_load_fpr_DT0(rd);
  1365 + gen_op_load_fpr_DT1(rs2);
  1366 + flush_T2(dc);
  1367 + gen_fcond[0][cond]();
  1368 + gen_op_fmovd_cc();
  1369 + gen_op_store_DT0_fpr(rd);
  1370 + break;
  1371 + case 0x003: /* V9 fmovqcc %fcc0 */
  1372 + goto nfpu_insn;
  1373 + case 0x041: /* V9 fmovscc %fcc1 */
  1374 + cond = GET_FIELD_SP(insn, 14, 17);
  1375 + gen_op_load_fpr_FT0(rd);
  1376 + gen_op_load_fpr_FT1(rs2);
  1377 + flush_T2(dc);
  1378 + gen_fcond[1][cond]();
  1379 + gen_op_fmovs_cc();
  1380 + gen_op_store_FT0_fpr(rd);
  1381 + break;
  1382 + case 0x042: /* V9 fmovdcc %fcc1 */
  1383 + cond = GET_FIELD_SP(insn, 14, 17);
  1384 + gen_op_load_fpr_DT0(rd);
  1385 + gen_op_load_fpr_DT1(rs2);
  1386 + flush_T2(dc);
  1387 + gen_fcond[1][cond]();
  1388 + gen_op_fmovd_cc();
  1389 + gen_op_store_DT0_fpr(rd);
  1390 + break;
  1391 + case 0x043: /* V9 fmovqcc %fcc1 */
  1392 + goto nfpu_insn;
  1393 + case 0x081: /* V9 fmovscc %fcc2 */
  1394 + cond = GET_FIELD_SP(insn, 14, 17);
  1395 + gen_op_load_fpr_FT0(rd);
  1396 + gen_op_load_fpr_FT1(rs2);
  1397 + flush_T2(dc);
  1398 + gen_fcond[2][cond]();
  1399 + gen_op_fmovs_cc();
  1400 + gen_op_store_FT0_fpr(rd);
  1401 + break;
  1402 + case 0x082: /* V9 fmovdcc %fcc2 */
  1403 + cond = GET_FIELD_SP(insn, 14, 17);
  1404 + gen_op_load_fpr_DT0(rd);
  1405 + gen_op_load_fpr_DT1(rs2);
  1406 + flush_T2(dc);
  1407 + gen_fcond[2][cond]();
  1408 + gen_op_fmovd_cc();
  1409 + gen_op_store_DT0_fpr(rd);
  1410 + break;
  1411 + case 0x083: /* V9 fmovqcc %fcc2 */
  1412 + goto nfpu_insn;
  1413 + case 0x0c1: /* V9 fmovscc %fcc3 */
  1414 + cond = GET_FIELD_SP(insn, 14, 17);
  1415 + gen_op_load_fpr_FT0(rd);
  1416 + gen_op_load_fpr_FT1(rs2);
  1417 + flush_T2(dc);
  1418 + gen_fcond[3][cond]();
  1419 + gen_op_fmovs_cc();
  1420 + gen_op_store_FT0_fpr(rd);
  1421 + break;
  1422 + case 0x0c2: /* V9 fmovdcc %fcc3 */
  1423 + cond = GET_FIELD_SP(insn, 14, 17);
  1424 + gen_op_load_fpr_DT0(rd);
  1425 + gen_op_load_fpr_DT1(rs2);
  1426 + flush_T2(dc);
  1427 + gen_fcond[3][cond]();
  1428 + gen_op_fmovd_cc();
  1429 + gen_op_store_DT0_fpr(rd);
  1430 + break;
  1431 + case 0x0c3: /* V9 fmovqcc %fcc3 */
  1432 + goto nfpu_insn;
  1433 + case 0x101: /* V9 fmovscc %icc */
  1434 + cond = GET_FIELD_SP(insn, 14, 17);
  1435 + gen_op_load_fpr_FT0(rd);
  1436 + gen_op_load_fpr_FT1(rs2);
  1437 + flush_T2(dc);
  1438 + gen_cond[0][cond]();
  1439 + gen_op_fmovs_cc();
  1440 + gen_op_store_FT0_fpr(rd);
  1441 + break;
  1442 + case 0x102: /* V9 fmovdcc %icc */
  1443 + cond = GET_FIELD_SP(insn, 14, 17);
  1444 + gen_op_load_fpr_DT0(rd);
  1445 + gen_op_load_fpr_DT1(rs2);
  1446 + flush_T2(dc);
  1447 + gen_cond[0][cond]();
  1448 + gen_op_fmovd_cc();
  1449 + gen_op_store_DT0_fpr(rd);
  1450 + break;
  1451 + case 0x103: /* V9 fmovqcc %icc */
  1452 + goto nfpu_insn;
  1453 + case 0x181: /* V9 fmovscc %xcc */
  1454 + cond = GET_FIELD_SP(insn, 14, 17);
  1455 + gen_op_load_fpr_FT0(rd);
  1456 + gen_op_load_fpr_FT1(rs2);
  1457 + flush_T2(dc);
  1458 + gen_cond[1][cond]();
  1459 + gen_op_fmovs_cc();
  1460 + gen_op_store_FT0_fpr(rd);
  1461 + break;
  1462 + case 0x182: /* V9 fmovdcc %xcc */
  1463 + cond = GET_FIELD_SP(insn, 14, 17);
  1464 + gen_op_load_fpr_DT0(rd);
  1465 + gen_op_load_fpr_DT1(rs2);
  1466 + flush_T2(dc);
  1467 + gen_cond[1][cond]();
  1468 + gen_op_fmovd_cc();
  1469 + gen_op_store_DT0_fpr(rd);
  1470 + break;
  1471 + case 0x183: /* V9 fmovqcc %xcc */
  1472 + goto nfpu_insn;
  1473 +#endif
  1474 + case 0x51: /* V9 %fcc */
938 gen_op_load_fpr_FT0(rs1); 1475 gen_op_load_fpr_FT0(rs1);
939 gen_op_load_fpr_FT1(rs2); 1476 gen_op_load_fpr_FT1(rs2);
  1477 +#ifdef TARGET_SPARC64
  1478 + gen_fcmps[rd & 3]();
  1479 +#else
940 gen_op_fcmps(); 1480 gen_op_fcmps();
  1481 +#endif
941 break; 1482 break;
942 - case 0x52:  
943 - gen_op_load_fpr_DT0(rs1);  
944 - gen_op_load_fpr_DT1(rs2); 1483 + case 0x52: /* V9 %fcc */
  1484 + gen_op_load_fpr_DT0(DFPREG(rs1));
  1485 + gen_op_load_fpr_DT1(DFPREG(rs2));
  1486 +#ifdef TARGET_SPARC64
  1487 + gen_fcmpd[rd & 3]();
  1488 +#else
945 gen_op_fcmpd(); 1489 gen_op_fcmpd();
  1490 +#endif
946 break; 1491 break;
947 case 0x53: /* fcmpq */ 1492 case 0x53: /* fcmpq */
948 goto nfpu_insn; 1493 goto nfpu_insn;
949 - case 0x55: /* fcmpes */ 1494 + case 0x55: /* fcmpes, V9 %fcc */
950 gen_op_load_fpr_FT0(rs1); 1495 gen_op_load_fpr_FT0(rs1);
951 gen_op_load_fpr_FT1(rs2); 1496 gen_op_load_fpr_FT1(rs2);
  1497 +#ifdef TARGET_SPARC64
  1498 + gen_fcmps[rd & 3]();
  1499 +#else
952 gen_op_fcmps(); /* XXX should trap if qNaN or sNaN */ 1500 gen_op_fcmps(); /* XXX should trap if qNaN or sNaN */
  1501 +#endif
953 break; 1502 break;
954 - case 0x56: /* fcmped */  
955 - gen_op_load_fpr_DT0(rs1);  
956 - gen_op_load_fpr_DT1(rs2); 1503 + case 0x56: /* fcmped, V9 %fcc */
  1504 + gen_op_load_fpr_DT0(DFPREG(rs1));
  1505 + gen_op_load_fpr_DT1(DFPREG(rs2));
  1506 +#ifdef TARGET_SPARC64
  1507 + gen_fcmpd[rd & 3]();
  1508 +#else
957 gen_op_fcmpd(); /* XXX should trap if qNaN or sNaN */ 1509 gen_op_fcmpd(); /* XXX should trap if qNaN or sNaN */
  1510 +#endif
958 break; 1511 break;
959 case 0x57: /* fcmpeq */ 1512 case 0x57: /* fcmpeq */
960 goto nfpu_insn; 1513 goto nfpu_insn;
@@ -970,7 +1523,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -970,7 +1523,7 @@ static void disas_sparc_insn(DisasContext * dc)
970 // or %g0, x, y -> mov T1, x; mov y, T1 1523 // or %g0, x, y -> mov T1, x; mov y, T1
971 if (IS_IMM) { /* immediate */ 1524 if (IS_IMM) { /* immediate */
972 rs2 = GET_FIELDs(insn, 19, 31); 1525 rs2 = GET_FIELDs(insn, 19, 31);
973 - gen_movl_imm_T1(rs2); 1526 + gen_movl_simm_T1(rs2);
974 } else { /* register */ 1527 } else { /* register */
975 rs2 = GET_FIELD(insn, 27, 31); 1528 rs2 = GET_FIELD(insn, 27, 31);
976 gen_movl_reg_T1(rs2); 1529 gen_movl_reg_T1(rs2);
@@ -982,7 +1535,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -982,7 +1535,7 @@ static void disas_sparc_insn(DisasContext * dc)
982 // or x, #0, y -> mov T1, x; mov y, T1 1535 // or x, #0, y -> mov T1, x; mov y, T1
983 rs2 = GET_FIELDs(insn, 19, 31); 1536 rs2 = GET_FIELDs(insn, 19, 31);
984 if (rs2 != 0) { 1537 if (rs2 != 0) {
985 - gen_movl_imm_T1(rs2); 1538 + gen_movl_simm_T1(rs2);
986 gen_op_or_T1_T0(); 1539 gen_op_or_T1_T0();
987 } 1540 }
988 } else { /* register */ 1541 } else { /* register */
@@ -1001,7 +1554,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1001,7 +1554,7 @@ static void disas_sparc_insn(DisasContext * dc)
1001 gen_movl_reg_T0(rs1); 1554 gen_movl_reg_T0(rs1);
1002 if (IS_IMM) { /* immediate */ 1555 if (IS_IMM) { /* immediate */
1003 rs2 = GET_FIELDs(insn, 19, 31); 1556 rs2 = GET_FIELDs(insn, 19, 31);
1004 - gen_movl_imm_T1(rs2); 1557 + gen_movl_simm_T1(rs2);
1005 } else { /* register */ 1558 } else { /* register */
1006 rs2 = GET_FIELD(insn, 27, 31); 1559 rs2 = GET_FIELD(insn, 27, 31);
1007 gen_movl_reg_T1(rs2); 1560 gen_movl_reg_T1(rs2);
@@ -1083,13 +1636,21 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1083,13 +1636,21 @@ static void disas_sparc_insn(DisasContext * dc)
1083 gen_op_div_cc(); 1636 gen_op_div_cc();
1084 break; 1637 break;
1085 default: 1638 default:
1086 - case 0x9: /* V9 mulx */  
1087 - case 0xd: /* V9 udivx */  
1088 goto illegal_insn; 1639 goto illegal_insn;
1089 } 1640 }
1090 gen_movl_T0_reg(rd); 1641 gen_movl_T0_reg(rd);
1091 } else { 1642 } else {
1092 switch (xop) { 1643 switch (xop) {
  1644 +#ifdef TARGET_SPARC64
  1645 + case 0x9: /* V9 mulx */
  1646 + gen_op_mulx_T1_T0();
  1647 + gen_movl_T0_reg(rd);
  1648 + break;
  1649 + case 0xd: /* V9 udivx */
  1650 + gen_op_udivx_T1_T0();
  1651 + gen_movl_T0_reg(rd);
  1652 + break;
  1653 +#endif
1093 case 0x20: /* taddcc */ 1654 case 0x20: /* taddcc */
1094 case 0x21: /* tsubcc */ 1655 case 0x21: /* tsubcc */
1095 case 0x22: /* taddcctv */ 1656 case 0x22: /* taddcctv */
@@ -1099,30 +1660,67 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1099,30 +1660,67 @@ static void disas_sparc_insn(DisasContext * dc)
1099 gen_op_mulscc_T1_T0(); 1660 gen_op_mulscc_T1_T0();
1100 gen_movl_T0_reg(rd); 1661 gen_movl_T0_reg(rd);
1101 break; 1662 break;
1102 - case 0x25: /* sll, V9 sllx */  
1103 - gen_op_sll(); 1663 + case 0x25: /* sll, V9 sllx ( == sll) */
  1664 + gen_op_sll();
1104 gen_movl_T0_reg(rd); 1665 gen_movl_T0_reg(rd);
1105 break; 1666 break;
1106 case 0x26: /* srl, V9 srlx */ 1667 case 0x26: /* srl, V9 srlx */
1107 - gen_op_srl(); 1668 +#ifdef TARGET_SPARC64
  1669 + if (insn & (1 << 12))
  1670 + gen_op_srlx();
  1671 + else
  1672 + gen_op_srl();
  1673 +#else
  1674 + gen_op_srl();
  1675 +#endif
1108 gen_movl_T0_reg(rd); 1676 gen_movl_T0_reg(rd);
1109 break; 1677 break;
1110 case 0x27: /* sra, V9 srax */ 1678 case 0x27: /* sra, V9 srax */
1111 - gen_op_sra(); 1679 +#ifdef TARGET_SPARC64
  1680 + if (insn & (1 << 12))
  1681 + gen_op_srax();
  1682 + else
  1683 + gen_op_sra();
  1684 +#else
  1685 + gen_op_sra();
  1686 +#endif
1112 gen_movl_T0_reg(rd); 1687 gen_movl_T0_reg(rd);
1113 break; 1688 break;
1114 case 0x30: 1689 case 0x30:
1115 { 1690 {
1116 - gen_op_xor_T1_T0();  
1117 switch(rd) { 1691 switch(rd) {
1118 - case 0:  
1119 - gen_op_wry(); 1692 + case 0: /* wry */
  1693 + gen_op_xor_T1_T0();
  1694 + gen_op_movtl_env_T0(offsetof(CPUSPARCState, y));
1120 break; 1695 break;
1121 - default: 1696 +#ifdef TARGET_SPARC64
1122 case 0x2: /* V9 wrccr */ 1697 case 0x2: /* V9 wrccr */
  1698 + gen_op_wrccr();
  1699 + break;
1123 case 0x3: /* V9 wrasi */ 1700 case 0x3: /* V9 wrasi */
  1701 + gen_op_movl_env_T0(offsetof(CPUSPARCState, asi));
  1702 + break;
1124 case 0x6: /* V9 wrfprs */ 1703 case 0x6: /* V9 wrfprs */
1125 - case 0xf: /* V9 sir */ 1704 + gen_op_movl_env_T0(offsetof(CPUSPARCState, fprs));
  1705 + break;
  1706 + case 0xf: /* V9 sir, nop if user */
  1707 +#if !defined(CONFIG_USER_ONLY)
  1708 + if (supervisor(dc))
  1709 + gen_op_sir();
  1710 +#endif
  1711 + break;
  1712 +#endif
  1713 + case 0x10: /* Performance Control */
  1714 + case 0x11: /* Performance Instrumentation Counter */
  1715 + case 0x12: /* Dispatch Control */
  1716 + case 0x13: /* Graphics Status */
  1717 + case 0x14: /* Softint set */
  1718 + case 0x15: /* Softint clear */
  1719 + case 0x16: /* Softint write */
  1720 + case 0x17: /* Tick compare */
  1721 + case 0x18: /* System tick */
  1722 + case 0x19: /* System tick compare */
  1723 + default:
1126 goto illegal_insn; 1724 goto illegal_insn;
1127 } 1725 }
1128 } 1726 }
@@ -1132,8 +1730,21 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1132,8 +1730,21 @@ static void disas_sparc_insn(DisasContext * dc)
1132 { 1730 {
1133 if (!supervisor(dc)) 1731 if (!supervisor(dc))
1134 goto priv_insn; 1732 goto priv_insn;
  1733 +#ifdef TARGET_SPARC64
  1734 + switch (rd) {
  1735 + case 0:
  1736 + gen_op_saved();
  1737 + break;
  1738 + case 1:
  1739 + gen_op_restored();
  1740 + break;
  1741 + default:
  1742 + goto illegal_insn;
  1743 + }
  1744 +#else
1135 gen_op_xor_T1_T0(); 1745 gen_op_xor_T1_T0();
1136 gen_op_wrpsr(); 1746 gen_op_wrpsr();
  1747 +#endif
1137 } 1748 }
1138 break; 1749 break;
1139 case 0x32: /* wrwim, V9 wrpr */ 1750 case 0x32: /* wrwim, V9 wrpr */
@@ -1141,28 +1752,179 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1141,28 +1752,179 @@ static void disas_sparc_insn(DisasContext * dc)
1141 if (!supervisor(dc)) 1752 if (!supervisor(dc))
1142 goto priv_insn; 1753 goto priv_insn;
1143 gen_op_xor_T1_T0(); 1754 gen_op_xor_T1_T0();
1144 - gen_op_wrwim(); 1755 +#ifdef TARGET_SPARC64
  1756 + switch (rd) {
  1757 + case 0: // tpc
  1758 + gen_op_wrtpc();
  1759 + break;
  1760 + case 1: // tnpc
  1761 + gen_op_wrtnpc();
  1762 + break;
  1763 + case 2: // tstate
  1764 + gen_op_wrtstate();
  1765 + break;
  1766 + case 3: // tt
  1767 + gen_op_wrtt();
  1768 + break;
  1769 + case 4: // tick
  1770 + gen_op_wrtick();
  1771 + break;
  1772 + case 5: // tba
  1773 + gen_op_movl_env_T0(offsetof(CPUSPARCState, tbr));
  1774 + break;
  1775 + case 6: // pstate
  1776 + gen_op_wrpstate();
  1777 + break;
  1778 + case 7: // tl
  1779 + gen_op_movl_env_T0(offsetof(CPUSPARCState, tl));
  1780 + break;
  1781 + case 8: // pil
  1782 + gen_op_movl_env_T0(offsetof(CPUSPARCState, psrpil));
  1783 + break;
  1784 + case 9: // cwp
  1785 + gen_op_wrcwp();
  1786 + break;
  1787 + case 10: // cansave
  1788 + gen_op_movl_env_T0(offsetof(CPUSPARCState, cansave));
  1789 + break;
  1790 + case 11: // canrestore
  1791 + gen_op_movl_env_T0(offsetof(CPUSPARCState, canrestore));
  1792 + break;
  1793 + case 12: // cleanwin
  1794 + gen_op_movl_env_T0(offsetof(CPUSPARCState, cleanwin));
  1795 + break;
  1796 + case 13: // otherwin
  1797 + gen_op_movl_env_T0(offsetof(CPUSPARCState, otherwin));
  1798 + break;
  1799 + case 14: // wstate
  1800 + gen_op_movl_env_T0(offsetof(CPUSPARCState, wstate));
  1801 + break;
  1802 + default:
  1803 + goto illegal_insn;
  1804 + }
  1805 +#else
  1806 + gen_op_movl_env_T0(offsetof(CPUSPARCState, wim));
  1807 +#endif
1145 } 1808 }
1146 break; 1809 break;
1147 - case 0x33: 1810 +#ifndef TARGET_SPARC64
  1811 + case 0x33: /* wrtbr, V9 unimp */
1148 { 1812 {
1149 if (!supervisor(dc)) 1813 if (!supervisor(dc))
1150 goto priv_insn; 1814 goto priv_insn;
1151 gen_op_xor_T1_T0(); 1815 gen_op_xor_T1_T0();
1152 - gen_op_wrtbr(); 1816 + gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
1153 } 1817 }
1154 break; 1818 break;
1155 #endif 1819 #endif
1156 - default:  
1157 - case 0x2a: /* V9 rdpr */  
1158 - case 0x2b: /* V9 flushw */ 1820 +#endif
  1821 +#ifdef TARGET_SPARC64
1159 case 0x2c: /* V9 movcc */ 1822 case 0x2c: /* V9 movcc */
  1823 + {
  1824 + int cc = GET_FIELD_SP(insn, 11, 12);
  1825 + int cond = GET_FIELD_SP(insn, 14, 17);
  1826 + if (IS_IMM) { /* immediate */
  1827 + rs2 = GET_FIELD_SPs(insn, 0, 10);
  1828 + gen_movl_simm_T1(rs2);
  1829 + }
  1830 + else {
  1831 + rs2 = GET_FIELD_SP(insn, 0, 4);
  1832 + gen_movl_reg_T1(rs2);
  1833 + }
  1834 + gen_movl_reg_T0(rd);
  1835 + flush_T2(dc);
  1836 + if (insn & (1 << 18)) {
  1837 + if (cc == 0)
  1838 + gen_cond[0][cond]();
  1839 + else if (cc == 2)
  1840 + gen_cond[1][cond]();
  1841 + else
  1842 + goto illegal_insn;
  1843 + } else {
  1844 + gen_fcond[cc][cond]();
  1845 + }
  1846 + gen_op_mov_cc();
  1847 + gen_movl_T0_reg(rd);
  1848 + break;
  1849 + }
1160 case 0x2d: /* V9 sdivx */ 1850 case 0x2d: /* V9 sdivx */
  1851 + gen_op_sdivx_T1_T0();
  1852 + gen_movl_T0_reg(rd);
  1853 + break;
1161 case 0x2e: /* V9 popc */ 1854 case 0x2e: /* V9 popc */
  1855 + {
  1856 + if (IS_IMM) { /* immediate */
  1857 + rs2 = GET_FIELD_SPs(insn, 0, 12);
  1858 + gen_movl_simm_T1(rs2);
  1859 + // XXX optimize: popc(constant)
  1860 + }
  1861 + else {
  1862 + rs2 = GET_FIELD_SP(insn, 0, 4);
  1863 + gen_movl_reg_T1(rs2);
  1864 + }
  1865 + gen_op_popc();
  1866 + gen_movl_T0_reg(rd);
  1867 + }
1162 case 0x2f: /* V9 movr */ 1868 case 0x2f: /* V9 movr */
  1869 + {
  1870 + int cond = GET_FIELD_SP(insn, 10, 12);
  1871 + rs1 = GET_FIELD(insn, 13, 17);
  1872 + flush_T2(dc);
  1873 + gen_movl_reg_T0(rs1);
  1874 + gen_cond_reg(cond);
  1875 + if (IS_IMM) { /* immediate */
  1876 + rs2 = GET_FIELD_SPs(insn, 0, 10);
  1877 + gen_movl_simm_T1(rs2);
  1878 + }
  1879 + else {
  1880 + rs2 = GET_FIELD_SP(insn, 0, 4);
  1881 + gen_movl_reg_T1(rs2);
  1882 + }
  1883 + gen_movl_reg_T0(rd);
  1884 + gen_op_mov_cc();
  1885 + gen_movl_T0_reg(rd);
  1886 + break;
  1887 + }
  1888 + case 0x36: /* UltraSparc shutdown, VIS */
  1889 + {
  1890 + // XXX
  1891 + }
  1892 +#endif
  1893 + default:
1163 goto illegal_insn; 1894 goto illegal_insn;
1164 } 1895 }
1165 } 1896 }
  1897 +#ifdef TARGET_SPARC64
  1898 + } else if (xop == 0x39) { /* V9 return */
  1899 + gen_op_restore();
  1900 + rs1 = GET_FIELD(insn, 13, 17);
  1901 + gen_movl_reg_T0(rs1);
  1902 + if (IS_IMM) { /* immediate */
  1903 + rs2 = GET_FIELDs(insn, 19, 31);
  1904 +#if defined(OPTIM)
  1905 + if (rs2) {
  1906 +#endif
  1907 + gen_movl_simm_T1(rs2);
  1908 + gen_op_add_T1_T0();
  1909 +#if defined(OPTIM)
  1910 + }
  1911 +#endif
  1912 + } else { /* register */
  1913 + rs2 = GET_FIELD(insn, 27, 31);
  1914 +#if defined(OPTIM)
  1915 + if (rs2) {
  1916 +#endif
  1917 + gen_movl_reg_T1(rs2);
  1918 + gen_op_add_T1_T0();
  1919 +#if defined(OPTIM)
  1920 + }
  1921 +#endif
  1922 + }
  1923 + gen_mov_pc_npc(dc);
  1924 + gen_op_movl_npc_T0();
  1925 + dc->npc = DYNAMIC_PC;
  1926 + goto jmp_insn;
  1927 +#endif
1166 } else { 1928 } else {
1167 rs1 = GET_FIELD(insn, 13, 17); 1929 rs1 = GET_FIELD(insn, 13, 17);
1168 gen_movl_reg_T0(rs1); 1930 gen_movl_reg_T0(rs1);
@@ -1171,7 +1933,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1171,7 +1933,7 @@ static void disas_sparc_insn(DisasContext * dc)
1171 #if defined(OPTIM) 1933 #if defined(OPTIM)
1172 if (rs2) { 1934 if (rs2) {
1173 #endif 1935 #endif
1174 - gen_movl_imm_T1(rs2); 1936 + gen_movl_simm_T1(rs2);
1175 gen_op_add_T1_T0(); 1937 gen_op_add_T1_T0();
1176 #if defined(OPTIM) 1938 #if defined(OPTIM)
1177 } 1939 }
@@ -1199,7 +1961,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1199,7 +1961,7 @@ static void disas_sparc_insn(DisasContext * dc)
1199 dc->npc = DYNAMIC_PC; 1961 dc->npc = DYNAMIC_PC;
1200 } 1962 }
1201 goto jmp_insn; 1963 goto jmp_insn;
1202 -#if !defined(CONFIG_USER_ONLY) 1964 +#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
1203 case 0x39: /* rett, V9 return */ 1965 case 0x39: /* rett, V9 return */
1204 { 1966 {
1205 if (!supervisor(dc)) 1967 if (!supervisor(dc))
@@ -1224,8 +1986,27 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1224,8 +1986,27 @@ static void disas_sparc_insn(DisasContext * dc)
1224 gen_op_restore(); 1986 gen_op_restore();
1225 gen_movl_T0_reg(rd); 1987 gen_movl_T0_reg(rd);
1226 break; 1988 break;
1227 - default: 1989 +#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
1228 case 0x3e: /* V9 done/retry */ 1990 case 0x3e: /* V9 done/retry */
  1991 + {
  1992 + switch (rd) {
  1993 + case 0:
  1994 + if (!supervisor(dc))
  1995 + goto priv_insn;
  1996 + gen_op_done();
  1997 + break;
  1998 + case 1:
  1999 + if (!supervisor(dc))
  2000 + goto priv_insn;
  2001 + gen_op_retry();
  2002 + break;
  2003 + default:
  2004 + goto illegal_insn;
  2005 + }
  2006 + }
  2007 + break;
  2008 +#endif
  2009 + default:
1229 goto illegal_insn; 2010 goto illegal_insn;
1230 } 2011 }
1231 } 2012 }
@@ -1242,7 +2023,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1242,7 +2023,7 @@ static void disas_sparc_insn(DisasContext * dc)
1242 #if defined(OPTIM) 2023 #if defined(OPTIM)
1243 if (rs2 != 0) { 2024 if (rs2 != 0) {
1244 #endif 2025 #endif
1245 - gen_movl_imm_T1(rs2); 2026 + gen_movl_simm_T1(rs2);
1246 gen_op_add_T1_T0(); 2027 gen_op_add_T1_T0();
1247 #if defined(OPTIM) 2028 #if defined(OPTIM)
1248 } 2029 }
@@ -1258,8 +2039,9 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1258,8 +2039,9 @@ static void disas_sparc_insn(DisasContext * dc)
1258 } 2039 }
1259 #endif 2040 #endif
1260 } 2041 }
1261 - if (xop < 4 || (xop > 7 && xop < 0x14) || \  
1262 - (xop > 0x17 && xop < 0x20)) { 2042 + if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) || \
  2043 + (xop > 0x17 && xop < 0x1d ) || \
  2044 + (xop > 0x2c && xop < 0x33) || xop == 0x1f) {
1263 switch (xop) { 2045 switch (xop) {
1264 case 0x0: /* load word */ 2046 case 0x0: /* load word */
1265 gen_op_ldst(ld); 2047 gen_op_ldst(ld);
@@ -1287,72 +2069,115 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1287,72 +2069,115 @@ static void disas_sparc_insn(DisasContext * dc)
1287 gen_movl_reg_T1(rd); 2069 gen_movl_reg_T1(rd);
1288 gen_op_ldst(swap); 2070 gen_op_ldst(swap);
1289 break; 2071 break;
1290 -#if !defined(CONFIG_USER_ONLY) 2072 +#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1291 case 0x10: /* load word alternate */ 2073 case 0x10: /* load word alternate */
  2074 +#ifndef TARGET_SPARC64
1292 if (!supervisor(dc)) 2075 if (!supervisor(dc))
1293 goto priv_insn; 2076 goto priv_insn;
  2077 +#endif
1294 gen_op_lda(insn, 1, 4, 0); 2078 gen_op_lda(insn, 1, 4, 0);
1295 break; 2079 break;
1296 case 0x11: /* load unsigned byte alternate */ 2080 case 0x11: /* load unsigned byte alternate */
  2081 +#ifndef TARGET_SPARC64
1297 if (!supervisor(dc)) 2082 if (!supervisor(dc))
1298 goto priv_insn; 2083 goto priv_insn;
  2084 +#endif
1299 gen_op_lduba(insn, 1, 1, 0); 2085 gen_op_lduba(insn, 1, 1, 0);
1300 break; 2086 break;
1301 case 0x12: /* load unsigned halfword alternate */ 2087 case 0x12: /* load unsigned halfword alternate */
  2088 +#ifndef TARGET_SPARC64
1302 if (!supervisor(dc)) 2089 if (!supervisor(dc))
1303 goto priv_insn; 2090 goto priv_insn;
  2091 +#endif
1304 gen_op_lduha(insn, 1, 2, 0); 2092 gen_op_lduha(insn, 1, 2, 0);
1305 break; 2093 break;
1306 case 0x13: /* load double word alternate */ 2094 case 0x13: /* load double word alternate */
  2095 +#ifndef TARGET_SPARC64
1307 if (!supervisor(dc)) 2096 if (!supervisor(dc))
1308 goto priv_insn; 2097 goto priv_insn;
  2098 +#endif
1309 gen_op_ldda(insn, 1, 8, 0); 2099 gen_op_ldda(insn, 1, 8, 0);
1310 gen_movl_T0_reg(rd + 1); 2100 gen_movl_T0_reg(rd + 1);
1311 break; 2101 break;
1312 case 0x19: /* load signed byte alternate */ 2102 case 0x19: /* load signed byte alternate */
  2103 +#ifndef TARGET_SPARC64
1313 if (!supervisor(dc)) 2104 if (!supervisor(dc))
1314 goto priv_insn; 2105 goto priv_insn;
  2106 +#endif
1315 gen_op_ldsba(insn, 1, 1, 1); 2107 gen_op_ldsba(insn, 1, 1, 1);
1316 break; 2108 break;
1317 case 0x1a: /* load signed halfword alternate */ 2109 case 0x1a: /* load signed halfword alternate */
  2110 +#ifndef TARGET_SPARC64
1318 if (!supervisor(dc)) 2111 if (!supervisor(dc))
1319 goto priv_insn; 2112 goto priv_insn;
  2113 +#endif
1320 gen_op_ldsha(insn, 1, 2 ,1); 2114 gen_op_ldsha(insn, 1, 2 ,1);
1321 break; 2115 break;
1322 case 0x1d: /* ldstuba -- XXX: should be atomically */ 2116 case 0x1d: /* ldstuba -- XXX: should be atomically */
  2117 +#ifndef TARGET_SPARC64
1323 if (!supervisor(dc)) 2118 if (!supervisor(dc))
1324 goto priv_insn; 2119 goto priv_insn;
  2120 +#endif
1325 gen_op_ldstuba(insn, 1, 1, 0); 2121 gen_op_ldstuba(insn, 1, 1, 0);
1326 break; 2122 break;
1327 case 0x1f: /* swap reg with alt. memory. Also atomically */ 2123 case 0x1f: /* swap reg with alt. memory. Also atomically */
  2124 +#ifndef TARGET_SPARC64
1328 if (!supervisor(dc)) 2125 if (!supervisor(dc))
1329 goto priv_insn; 2126 goto priv_insn;
  2127 +#endif
1330 gen_movl_reg_T1(rd); 2128 gen_movl_reg_T1(rd);
1331 gen_op_swapa(insn, 1, 4, 0); 2129 gen_op_swapa(insn, 1, 4, 0);
1332 break; 2130 break;
1333 - 2131 +
  2132 +#ifndef TARGET_SPARC64
1334 /* avoid warnings */ 2133 /* avoid warnings */
1335 (void) &gen_op_stfa; 2134 (void) &gen_op_stfa;
1336 (void) &gen_op_stdfa; 2135 (void) &gen_op_stdfa;
1337 (void) &gen_op_ldfa; 2136 (void) &gen_op_ldfa;
1338 (void) &gen_op_lddfa; 2137 (void) &gen_op_lddfa;
  2138 +#else
  2139 +#if !defined(CONFIG_USER_ONLY)
  2140 + (void) &gen_op_cas;
  2141 + (void) &gen_op_casx;
1339 #endif 2142 #endif
1340 - default: 2143 +#endif
  2144 +#endif
  2145 +#ifdef TARGET_SPARC64
1341 case 0x08: /* V9 ldsw */ 2146 case 0x08: /* V9 ldsw */
  2147 + gen_op_ldst(ldsw);
  2148 + break;
1342 case 0x0b: /* V9 ldx */ 2149 case 0x0b: /* V9 ldx */
  2150 + gen_op_ldst(ldx);
  2151 + break;
1343 case 0x18: /* V9 ldswa */ 2152 case 0x18: /* V9 ldswa */
  2153 + gen_op_ldswa(insn, 1, 4, 1);
  2154 + break;
1344 case 0x1b: /* V9 ldxa */ 2155 case 0x1b: /* V9 ldxa */
1345 - case 0x2d: /* V9 prefetch */ 2156 + gen_op_ldxa(insn, 1, 8, 0);
  2157 + break;
  2158 + case 0x2d: /* V9 prefetch, no effect */
  2159 + goto skip_move;
1346 case 0x30: /* V9 ldfa */ 2160 case 0x30: /* V9 ldfa */
  2161 + gen_op_ldfa(insn, 1, 8, 0); // XXX
  2162 + break;
1347 case 0x33: /* V9 lddfa */ 2163 case 0x33: /* V9 lddfa */
1348 - case 0x3d: /* V9 prefetcha */ 2164 + gen_op_lddfa(insn, 1, 8, 0); // XXX
1349 2165
  2166 + break;
  2167 + case 0x3d: /* V9 prefetcha, no effect */
  2168 + goto skip_move;
1350 case 0x32: /* V9 ldqfa */ 2169 case 0x32: /* V9 ldqfa */
  2170 + goto nfpu_insn;
  2171 +#endif
  2172 + default:
1351 goto illegal_insn; 2173 goto illegal_insn;
1352 } 2174 }
1353 gen_movl_T1_reg(rd); 2175 gen_movl_T1_reg(rd);
  2176 +#ifdef TARGET_SPARC64
  2177 + skip_move: ;
  2178 +#endif
1354 } else if (xop >= 0x20 && xop < 0x24) { 2179 } else if (xop >= 0x20 && xop < 0x24) {
1355 -#if !defined(CONFIG_USER_ONLY) 2180 +#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1356 gen_op_trap_ifnofpu(); 2181 gen_op_trap_ifnofpu();
1357 #endif 2182 #endif
1358 switch (xop) { 2183 switch (xop) {
@@ -1368,12 +2193,13 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1368,12 +2193,13 @@ static void disas_sparc_insn(DisasContext * dc)
1368 goto nfpu_insn; 2193 goto nfpu_insn;
1369 case 0x23: /* load double fpreg */ 2194 case 0x23: /* load double fpreg */
1370 gen_op_ldst(lddf); 2195 gen_op_ldst(lddf);
1371 - gen_op_store_DT0_fpr(rd); 2196 + gen_op_store_DT0_fpr(DFPREG(rd));
1372 break; 2197 break;
1373 default: 2198 default:
1374 goto illegal_insn; 2199 goto illegal_insn;
1375 } 2200 }
1376 - } else if (xop < 8 || (xop >= 0x14 && xop < 0x18)) { 2201 + } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) || \
  2202 + xop == 0xe || xop == 0x1e) {
1377 gen_movl_reg_T1(rd); 2203 gen_movl_reg_T1(rd);
1378 switch (xop) { 2204 switch (xop) {
1379 case 0x4: 2205 case 0x4:
@@ -1390,33 +2216,47 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1390,33 +2216,47 @@ static void disas_sparc_insn(DisasContext * dc)
1390 gen_movl_reg_T2(rd + 1); 2216 gen_movl_reg_T2(rd + 1);
1391 gen_op_ldst(std); 2217 gen_op_ldst(std);
1392 break; 2218 break;
1393 -#if !defined(CONFIG_USER_ONLY) 2219 +#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1394 case 0x14: 2220 case 0x14:
  2221 +#ifndef TARGET_SPARC64
1395 if (!supervisor(dc)) 2222 if (!supervisor(dc))
1396 goto priv_insn; 2223 goto priv_insn;
  2224 +#endif
1397 gen_op_sta(insn, 0, 4, 0); 2225 gen_op_sta(insn, 0, 4, 0);
1398 break; 2226 break;
1399 case 0x15: 2227 case 0x15:
  2228 +#ifndef TARGET_SPARC64
1400 if (!supervisor(dc)) 2229 if (!supervisor(dc))
1401 goto priv_insn; 2230 goto priv_insn;
  2231 +#endif
1402 gen_op_stba(insn, 0, 1, 0); 2232 gen_op_stba(insn, 0, 1, 0);
1403 break; 2233 break;
1404 case 0x16: 2234 case 0x16:
  2235 +#ifndef TARGET_SPARC64
1405 if (!supervisor(dc)) 2236 if (!supervisor(dc))
1406 goto priv_insn; 2237 goto priv_insn;
  2238 +#endif
1407 gen_op_stha(insn, 0, 2, 0); 2239 gen_op_stha(insn, 0, 2, 0);
1408 break; 2240 break;
1409 case 0x17: 2241 case 0x17:
  2242 +#ifndef TARGET_SPARC64
1410 if (!supervisor(dc)) 2243 if (!supervisor(dc))
1411 goto priv_insn; 2244 goto priv_insn;
  2245 +#endif
1412 flush_T2(dc); 2246 flush_T2(dc);
1413 gen_movl_reg_T2(rd + 1); 2247 gen_movl_reg_T2(rd + 1);
1414 gen_op_stda(insn, 0, 8, 0); 2248 gen_op_stda(insn, 0, 8, 0);
1415 break; 2249 break;
1416 #endif 2250 #endif
1417 - default: 2251 +#ifdef TARGET_SPARC64
1418 case 0x0e: /* V9 stx */ 2252 case 0x0e: /* V9 stx */
  2253 + gen_op_ldst(stx);
  2254 + break;
1419 case 0x1e: /* V9 stxa */ 2255 case 0x1e: /* V9 stxa */
  2256 + gen_op_stxa(insn, 0, 8, 0); // XXX
  2257 + break;
  2258 +#endif
  2259 + default:
1420 goto illegal_insn; 2260 goto illegal_insn;
1421 } 2261 }
1422 } else if (xop > 0x23 && xop < 0x28) { 2262 } else if (xop > 0x23 && xop < 0x28) {
@@ -1430,26 +2270,41 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1430,26 +2270,41 @@ static void disas_sparc_insn(DisasContext * dc)
1430 break; 2270 break;
1431 case 0x25: /* stfsr, V9 stxfsr */ 2271 case 0x25: /* stfsr, V9 stxfsr */
1432 gen_op_load_fpr_FT0(rd); 2272 gen_op_load_fpr_FT0(rd);
  2273 + // XXX
1433 gen_op_stfsr(); 2274 gen_op_stfsr();
1434 break; 2275 break;
1435 case 0x26: /* stdfq */ 2276 case 0x26: /* stdfq */
1436 goto nfpu_insn; 2277 goto nfpu_insn;
1437 case 0x27: 2278 case 0x27:
1438 - gen_op_load_fpr_DT0(rd); 2279 + gen_op_load_fpr_DT0(DFPREG(rd));
1439 gen_op_ldst(stdf); 2280 gen_op_ldst(stdf);
1440 break; 2281 break;
1441 default: 2282 default:
  2283 + goto illegal_insn;
  2284 + }
  2285 + } else if (xop > 0x33 && xop < 0x3f) {
  2286 +#ifdef TARGET_SPARC64
  2287 + switch (xop) {
1442 case 0x34: /* V9 stfa */ 2288 case 0x34: /* V9 stfa */
  2289 + gen_op_stfa(insn, 0, 0, 0); // XXX
  2290 + break;
1443 case 0x37: /* V9 stdfa */ 2291 case 0x37: /* V9 stdfa */
  2292 + gen_op_stdfa(insn, 0, 0, 0); // XXX
  2293 + break;
1444 case 0x3c: /* V9 casa */ 2294 case 0x3c: /* V9 casa */
  2295 + gen_op_casa(insn, 0, 4, 0); // XXX
  2296 + break;
1445 case 0x3e: /* V9 casxa */ 2297 case 0x3e: /* V9 casxa */
1446 - 2298 + gen_op_casxa(insn, 0, 8, 0); // XXX
  2299 + break;
1447 case 0x36: /* V9 stqfa */ 2300 case 0x36: /* V9 stqfa */
  2301 + goto nfpu_insn;
  2302 + default:
1448 goto illegal_insn; 2303 goto illegal_insn;
1449 } 2304 }
1450 - } else if (xop > 0x33 && xop < 0x38) {  
1451 - /* Co-processor */ 2305 +#else
1452 goto illegal_insn; 2306 goto illegal_insn;
  2307 +#endif
1453 } 2308 }
1454 else 2309 else
1455 goto illegal_insn; 2310 goto illegal_insn;
@@ -1540,6 +2395,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb, @@ -1540,6 +2395,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
1540 } 2395 }
1541 last_pc = dc->pc; 2396 last_pc = dc->pc;
1542 disas_sparc_insn(dc); 2397 disas_sparc_insn(dc);
  2398 +
1543 if (dc->is_br) 2399 if (dc->is_br)
1544 break; 2400 break;
1545 /* if the next PC is different, we abort now */ 2401 /* if the next PC is different, we abort now */
@@ -1552,7 +2408,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb, @@ -1552,7 +2408,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
1552 /* if single step mode, we generate only one instruction and 2408 /* if single step mode, we generate only one instruction and
1553 generate an exception */ 2409 generate an exception */
1554 if (env->singlestep_enabled) { 2410 if (env->singlestep_enabled) {
1555 - gen_op_jmp_im(dc->pc); 2411 + gen_jmp_im(dc->pc);
1556 gen_op_movl_T0_0(); 2412 gen_op_movl_T0_0();
1557 gen_op_exit_tb(); 2413 gen_op_exit_tb();
1558 break; 2414 break;
@@ -1568,7 +2424,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb, @@ -1568,7 +2424,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
1568 gen_op_branch((long)tb, dc->pc, dc->npc); 2424 gen_op_branch((long)tb, dc->pc, dc->npc);
1569 } else { 2425 } else {
1570 if (dc->pc != DYNAMIC_PC) 2426 if (dc->pc != DYNAMIC_PC)
1571 - gen_op_jmp_im(dc->pc); 2427 + gen_jmp_im(dc->pc);
1572 save_npc(dc); 2428 save_npc(dc);
1573 gen_op_movl_T0_0(); 2429 gen_op_movl_T0_0();
1574 gen_op_exit_tb(); 2430 gen_op_exit_tb();
@@ -1633,8 +2489,13 @@ void cpu_reset(CPUSPARCState *env) @@ -1633,8 +2489,13 @@ void cpu_reset(CPUSPARCState *env)
1633 env->psrps = 1; 2489 env->psrps = 1;
1634 env->pc = 0xffd00000; 2490 env->pc = 0xffd00000;
1635 env->gregs[1] = ram_size; 2491 env->gregs[1] = ram_size;
1636 - env->mmuregs[0] = (0x04 << 24); /* Impl 0, ver 4, MMU disabled */  
1637 env->npc = env->pc + 4; 2492 env->npc = env->pc + 4;
  2493 +#ifdef TARGET_SPARC64
  2494 + env->pstate = PS_AM | PS_PRIV; // XXX: Force AM
  2495 + env->version = GET_VER(env);
  2496 +#else
  2497 + env->mmuregs[0] = (0x04 << 24); /* Impl 0, ver 4, MMU disabled */
  2498 +#endif
1638 #endif 2499 #endif
1639 } 2500 }
1640 2501
@@ -1692,7 +2553,7 @@ void cpu_dump_state(CPUState *env, FILE *f, @@ -1692,7 +2553,7 @@ void cpu_dump_state(CPUState *env, FILE *f,
1692 GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'), 2553 GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
1693 env->psrs?'S':'-', env->psrps?'P':'-', 2554 env->psrs?'S':'-', env->psrps?'P':'-',
1694 env->psret?'E':'-', env->wim); 2555 env->psret?'E':'-', env->wim);
1695 - cpu_fprintf(f, "fsr: 0x%08x\n", env->fsr); 2556 + cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env));
1696 } 2557 }
1697 2558
1698 #if defined(CONFIG_USER_ONLY) 2559 #if defined(CONFIG_USER_ONLY)
@@ -2375,12 +2375,14 @@ void cpu_save(QEMUFile *f, void *opaque) @@ -2375,12 +2375,14 @@ void cpu_save(QEMUFile *f, void *opaque)
2375 qemu_put_betls(f, &env->y); 2375 qemu_put_betls(f, &env->y);
2376 tmp = GET_PSR(env); 2376 tmp = GET_PSR(env);
2377 qemu_put_be32(f, tmp); 2377 qemu_put_be32(f, tmp);
2378 - qemu_put_be32s(f, &env->fsr); 2378 + qemu_put_betls(f, &env->fsr);
  2379 + qemu_put_betls(f, &env->tbr);
  2380 +#ifndef TARGET_SPARC64
2379 qemu_put_be32s(f, &env->wim); 2381 qemu_put_be32s(f, &env->wim);
2380 - qemu_put_be32s(f, &env->tbr);  
2381 /* MMU */ 2382 /* MMU */
2382 for(i = 0; i < 16; i++) 2383 for(i = 0; i < 16; i++)
2383 qemu_put_be32s(f, &env->mmuregs[i]); 2384 qemu_put_be32s(f, &env->mmuregs[i]);
  2385 +#endif
2384 } 2386 }
2385 2387
2386 int cpu_load(QEMUFile *f, void *opaque, int version_id) 2388 int cpu_load(QEMUFile *f, void *opaque, int version_id)
@@ -2411,13 +2413,14 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) @@ -2411,13 +2413,14 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
2411 env->cwp = 0; /* needed to ensure that the wrapping registers are 2413 env->cwp = 0; /* needed to ensure that the wrapping registers are
2412 correctly updated */ 2414 correctly updated */
2413 PUT_PSR(env, tmp); 2415 PUT_PSR(env, tmp);
2414 - qemu_get_be32s(f, &env->fsr); 2416 + qemu_get_betls(f, &env->fsr);
  2417 + qemu_get_betls(f, &env->tbr);
  2418 +#ifndef TARGET_SPARC64
2415 qemu_get_be32s(f, &env->wim); 2419 qemu_get_be32s(f, &env->wim);
2416 - qemu_get_be32s(f, &env->tbr);  
2417 /* MMU */ 2420 /* MMU */
2418 for(i = 0; i < 16; i++) 2421 for(i = 0; i < 16; i++)
2419 qemu_get_be32s(f, &env->mmuregs[i]); 2422 qemu_get_be32s(f, &env->mmuregs[i]);
2420 - 2423 +#endif
2421 tlb_flush(env, 1); 2424 tlb_flush(env, 1);
2422 return 0; 2425 return 0;
2423 } 2426 }
@@ -2577,6 +2580,7 @@ typedef struct QEMUResetEntry { @@ -2577,6 +2580,7 @@ typedef struct QEMUResetEntry {
2577 static QEMUResetEntry *first_reset_entry; 2580 static QEMUResetEntry *first_reset_entry;
2578 static int reset_requested; 2581 static int reset_requested;
2579 static int shutdown_requested; 2582 static int shutdown_requested;
  2583 +static int powerdown_requested;
2580 2584
2581 void qemu_register_reset(QEMUResetHandler *func, void *opaque) 2585 void qemu_register_reset(QEMUResetHandler *func, void *opaque)
2582 { 2586 {
@@ -2614,6 +2618,12 @@ void qemu_system_shutdown_request(void) @@ -2614,6 +2618,12 @@ void qemu_system_shutdown_request(void)
2614 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); 2618 cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
2615 } 2619 }
2616 2620
  2621 +void qemu_system_powerdown_request(void)
  2622 +{
  2623 + powerdown_requested = 1;
  2624 + cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
  2625 +}
  2626 +
2617 static void main_cpu_reset(void *opaque) 2627 static void main_cpu_reset(void *opaque)
2618 { 2628 {
2619 #if defined(TARGET_I386) || defined(TARGET_SPARC) 2629 #if defined(TARGET_I386) || defined(TARGET_SPARC)
@@ -2728,20 +2738,25 @@ int main_loop(void) @@ -2728,20 +2738,25 @@ int main_loop(void)
2728 if (vm_running) { 2738 if (vm_running) {
2729 ret = cpu_exec(env); 2739 ret = cpu_exec(env);
2730 if (shutdown_requested) { 2740 if (shutdown_requested) {
2731 - ret = EXCP_INTERRUPT; 2741 + ret = EXCP_INTERRUPT;
2732 break; 2742 break;
2733 } 2743 }
2734 if (reset_requested) { 2744 if (reset_requested) {
2735 reset_requested = 0; 2745 reset_requested = 0;
2736 qemu_system_reset(); 2746 qemu_system_reset();
2737 - ret = EXCP_INTERRUPT; 2747 + ret = EXCP_INTERRUPT;
  2748 + }
  2749 + if (powerdown_requested) {
  2750 + powerdown_requested = 0;
  2751 + qemu_system_powerdown();
  2752 + ret = EXCP_INTERRUPT;
2738 } 2753 }
2739 if (ret == EXCP_DEBUG) { 2754 if (ret == EXCP_DEBUG) {
2740 vm_stop(EXCP_DEBUG); 2755 vm_stop(EXCP_DEBUG);
2741 } 2756 }
2742 /* if hlt instruction, we wait until the next IRQ */ 2757 /* if hlt instruction, we wait until the next IRQ */
2743 /* XXX: use timeout computed from timers */ 2758 /* XXX: use timeout computed from timers */
2744 - if (ret == EXCP_HLT) 2759 + if (ret == EXCP_HLT)
2745 timeout = 10; 2760 timeout = 10;
2746 else 2761 else
2747 timeout = 0; 2762 timeout = 0;
@@ -3044,8 +3059,12 @@ void register_machines(void) @@ -3044,8 +3059,12 @@ void register_machines(void)
3044 qemu_register_machine(&core99_machine); 3059 qemu_register_machine(&core99_machine);
3045 qemu_register_machine(&prep_machine); 3060 qemu_register_machine(&prep_machine);
3046 #elif defined(TARGET_SPARC) 3061 #elif defined(TARGET_SPARC)
  3062 +#ifdef TARGET_SPARC64
  3063 + qemu_register_machine(&sun4u_machine);
  3064 +#else
3047 qemu_register_machine(&sun4m_machine); 3065 qemu_register_machine(&sun4m_machine);
3048 #endif 3066 #endif
  3067 +#endif
3049 } 3068 }
3050 3069
3051 #define NET_IF_TUN 0 3070 #define NET_IF_TUN 0
@@ -110,6 +110,13 @@ typedef void QEMUResetHandler(void *opaque); @@ -110,6 +110,13 @@ typedef void QEMUResetHandler(void *opaque);
110 void qemu_register_reset(QEMUResetHandler *func, void *opaque); 110 void qemu_register_reset(QEMUResetHandler *func, void *opaque);
111 void qemu_system_reset_request(void); 111 void qemu_system_reset_request(void);
112 void qemu_system_shutdown_request(void); 112 void qemu_system_shutdown_request(void);
  113 +void qemu_system_powerdown_request(void);
  114 +#if !defined(TARGET_SPARC)
  115 +// Please implement a power failure function to signal the OS
  116 +#define qemu_system_powerdown() do{}while(0)
  117 +#else
  118 +void qemu_system_powerdown(void);
  119 +#endif
113 120
114 void main_loop_wait(int timeout); 121 void main_loop_wait(int timeout);
115 122
@@ -753,9 +760,16 @@ void slavio_timer_init(uint32_t addr1, int irq1, uint32_t addr2, int irq2); @@ -753,9 +760,16 @@ void slavio_timer_init(uint32_t addr1, int irq1, uint32_t addr2, int irq2);
753 SerialState *slavio_serial_init(int base, int irq, CharDriverState *chr1, CharDriverState *chr2); 760 SerialState *slavio_serial_init(int base, int irq, CharDriverState *chr1, CharDriverState *chr2);
754 void slavio_serial_ms_kbd_init(int base, int irq); 761 void slavio_serial_ms_kbd_init(int base, int irq);
755 762
  763 +/* slavio_misc.c */
  764 +void *slavio_misc_init(uint32_t base, int irq);
  765 +void slavio_set_power_fail(void *opaque, int power_failing);
  766 +
756 /* esp.c */ 767 /* esp.c */
757 void esp_init(BlockDriverState **bd, int irq, uint32_t espaddr, uint32_t espdaddr); 768 void esp_init(BlockDriverState **bd, int irq, uint32_t espaddr, uint32_t espdaddr);
758 769
  770 +/* sun4u.c */
  771 +extern QEMUMachine sun4u_machine;
  772 +
759 /* NVRAM helpers */ 773 /* NVRAM helpers */
760 #include "hw/m48t59.h" 774 #include "hw/m48t59.h"
761 775