Commit af7bf89b1f525bb684f48ed0e847ad2d2d11c5e5

Authored by bellard
1 parent 49be8030

initial sparc64 support - sparc fixes (Blue Swirl)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1251 c046a42c-6fe2-441c-8c8c-71466251a162
target-sparc/cpu.h
1 #ifndef CPU_SPARC_H 1 #ifndef CPU_SPARC_H
2 #define CPU_SPARC_H 2 #define CPU_SPARC_H
3 3
  4 +#include "config.h"
  5 +
  6 +#if !defined(TARGET_SPARC64)
4 #define TARGET_LONG_BITS 32 7 #define TARGET_LONG_BITS 32
  8 +#define TARGET_FPREGS 32
  9 +#define TARGET_FPREG_T float
  10 +#else
  11 +#define TARGET_LONG_BITS 64
  12 +#define TARGET_FPREGS 64
  13 +#define TARGET_FPREG_T double
  14 +#endif
5 15
6 #include "cpu-defs.h" 16 #include "cpu-defs.h"
7 17
@@ -95,15 +105,14 @@ @@ -95,15 +105,14 @@
95 #define NWINDOWS 32 105 #define NWINDOWS 32
96 106
97 typedef struct CPUSPARCState { 107 typedef struct CPUSPARCState {
98 - uint32_t gregs[8]; /* general registers */  
99 - uint32_t *regwptr; /* pointer to current register window */  
100 - float fpr[32]; /* floating point registers */  
101 - uint32_t pc; /* program counter */  
102 - uint32_t npc; /* next program counter */  
103 - uint32_t y; /* multiply/divide register */ 108 + target_ulong gregs[8]; /* general registers */
  109 + target_ulong *regwptr; /* pointer to current register window */
  110 + TARGET_FPREG_T fpr[TARGET_FPREGS]; /* floating point registers */
  111 + target_ulong pc; /* program counter */
  112 + target_ulong npc; /* next program counter */
  113 + target_ulong y; /* multiply/divide register */
104 uint32_t psr; /* processor state register */ 114 uint32_t psr; /* processor state register */
105 uint32_t fsr; /* FPU state register */ 115 uint32_t fsr; /* FPU state register */
106 - uint32_t T2;  
107 uint32_t cwp; /* index of current register window (extracted 116 uint32_t cwp; /* index of current register window (extracted
108 from PSR) */ 117 from PSR) */
109 uint32_t wim; /* window invalid mask */ 118 uint32_t wim; /* window invalid mask */
@@ -118,11 +127,11 @@ typedef struct CPUSPARCState { @@ -118,11 +127,11 @@ typedef struct CPUSPARCState {
118 int exception_index; 127 int exception_index;
119 int interrupt_index; 128 int interrupt_index;
120 int interrupt_request; 129 int interrupt_request;
121 - uint32_t exception_next_pc; 130 + target_ulong exception_next_pc;
122 struct TranslationBlock *current_tb; 131 struct TranslationBlock *current_tb;
123 void *opaque; 132 void *opaque;
124 /* NOTE: we allow 8 more registers to handle wrapping */ 133 /* NOTE: we allow 8 more registers to handle wrapping */
125 - uint32_t regbase[NWINDOWS * 16 + 8]; 134 + target_ulong regbase[NWINDOWS * 16 + 8];
126 135
127 /* in order to avoid passing too many arguments to the memory 136 /* in order to avoid passing too many arguments to the memory
128 write helpers, we store some rarely used information in the CPU 137 write helpers, we store some rarely used information in the CPU
@@ -140,9 +149,12 @@ typedef struct CPUSPARCState { @@ -140,9 +149,12 @@ typedef struct CPUSPARCState {
140 /* temporary float registers */ 149 /* temporary float registers */
141 float ft0, ft1, ft2; 150 float ft0, ft1, ft2;
142 double dt0, dt1, dt2; 151 double dt0, dt1, dt2;
  152 +#if defined(TARGET_SPARC64)
  153 + target_ulong t0, t1, t2;
  154 +#endif
143 155
144 /* ice debug support */ 156 /* ice debug support */
145 - uint32_t breakpoints[MAX_BREAKPOINTS]; 157 + target_ulong breakpoints[MAX_BREAKPOINTS];
146 int nb_breakpoints; 158 int nb_breakpoints;
147 int singlestep_enabled; /* XXX: should use CPU single step mode instead */ 159 int singlestep_enabled; /* XXX: should use CPU single step mode instead */
148 160
@@ -155,7 +167,7 @@ void cpu_get_fp64(uint64_t *pmant, uint16_t *pexp, double f); @@ -155,7 +167,7 @@ void cpu_get_fp64(uint64_t *pmant, uint16_t *pexp, double f);
155 double cpu_put_fp64(uint64_t mant, uint16_t exp); 167 double cpu_put_fp64(uint64_t mant, uint16_t exp);
156 168
157 /* Fake impl 0, version 4 */ 169 /* Fake impl 0, version 4 */
158 -#define GET_PSR(env) ((0 << 28) | (4 << 24) | env->psr | \ 170 +#define GET_PSR(env) ((0 << 28) | (4 << 24) | (env->psr & PSR_ICC) | \
159 (env->psref? PSR_EF : 0) | \ 171 (env->psref? PSR_EF : 0) | \
160 (env->psrpil << 8) | \ 172 (env->psrpil << 8) | \
161 (env->psrs? PSR_S : 0) | \ 173 (env->psrs? PSR_S : 0) | \
@@ -167,7 +179,7 @@ void cpu_set_cwp(CPUSPARCState *env1, int new_cwp); @@ -167,7 +179,7 @@ void cpu_set_cwp(CPUSPARCState *env1, int new_cwp);
167 #endif 179 #endif
168 180
169 #define PUT_PSR(env, val) do { int _tmp = val; \ 181 #define PUT_PSR(env, val) do { int _tmp = val; \
170 - env->psr = _tmp & ~PSR_ICC; \ 182 + env->psr = _tmp & PSR_ICC; \
171 env->psref = (_tmp & PSR_EF)? 1 : 0; \ 183 env->psref = (_tmp & PSR_EF)? 1 : 0; \
172 env->psrpil = (_tmp & PSR_PIL) >> 8; \ 184 env->psrpil = (_tmp & PSR_PIL) >> 8; \
173 env->psrs = (_tmp & PSR_S)? 1 : 0; \ 185 env->psrs = (_tmp & PSR_S)? 1 : 0; \
target-sparc/exec.h
@@ -3,9 +3,15 @@ @@ -3,9 +3,15 @@
3 #include "dyngen-exec.h" 3 #include "dyngen-exec.h"
4 4
5 register struct CPUSPARCState *env asm(AREG0); 5 register struct CPUSPARCState *env asm(AREG0);
  6 +#ifdef TARGET_SPARC64
  7 +#define T0 (env->t0)
  8 +#define T1 (env->t1)
  9 +#define T2 (env->t2)
  10 +#else
6 register uint32_t T0 asm(AREG1); 11 register uint32_t T0 asm(AREG1);
7 register uint32_t T1 asm(AREG2); 12 register uint32_t T1 asm(AREG2);
8 register uint32_t T2 asm(AREG3); 13 register uint32_t T2 asm(AREG3);
  14 +#endif
9 #define FT0 (env->ft0) 15 #define FT0 (env->ft0)
10 #define FT1 (env->ft1) 16 #define FT1 (env->ft1)
11 #define FT2 (env->ft2) 17 #define FT2 (env->ft2)
@@ -32,17 +38,19 @@ void do_fsqrts(void); @@ -32,17 +38,19 @@ void do_fsqrts(void);
32 void do_fsqrtd(void); 38 void do_fsqrtd(void);
33 void do_fcmps(void); 39 void do_fcmps(void);
34 void do_fcmpd(void); 40 void do_fcmpd(void);
35 -void do_ldd_kernel(uint32_t addr);  
36 -void do_ldd_user(uint32_t addr);  
37 -void do_ldd_raw(uint32_t addr); 41 +void do_ldd_kernel(target_ulong addr);
  42 +void do_ldd_user(target_ulong addr);
  43 +void do_ldd_raw(target_ulong addr);
38 void do_interrupt(int intno, int is_int, int error_code, 44 void do_interrupt(int intno, int is_int, int error_code,
39 unsigned int next_eip, int is_hw); 45 unsigned int next_eip, int is_hw);
40 void raise_exception_err(int exception_index, int error_code); 46 void raise_exception_err(int exception_index, int error_code);
41 void raise_exception(int tt); 47 void raise_exception(int tt);
42 -void memcpy32(uint32_t *dst, const uint32_t *src);  
43 -uint32_t mmu_probe(uint32_t address, int mmulev); 48 +void memcpy32(target_ulong *dst, const target_ulong *src);
  49 +target_ulong mmu_probe(target_ulong address, int mmulev);
44 void dump_mmu(void); 50 void dump_mmu(void);
45 void helper_debug(); 51 void helper_debug();
  52 +void do_wrpsr();
  53 +void do_rdpsr();
46 54
47 /* XXX: move that to a generic header */ 55 /* XXX: move that to a generic header */
48 #if !defined(CONFIG_USER_ONLY) 56 #if !defined(CONFIG_USER_ONLY)
target-sparc/helper.c
@@ -23,7 +23,7 @@ @@ -23,7 +23,7 @@
23 //#define DEBUG_MMU 23 //#define DEBUG_MMU
24 24
25 /* Sparc MMU emulation */ 25 /* Sparc MMU emulation */
26 -int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, 26 +int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
27 int is_user, int is_softmmu); 27 int is_user, int is_softmmu);
28 28
29 /* thread support */ 29 /* thread support */
@@ -109,13 +109,14 @@ static const int rw_table[2][8] = { @@ -109,13 +109,14 @@ static const int rw_table[2][8] = {
109 { 0, 1, 0, 1, 0, 0, 0, 0 } 109 { 0, 1, 0, 1, 0, 0, 0, 0 }
110 }; 110 };
111 111
112 -int get_physical_address (CPUState *env, uint32_t *physical, int *prot,  
113 - int *access_index, uint32_t address, int rw, 112 +int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
  113 + int *access_index, target_ulong address, int rw,
114 int is_user) 114 int is_user)
115 { 115 {
116 int access_perms = 0; 116 int access_perms = 0;
117 target_phys_addr_t pde_ptr; 117 target_phys_addr_t pde_ptr;
118 - uint32_t pde, virt_addr; 118 + uint32_t pde;
  119 + target_ulong virt_addr;
119 int error_code = 0, is_dirty; 120 int error_code = 0, is_dirty;
120 unsigned long page_offset; 121 unsigned long page_offset;
121 122
@@ -217,11 +218,12 @@ int get_physical_address (CPUState *env, uint32_t *physical, int *prot, @@ -217,11 +218,12 @@ int get_physical_address (CPUState *env, uint32_t *physical, int *prot,
217 } 218 }
218 219
219 /* Perform address translation */ 220 /* Perform address translation */
220 -int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, 221 +int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
221 int is_user, int is_softmmu) 222 int is_user, int is_softmmu)
222 { 223 {
223 int exception = 0; 224 int exception = 0;
224 - uint32_t virt_addr, paddr; 225 + target_ulong virt_addr;
  226 + target_phys_addr_t paddr;
225 unsigned long vaddr; 227 unsigned long vaddr;
226 int error_code = 0, prot, ret = 0, access_index; 228 int error_code = 0, prot, ret = 0, access_index;
227 229
@@ -252,7 +254,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, @@ -252,7 +254,7 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,
252 return error_code; 254 return error_code;
253 } 255 }
254 256
255 -void memcpy32(uint32_t *dst, const uint32_t *src) 257 +void memcpy32(target_ulong *dst, const target_ulong *src)
256 { 258 {
257 dst[0] = src[0]; 259 dst[0] = src[0];
258 dst[1] = src[1]; 260 dst[1] = src[1];
@@ -328,8 +330,13 @@ void do_interrupt(int intno, int is_int, int error_code, @@ -328,8 +330,13 @@ void do_interrupt(int intno, int is_int, int error_code,
328 env->psret = 0; 330 env->psret = 0;
329 cwp = (env->cwp - 1) & (NWINDOWS - 1); 331 cwp = (env->cwp - 1) & (NWINDOWS - 1);
330 set_cwp(cwp); 332 set_cwp(cwp);
331 - env->regwptr[9] = env->pc - 4; // XXX?  
332 - env->regwptr[10] = env->pc; 333 + if (intno & 0x80) {
  334 + env->regwptr[9] = env->pc;
  335 + env->regwptr[10] = env->npc;
  336 + } else {
  337 + env->regwptr[9] = env->pc - 4; // XXX?
  338 + env->regwptr[10] = env->pc;
  339 + }
333 env->psrps = env->psrs; 340 env->psrps = env->psrs;
334 env->psrs = 1; 341 env->psrs = 1;
335 env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4); 342 env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
@@ -343,7 +350,7 @@ void raise_exception_err(int exception_index, int error_code) @@ -343,7 +350,7 @@ void raise_exception_err(int exception_index, int error_code)
343 raise_exception(exception_index); 350 raise_exception(exception_index);
344 } 351 }
345 352
346 -uint32_t mmu_probe(uint32_t address, int mmulev) 353 +target_ulong mmu_probe(target_ulong address, int mmulev)
347 { 354 {
348 target_phys_addr_t pde_ptr; 355 target_phys_addr_t pde_ptr;
349 uint32_t pde; 356 uint32_t pde;
@@ -408,30 +415,30 @@ uint32_t mmu_probe(uint32_t address, int mmulev) @@ -408,30 +415,30 @@ uint32_t mmu_probe(uint32_t address, int mmulev)
408 void dump_mmu(void) 415 void dump_mmu(void)
409 { 416 {
410 #ifdef DEBUG_MMU 417 #ifdef DEBUG_MMU
411 - uint32_t pa, va, va1, va2;  
412 - int n, m, o;  
413 - target_phys_addr_t pde_ptr; 418 + target_ulong va, va1, va2;
  419 + unsigned int n, m, o;
  420 + target_phys_addr_t pde_ptr, pa;
414 uint32_t pde; 421 uint32_t pde;
415 422
416 printf("MMU dump:\n"); 423 printf("MMU dump:\n");
417 pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 4); 424 pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 4);
418 pde = ldl_phys(pde_ptr); 425 pde = ldl_phys(pde_ptr);
419 - printf("Root ptr: 0x%08x, ctx: %d\n", env->mmuregs[1] << 4, env->mmuregs[2]); 426 + printf("Root ptr: " TARGET_FMT_lx ", ctx: %d\n", env->mmuregs[1] << 4, env->mmuregs[2]);
420 for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) { 427 for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
421 pde_ptr = mmu_probe(va, 2); 428 pde_ptr = mmu_probe(va, 2);
422 if (pde_ptr) { 429 if (pde_ptr) {
423 pa = cpu_get_phys_page_debug(env, va); 430 pa = cpu_get_phys_page_debug(env, va);
424 - printf("VA: 0x%08x, PA: 0x%08x PDE: 0x%08x\n", va, pa, pde_ptr); 431 + printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va, pa, pde_ptr);
425 for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) { 432 for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
426 pde_ptr = mmu_probe(va1, 1); 433 pde_ptr = mmu_probe(va1, 1);
427 if (pde_ptr) { 434 if (pde_ptr) {
428 pa = cpu_get_phys_page_debug(env, va1); 435 pa = cpu_get_phys_page_debug(env, va1);
429 - printf(" VA: 0x%08x, PA: 0x%08x PDE: 0x%08x\n", va1, pa, pde_ptr); 436 + printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va1, pa, pde_ptr);
430 for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) { 437 for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
431 pde_ptr = mmu_probe(va2, 0); 438 pde_ptr = mmu_probe(va2, 0);
432 if (pde_ptr) { 439 if (pde_ptr) {
433 pa = cpu_get_phys_page_debug(env, va2); 440 pa = cpu_get_phys_page_debug(env, va2);
434 - printf(" VA: 0x%08x, PA: 0x%08x PTE: 0x%08x\n", va2, pa, pde_ptr); 441 + printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PTE: " TARGET_FMT_lx "\n", va2, pa, pde_ptr);
435 } 442 }
436 } 443 }
437 } 444 }
target-sparc/op.c
@@ -217,7 +217,7 @@ @@ -217,7 +217,7 @@
217 217
218 #define EIP (env->pc) 218 #define EIP (env->pc)
219 219
220 -#define FLAG_SET(x) (env->psr&x)?1:0 220 +#define FLAG_SET(x) ((env->psr&x)?1:0)
221 #define FFLAG_SET(x) ((env->fsr&x)?1:0) 221 #define FFLAG_SET(x) ((env->fsr&x)?1:0)
222 222
223 void OPPROTO op_movl_T0_0(void) 223 void OPPROTO op_movl_T0_0(void)
@@ -225,11 +225,6 @@ void OPPROTO op_movl_T0_0(void) @@ -225,11 +225,6 @@ void OPPROTO op_movl_T0_0(void)
225 T0 = 0; 225 T0 = 0;
226 } 226 }
227 227
228 -void OPPROTO op_movl_T0_1(void)  
229 -{  
230 - T0 = 1;  
231 -}  
232 -  
233 void OPPROTO op_movl_T0_im(void) 228 void OPPROTO op_movl_T0_im(void)
234 { 229 {
235 T0 = PARAM1; 230 T0 = PARAM1;
@@ -245,40 +240,51 @@ void OPPROTO op_movl_T2_im(void) @@ -245,40 +240,51 @@ void OPPROTO op_movl_T2_im(void)
245 T2 = PARAM1; 240 T2 = PARAM1;
246 } 241 }
247 242
248 -void OPPROTO op_addl_T1_im(void) 243 +void OPPROTO op_add_T1_T0(void)
249 { 244 {
250 - T1 += PARAM1; 245 + T0 += T1;
251 } 246 }
252 247
253 -void OPPROTO op_addl_T1_T2(void) 248 +void OPPROTO op_add_T1_T0_cc(void)
254 { 249 {
255 - T1 += T2;  
256 -} 250 + target_ulong src1;
257 251
258 -void OPPROTO op_subl_T1_T2(void)  
259 -{  
260 - T1 -= T2; 252 + src1 = T0;
  253 + T0 += T1;
  254 + env->psr = 0;
  255 + if (!T0)
  256 + env->psr |= PSR_ZERO;
  257 + if ((int32_t) T0 < 0)
  258 + env->psr |= PSR_NEG;
  259 + if (T0 < src1)
  260 + env->psr |= PSR_CARRY;
  261 + if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
  262 + env->psr |= PSR_OVF;
  263 + /* V9 xcc */
  264 + FORCE_RET();
261 } 265 }
262 266
263 -void OPPROTO op_add_T1_T0(void) 267 +void OPPROTO op_addx_T1_T0(void)
264 { 268 {
265 - T0 += T1; 269 + T0 += T1 + FLAG_SET(PSR_CARRY);
266 } 270 }
267 271
268 -void OPPROTO op_add_T1_T0_cc(void) 272 +void OPPROTO op_addx_T1_T0_cc(void)
269 { 273 {
270 - unsigned int src1; 274 + target_ulong src1;
  275 +
271 src1 = T0; 276 src1 = T0;
272 - T0 += T1; 277 + T0 += T1 + FLAG_SET(PSR_CARRY);
273 env->psr = 0; 278 env->psr = 0;
274 if (!T0) 279 if (!T0)
275 env->psr |= PSR_ZERO; 280 env->psr |= PSR_ZERO;
276 - if ((int) T0 < 0) 281 + if ((int32_t) T0 < 0)
277 env->psr |= PSR_NEG; 282 env->psr |= PSR_NEG;
278 if (T0 < src1) 283 if (T0 < src1)
279 env->psr |= PSR_CARRY; 284 env->psr |= PSR_CARRY;
280 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31)) 285 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
281 env->psr |= PSR_OVF; 286 env->psr |= PSR_OVF;
  287 + /* V9 xcc */
282 FORCE_RET(); 288 FORCE_RET();
283 } 289 }
284 290
@@ -289,19 +295,44 @@ void OPPROTO op_sub_T1_T0(void) @@ -289,19 +295,44 @@ void OPPROTO op_sub_T1_T0(void)
289 295
290 void OPPROTO op_sub_T1_T0_cc(void) 296 void OPPROTO op_sub_T1_T0_cc(void)
291 { 297 {
292 - unsigned int src1; 298 + target_ulong src1;
293 299
294 src1 = T0; 300 src1 = T0;
295 T0 -= T1; 301 T0 -= T1;
296 env->psr = 0; 302 env->psr = 0;
297 if (!T0) 303 if (!T0)
298 env->psr |= PSR_ZERO; 304 env->psr |= PSR_ZERO;
299 - if ((int) T0 < 0) 305 + if ((int32_t) T0 < 0)
300 env->psr |= PSR_NEG; 306 env->psr |= PSR_NEG;
301 if (src1 < T1) 307 if (src1 < T1)
302 env->psr |= PSR_CARRY; 308 env->psr |= PSR_CARRY;
303 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31)) 309 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
304 env->psr |= PSR_OVF; 310 env->psr |= PSR_OVF;
  311 + /* V9 xcc */
  312 + FORCE_RET();
  313 +}
  314 +
  315 +void OPPROTO op_subx_T1_T0(void)
  316 +{
  317 + T0 -= T1 + FLAG_SET(PSR_CARRY);
  318 +}
  319 +
  320 +void OPPROTO op_subx_T1_T0_cc(void)
  321 +{
  322 + target_ulong src1;
  323 +
  324 + src1 = T0;
  325 + T0 -= T1 + FLAG_SET(PSR_CARRY);
  326 + env->psr = 0;
  327 + if (!T0)
  328 + env->psr |= PSR_ZERO;
  329 + if ((int32_t) T0 < 0)
  330 + env->psr |= PSR_NEG;
  331 + if (src1 < T1)
  332 + env->psr |= PSR_CARRY;
  333 + if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
  334 + env->psr |= PSR_OVF;
  335 + /* V9 xcc */
305 FORCE_RET(); 336 FORCE_RET();
306 } 337 }
307 338
@@ -335,15 +366,10 @@ void OPPROTO op_xnor_T1_T0(void) @@ -335,15 +366,10 @@ void OPPROTO op_xnor_T1_T0(void)
335 T0 ^= ~T1; 366 T0 ^= ~T1;
336 } 367 }
337 368
338 -void OPPROTO op_addx_T1_T0(void)  
339 -{  
340 - T0 += T1 + ((env->psr & PSR_CARRY) ? 1 : 0);  
341 -}  
342 -  
343 void OPPROTO op_umul_T1_T0(void) 369 void OPPROTO op_umul_T1_T0(void)
344 { 370 {
345 uint64_t res; 371 uint64_t res;
346 - res = (uint64_t) T0 *(uint64_t) T1; 372 + res = (uint64_t) T0 * (uint64_t) T1;
347 T0 = res & 0xffffffff; 373 T0 = res & 0xffffffff;
348 env->y = res >> 32; 374 env->y = res >> 32;
349 } 375 }
@@ -358,7 +384,9 @@ void OPPROTO op_smul_T1_T0(void) @@ -358,7 +384,9 @@ void OPPROTO op_smul_T1_T0(void)
358 384
359 void OPPROTO op_mulscc_T1_T0(void) 385 void OPPROTO op_mulscc_T1_T0(void)
360 { 386 {
361 - unsigned int b1, N, V, b2, src1; 387 + unsigned int b1, N, V, b2;
  388 + target_ulong src1;
  389 +
362 N = FLAG_SET(PSR_NEG); 390 N = FLAG_SET(PSR_NEG);
363 V = FLAG_SET(PSR_OVF); 391 V = FLAG_SET(PSR_OVF);
364 b1 = N ^ V; 392 b1 = N ^ V;
@@ -372,7 +400,7 @@ void OPPROTO op_mulscc_T1_T0(void) @@ -372,7 +400,7 @@ void OPPROTO op_mulscc_T1_T0(void)
372 env->psr = 0; 400 env->psr = 0;
373 if (!T0) 401 if (!T0)
374 env->psr |= PSR_ZERO; 402 env->psr |= PSR_ZERO;
375 - if ((int) T0 < 0) 403 + if ((int32_t) T0 < 0)
376 env->psr |= PSR_NEG; 404 env->psr |= PSR_NEG;
377 if (T0 < src1) 405 if (T0 < src1)
378 env->psr |= PSR_CARRY; 406 env->psr |= PSR_CARRY;
@@ -405,11 +433,11 @@ void OPPROTO op_sdiv_T1_T0(void) @@ -405,11 +433,11 @@ void OPPROTO op_sdiv_T1_T0(void)
405 int64_t x0; 433 int64_t x0;
406 int32_t x1; 434 int32_t x1;
407 435
408 - x0 = T0 | ((uint64_t) (env->y) << 32); 436 + x0 = T0 | ((int64_t) (env->y) << 32);
409 x1 = T1; 437 x1 = T1;
410 x0 = x0 / x1; 438 x0 = x0 / x1;
411 if ((int32_t) x0 != x0) { 439 if ((int32_t) x0 != x0) {
412 - T0 = x0 >> 63; 440 + T0 = x0 < 0? 0x80000000: 0x7fffffff;
413 T1 = 1; 441 T1 = 1;
414 } else { 442 } else {
415 T0 = x0; 443 T0 = x0;
@@ -423,39 +451,22 @@ void OPPROTO op_div_cc(void) @@ -423,39 +451,22 @@ void OPPROTO op_div_cc(void)
423 env->psr = 0; 451 env->psr = 0;
424 if (!T0) 452 if (!T0)
425 env->psr |= PSR_ZERO; 453 env->psr |= PSR_ZERO;
426 - if ((int) T0 < 0) 454 + if ((int32_t) T0 < 0)
427 env->psr |= PSR_NEG; 455 env->psr |= PSR_NEG;
428 if (T1) 456 if (T1)
429 env->psr |= PSR_OVF; 457 env->psr |= PSR_OVF;
  458 + /* V9 xcc */
430 FORCE_RET(); 459 FORCE_RET();
431 } 460 }
432 461
433 -void OPPROTO op_subx_T1_T0(void)  
434 -{  
435 - T0 -= T1 + ((env->psr & PSR_CARRY) ? 1 : 0);  
436 -}  
437 -  
438 void OPPROTO op_logic_T0_cc(void) 462 void OPPROTO op_logic_T0_cc(void)
439 { 463 {
440 env->psr = 0; 464 env->psr = 0;
441 if (!T0) 465 if (!T0)
442 env->psr |= PSR_ZERO; 466 env->psr |= PSR_ZERO;
443 - if ((int) T0 < 0)  
444 - env->psr |= PSR_NEG;  
445 - FORCE_RET();  
446 -}  
447 -  
448 -void OPPROTO op_set_flags(void)  
449 -{  
450 - env->psr = 0;  
451 - if (!T0)  
452 - env->psr |= PSR_ZERO;  
453 - if ((unsigned int) T0 < (unsigned int) T1)  
454 - env->psr |= PSR_CARRY;  
455 - if ((int) T0 < (int) T1)  
456 - env->psr |= PSR_OVF;  
457 - if ((int) T0 < 0) 467 + if ((int32_t) T0 < 0)
458 env->psr |= PSR_NEG; 468 env->psr |= PSR_NEG;
  469 + /* V9 xcc */
459 FORCE_RET(); 470 FORCE_RET();
460 } 471 }
461 472
@@ -519,12 +530,12 @@ void OPPROTO op_wrwim(void) @@ -519,12 +530,12 @@ void OPPROTO op_wrwim(void)
519 530
520 void OPPROTO op_rdpsr(void) 531 void OPPROTO op_rdpsr(void)
521 { 532 {
522 - T0 = GET_PSR(env); 533 + do_rdpsr();
523 } 534 }
524 535
525 void OPPROTO op_wrpsr(void) 536 void OPPROTO op_wrpsr(void)
526 { 537 {
527 - PUT_PSR(env,T0); 538 + do_wrpsr();
528 FORCE_RET(); 539 FORCE_RET();
529 } 540 }
530 541
@@ -555,7 +566,7 @@ void raise_exception(int tt) @@ -555,7 +566,7 @@ void raise_exception(int tt)
555 handling ? */ 566 handling ? */
556 void OPPROTO op_save(void) 567 void OPPROTO op_save(void)
557 { 568 {
558 - int cwp; 569 + uint32_t cwp;
559 cwp = (env->cwp - 1) & (NWINDOWS - 1); 570 cwp = (env->cwp - 1) & (NWINDOWS - 1);
560 if (env->wim & (1 << cwp)) { 571 if (env->wim & (1 << cwp)) {
561 raise_exception(TT_WIN_OVF); 572 raise_exception(TT_WIN_OVF);
@@ -566,7 +577,7 @@ void OPPROTO op_save(void) @@ -566,7 +577,7 @@ void OPPROTO op_save(void)
566 577
567 void OPPROTO op_restore(void) 578 void OPPROTO op_restore(void)
568 { 579 {
569 - int cwp; 580 + uint32_t cwp;
570 cwp = (env->cwp + 1) & (NWINDOWS - 1); 581 cwp = (env->cwp + 1) & (NWINDOWS - 1);
571 if (env->wim & (1 << cwp)) { 582 if (env->wim & (1 << cwp)) {
572 raise_exception(TT_WIN_UNF); 583 raise_exception(TT_WIN_UNF);
@@ -626,84 +637,84 @@ void OPPROTO op_exit_tb(void) @@ -626,84 +637,84 @@ void OPPROTO op_exit_tb(void)
626 637
627 void OPPROTO op_eval_be(void) 638 void OPPROTO op_eval_be(void)
628 { 639 {
629 - T2 = (env->psr & PSR_ZERO); 640 + T2 = FLAG_SET(PSR_ZERO);
630 } 641 }
631 642
632 void OPPROTO op_eval_ble(void) 643 void OPPROTO op_eval_ble(void)
633 { 644 {
634 - unsigned int Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); 645 + target_ulong Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
635 646
636 T2 = Z | (N ^ V); 647 T2 = Z | (N ^ V);
637 } 648 }
638 649
639 void OPPROTO op_eval_bl(void) 650 void OPPROTO op_eval_bl(void)
640 { 651 {
641 - unsigned int N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); 652 + target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
642 653
643 T2 = N ^ V; 654 T2 = N ^ V;
644 } 655 }
645 656
646 void OPPROTO op_eval_bleu(void) 657 void OPPROTO op_eval_bleu(void)
647 { 658 {
648 - unsigned int Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY); 659 + target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
649 660
650 T2 = C | Z; 661 T2 = C | Z;
651 } 662 }
652 663
653 void OPPROTO op_eval_bcs(void) 664 void OPPROTO op_eval_bcs(void)
654 { 665 {
655 - T2 = (env->psr & PSR_CARRY); 666 + T2 = FLAG_SET(PSR_CARRY);
656 } 667 }
657 668
658 void OPPROTO op_eval_bvs(void) 669 void OPPROTO op_eval_bvs(void)
659 { 670 {
660 - T2 = (env->psr & PSR_OVF); 671 + T2 = FLAG_SET(PSR_OVF);
661 } 672 }
662 673
663 void OPPROTO op_eval_bneg(void) 674 void OPPROTO op_eval_bneg(void)
664 { 675 {
665 - T2 = (env->psr & PSR_NEG); 676 + T2 = FLAG_SET(PSR_NEG);
666 } 677 }
667 678
668 void OPPROTO op_eval_bne(void) 679 void OPPROTO op_eval_bne(void)
669 { 680 {
670 - T2 = !(env->psr & PSR_ZERO); 681 + T2 = !FLAG_SET(PSR_ZERO);
671 } 682 }
672 683
673 void OPPROTO op_eval_bg(void) 684 void OPPROTO op_eval_bg(void)
674 { 685 {
675 - unsigned int Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); 686 + target_ulong Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
676 687
677 T2 = !(Z | (N ^ V)); 688 T2 = !(Z | (N ^ V));
678 } 689 }
679 690
680 void OPPROTO op_eval_bge(void) 691 void OPPROTO op_eval_bge(void)
681 { 692 {
682 - unsigned int N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF); 693 + target_ulong N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF);
683 694
684 T2 = !(N ^ V); 695 T2 = !(N ^ V);
685 } 696 }
686 697
687 void OPPROTO op_eval_bgu(void) 698 void OPPROTO op_eval_bgu(void)
688 { 699 {
689 - unsigned int Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY); 700 + target_ulong Z = FLAG_SET(PSR_ZERO), C = FLAG_SET(PSR_CARRY);
690 701
691 T2 = !(C | Z); 702 T2 = !(C | Z);
692 } 703 }
693 704
694 void OPPROTO op_eval_bcc(void) 705 void OPPROTO op_eval_bcc(void)
695 { 706 {
696 - T2 = !(env->psr & PSR_CARRY); 707 + T2 = !FLAG_SET(PSR_CARRY);
697 } 708 }
698 709
699 void OPPROTO op_eval_bpos(void) 710 void OPPROTO op_eval_bpos(void)
700 { 711 {
701 - T2 = !(env->psr & PSR_NEG); 712 + T2 = !FLAG_SET(PSR_NEG);
702 } 713 }
703 714
704 void OPPROTO op_eval_bvc(void) 715 void OPPROTO op_eval_bvc(void)
705 { 716 {
706 - T2 = !(env->psr & PSR_OVF); 717 + T2 = !FLAG_SET(PSR_OVF);
707 } 718 }
708 719
709 /* FCC1:FCC0: 0 =, 1 <, 2 >, 3 u */ 720 /* FCC1:FCC0: 0 =, 1 <, 2 >, 3 u */
@@ -792,16 +803,6 @@ void OPPROTO op_eval_fbo(void) @@ -792,16 +803,6 @@ void OPPROTO op_eval_fbo(void)
792 T2 = !(FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1)); 803 T2 = !(FFLAG_SET(FSR_FCC0) & FFLAG_SET(FSR_FCC1));
793 } 804 }
794 805
795 -void OPPROTO op_movl_T2_0(void)  
796 -{  
797 - T2 = 0;  
798 -}  
799 -  
800 -void OPPROTO op_movl_T2_1(void)  
801 -{  
802 - T2 = 1;  
803 -}  
804 -  
805 void OPPROTO op_jmp_im(void) 806 void OPPROTO op_jmp_im(void)
806 { 807 {
807 env->pc = PARAM1; 808 env->pc = PARAM1;
@@ -845,10 +846,10 @@ void OPPROTO op_branch_a(void) @@ -845,10 +846,10 @@ void OPPROTO op_branch_a(void)
845 { 846 {
846 if (T2) { 847 if (T2) {
847 env->npc = PARAM2; /* XXX: optimize */ 848 env->npc = PARAM2; /* XXX: optimize */
848 - JUMP_TB(op_generic_branch_a, PARAM1, 0, PARAM3); 849 + JUMP_TB(op_branch_a, PARAM1, 0, PARAM3);
849 } else { 850 } else {
850 env->npc = PARAM3 + 8; /* XXX: optimize */ 851 env->npc = PARAM3 + 8; /* XXX: optimize */
851 - JUMP_TB(op_generic_branch_a, PARAM1, 1, PARAM3 + 4); 852 + JUMP_TB(op_branch_a, PARAM1, 1, PARAM3 + 4);
852 } 853 }
853 FORCE_RET(); 854 FORCE_RET();
854 } 855 }
target-sparc/op_helper.c
@@ -209,7 +209,8 @@ void helper_st_asi(int asi, int size, int sign) @@ -209,7 +209,8 @@ void helper_st_asi(int asi, int size, int sign)
209 209
210 void helper_rett() 210 void helper_rett()
211 { 211 {
212 - int cwp; 212 + unsigned int cwp;
  213 +
213 env->psret = 1; 214 env->psret = 1;
214 cwp = (env->cwp + 1) & (NWINDOWS - 1); 215 cwp = (env->cwp + 1) & (NWINDOWS - 1);
215 if (env->wim & (1 << cwp)) { 216 if (env->wim & (1 << cwp)) {
@@ -255,3 +256,13 @@ void helper_debug() @@ -255,3 +256,13 @@ void helper_debug()
255 env->exception_index = EXCP_DEBUG; 256 env->exception_index = EXCP_DEBUG;
256 cpu_loop_exit(); 257 cpu_loop_exit();
257 } 258 }
  259 +
  260 +void do_wrpsr()
  261 +{
  262 + PUT_PSR(env, T0);
  263 +}
  264 +
  265 +void do_rdpsr()
  266 +{
  267 + T0 = GET_PSR(env);
  268 +}
target-sparc/op_mem.h
@@ -36,7 +36,7 @@ void OPPROTO glue(op_ldstub, MEMSUFFIX)(void) @@ -36,7 +36,7 @@ void OPPROTO glue(op_ldstub, MEMSUFFIX)(void)
36 36
37 void OPPROTO glue(op_swap, MEMSUFFIX)(void) 37 void OPPROTO glue(op_swap, MEMSUFFIX)(void)
38 { 38 {
39 - unsigned int tmp = glue(ldl, MEMSUFFIX)(T0); 39 + target_ulong tmp = glue(ldl, MEMSUFFIX)(T0);
40 glue(stl, MEMSUFFIX)(T0, T1); /* XXX: Should be Atomically */ 40 glue(stl, MEMSUFFIX)(T0, T1); /* XXX: Should be Atomically */
41 T1 = tmp; 41 T1 = tmp;
42 } 42 }
target-sparc/translate.c
@@ -423,16 +423,13 @@ static inline void save_npc(DisasContext * dc) @@ -423,16 +423,13 @@ static inline void save_npc(DisasContext * dc)
423 423
424 static inline void save_state(DisasContext * dc) 424 static inline void save_state(DisasContext * dc)
425 { 425 {
426 - gen_op_jmp_im((uint32_t)dc->pc); 426 + gen_op_jmp_im(dc->pc);
427 save_npc(dc); 427 save_npc(dc);
428 } 428 }
429 429
430 static void gen_cond(int cond) 430 static void gen_cond(int cond)
431 { 431 {
432 switch (cond) { 432 switch (cond) {
433 - case 0x0:  
434 - gen_op_movl_T2_0();  
435 - break;  
436 case 0x1: 433 case 0x1:
437 gen_op_eval_be(); 434 gen_op_eval_be();
438 break; 435 break;
@@ -454,9 +451,6 @@ static void gen_cond(int cond) @@ -454,9 +451,6 @@ static void gen_cond(int cond)
454 case 0x7: 451 case 0x7:
455 gen_op_eval_bvs(); 452 gen_op_eval_bvs();
456 break; 453 break;
457 - case 0x8:  
458 - gen_op_movl_T2_1();  
459 - break;  
460 case 0x9: 454 case 0x9:
461 gen_op_eval_bne(); 455 gen_op_eval_bne();
462 break; 456 break;
@@ -485,9 +479,6 @@ static void gen_cond(int cond) @@ -485,9 +479,6 @@ static void gen_cond(int cond)
485 static void gen_fcond(int cond) 479 static void gen_fcond(int cond)
486 { 480 {
487 switch (cond) { 481 switch (cond) {
488 - case 0x0:  
489 - gen_op_movl_T2_0();  
490 - break;  
491 case 0x1: 482 case 0x1:
492 gen_op_eval_fbne(); 483 gen_op_eval_fbne();
493 break; 484 break;
@@ -509,9 +500,6 @@ static void gen_fcond(int cond) @@ -509,9 +500,6 @@ static void gen_fcond(int cond)
509 case 0x7: 500 case 0x7:
510 gen_op_eval_fbu(); 501 gen_op_eval_fbu();
511 break; 502 break;
512 - case 0x8:  
513 - gen_op_movl_T2_1();  
514 - break;  
515 case 0x9: 503 case 0x9:
516 gen_op_eval_fbe(); 504 gen_op_eval_fbe();
517 break; 505 break;
@@ -537,10 +525,11 @@ static void gen_fcond(int cond) @@ -537,10 +525,11 @@ static void gen_fcond(int cond)
537 } 525 }
538 } 526 }
539 527
540 -static void do_branch(DisasContext * dc, uint32_t target, uint32_t insn) 528 +static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn)
541 { 529 {
542 unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29)); 530 unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
543 - target += (uint32_t) dc->pc; 531 + target_ulong target = dc->pc + offset;
  532 +
544 if (cond == 0x0) { 533 if (cond == 0x0) {
545 /* unconditional not taken */ 534 /* unconditional not taken */
546 if (a) { 535 if (a) {
@@ -574,10 +563,11 @@ static void do_branch(DisasContext * dc, uint32_t target, uint32_t insn) @@ -574,10 +563,11 @@ static void do_branch(DisasContext * dc, uint32_t target, uint32_t insn)
574 } 563 }
575 } 564 }
576 565
577 -static void do_fbranch(DisasContext * dc, uint32_t target, uint32_t insn) 566 +static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn)
578 { 567 {
579 unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29)); 568 unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
580 - target += (uint32_t) dc->pc; 569 + target_ulong target = dc->pc + offset;
  570 +
581 if (cond == 0x0) { 571 if (cond == 0x0) {
582 /* unconditional not taken */ 572 /* unconditional not taken */
583 if (a) { 573 if (a) {
@@ -611,15 +601,6 @@ static void do_fbranch(DisasContext * dc, uint32_t target, uint32_t insn) @@ -611,15 +601,6 @@ static void do_fbranch(DisasContext * dc, uint32_t target, uint32_t insn)
611 } 601 }
612 } 602 }
613 603
614 -#if 0  
615 -static void gen_debug(DisasContext *s, uint32_t pc)  
616 -{  
617 - gen_op_jmp_im(pc);  
618 - gen_op_debug();  
619 - s->is_br = 1;  
620 -}  
621 -#endif  
622 -  
623 #define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1) 604 #define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
624 605
625 static int sign_extend(int x, int len) 606 static int sign_extend(int x, int len)
@@ -640,12 +621,13 @@ static void disas_sparc_insn(DisasContext * dc) @@ -640,12 +621,13 @@ static void disas_sparc_insn(DisasContext * dc)
640 case 0: /* branches/sethi */ 621 case 0: /* branches/sethi */
641 { 622 {
642 unsigned int xop = GET_FIELD(insn, 7, 9); 623 unsigned int xop = GET_FIELD(insn, 7, 9);
643 - int target; 624 + int32_t target;
644 target = GET_FIELD(insn, 10, 31); 625 target = GET_FIELD(insn, 10, 31);
645 switch (xop) { 626 switch (xop) {
646 - case 0x0:  
647 - case 0x1: /* UNIMPL */  
648 - case 0x5: /*CBN+x */ 627 + case 0x0: /* UNIMPL */
  628 + case 0x1: /* V9 BPcc */
  629 + case 0x3: /* V9 BPr */
  630 + case 0x5: /* V9 FBPcc */
649 default: 631 default:
650 goto illegal_insn; 632 goto illegal_insn;
651 case 0x2: /* BN+x */ 633 case 0x2: /* BN+x */
@@ -679,13 +661,14 @@ static void disas_sparc_insn(DisasContext * dc) @@ -679,13 +661,14 @@ static void disas_sparc_insn(DisasContext * dc)
679 } 661 }
680 break; 662 break;
681 } 663 }
  664 + break;
682 case 1: 665 case 1:
683 /*CALL*/ { 666 /*CALL*/ {
684 - unsigned int target = GET_FIELDs(insn, 2, 31) << 2; 667 + target_long target = GET_FIELDs(insn, 2, 31) << 2;
685 668
686 - gen_op_movl_T0_im((long) (dc->pc)); 669 + gen_op_movl_T0_im(dc->pc);
687 gen_movl_T0_reg(15); 670 gen_movl_T0_reg(15);
688 - target = dc->pc + target; 671 + target += dc->pc;
689 dc->pc = dc->npc; 672 dc->pc = dc->npc;
690 dc->npc = target; 673 dc->npc = target;
691 } 674 }
@@ -719,12 +702,13 @@ static void disas_sparc_insn(DisasContext * dc) @@ -719,12 +702,13 @@ static void disas_sparc_insn(DisasContext * dc)
719 #endif 702 #endif
720 } 703 }
721 save_state(dc); 704 save_state(dc);
  705 + /* V9 icc/xcc */
722 cond = GET_FIELD(insn, 3, 6); 706 cond = GET_FIELD(insn, 3, 6);
723 if (cond == 0x8) { 707 if (cond == 0x8) {
724 gen_op_trap_T0(); 708 gen_op_trap_T0();
725 dc->is_br = 1; 709 dc->is_br = 1;
726 goto jmp_insn; 710 goto jmp_insn;
727 - } else { 711 + } else if (cond != 0) {
728 gen_cond(cond); 712 gen_cond(cond);
729 gen_op_trapcc_T0(); 713 gen_op_trapcc_T0();
730 } 714 }
@@ -735,9 +719,14 @@ static void disas_sparc_insn(DisasContext * dc) @@ -735,9 +719,14 @@ static void disas_sparc_insn(DisasContext * dc)
735 gen_op_rdy(); 719 gen_op_rdy();
736 gen_movl_T0_reg(rd); 720 gen_movl_T0_reg(rd);
737 break; 721 break;
738 - case 15: /* stbar */ 722 + case 15: /* stbar / V9 membar */
739 break; /* no effect? */ 723 break; /* no effect? */
740 default: 724 default:
  725 + case 0x2: /* V9 rdccr */
  726 + case 0x3: /* V9 rdasi */
  727 + case 0x4: /* V9 rdtick */
  728 + case 0x5: /* V9 rdpc */
  729 + case 0x6: /* V9 rdfprs */
741 goto illegal_insn; 730 goto illegal_insn;
742 } 731 }
743 #if !defined(CONFIG_USER_ONLY) 732 #if !defined(CONFIG_USER_ONLY)
@@ -901,6 +890,19 @@ static void disas_sparc_insn(DisasContext * dc) @@ -901,6 +890,19 @@ static void disas_sparc_insn(DisasContext * dc)
901 case 0xd3: /* fqtoi */ 890 case 0xd3: /* fqtoi */
902 goto nfpu_insn; 891 goto nfpu_insn;
903 default: 892 default:
  893 + case 0x2: /* V9 fmovd */
  894 + case 0x6: /* V9 fnegd */
  895 + case 0xa: /* V9 fabsd */
  896 + case 0x81: /* V9 fstox */
  897 + case 0x82: /* V9 fdtox */
  898 + case 0x84: /* V9 fxtos */
  899 + case 0x88: /* V9 fxtod */
  900 +
  901 + case 0x3: /* V9 fmovq */
  902 + case 0x7: /* V9 fnegq */
  903 + case 0xb: /* V9 fabsq */
  904 + case 0x83: /* V9 fqtox */
  905 + case 0x8c: /* V9 fxtoq */
904 goto illegal_insn; 906 goto illegal_insn;
905 } 907 }
906 } else if (xop == 0x35) { /* FPU Operations */ 908 } else if (xop == 0x35) { /* FPU Operations */
@@ -910,6 +912,10 @@ static void disas_sparc_insn(DisasContext * dc) @@ -910,6 +912,10 @@ static void disas_sparc_insn(DisasContext * dc)
910 rs1 = GET_FIELD(insn, 13, 17); 912 rs1 = GET_FIELD(insn, 13, 17);
911 rs2 = GET_FIELD(insn, 27, 31); 913 rs2 = GET_FIELD(insn, 27, 31);
912 xop = GET_FIELD(insn, 18, 26); 914 xop = GET_FIELD(insn, 18, 26);
  915 + /* V9 fmovscc: x5, cond = x >> 1 */
  916 + /* V9 fmovdcc: x6, cond = x >> 1 */
  917 +
  918 + /* V9 fmovqcc: x7, cond = x >> 1 */
913 switch (xop) { 919 switch (xop) {
914 case 0x51: 920 case 0x51:
915 gen_op_load_fpr_FT0(rs1); 921 gen_op_load_fpr_FT0(rs1);
@@ -1028,9 +1034,10 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1028,9 +1034,10 @@ static void disas_sparc_insn(DisasContext * dc)
1028 gen_op_logic_T0_cc(); 1034 gen_op_logic_T0_cc();
1029 break; 1035 break;
1030 case 0x8: 1036 case 0x8:
1031 - gen_op_addx_T1_T0();  
1032 if (xop & 0x10) 1037 if (xop & 0x10)
1033 - gen_op_set_flags(); 1038 + gen_op_addx_T1_T0_cc();
  1039 + else
  1040 + gen_op_addx_T1_T0();
1034 break; 1041 break;
1035 case 0xa: 1042 case 0xa:
1036 gen_op_umul_T1_T0(); 1043 gen_op_umul_T1_T0();
@@ -1043,9 +1050,10 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1043,9 +1050,10 @@ static void disas_sparc_insn(DisasContext * dc)
1043 gen_op_logic_T0_cc(); 1050 gen_op_logic_T0_cc();
1044 break; 1051 break;
1045 case 0xc: 1052 case 0xc:
1046 - gen_op_subx_T1_T0();  
1047 if (xop & 0x10) 1053 if (xop & 0x10)
1048 - gen_op_set_flags(); 1054 + gen_op_subx_T1_T0_cc();
  1055 + else
  1056 + gen_op_subx_T1_T0();
1049 break; 1057 break;
1050 case 0xe: 1058 case 0xe:
1051 gen_op_udiv_T1_T0(); 1059 gen_op_udiv_T1_T0();
@@ -1058,6 +1066,8 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1058,6 +1066,8 @@ static void disas_sparc_insn(DisasContext * dc)
1058 gen_op_div_cc(); 1066 gen_op_div_cc();
1059 break; 1067 break;
1060 default: 1068 default:
  1069 + case 0x9: /* V9 mulx */
  1070 + case 0xd: /* V9 udivx */
1061 goto illegal_insn; 1071 goto illegal_insn;
1062 } 1072 }
1063 gen_movl_T0_reg(rd); 1073 gen_movl_T0_reg(rd);
@@ -1072,15 +1082,15 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1072,15 +1082,15 @@ static void disas_sparc_insn(DisasContext * dc)
1072 gen_op_mulscc_T1_T0(); 1082 gen_op_mulscc_T1_T0();
1073 gen_movl_T0_reg(rd); 1083 gen_movl_T0_reg(rd);
1074 break; 1084 break;
1075 - case 0x25: /* SLL */ 1085 + case 0x25: /* sll, V9 sllx */
1076 gen_op_sll(); 1086 gen_op_sll();
1077 gen_movl_T0_reg(rd); 1087 gen_movl_T0_reg(rd);
1078 break; 1088 break;
1079 - case 0x26: 1089 + case 0x26: /* srl, V9 srlx */
1080 gen_op_srl(); 1090 gen_op_srl();
1081 gen_movl_T0_reg(rd); 1091 gen_movl_T0_reg(rd);
1082 break; 1092 break;
1083 - case 0x27: 1093 + case 0x27: /* sra, V9 srax */
1084 gen_op_sra(); 1094 gen_op_sra();
1085 gen_movl_T0_reg(rd); 1095 gen_movl_T0_reg(rd);
1086 break; 1096 break;
@@ -1092,12 +1102,16 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1092,12 +1102,16 @@ static void disas_sparc_insn(DisasContext * dc)
1092 gen_op_wry(); 1102 gen_op_wry();
1093 break; 1103 break;
1094 default: 1104 default:
  1105 + case 0x2: /* V9 wrccr */
  1106 + case 0x3: /* V9 wrasi */
  1107 + case 0x6: /* V9 wrfprs */
  1108 + case 0xf: /* V9 sir */
1095 goto illegal_insn; 1109 goto illegal_insn;
1096 } 1110 }
1097 } 1111 }
1098 break; 1112 break;
1099 #if !defined(CONFIG_USER_ONLY) 1113 #if !defined(CONFIG_USER_ONLY)
1100 - case 0x31: 1114 + case 0x31: /* wrpsr, V9 saved, restored */
1101 { 1115 {
1102 if (!supervisor(dc)) 1116 if (!supervisor(dc))
1103 goto priv_insn; 1117 goto priv_insn;
@@ -1105,7 +1119,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1105,7 +1119,7 @@ static void disas_sparc_insn(DisasContext * dc)
1105 gen_op_wrpsr(); 1119 gen_op_wrpsr();
1106 } 1120 }
1107 break; 1121 break;
1108 - case 0x32: 1122 + case 0x32: /* wrwim, V9 wrpr */
1109 { 1123 {
1110 if (!supervisor(dc)) 1124 if (!supervisor(dc))
1111 goto priv_insn; 1125 goto priv_insn;
@@ -1123,6 +1137,12 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1123,6 +1137,12 @@ static void disas_sparc_insn(DisasContext * dc)
1123 break; 1137 break;
1124 #endif 1138 #endif
1125 default: 1139 default:
  1140 + case 0x2a: /* V9 rdpr */
  1141 + case 0x2b: /* V9 flushw */
  1142 + case 0x2c: /* V9 movcc */
  1143 + case 0x2d: /* V9 sdivx */
  1144 + case 0x2e: /* V9 popc */
  1145 + case 0x2f: /* V9 movr */
1126 goto illegal_insn; 1146 goto illegal_insn;
1127 } 1147 }
1128 } 1148 }
@@ -1155,7 +1175,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1155,7 +1175,7 @@ static void disas_sparc_insn(DisasContext * dc)
1155 { 1175 {
1156 gen_op_movl_npc_T0(); 1176 gen_op_movl_npc_T0();
1157 if (rd != 0) { 1177 if (rd != 0) {
1158 - gen_op_movl_T0_im((long) (dc->pc)); 1178 + gen_op_movl_T0_im(dc->pc);
1159 gen_movl_T0_reg(rd); 1179 gen_movl_T0_reg(rd);
1160 } 1180 }
1161 dc->pc = dc->npc; 1181 dc->pc = dc->npc;
@@ -1163,7 +1183,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1163,7 +1183,7 @@ static void disas_sparc_insn(DisasContext * dc)
1163 } 1183 }
1164 goto jmp_insn; 1184 goto jmp_insn;
1165 #if !defined(CONFIG_USER_ONLY) 1185 #if !defined(CONFIG_USER_ONLY)
1166 - case 0x39: /* rett */ 1186 + case 0x39: /* rett, V9 return */
1167 { 1187 {
1168 if (!supervisor(dc)) 1188 if (!supervisor(dc))
1169 goto priv_insn; 1189 goto priv_insn;
@@ -1186,11 +1206,13 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1186,11 +1206,13 @@ static void disas_sparc_insn(DisasContext * dc)
1186 gen_movl_T0_reg(rd); 1206 gen_movl_T0_reg(rd);
1187 break; 1207 break;
1188 default: 1208 default:
  1209 + case 0x3e: /* V9 done/retry */
1189 goto illegal_insn; 1210 goto illegal_insn;
1190 } 1211 }
1191 } 1212 }
1192 break; 1213 break;
1193 } 1214 }
  1215 + break;
1194 case 3: /* load/store instructions */ 1216 case 3: /* load/store instructions */
1195 { 1217 {
1196 unsigned int xop = GET_FIELD(insn, 7, 12); 1218 unsigned int xop = GET_FIELD(insn, 7, 12);
@@ -1297,6 +1319,16 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1297,6 +1319,16 @@ static void disas_sparc_insn(DisasContext * dc)
1297 (void) &gen_op_lddfa; 1319 (void) &gen_op_lddfa;
1298 #endif 1320 #endif
1299 default: 1321 default:
  1322 + case 0x08: /* V9 ldsw */
  1323 + case 0x0b: /* V9 ldx */
  1324 + case 0x18: /* V9 ldswa */
  1325 + case 0x1b: /* V9 ldxa */
  1326 + case 0x2d: /* V9 prefetch */
  1327 + case 0x30: /* V9 ldfa */
  1328 + case 0x33: /* V9 lddfa */
  1329 + case 0x3d: /* V9 prefetcha */
  1330 +
  1331 + case 0x32: /* V9 ldqfa */
1300 goto illegal_insn; 1332 goto illegal_insn;
1301 } 1333 }
1302 gen_movl_T1_reg(rd); 1334 gen_movl_T1_reg(rd);
@@ -1313,6 +1345,8 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1313,6 +1345,8 @@ static void disas_sparc_insn(DisasContext * dc)
1313 gen_op_ldfsr(); 1345 gen_op_ldfsr();
1314 gen_op_store_FT0_fpr(rd); 1346 gen_op_store_FT0_fpr(rd);
1315 break; 1347 break;
  1348 + case 0x22: /* load quad fpreg */
  1349 + goto nfpu_insn;
1316 case 0x23: /* load double fpreg */ 1350 case 0x23: /* load double fpreg */
1317 gen_op_ldst(lddf); 1351 gen_op_ldst(lddf);
1318 gen_op_store_DT0_fpr(rd); 1352 gen_op_store_DT0_fpr(rd);
@@ -1362,6 +1396,8 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1362,6 +1396,8 @@ static void disas_sparc_insn(DisasContext * dc)
1362 break; 1396 break;
1363 #endif 1397 #endif
1364 default: 1398 default:
  1399 + case 0x0e: /* V9 stx */
  1400 + case 0x1e: /* V9 stxa */
1365 goto illegal_insn; 1401 goto illegal_insn;
1366 } 1402 }
1367 } else if (xop > 0x23 && xop < 0x28) { 1403 } else if (xop > 0x23 && xop < 0x28) {
@@ -1373,16 +1409,23 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1373,16 +1409,23 @@ static void disas_sparc_insn(DisasContext * dc)
1373 gen_op_load_fpr_FT0(rd); 1409 gen_op_load_fpr_FT0(rd);
1374 gen_op_ldst(stf); 1410 gen_op_ldst(stf);
1375 break; 1411 break;
1376 - case 0x25: 1412 + case 0x25: /* stfsr, V9 stxfsr */
1377 gen_op_load_fpr_FT0(rd); 1413 gen_op_load_fpr_FT0(rd);
1378 gen_op_stfsr(); 1414 gen_op_stfsr();
1379 break; 1415 break;
  1416 + case 0x26: /* stdfq */
  1417 + goto nfpu_insn;
1380 case 0x27: 1418 case 0x27:
1381 gen_op_load_fpr_DT0(rd); 1419 gen_op_load_fpr_DT0(rd);
1382 gen_op_ldst(stdf); 1420 gen_op_ldst(stdf);
1383 break; 1421 break;
1384 - case 0x26: /* stdfq */  
1385 default: 1422 default:
  1423 + case 0x34: /* V9 stfa */
  1424 + case 0x37: /* V9 stdfa */
  1425 + case 0x3c: /* V9 casa */
  1426 + case 0x3e: /* V9 casxa */
  1427 +
  1428 + case 0x36: /* V9 stqfa */
1386 goto illegal_insn; 1429 goto illegal_insn;
1387 } 1430 }
1388 } else if (xop > 0x33 && xop < 0x38) { 1431 } else if (xop > 0x33 && xop < 0x38) {
@@ -1392,6 +1435,7 @@ static void disas_sparc_insn(DisasContext * dc) @@ -1392,6 +1435,7 @@ static void disas_sparc_insn(DisasContext * dc)
1392 else 1435 else
1393 goto illegal_insn; 1436 goto illegal_insn;
1394 } 1437 }
  1438 + break;
1395 } 1439 }
1396 /* default case for non jump instructions */ 1440 /* default case for non jump instructions */
1397 if (dc->npc == DYNAMIC_PC) { 1441 if (dc->npc == DYNAMIC_PC) {
@@ -1589,22 +1633,22 @@ void cpu_dump_state(CPUState *env, FILE *f, @@ -1589,22 +1633,22 @@ void cpu_dump_state(CPUState *env, FILE *f,
1589 { 1633 {
1590 int i, x; 1634 int i, x;
1591 1635
1592 - cpu_fprintf(f, "pc: 0x%08x npc: 0x%08x\n", (int) env->pc, (int) env->npc); 1636 + cpu_fprintf(f, "pc: " TARGET_FMT_lx " npc: " TARGET_FMT_lx "\n", env->pc, env->npc);
1593 cpu_fprintf(f, "General Registers:\n"); 1637 cpu_fprintf(f, "General Registers:\n");
1594 for (i = 0; i < 4; i++) 1638 for (i = 0; i < 4; i++)
1595 - cpu_fprintf(f, "%%g%c: 0x%08x\t", i + '0', env->gregs[i]); 1639 + cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
1596 cpu_fprintf(f, "\n"); 1640 cpu_fprintf(f, "\n");
1597 for (; i < 8; i++) 1641 for (; i < 8; i++)
1598 - cpu_fprintf(f, "%%g%c: 0x%08x\t", i + '0', env->gregs[i]); 1642 + cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
1599 cpu_fprintf(f, "\nCurrent Register Window:\n"); 1643 cpu_fprintf(f, "\nCurrent Register Window:\n");
1600 for (x = 0; x < 3; x++) { 1644 for (x = 0; x < 3; x++) {
1601 for (i = 0; i < 4; i++) 1645 for (i = 0; i < 4; i++)
1602 - cpu_fprintf(f, "%%%c%d: 0x%08x\t", 1646 + cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
1603 (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i, 1647 (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
1604 env->regwptr[i + x * 8]); 1648 env->regwptr[i + x * 8]);
1605 cpu_fprintf(f, "\n"); 1649 cpu_fprintf(f, "\n");
1606 for (; i < 8; i++) 1650 for (; i < 8; i++)
1607 - cpu_fprintf(f, "%%%c%d: 0x%08x\t", 1651 + cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
1608 (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i, 1652 (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
1609 env->regwptr[i + x * 8]); 1653 env->regwptr[i + x * 8]);
1610 cpu_fprintf(f, "\n"); 1654 cpu_fprintf(f, "\n");
@@ -1626,19 +1670,19 @@ void cpu_dump_state(CPUState *env, FILE *f, @@ -1626,19 +1670,19 @@ void cpu_dump_state(CPUState *env, FILE *f,
1626 } 1670 }
1627 1671
1628 #if defined(CONFIG_USER_ONLY) 1672 #if defined(CONFIG_USER_ONLY)
1629 -target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr) 1673 +target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
1630 { 1674 {
1631 return addr; 1675 return addr;
1632 } 1676 }
1633 1677
1634 #else 1678 #else
1635 -extern int get_physical_address (CPUState *env, uint32_t *physical, int *prot,  
1636 - int *access_index, uint32_t address, int rw, 1679 +extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
  1680 + int *access_index, target_ulong address, int rw,
1637 int is_user); 1681 int is_user);
1638 1682
1639 -target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr) 1683 +target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
1640 { 1684 {
1641 - uint32_t phys_addr; 1685 + target_phys_addr_t phys_addr;
1642 int prot, access_index; 1686 int prot, access_index;
1643 1687
1644 if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2, 0) != 0) 1688 if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2, 0) != 0)