Commit cf495bcf9ffe0f1450a5de7497612dd1be23ff2a

Authored by bellard
1 parent fb0eaffc

SPARC fixes: corrected PC/NPC logic (now slower but can be optimized a lot) - fi…

…xed flags computations - added register window exceptions support - fixed mul and div - added mulscc - fixed immediate field decoding


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@484 c046a42c-6fe2-441c-8c8c-71466251a162
linux-user/sparc/syscall_nr.h
@@ -182,7 +182,7 @@ @@ -182,7 +182,7 @@
182 #define TARGET_NR_sysinfo 214 /* Linux Specific */ 182 #define TARGET_NR_sysinfo 214 /* Linux Specific */
183 #define TARGET_NR_ipc 215 /* Linux Specific */ 183 #define TARGET_NR_ipc 215 /* Linux Specific */
184 #define TARGET_NR_sigreturn 216 /* Linux Specific */ 184 #define TARGET_NR_sigreturn 216 /* Linux Specific */
185 -#define TARGET_NR_clone 217 /* Linux Specific */ 185 +#define TARGET_NR_clone 2170 /* Linux Specific */
186 #define TARGET_NR_adjtimex 219 /* Linux Specific */ 186 #define TARGET_NR_adjtimex 219 /* Linux Specific */
187 #define TARGET_NR_sigprocmask 220 /* Linux Specific */ 187 #define TARGET_NR_sigprocmask 220 /* Linux Specific */
188 #define TARGET_NR_create_module 221 /* Linux Specific */ 188 #define TARGET_NR_create_module 221 /* Linux Specific */
target-sparc/cpu.h
@@ -7,29 +7,42 @@ @@ -7,29 +7,42 @@
7 7
8 /*#define EXCP_INTERRUPT 0x100*/ 8 /*#define EXCP_INTERRUPT 0x100*/
9 9
  10 +/* trap definitions */
  11 +#define TT_ILL_INSN 0x02
  12 +#define TT_WIN_OVF 0x05
  13 +#define TT_WIN_UNF 0x06
  14 +#define TT_DIV_ZERO 0x2a
  15 +#define TT_TRAP 0x80
10 16
11 #define PSR_NEG (1<<23) 17 #define PSR_NEG (1<<23)
12 #define PSR_ZERO (1<<22) 18 #define PSR_ZERO (1<<22)
13 #define PSR_OVF (1<<21) 19 #define PSR_OVF (1<<21)
14 #define PSR_CARRY (1<<20) 20 #define PSR_CARRY (1<<20)
15 21
  22 +#define NWINDOWS 32
  23 +
16 typedef struct CPUSPARCState { 24 typedef struct CPUSPARCState {
17 - uint32_t gregs[8]; /* general registers */  
18 - uint32_t *regwptr; /* pointer to current register window */  
19 - double *regfptr; /* floating point registers */  
20 - uint32_t pc; /* program counter */  
21 - uint32_t npc; /* next program counter */  
22 - uint32_t sp; /* stack pointer */  
23 - uint32_t y; /* multiply/divide register */  
24 - uint32_t psr; /* processor state register */  
25 - uint32_t T2;  
26 - jmp_buf jmp_env;  
27 - int user_mode_only;  
28 - int exception_index;  
29 - int interrupt_index;  
30 - int interrupt_request;  
31 - struct TranslationBlock *current_tb;  
32 - void *opaque; 25 + uint32_t gregs[8]; /* general registers */
  26 + uint32_t *regwptr; /* pointer to current register window */
  27 + double *regfptr; /* floating point registers */
  28 + uint32_t pc; /* program counter */
  29 + uint32_t npc; /* next program counter */
  30 + uint32_t sp; /* stack pointer */
  31 + uint32_t y; /* multiply/divide register */
  32 + uint32_t psr; /* processor state register */
  33 + uint32_t T2;
  34 + uint32_t cwp; /* index of current register window (extracted
  35 + from PSR) */
  36 + uint32_t wim; /* window invalid mask */
  37 + jmp_buf jmp_env;
  38 + int user_mode_only;
  39 + int exception_index;
  40 + int interrupt_index;
  41 + int interrupt_request;
  42 + struct TranslationBlock *current_tb;
  43 + void *opaque;
  44 + /* NOTE: we allow 8 more registers to handle wrapping */
  45 + uint32_t regbase[NWINDOWS * 16 + 8];
33 } CPUSPARCState; 46 } CPUSPARCState;
34 47
35 CPUSPARCState *cpu_sparc_init(void); 48 CPUSPARCState *cpu_sparc_init(void);
target-sparc/op.c
@@ -20,7 +20,7 @@ @@ -20,7 +20,7 @@
20 20
21 #include "exec.h" 21 #include "exec.h"
22 22
23 -/*XXX*/ 23 + /*XXX*/
24 #define REGNAME g0 24 #define REGNAME g0
25 #define REG (env->gregs[0]) 25 #define REG (env->gregs[0])
26 #include "op_template.h" 26 #include "op_template.h"
@@ -117,380 +117,545 @@ @@ -117,380 +117,545 @@
117 #define REGNAME o7 117 #define REGNAME o7
118 #define REG (env->regwptr[7]) 118 #define REG (env->regwptr[7])
119 #include "op_template.h" 119 #include "op_template.h"
120 -  
121 #define EIP (env->pc) 120 #define EIP (env->pc)
122 121
  122 +#define FLAG_SET(x) (env->psr&x)?1:0
  123 +#define GET_FLAGS unsigned int Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF), C = FLAG_SET(PSR_CARRY)
  124 +
123 void OPPROTO op_movl_T0_0(void) 125 void OPPROTO op_movl_T0_0(void)
124 { 126 {
125 - T0 = 0; 127 + T0 = 0;
126 } 128 }
127 129
128 void OPPROTO op_movl_T0_1(void) 130 void OPPROTO op_movl_T0_1(void)
129 { 131 {
130 - T0 = 1; 132 + T0 = 1;
131 } 133 }
132 134
133 void OPPROTO op_movl_T0_im(void) 135 void OPPROTO op_movl_T0_im(void)
134 { 136 {
135 - T0 = PARAM1; 137 + T0 = PARAM1;
136 } 138 }
137 139
138 void OPPROTO op_movl_T1_im(void) 140 void OPPROTO op_movl_T1_im(void)
139 { 141 {
140 - T1 = PARAM1; 142 + T1 = PARAM1;
141 } 143 }
142 144
143 void OPPROTO op_movl_T2_im(void) 145 void OPPROTO op_movl_T2_im(void)
144 { 146 {
145 - T2 = PARAM1; 147 + T2 = PARAM1;
146 } 148 }
147 149
148 void OPPROTO op_addl_T1_im(void) 150 void OPPROTO op_addl_T1_im(void)
149 { 151 {
150 - T1 += PARAM1; 152 + T1 += PARAM1;
151 } 153 }
152 154
153 void OPPROTO op_addl_T1_T2(void) 155 void OPPROTO op_addl_T1_T2(void)
154 { 156 {
155 - T1 += T2; 157 + T1 += T2;
156 } 158 }
157 159
158 void OPPROTO op_subl_T1_T2(void) 160 void OPPROTO op_subl_T1_T2(void)
159 { 161 {
160 - T1 -= T2; 162 + T1 -= T2;
161 } 163 }
162 164
163 -void OPPROTO op_add_T1_T0 (void) 165 +void OPPROTO op_add_T1_T0(void)
164 { 166 {
165 - T0 += T1; 167 + T0 += T1;
166 } 168 }
167 169
168 -void OPPROTO op_and_T1_T0 (void) 170 +void OPPROTO op_add_T1_T0_cc(void)
169 { 171 {
170 - T0 &= T1; 172 + unsigned int src1;
  173 + src1 = T0;
  174 + T0 += T1;
  175 + env->psr = 0;
  176 + if (!T0)
  177 + env->psr |= PSR_ZERO;
  178 + if ((int) T0 < 0)
  179 + env->psr |= PSR_NEG;
  180 + if (T0 < src1)
  181 + env->psr |= PSR_CARRY;
  182 + if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
  183 + env->psr |= PSR_OVF;
  184 + FORCE_RET();
171 } 185 }
172 186
173 -void OPPROTO op_or_T1_T0 (void) 187 +void OPPROTO op_sub_T1_T0(void)
174 { 188 {
175 - T0 |= T1; 189 + T0 -= T1;
176 } 190 }
177 191
178 -void OPPROTO op_xor_T1_T0 (void) 192 +void OPPROTO op_sub_T1_T0_cc(void)
179 { 193 {
180 - T0 ^= T1; 194 + unsigned int src1;
  195 +
  196 + src1 = T0;
  197 + T0 -= T1;
  198 + env->psr = 0;
  199 + if (!T0)
  200 + env->psr |= PSR_ZERO;
  201 + if ((int) T0 < 0)
  202 + env->psr |= PSR_NEG;
  203 + if (src1 < T1)
  204 + env->psr |= PSR_CARRY;
  205 + if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
  206 + env->psr |= PSR_OVF;
  207 + FORCE_RET();
181 } 208 }
182 209
183 -void OPPROTO op_sub_T1_T0 (void) 210 +void OPPROTO op_and_T1_T0(void)
184 { 211 {
185 - T0 -= T1; 212 + T0 &= T1;
186 } 213 }
187 214
188 -void OPPROTO op_andn_T1_T0 (void) 215 +void OPPROTO op_or_T1_T0(void)
189 { 216 {
190 - T0 &= ~T1; 217 + T0 |= T1;
191 } 218 }
192 219
193 -void OPPROTO op_orn_T1_T0 (void) 220 +void OPPROTO op_xor_T1_T0(void)
194 { 221 {
195 - T0 |= ~T1; 222 + T0 ^= T1;
196 } 223 }
197 224
198 -void OPPROTO op_xnor_T1_T0 (void) 225 +void OPPROTO op_andn_T1_T0(void)
199 { 226 {
200 - T0 ^= ~T1; 227 + T0 &= ~T1;
201 } 228 }
202 229
203 -void OPPROTO op_addx_T1_T0 (void) 230 +void OPPROTO op_orn_T1_T0(void)
204 { 231 {
205 - T0 += T1+((env->psr & PSR_CARRY)?1:0); 232 + T0 |= ~T1;
206 } 233 }
207 234
208 -void OPPROTO op_umul_T1_T0 (void) 235 +void OPPROTO op_xnor_T1_T0(void)
209 { 236 {
210 - unsigned long long res = T0*T1;  
211 - T0 = res & 0xffffffff;  
212 - env->y = res >> 32; 237 + T0 ^= ~T1;
213 } 238 }
214 239
215 -void OPPROTO op_smul_T1_T0 (void) 240 +void OPPROTO op_addx_T1_T0(void)
216 { 241 {
217 - long long res = T0*T1;  
218 - T0 = res & 0xffffffff;  
219 - env->y = res >> 32; 242 + T0 += T1 + ((env->psr & PSR_CARRY) ? 1 : 0);
220 } 243 }
221 244
222 -void OPPROTO op_udiv_T1_T0 (void) 245 +void OPPROTO op_umul_T1_T0(void)
223 { 246 {
224 - unsigned long long x0 = T0 * env->y;  
225 - unsigned int x1 = T1;  
226 - T0 = x0 / x1; 247 + uint64_t res;
  248 + res = (uint64_t) T0 *(uint64_t) T1;
  249 + T0 = res & 0xffffffff;
  250 + env->y = res >> 32;
227 } 251 }
228 252
229 -void OPPROTO op_sdiv_T1_T0 (void) 253 +void OPPROTO op_smul_T1_T0(void)
230 { 254 {
231 - long long x0 = T0 * env->y;  
232 - int x1 = T1;  
233 - T0 = x0 / x1; 255 + uint64_t res;
  256 + res = (int64_t) ((int32_t) T0) * (int64_t) ((int32_t) T1);
  257 + T0 = res & 0xffffffff;
  258 + env->y = res >> 32;
234 } 259 }
235 260
236 -void OPPROTO op_subx_T1_T0 (void) 261 +void OPPROTO op_mulscc_T1_T0(void)
237 { 262 {
238 - T0 -= T1+((env->psr & PSR_CARRY)?1:0); 263 + unsigned int b1, C, V, b2, src1;
  264 + C = FLAG_SET(PSR_CARRY);
  265 + V = FLAG_SET(PSR_OVF);
  266 + b1 = C ^ V;
  267 + b2 = T0 & 1;
  268 + T0 = (b1 << 31) | (T0 >> 1);
  269 + if (!(env->y & 1))
  270 + T1 = 0;
  271 + /* do addition and update flags */
  272 + src1 = T0;
  273 + T0 += T1;
  274 + env->psr = 0;
  275 + if (!T0)
  276 + env->psr |= PSR_ZERO;
  277 + if ((int) T0 < 0)
  278 + env->psr |= PSR_NEG;
  279 + if (T0 < src1)
  280 + env->psr |= PSR_CARRY;
  281 + if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
  282 + env->psr |= PSR_OVF;
  283 + env->y = (b2 << 31) | (env->y >> 1);
  284 + FORCE_RET();
  285 +}
  286 +
  287 +void OPPROTO op_udiv_T1_T0(void)
  288 +{
  289 + uint64_t x0;
  290 + uint32_t x1;
  291 +
  292 + x0 = T0 | ((uint64_t) (env->y) << 32);
  293 + x1 = T1;
  294 + x0 = x0 / x1;
  295 + if (x0 > 0xffffffff) {
  296 + T0 = 0xffffffff;
  297 + T1 = 1;
  298 + } else {
  299 + T0 = x0;
  300 + T1 = 0;
  301 + }
  302 + FORCE_RET();
239 } 303 }
240 304
241 -void OPPROTO op_set_flags (void) 305 +void OPPROTO op_sdiv_T1_T0(void)
242 { 306 {
243 - env->psr = 0;  
244 - if (!T0) env->psr |= PSR_ZERO;  
245 - if ((unsigned int) T0 < (unsigned int) T1) env->psr |= PSR_CARRY;  
246 - if ((int) T0 < (int) T1) env->psr |= PSR_OVF;  
247 - if ((int) T0 < 0) env->psr |= PSR_NEG; 307 + int64_t x0;
  308 + int32_t x1;
  309 +
  310 + x0 = T0 | ((uint64_t) (env->y) << 32);
  311 + x1 = T1;
  312 + x0 = x0 / x1;
  313 + if ((int32_t) x0 != x0) {
  314 + T0 = x0 >> 63;
  315 + T1 = 1;
  316 + } else {
  317 + T0 = x0;
  318 + T1 = 0;
  319 + }
  320 + FORCE_RET();
248 } 321 }
249 322
250 -void OPPROTO op_sll (void) 323 +void OPPROTO op_div_cc(void)
251 { 324 {
252 - T0 <<= T1; 325 + env->psr = 0;
  326 + if (!T0)
  327 + env->psr |= PSR_ZERO;
  328 + if ((int) T0 < 0)
  329 + env->psr |= PSR_NEG;
  330 + if (T1)
  331 + env->psr |= PSR_OVF;
  332 + FORCE_RET();
253 } 333 }
254 334
255 -void OPPROTO op_srl (void) 335 +void OPPROTO op_subx_T1_T0(void)
256 { 336 {
257 - T0 >>= T1; 337 + T0 -= T1 + ((env->psr & PSR_CARRY) ? 1 : 0);
258 } 338 }
259 339
260 -void OPPROTO op_sra (void) 340 +void OPPROTO op_logic_T0_cc(void)
261 { 341 {
262 - int x = T0 >> T1;  
263 - T0 = x; 342 + env->psr = 0;
  343 + if (!T0)
  344 + env->psr |= PSR_ZERO;
  345 + if ((int) T0 < 0)
  346 + env->psr |= PSR_NEG;
  347 + FORCE_RET();
264 } 348 }
265 349
266 -void OPPROTO op_st (void) 350 +void OPPROTO op_set_flags(void)
267 { 351 {
268 - stl ((void *) T0, T1); 352 + env->psr = 0;
  353 + if (!T0)
  354 + env->psr |= PSR_ZERO;
  355 + if ((unsigned int) T0 < (unsigned int) T1)
  356 + env->psr |= PSR_CARRY;
  357 + if ((int) T0 < (int) T1)
  358 + env->psr |= PSR_OVF;
  359 + if ((int) T0 < 0)
  360 + env->psr |= PSR_NEG;
  361 + FORCE_RET();
269 } 362 }
270 363
271 -void OPPROTO op_stb (void) 364 +void OPPROTO op_sll(void)
272 { 365 {
273 - stb ((void *) T0, T1); 366 + T0 <<= T1;
274 } 367 }
275 368
276 -void OPPROTO op_sth (void) 369 +void OPPROTO op_srl(void)
277 { 370 {
278 - stw ((void *) T0, T1); 371 + T0 >>= T1;
279 } 372 }
280 373
281 -void OPPROTO op_ld (void) 374 +void OPPROTO op_sra(void)
282 { 375 {
283 - T1 = ldl ((void *) T0); 376 + T0 = ((int32_t) T0) >> T1;
284 } 377 }
285 378
286 -void OPPROTO op_ldub (void) 379 +void OPPROTO op_st(void)
287 { 380 {
288 - T1 = ldub ((void *) T0); 381 + stl((void *) T0, T1);
289 } 382 }
290 383
291 -void OPPROTO op_lduh (void) 384 +void OPPROTO op_stb(void)
292 { 385 {
293 - T1 = lduw ((void *) T0); 386 + stb((void *) T0, T1);
294 } 387 }
295 388
296 -void OPPROTO op_ldsb (void) 389 +void OPPROTO op_sth(void)
297 { 390 {
298 - T1 = ldsb ((void *) T0); 391 + stw((void *) T0, T1);
299 } 392 }
300 393
301 -void OPPROTO op_ldsh (void) 394 +void OPPROTO op_std(void)
302 { 395 {
303 - T1 = ldsw ((void *) T0); 396 + stl((void *) T0, T1);
  397 + stl((void *) (T0 + 4), T2);
304 } 398 }
305 399
306 -void OPPROTO op_ldstub (void) 400 +void OPPROTO op_ld(void)
307 { 401 {
308 - T1 = ldub ((void *) T0);  
309 - stb ((void *) T0, 0xff); /* XXX: Should be Atomically */ 402 + T1 = ldl((void *) T0);
310 } 403 }
311 404
312 -void OPPROTO op_swap (void) 405 +void OPPROTO op_ldub(void)
313 { 406 {
314 - unsigned int tmp = ldl ((void *) T0);  
315 - stl ((void *) T0, T1); /* XXX: Should be Atomically */  
316 - T1 = tmp; 407 + T1 = ldub((void *) T0);
317 } 408 }
318 409
319 -void OPPROTO op_ldd (void) 410 +void OPPROTO op_lduh(void)
320 { 411 {
321 - T1 = ldl ((void *) T0);  
322 - T0 = ldl ((void *) T0+4); 412 + T1 = lduw((void *) T0);
323 } 413 }
324 414
325 -void OPPROTO op_wry (void) 415 +void OPPROTO op_ldsb(void)
326 { 416 {
327 - env->y = T0^T1; 417 + T1 = ldsb((void *) T0);
328 } 418 }
329 419
330 -void OPPROTO op_rdy (void) 420 +void OPPROTO op_ldsh(void)
331 { 421 {
332 - T0 = env->y; 422 + T1 = ldsw((void *) T0);
333 } 423 }
334 424
335 -#define regwptr (env->regwptr) 425 +void OPPROTO op_ldstub(void)
  426 +{
  427 + T1 = ldub((void *) T0);
  428 + stb((void *) T0, 0xff); /* XXX: Should be Atomically */
  429 +}
336 430
337 -void OPPROTO op_save (void) 431 +void OPPROTO op_swap(void)
338 { 432 {
339 - regwptr -= 16; 433 + unsigned int tmp = ldl((void *) T0);
  434 + stl((void *) T0, T1); /* XXX: Should be Atomically */
  435 + T1 = tmp;
340 } 436 }
341 437
342 -void OPPROTO op_restore (void) 438 +void OPPROTO op_ldd(void)
343 { 439 {
344 - regwptr += 16; 440 + T1 = ldl((void *) T0);
  441 + T0 = ldl((void *) (T0 + 4));
345 } 442 }
346 443
347 -void OPPROTO op_trap (void) 444 +void OPPROTO op_wry(void)
348 { 445 {
349 - env->exception_index = PARAM1;  
350 - cpu_loop_exit (); 446 + env->y = T0;
351 } 447 }
352 448
353 -void OPPROTO op_exit_tb (void) 449 +void OPPROTO op_rdy(void)
354 { 450 {
355 - EXIT_TB (); 451 + T0 = env->y;
356 } 452 }
357 453
358 -void OPPROTO op_eval_be (void) 454 +void raise_exception(int tt)
  455 +{
  456 + env->exception_index = tt;
  457 + cpu_loop_exit();
  458 +}
  459 +
  460 +void memcpy32(uint32_t *dst, const uint32_t *src)
359 { 461 {
360 - T0 = (env->psr & PSR_ZERO); 462 + dst[0] = src[0];
  463 + dst[1] = src[1];
  464 + dst[2] = src[2];
  465 + dst[3] = src[3];
  466 + dst[4] = src[4];
  467 + dst[5] = src[5];
  468 + dst[6] = src[6];
  469 + dst[7] = src[7];
361 } 470 }
362 471
363 -#define FLAG_SET(x) (env->psr&x)?1:0  
364 -#define GET_FLAGS unsigned int Z = FLAG_SET(PSR_ZERO), N = FLAG_SET(PSR_NEG), V = FLAG_SET(PSR_OVF), C = FLAG_SET(PSR_CARRY) 472 +static inline void set_cwp(int new_cwp)
  473 +{
  474 + /* put the modified wrap registers at their proper location */
  475 + if (env->cwp == (NWINDOWS - 1))
  476 + memcpy32(env->regbase, env->regbase + NWINDOWS * 16);
  477 + env->cwp = new_cwp;
  478 + /* put the wrap registers at their temporary location */
  479 + if (new_cwp == (NWINDOWS - 1))
  480 + memcpy32(env->regbase + NWINDOWS * 16, env->regbase);
  481 + env->regwptr = env->regbase + (new_cwp * 16);
  482 +}
365 483
366 -void OPPROTO op_eval_ble (void) 484 +/* XXX: use another pointer for %iN registers to avoid slow wrapping
  485 + handling ? */
  486 +void OPPROTO op_save(void)
367 { 487 {
368 - GET_FLAGS;  
369 - T0 = Z | (N^V); 488 + int cwp;
  489 + cwp = (env->cwp - 1) & (NWINDOWS - 1);
  490 + if (env->wim & (1 << cwp)) {
  491 + raise_exception(TT_WIN_OVF);
  492 + }
  493 + set_cwp(cwp);
  494 + FORCE_RET();
370 } 495 }
371 496
372 -void OPPROTO op_eval_bl (void) 497 +void OPPROTO op_restore(void)
373 { 498 {
374 - GET_FLAGS;  
375 - T0 = N^V; 499 + int cwp;
  500 + cwp = (env->cwp + 1) & (NWINDOWS - 1);
  501 + if (env->wim & (1 << cwp)) {
  502 + raise_exception(TT_WIN_UNF);
  503 + }
  504 + set_cwp(cwp);
  505 + FORCE_RET();
376 } 506 }
377 507
378 -void OPPROTO op_eval_bleu (void) 508 +void OPPROTO op_exception(void)
379 { 509 {
380 - GET_FLAGS;  
381 - T0 = C|Z; 510 + env->exception_index = PARAM1;
  511 + cpu_loop_exit();
382 } 512 }
383 513
384 -void OPPROTO op_eval_bcs (void) 514 +void OPPROTO op_trap_T0(void)
385 { 515 {
386 - T0 = (env->psr & PSR_CARRY); 516 + env->exception_index = TT_TRAP + (T0 & 0x7f);
  517 + cpu_loop_exit();
387 } 518 }
388 519
389 -void OPPROTO op_eval_bvs (void) 520 +void OPPROTO op_trapcc_T0(void)
390 { 521 {
391 - T0 = (env->psr & PSR_OVF); 522 + if (T2) {
  523 + env->exception_index = TT_TRAP + (T0 & 0x7f);
  524 + cpu_loop_exit();
  525 + }
  526 + FORCE_RET();
392 } 527 }
393 528
394 -void OPPROTO op_eval_bneg (void) 529 +void OPPROTO op_exit_tb(void)
395 { 530 {
396 - T0 = (env->psr & PSR_NEG); 531 + EXIT_TB();
397 } 532 }
398 533
399 -void OPPROTO op_eval_bne (void) 534 +void OPPROTO op_eval_be(void)
400 { 535 {
401 - T0 = !(env->psr & PSR_ZERO); 536 + T2 = (env->psr & PSR_ZERO);
402 } 537 }
403 538
404 -void OPPROTO op_eval_bg (void) 539 +void OPPROTO op_eval_ble(void)
405 { 540 {
406 - GET_FLAGS;  
407 - T0 = !(Z | (N^V)); 541 + GET_FLAGS;
  542 + T2 = Z | (N ^ V);
408 } 543 }
409 544
410 -/*XXX: This seems to be documented wrong in the SPARC V8 Manual  
411 - The manual states: !(N^V)  
412 - but I assume Z | !(N^V) to be correct */  
413 -void OPPROTO op_eval_bge (void) 545 +void OPPROTO op_eval_bl(void)
414 { 546 {
415 - GET_FLAGS;  
416 - T0 = Z | !(N^V); 547 + GET_FLAGS;
  548 + T2 = N ^ V;
417 } 549 }
418 550
419 -void OPPROTO op_eval_bgu (void) 551 +void OPPROTO op_eval_bleu(void)
420 { 552 {
421 - GET_FLAGS;  
422 - T0 = !(C | Z); 553 + GET_FLAGS;
  554 + T2 = C | Z;
423 } 555 }
424 556
425 -void OPPROTO op_eval_bcc (void) 557 +void OPPROTO op_eval_bcs(void)
426 { 558 {
427 - T0 = !(env->psr & PSR_CARRY); 559 + T2 = (env->psr & PSR_CARRY);
428 } 560 }
429 561
430 -void OPPROTO op_eval_bpos (void) 562 +void OPPROTO op_eval_bvs(void)
431 { 563 {
432 - T0 = !(env->psr & PSR_NEG); 564 + T2 = (env->psr & PSR_OVF);
433 } 565 }
434 566
435 -void OPPROTO op_eval_bvc (void) 567 +void OPPROTO op_eval_bneg(void)
436 { 568 {
437 - T0 = !(env->psr & PSR_OVF); 569 + T2 = (env->psr & PSR_NEG);
438 } 570 }
439 571
440 -void OPPROTO op_jmp_im (void) 572 +void OPPROTO op_eval_bne(void)
441 { 573 {
442 - env->pc = PARAM1; 574 + T2 = !(env->psr & PSR_ZERO);
443 } 575 }
444 576
445 -void OPPROTO op_call (void) 577 +void OPPROTO op_eval_bg(void)
446 { 578 {
447 - regwptr[7] = PARAM1-4;  
448 - env->pc = PARAM1+PARAM2; 579 + GET_FLAGS;
  580 + T2 = !(Z | (N ^ V));
449 } 581 }
450 582
451 -void OPPROTO op_jmpl (void) 583 +void OPPROTO op_eval_bge(void)
452 { 584 {
453 - env->npc = T0; 585 + GET_FLAGS;
  586 + T2 = !(N ^ V);
454 } 587 }
455 588
456 -void OPPROTO op_generic_jmp_1 (void) 589 +void OPPROTO op_eval_bgu(void)
457 { 590 {
458 - T1 = PARAM1;  
459 - env->pc = PARAM1+PARAM2; 591 + GET_FLAGS;
  592 + T2 = !(C | Z);
460 } 593 }
461 594
462 -void OPPROTO op_generic_jmp_2 (void) 595 +void OPPROTO op_eval_bcc(void)
463 { 596 {
464 - T1 = PARAM1;  
465 - env->pc = env->npc; 597 + T2 = !(env->psr & PSR_CARRY);
466 } 598 }
467 599
468 -unsigned long old_T0; 600 +void OPPROTO op_eval_bpos(void)
  601 +{
  602 + T2 = !(env->psr & PSR_NEG);
  603 +}
  604 +
  605 +void OPPROTO op_eval_bvc(void)
  606 +{
  607 + T2 = !(env->psr & PSR_OVF);
  608 +}
  609 +
  610 +void OPPROTO op_movl_T2_0(void)
  611 +{
  612 + T2 = 0;
  613 +}
  614 +
  615 +void OPPROTO op_movl_T2_1(void)
  616 +{
  617 + T2 = 1;
  618 +}
  619 +
  620 +void OPPROTO op_jmp_im(void)
  621 +{
  622 + env->pc = PARAM1;
  623 +}
  624 +
  625 +void OPPROTO op_movl_npc_im(void)
  626 +{
  627 + env->npc = PARAM1;
  628 +}
469 629
470 -void OPPROTO op_save_T0 (void) 630 +void OPPROTO op_movl_npc_T0(void)
471 { 631 {
472 - old_T0 = T0; 632 + env->npc = T0;
473 } 633 }
474 634
475 -void OPPROTO op_restore_T0 (void) 635 +void OPPROTO op_next_insn(void)
476 { 636 {
477 - T0 = old_T0; 637 + env->pc = env->npc;
  638 + env->npc = env->npc + 4;
478 } 639 }
479 640
480 -void OPPROTO op_generic_branch (void) 641 +void OPPROTO op_generic_branch(void)
481 { 642 {
482 - if (T0)  
483 - JUMP_TB (op_generic_branch, PARAM1, 0, PARAM2);  
484 - else  
485 - JUMP_TB (op_generic_branch, PARAM1, 1, PARAM3);  
486 - FORCE_RET (); 643 + if (T2) {
  644 + env->npc = PARAM1;
  645 + } else {
  646 + env->npc = PARAM2;
  647 + }
  648 + FORCE_RET();
487 } 649 }
488 650
489 -void OPPROTO op_generic_branch_a (void) 651 +void OPPROTO op_generic_branch_a(void)
490 { 652 {
491 - if (T0)  
492 - env->npc = PARAM3;  
493 - else  
494 - JUMP_TB (op_generic_branch_a, PARAM1, 0, PARAM2);  
495 - FORCE_RET (); 653 + if (T2) {
  654 + env->pc = PARAM2;
  655 + env->npc = PARAM1;
  656 + } else {
  657 + env->pc = PARAM2 + 4;
  658 + env->npc = PARAM2 + 8;
  659 + }
  660 + FORCE_RET();
496 } 661 }
target-sparc/translate.c
@@ -34,18 +34,13 @@ @@ -34,18 +34,13 @@
34 and the 'anull' bit in the branch instruction opcode is set. This is 34 and the 'anull' bit in the branch instruction opcode is set. This is
35 currently solved by doing a jump after the delay slot instruction. 35 currently solved by doing a jump after the delay slot instruction.
36 36
37 - There is also one big (currently unsolved) bug in the branch code:  
38 - If a delay slot modifies the condition codes then the new condition  
39 - codes, instead of the old ones will be used.  
40 -  
41 TODO-list: 37 TODO-list:
42 38
  39 + Register window overflow/underflow check
43 FPU-Instructions 40 FPU-Instructions
44 Coprocessor-Instructions 41 Coprocessor-Instructions
45 - Fix above bug  
46 Check signedness issues 42 Check signedness issues
47 Privileged instructions 43 Privileged instructions
48 - Register window overflow/underflow check  
49 Optimize synthetic instructions 44 Optimize synthetic instructions
50 Optional alignment and privileged instruction check 45 Optional alignment and privileged instruction check
51 46
@@ -65,14 +60,10 @@ @@ -65,14 +60,10 @@
65 #define DEBUG_DISAS 60 #define DEBUG_DISAS
66 61
67 typedef struct DisasContext { 62 typedef struct DisasContext {
68 - uint8_t *pc;  
69 - uint8_t *npc;  
70 - void (*branch) (struct DisasContext *, uint32_t, uint32_t);  
71 - unsigned int delay_slot:2;  
72 - uint32_t insn;  
73 - uint32_t target;  
74 - int is_br;  
75 - struct TranslationBlock *tb; 63 + uint8_t *pc; /* NULL means dynamic value */
  64 + uint8_t *npc; /* NULL means dynamic value */
  65 + int is_br;
  66 + struct TranslationBlock *tb;
76 } DisasContext; 67 } DisasContext;
77 68
78 static uint16_t *gen_opc_ptr; 69 static uint16_t *gen_opc_ptr;
@@ -84,7 +75,7 @@ enum { @@ -84,7 +75,7 @@ enum {
84 #define DEF(s,n,copy_size) INDEX_op_ ## s, 75 #define DEF(s,n,copy_size) INDEX_op_ ## s,
85 #include "opc.h" 76 #include "opc.h"
86 #undef DEF 77 #undef DEF
87 - NB_OPS 78 + NB_OPS
88 }; 79 };
89 80
90 #include "gen-op.h" 81 #include "gen-op.h"
@@ -94,651 +85,781 @@ enum { @@ -94,651 +85,781 @@ enum {
94 85
95 #define IS_IMM (insn & (1<<13)) 86 #define IS_IMM (insn & (1<<13))
96 87
97 -static void disas_sparc_insn (DisasContext *dc); 88 +static void disas_sparc_insn(DisasContext * dc);
98 89
99 -typedef void (GenOpFunc)(void);  
100 -typedef void (GenOpFunc1)(long);  
101 -typedef void (GenOpFunc2)(long, long);  
102 -typedef void (GenOpFunc3)(long, long, long); 90 +typedef void (GenOpFunc) (void);
  91 +typedef void (GenOpFunc1) (long);
  92 +typedef void (GenOpFunc2) (long, long);
  93 +typedef void (GenOpFunc3) (long, long, long);
103 94
104 static GenOpFunc *gen_op_movl_TN_reg[2][32] = { 95 static GenOpFunc *gen_op_movl_TN_reg[2][32] = {
105 - {  
106 - gen_op_movl_g0_T0,  
107 - gen_op_movl_g1_T0,  
108 - gen_op_movl_g2_T0,  
109 - gen_op_movl_g3_T0,  
110 - gen_op_movl_g4_T0,  
111 - gen_op_movl_g5_T0,  
112 - gen_op_movl_g6_T0,  
113 - gen_op_movl_g7_T0,  
114 - gen_op_movl_o0_T0,  
115 - gen_op_movl_o1_T0,  
116 - gen_op_movl_o2_T0,  
117 - gen_op_movl_o3_T0,  
118 - gen_op_movl_o4_T0,  
119 - gen_op_movl_o5_T0,  
120 - gen_op_movl_o6_T0,  
121 - gen_op_movl_o7_T0,  
122 - gen_op_movl_l0_T0,  
123 - gen_op_movl_l1_T0,  
124 - gen_op_movl_l2_T0,  
125 - gen_op_movl_l3_T0,  
126 - gen_op_movl_l4_T0,  
127 - gen_op_movl_l5_T0,  
128 - gen_op_movl_l6_T0,  
129 - gen_op_movl_l7_T0,  
130 - gen_op_movl_i0_T0,  
131 - gen_op_movl_i1_T0,  
132 - gen_op_movl_i2_T0,  
133 - gen_op_movl_i3_T0,  
134 - gen_op_movl_i4_T0,  
135 - gen_op_movl_i5_T0,  
136 - gen_op_movl_i6_T0,  
137 - gen_op_movl_i7_T0,  
138 - },  
139 - {  
140 - gen_op_movl_g0_T1,  
141 - gen_op_movl_g1_T1,  
142 - gen_op_movl_g2_T1,  
143 - gen_op_movl_g3_T1,  
144 - gen_op_movl_g4_T1,  
145 - gen_op_movl_g5_T1,  
146 - gen_op_movl_g6_T1,  
147 - gen_op_movl_g7_T1,  
148 - gen_op_movl_o0_T1,  
149 - gen_op_movl_o1_T1,  
150 - gen_op_movl_o2_T1,  
151 - gen_op_movl_o3_T1,  
152 - gen_op_movl_o4_T1,  
153 - gen_op_movl_o5_T1,  
154 - gen_op_movl_o6_T1,  
155 - gen_op_movl_o7_T1,  
156 - gen_op_movl_l0_T1,  
157 - gen_op_movl_l1_T1,  
158 - gen_op_movl_l2_T1,  
159 - gen_op_movl_l3_T1,  
160 - gen_op_movl_l4_T1,  
161 - gen_op_movl_l5_T1,  
162 - gen_op_movl_l6_T1,  
163 - gen_op_movl_l7_T1,  
164 - gen_op_movl_i0_T1,  
165 - gen_op_movl_i1_T1,  
166 - gen_op_movl_i2_T1,  
167 - gen_op_movl_i3_T1,  
168 - gen_op_movl_i4_T1,  
169 - gen_op_movl_i5_T1,  
170 - gen_op_movl_i6_T1,  
171 - gen_op_movl_i7_T1,  
172 - } 96 + {
  97 + gen_op_movl_g0_T0,
  98 + gen_op_movl_g1_T0,
  99 + gen_op_movl_g2_T0,
  100 + gen_op_movl_g3_T0,
  101 + gen_op_movl_g4_T0,
  102 + gen_op_movl_g5_T0,
  103 + gen_op_movl_g6_T0,
  104 + gen_op_movl_g7_T0,
  105 + gen_op_movl_o0_T0,
  106 + gen_op_movl_o1_T0,
  107 + gen_op_movl_o2_T0,
  108 + gen_op_movl_o3_T0,
  109 + gen_op_movl_o4_T0,
  110 + gen_op_movl_o5_T0,
  111 + gen_op_movl_o6_T0,
  112 + gen_op_movl_o7_T0,
  113 + gen_op_movl_l0_T0,
  114 + gen_op_movl_l1_T0,
  115 + gen_op_movl_l2_T0,
  116 + gen_op_movl_l3_T0,
  117 + gen_op_movl_l4_T0,
  118 + gen_op_movl_l5_T0,
  119 + gen_op_movl_l6_T0,
  120 + gen_op_movl_l7_T0,
  121 + gen_op_movl_i0_T0,
  122 + gen_op_movl_i1_T0,
  123 + gen_op_movl_i2_T0,
  124 + gen_op_movl_i3_T0,
  125 + gen_op_movl_i4_T0,
  126 + gen_op_movl_i5_T0,
  127 + gen_op_movl_i6_T0,
  128 + gen_op_movl_i7_T0,
  129 + },
  130 + {
  131 + gen_op_movl_g0_T1,
  132 + gen_op_movl_g1_T1,
  133 + gen_op_movl_g2_T1,
  134 + gen_op_movl_g3_T1,
  135 + gen_op_movl_g4_T1,
  136 + gen_op_movl_g5_T1,
  137 + gen_op_movl_g6_T1,
  138 + gen_op_movl_g7_T1,
  139 + gen_op_movl_o0_T1,
  140 + gen_op_movl_o1_T1,
  141 + gen_op_movl_o2_T1,
  142 + gen_op_movl_o3_T1,
  143 + gen_op_movl_o4_T1,
  144 + gen_op_movl_o5_T1,
  145 + gen_op_movl_o6_T1,
  146 + gen_op_movl_o7_T1,
  147 + gen_op_movl_l0_T1,
  148 + gen_op_movl_l1_T1,
  149 + gen_op_movl_l2_T1,
  150 + gen_op_movl_l3_T1,
  151 + gen_op_movl_l4_T1,
  152 + gen_op_movl_l5_T1,
  153 + gen_op_movl_l6_T1,
  154 + gen_op_movl_l7_T1,
  155 + gen_op_movl_i0_T1,
  156 + gen_op_movl_i1_T1,
  157 + gen_op_movl_i2_T1,
  158 + gen_op_movl_i3_T1,
  159 + gen_op_movl_i4_T1,
  160 + gen_op_movl_i5_T1,
  161 + gen_op_movl_i6_T1,
  162 + gen_op_movl_i7_T1,
  163 + }
173 }; 164 };
174 165
175 static GenOpFunc *gen_op_movl_reg_TN[3][32] = { 166 static GenOpFunc *gen_op_movl_reg_TN[3][32] = {
176 - {  
177 - gen_op_movl_T0_g0,  
178 - gen_op_movl_T0_g1,  
179 - gen_op_movl_T0_g2,  
180 - gen_op_movl_T0_g3,  
181 - gen_op_movl_T0_g4,  
182 - gen_op_movl_T0_g5,  
183 - gen_op_movl_T0_g6,  
184 - gen_op_movl_T0_g7,  
185 - gen_op_movl_T0_o0,  
186 - gen_op_movl_T0_o1,  
187 - gen_op_movl_T0_o2,  
188 - gen_op_movl_T0_o3,  
189 - gen_op_movl_T0_o4,  
190 - gen_op_movl_T0_o5,  
191 - gen_op_movl_T0_o6,  
192 - gen_op_movl_T0_o7,  
193 - gen_op_movl_T0_l0,  
194 - gen_op_movl_T0_l1,  
195 - gen_op_movl_T0_l2,  
196 - gen_op_movl_T0_l3,  
197 - gen_op_movl_T0_l4,  
198 - gen_op_movl_T0_l5,  
199 - gen_op_movl_T0_l6,  
200 - gen_op_movl_T0_l7,  
201 - gen_op_movl_T0_i0,  
202 - gen_op_movl_T0_i1,  
203 - gen_op_movl_T0_i2,  
204 - gen_op_movl_T0_i3,  
205 - gen_op_movl_T0_i4,  
206 - gen_op_movl_T0_i5,  
207 - gen_op_movl_T0_i6,  
208 - gen_op_movl_T0_i7,  
209 - },  
210 - {  
211 - gen_op_movl_T1_g0,  
212 - gen_op_movl_T1_g1,  
213 - gen_op_movl_T1_g2,  
214 - gen_op_movl_T1_g3,  
215 - gen_op_movl_T1_g4,  
216 - gen_op_movl_T1_g5,  
217 - gen_op_movl_T1_g6,  
218 - gen_op_movl_T1_g7,  
219 - gen_op_movl_T1_o0,  
220 - gen_op_movl_T1_o1,  
221 - gen_op_movl_T1_o2,  
222 - gen_op_movl_T1_o3,  
223 - gen_op_movl_T1_o4,  
224 - gen_op_movl_T1_o5,  
225 - gen_op_movl_T1_o6,  
226 - gen_op_movl_T1_o7,  
227 - gen_op_movl_T1_l0,  
228 - gen_op_movl_T1_l1,  
229 - gen_op_movl_T1_l2,  
230 - gen_op_movl_T1_l3,  
231 - gen_op_movl_T1_l4,  
232 - gen_op_movl_T1_l5,  
233 - gen_op_movl_T1_l6,  
234 - gen_op_movl_T1_l7,  
235 - gen_op_movl_T1_i0,  
236 - gen_op_movl_T1_i1,  
237 - gen_op_movl_T1_i2,  
238 - gen_op_movl_T1_i3,  
239 - gen_op_movl_T1_i4,  
240 - gen_op_movl_T1_i5,  
241 - gen_op_movl_T1_i6,  
242 - gen_op_movl_T1_i7,  
243 - },  
244 - {  
245 - gen_op_movl_T2_g0,  
246 - gen_op_movl_T2_g1,  
247 - gen_op_movl_T2_g2,  
248 - gen_op_movl_T2_g3,  
249 - gen_op_movl_T2_g4,  
250 - gen_op_movl_T2_g5,  
251 - gen_op_movl_T2_g6,  
252 - gen_op_movl_T2_g7,  
253 - gen_op_movl_T2_o0,  
254 - gen_op_movl_T2_o1,  
255 - gen_op_movl_T2_o2,  
256 - gen_op_movl_T2_o3,  
257 - gen_op_movl_T2_o4,  
258 - gen_op_movl_T2_o5,  
259 - gen_op_movl_T2_o6,  
260 - gen_op_movl_T2_o7,  
261 - gen_op_movl_T2_l0,  
262 - gen_op_movl_T2_l1,  
263 - gen_op_movl_T2_l2,  
264 - gen_op_movl_T2_l3,  
265 - gen_op_movl_T2_l4,  
266 - gen_op_movl_T2_l5,  
267 - gen_op_movl_T2_l6,  
268 - gen_op_movl_T2_l7,  
269 - gen_op_movl_T2_i0,  
270 - gen_op_movl_T2_i1,  
271 - gen_op_movl_T2_i2,  
272 - gen_op_movl_T2_i3,  
273 - gen_op_movl_T2_i4,  
274 - gen_op_movl_T2_i5,  
275 - gen_op_movl_T2_i6,  
276 - gen_op_movl_T2_i7,  
277 - } 167 + {
  168 + gen_op_movl_T0_g0,
  169 + gen_op_movl_T0_g1,
  170 + gen_op_movl_T0_g2,
  171 + gen_op_movl_T0_g3,
  172 + gen_op_movl_T0_g4,
  173 + gen_op_movl_T0_g5,
  174 + gen_op_movl_T0_g6,
  175 + gen_op_movl_T0_g7,
  176 + gen_op_movl_T0_o0,
  177 + gen_op_movl_T0_o1,
  178 + gen_op_movl_T0_o2,
  179 + gen_op_movl_T0_o3,
  180 + gen_op_movl_T0_o4,
  181 + gen_op_movl_T0_o5,
  182 + gen_op_movl_T0_o6,
  183 + gen_op_movl_T0_o7,
  184 + gen_op_movl_T0_l0,
  185 + gen_op_movl_T0_l1,
  186 + gen_op_movl_T0_l2,
  187 + gen_op_movl_T0_l3,
  188 + gen_op_movl_T0_l4,
  189 + gen_op_movl_T0_l5,
  190 + gen_op_movl_T0_l6,
  191 + gen_op_movl_T0_l7,
  192 + gen_op_movl_T0_i0,
  193 + gen_op_movl_T0_i1,
  194 + gen_op_movl_T0_i2,
  195 + gen_op_movl_T0_i3,
  196 + gen_op_movl_T0_i4,
  197 + gen_op_movl_T0_i5,
  198 + gen_op_movl_T0_i6,
  199 + gen_op_movl_T0_i7,
  200 + },
  201 + {
  202 + gen_op_movl_T1_g0,
  203 + gen_op_movl_T1_g1,
  204 + gen_op_movl_T1_g2,
  205 + gen_op_movl_T1_g3,
  206 + gen_op_movl_T1_g4,
  207 + gen_op_movl_T1_g5,
  208 + gen_op_movl_T1_g6,
  209 + gen_op_movl_T1_g7,
  210 + gen_op_movl_T1_o0,
  211 + gen_op_movl_T1_o1,
  212 + gen_op_movl_T1_o2,
  213 + gen_op_movl_T1_o3,
  214 + gen_op_movl_T1_o4,
  215 + gen_op_movl_T1_o5,
  216 + gen_op_movl_T1_o6,
  217 + gen_op_movl_T1_o7,
  218 + gen_op_movl_T1_l0,
  219 + gen_op_movl_T1_l1,
  220 + gen_op_movl_T1_l2,
  221 + gen_op_movl_T1_l3,
  222 + gen_op_movl_T1_l4,
  223 + gen_op_movl_T1_l5,
  224 + gen_op_movl_T1_l6,
  225 + gen_op_movl_T1_l7,
  226 + gen_op_movl_T1_i0,
  227 + gen_op_movl_T1_i1,
  228 + gen_op_movl_T1_i2,
  229 + gen_op_movl_T1_i3,
  230 + gen_op_movl_T1_i4,
  231 + gen_op_movl_T1_i5,
  232 + gen_op_movl_T1_i6,
  233 + gen_op_movl_T1_i7,
  234 + },
  235 + {
  236 + gen_op_movl_T2_g0,
  237 + gen_op_movl_T2_g1,
  238 + gen_op_movl_T2_g2,
  239 + gen_op_movl_T2_g3,
  240 + gen_op_movl_T2_g4,
  241 + gen_op_movl_T2_g5,
  242 + gen_op_movl_T2_g6,
  243 + gen_op_movl_T2_g7,
  244 + gen_op_movl_T2_o0,
  245 + gen_op_movl_T2_o1,
  246 + gen_op_movl_T2_o2,
  247 + gen_op_movl_T2_o3,
  248 + gen_op_movl_T2_o4,
  249 + gen_op_movl_T2_o5,
  250 + gen_op_movl_T2_o6,
  251 + gen_op_movl_T2_o7,
  252 + gen_op_movl_T2_l0,
  253 + gen_op_movl_T2_l1,
  254 + gen_op_movl_T2_l2,
  255 + gen_op_movl_T2_l3,
  256 + gen_op_movl_T2_l4,
  257 + gen_op_movl_T2_l5,
  258 + gen_op_movl_T2_l6,
  259 + gen_op_movl_T2_l7,
  260 + gen_op_movl_T2_i0,
  261 + gen_op_movl_T2_i1,
  262 + gen_op_movl_T2_i2,
  263 + gen_op_movl_T2_i3,
  264 + gen_op_movl_T2_i4,
  265 + gen_op_movl_T2_i5,
  266 + gen_op_movl_T2_i6,
  267 + gen_op_movl_T2_i7,
  268 + }
278 }; 269 };
279 270
280 static GenOpFunc1 *gen_op_movl_TN_im[3] = { 271 static GenOpFunc1 *gen_op_movl_TN_im[3] = {
281 - gen_op_movl_T0_im,  
282 - gen_op_movl_T1_im,  
283 - gen_op_movl_T2_im 272 + gen_op_movl_T0_im,
  273 + gen_op_movl_T1_im,
  274 + gen_op_movl_T2_im
284 }; 275 };
285 276
286 -static inline void gen_movl_imm_TN (int reg, int imm) 277 +static inline void gen_movl_imm_TN(int reg, int imm)
287 { 278 {
288 - gen_op_movl_TN_im[reg](imm); 279 + gen_op_movl_TN_im[reg] (imm);
289 } 280 }
290 281
291 -static inline void gen_movl_imm_T1 (int val) 282 +static inline void gen_movl_imm_T1(int val)
292 { 283 {
293 - gen_movl_imm_TN (1, val); 284 + gen_movl_imm_TN(1, val);
294 } 285 }
295 286
296 -static inline void gen_movl_imm_T0 (int val) 287 +static inline void gen_movl_imm_T0(int val)
297 { 288 {
298 - gen_movl_imm_TN (0, val); 289 + gen_movl_imm_TN(0, val);
299 } 290 }
300 291
301 -static inline void gen_movl_reg_TN (int reg, int t) 292 +static inline void gen_movl_reg_TN(int reg, int t)
302 { 293 {
303 - if (reg) gen_op_movl_reg_TN[t][reg]();  
304 - else gen_movl_imm_TN (t, 0); 294 + if (reg)
  295 + gen_op_movl_reg_TN[t][reg] ();
  296 + else
  297 + gen_movl_imm_TN(t, 0);
305 } 298 }
306 299
307 -static inline void gen_movl_reg_T0 (int reg) 300 +static inline void gen_movl_reg_T0(int reg)
308 { 301 {
309 - gen_movl_reg_TN (reg, 0); 302 + gen_movl_reg_TN(reg, 0);
310 } 303 }
311 304
312 -static inline void gen_movl_reg_T1 (int reg) 305 +static inline void gen_movl_reg_T1(int reg)
313 { 306 {
314 - gen_movl_reg_TN (reg, 1); 307 + gen_movl_reg_TN(reg, 1);
315 } 308 }
316 309
317 -static inline void gen_movl_reg_T2 (int reg) 310 +static inline void gen_movl_reg_T2(int reg)
318 { 311 {
319 - gen_movl_reg_TN (reg, 2); 312 + gen_movl_reg_TN(reg, 2);
320 } 313 }
321 314
322 -static inline void gen_movl_TN_reg (int reg, int t) 315 +static inline void gen_movl_TN_reg(int reg, int t)
323 { 316 {
324 - if (reg) gen_op_movl_TN_reg[t][reg](); 317 + if (reg)
  318 + gen_op_movl_TN_reg[t][reg] ();
325 } 319 }
326 320
327 -static inline void gen_movl_T0_reg (int reg) 321 +static inline void gen_movl_T0_reg(int reg)
328 { 322 {
329 - gen_movl_TN_reg (reg, 0); 323 + gen_movl_TN_reg(reg, 0);
330 } 324 }
331 325
332 -static inline void gen_movl_T1_reg (int reg) 326 +static inline void gen_movl_T1_reg(int reg)
333 { 327 {
334 - gen_movl_TN_reg (reg, 1); 328 + gen_movl_TN_reg(reg, 1);
335 } 329 }
336 330
337 -static void do_branch (DisasContext *dc, uint32_t target, uint32_t insn) 331 +static void gen_cond(int cond)
338 { 332 {
339 - unsigned int cond = GET_FIELD (insn, 3, 6), a = (insn & (1<<29)), ib = 0;  
340 - target += (uint32_t) dc->pc-4;  
341 - if (!a) disas_sparc_insn (dc);  
342 switch (cond) { 333 switch (cond) {
343 - case 0x0: gen_op_movl_T0_0 (); break;  
344 - case 0x1: gen_op_eval_be (); break;  
345 - case 0x2: gen_op_eval_ble (); break;  
346 - case 0x3: gen_op_eval_bl (); break;  
347 - case 0x4: gen_op_eval_bleu (); break;  
348 - case 0x5: gen_op_eval_bcs (); break;  
349 - case 0x6: gen_op_eval_bneg (); break;  
350 - case 0x7: gen_op_eval_bvs (); break;  
351 - case 0x8: gen_op_movl_T0_1 (); break;  
352 - case 0x9: gen_op_eval_bne (); break;  
353 - case 0xa: gen_op_eval_bg (); break;  
354 - case 0xb: gen_op_eval_bge (); break;  
355 - case 0xc: gen_op_eval_bgu (); break;  
356 - case 0xd: gen_op_eval_bcc (); break;  
357 - case 0xe: gen_op_eval_bpos (); break;  
358 - case 0xf: gen_op_eval_bvc (); break;  
359 - }  
360 - if (a && ((cond|0x8) != 0x8)) {  
361 - gen_op_generic_branch_a ((uint32_t) dc->tb,  
362 - (uint32_t) dc->pc+4, target);  
363 - disas_sparc_insn (dc);  
364 - ib = 1; 334 + case 0x0:
  335 + gen_op_movl_T2_0();
  336 + break;
  337 + case 0x1:
  338 + gen_op_eval_be();
  339 + break;
  340 + case 0x2:
  341 + gen_op_eval_ble();
  342 + break;
  343 + case 0x3:
  344 + gen_op_eval_bl();
  345 + break;
  346 + case 0x4:
  347 + gen_op_eval_bleu();
  348 + break;
  349 + case 0x5:
  350 + gen_op_eval_bcs();
  351 + break;
  352 + case 0x6:
  353 + gen_op_eval_bneg();
  354 + break;
  355 + case 0x7:
  356 + gen_op_eval_bvs();
  357 + break;
  358 + case 0x8:
  359 + gen_op_movl_T2_1();
  360 + break;
  361 + case 0x9:
  362 + gen_op_eval_bne();
  363 + break;
  364 + case 0xa:
  365 + gen_op_eval_bg();
  366 + break;
  367 + case 0xb:
  368 + gen_op_eval_bge();
  369 + break;
  370 + case 0xc:
  371 + gen_op_eval_bgu();
  372 + break;
  373 + case 0xd:
  374 + gen_op_eval_bcc();
  375 + break;
  376 + case 0xe:
  377 + gen_op_eval_bpos();
  378 + break;
  379 + default:
  380 + case 0xf:
  381 + gen_op_eval_bvc();
  382 + break;
365 } 383 }
366 - else  
367 - if (cond && !a) {  
368 - gen_op_generic_branch ((uint32_t) dc->tb, (uint32_t) target,  
369 - (uint32_t) dc->pc);  
370 - ib = 1;  
371 - }  
372 - if (ib) dc->is_br = DISAS_JUMP;  
373 } 384 }
374 385
375 -/* target == 0x1 means CALL- else JMPL-instruction */  
376 -static void do_jump (DisasContext *dc, uint32_t target, uint32_t rd) 386 +
  387 +static void do_branch(DisasContext * dc, uint32_t target, uint32_t insn)
377 { 388 {
378 - uint32_t orig_pc = (uint32_t) dc->pc-8;  
379 - if (target != 0x1)  
380 - gen_op_generic_jmp_1 (orig_pc, target);  
381 - else  
382 - gen_op_generic_jmp_2 (orig_pc);  
383 - gen_movl_T1_reg (rd);  
384 - dc->is_br = DISAS_JUMP;  
385 - gen_op_movl_T0_0 (); 389 + unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
  390 + target += (uint32_t) dc->pc;
  391 + if (cond == 0x0) {
  392 + /* unconditional not taken */
  393 + if (a) {
  394 + dc->pc = dc->npc + 4;
  395 + dc->npc = dc->pc + 4;
  396 + } else {
  397 + dc->pc = dc->npc;
  398 + dc->npc = dc->pc + 4;
  399 + }
  400 + } else if (cond == 0x8) {
  401 + /* unconditional taken */
  402 + if (a) {
  403 + dc->pc = (uint8_t *) target;
  404 + dc->npc = dc->pc + 4;
  405 + } else {
  406 + dc->pc = dc->npc;
  407 + dc->npc = (uint8_t *) target;
  408 + }
  409 + } else {
  410 + gen_cond(cond);
  411 + if (a) {
  412 + gen_op_generic_branch_a((uint32_t) target,
  413 + (uint32_t) (dc->npc));
  414 + dc->is_br = 1;
  415 + dc->pc = NULL;
  416 + dc->npc = NULL;
  417 + } else {
  418 + dc->pc = dc->npc;
  419 + gen_op_generic_branch((uint32_t) target,
  420 + (uint32_t) (dc->npc + 4));
  421 + dc->npc = NULL;
  422 + }
  423 + }
386 } 424 }
387 425
388 -#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), b-a) 426 +#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
389 427
390 -static int  
391 -sign_extend (x, len)  
392 - int x, len; 428 +static int sign_extend(int x, int len)
393 { 429 {
394 - int signbit = (1 << (len - 1));  
395 - int mask = (signbit << 1) - 1;  
396 - return ((x & mask) ^ signbit) - signbit; 430 + len = 32 - len;
  431 + return (x << len) >> len;
397 } 432 }
398 433
399 -static void disas_sparc_insn (DisasContext *dc) 434 +static inline void save_state(DisasContext * dc)
400 { 435 {
401 - unsigned int insn, opc, rs1, rs2, rd; 436 + gen_op_jmp_im((uint32_t)dc->pc);
  437 + if (dc->npc != NULL)
  438 + gen_op_movl_npc_im((long) dc->npc);
  439 +}
402 440
403 - if (dc->delay_slot == 1) {  
404 - insn = dc->insn;  
405 - } else {  
406 - if (dc->delay_slot) dc->delay_slot--;  
407 - insn = htonl (*(unsigned int *) (dc->pc));  
408 - dc->pc += 4;  
409 - } 441 +static void disas_sparc_insn(DisasContext * dc)
  442 +{
  443 + unsigned int insn, opc, rs1, rs2, rd;
410 444
411 - opc = GET_FIELD (insn, 0, 1); 445 + insn = ldl_code(dc->pc);
  446 + opc = GET_FIELD(insn, 0, 1);
412 447
413 - rd = GET_FIELD (insn, 2, 6);  
414 - switch (opc) {  
415 - case 0: /* branches/sethi */  
416 - {  
417 - unsigned int xop = GET_FIELD (insn, 7, 9);  
418 - int target;  
419 - target = GET_FIELD (insn, 10, 31);  
420 - switch (xop) {  
421 - case 0x0: case 0x1: /* UNIMPL */  
422 - printf ("UNIMPLEMENTED: %p\n", dc->pc-4);  
423 - exit (23);  
424 - break;  
425 - case 0x2: /* BN+x */  
426 - {  
427 - target <<= 2;  
428 - target = sign_extend (target, 22);  
429 - do_branch (dc, target, insn);  
430 - break;  
431 - }  
432 - case 0x3: /* FBN+x */  
433 - break;  
434 - case 0x4: /* SETHI */  
435 - gen_movl_imm_T0 (target<<10);  
436 - gen_movl_T0_reg (rd);  
437 - break;  
438 - case 0x5: /*CBN+x*/  
439 - break;  
440 - }  
441 - break;  
442 - }  
443 - case 1: /*CALL*/ 448 + rd = GET_FIELD(insn, 2, 6);
  449 + switch (opc) {
  450 + case 0: /* branches/sethi */
  451 + {
  452 + unsigned int xop = GET_FIELD(insn, 7, 9);
  453 + int target;
  454 + target = GET_FIELD(insn, 10, 31);
  455 + switch (xop) {
  456 + case 0x0:
  457 + case 0x1: /* UNIMPL */
  458 + goto illegal_insn;
  459 + case 0x2: /* BN+x */
444 { 460 {
445 - unsigned int target = GET_FIELDs (insn, 2, 31) << 2;  
446 - if (dc->delay_slot) {  
447 - do_jump (dc, target, 15);  
448 - dc->delay_slot = 0;  
449 - } else {  
450 - dc->insn = insn;  
451 - dc->delay_slot = 2;  
452 - }  
453 - break; 461 + target <<= 2;
  462 + target = sign_extend(target, 22);
  463 + do_branch(dc, target, insn);
  464 + goto jmp_insn;
454 } 465 }
455 - case 2: /* FPU & Logical Operations */  
456 - {  
457 - unsigned int xop = GET_FIELD (insn, 7, 12);  
458 - if (xop == 58) { /* generate trap */  
459 - dc->is_br = DISAS_JUMP;  
460 - gen_op_jmp_im ((uint32_t) dc->pc);  
461 - if (IS_IMM) gen_op_trap (GET_FIELD (insn, 25, 31));  
462 - /* else XXX*/  
463 - gen_op_movl_T0_0 ();  
464 - break;  
465 - }  
466 - if (xop == 0x34 || xop == 0x35) { /* FPU Operations */  
467 - exit (33);  
468 - }  
469 - rs1 = GET_FIELD (insn, 13, 17);  
470 - gen_movl_reg_T0 (rs1);  
471 - if (IS_IMM) { /* immediate */  
472 - rs2 = GET_FIELDs (insn, 20, 31);  
473 - gen_movl_imm_T1 (rs2);  
474 - } else { /* register */  
475 - rs2 = GET_FIELD (insn, 27, 31);  
476 - gen_movl_reg_T1 (rs2);  
477 - }  
478 - if (xop < 0x20) {  
479 - switch (xop &~ 0x10) {  
480 - case 0x0:  
481 - gen_op_add_T1_T0 ();  
482 - break;  
483 - case 0x1:  
484 - gen_op_and_T1_T0 ();  
485 - break;  
486 - case 0x2:  
487 - gen_op_or_T1_T0 ();  
488 - break;  
489 - case 0x3:  
490 - gen_op_xor_T1_T0 ();  
491 - break;  
492 - case 0x4:  
493 - gen_op_sub_T1_T0 ();  
494 - break;  
495 - case 0x5:  
496 - gen_op_andn_T1_T0 ();  
497 - break;  
498 - case 0x6:  
499 - gen_op_orn_T1_T0 ();  
500 - break;  
501 - case 0x7:  
502 - gen_op_xnor_T1_T0 ();  
503 - break;  
504 - case 0x8:  
505 - gen_op_addx_T1_T0 ();  
506 - break;  
507 - case 0xa:  
508 - gen_op_umul_T1_T0 ();  
509 - break;  
510 - case 0xb:  
511 - gen_op_smul_T1_T0 ();  
512 - break;  
513 - case 0xc:  
514 - gen_op_subx_T1_T0 ();  
515 - break;  
516 - case 0xe:  
517 - gen_op_udiv_T1_T0 ();  
518 - break;  
519 - case 0xf:  
520 - gen_op_sdiv_T1_T0 ();  
521 - break;  
522 - default:  
523 - exit (17);  
524 - break;  
525 - }  
526 - gen_movl_T0_reg (rd);  
527 - if (xop & 0x10) {  
528 - gen_op_set_flags ();  
529 - }  
530 - } else {  
531 - switch (xop) {  
532 - case 0x25: /* SLL */  
533 - gen_op_sll ();  
534 - break;  
535 - case 0x26:  
536 - gen_op_srl ();  
537 - break;  
538 - case 0x27:  
539 - gen_op_sra ();  
540 - break;  
541 - case 0x28: case 0x30:  
542 - {  
543 - unsigned int rdi = GET_FIELD (insn, 13, 17);  
544 - if (!rdi) (xop==0x28?gen_op_rdy ():gen_op_wry());  
545 - /* else gen_op_su_trap (); */  
546 - break;  
547 - }  
548 - /* Problem with jmpl: if restore is executed in the delay  
549 - slot, then the wrong registers are beeing used */  
550 - case 0x38: /* jmpl */  
551 - {  
552 - if (dc->delay_slot) {  
553 - gen_op_add_T1_T0 ();  
554 - do_jump (dc, 1, rd);  
555 - dc->delay_slot = 0;  
556 - } else {  
557 - gen_op_add_T1_T0 ();  
558 - gen_op_jmpl ();  
559 - dc->insn = insn;  
560 - dc->delay_slot = 2;  
561 - }  
562 - break;  
563 - }  
564 - case 0x3c: /* save */  
565 - gen_op_add_T1_T0 ();  
566 - gen_op_save ();  
567 - gen_movl_T0_reg (rd);  
568 - break;  
569 - case 0x3d: /* restore */  
570 - gen_op_add_T1_T0 ();  
571 - gen_op_restore ();  
572 - gen_movl_T0_reg (rd);  
573 - break;  
574 - }  
575 - }  
576 - break; 466 + case 0x3: /* FBN+x */
  467 + break;
  468 + case 0x4: /* SETHI */
  469 + gen_movl_imm_T0(target << 10);
  470 + gen_movl_T0_reg(rd);
  471 + break;
  472 + case 0x5: /*CBN+x */
  473 + break;
  474 + }
  475 + break;
  476 + }
  477 + case 1:
  478 + /*CALL*/ {
  479 + unsigned int target = GET_FIELDs(insn, 2, 31) << 2;
  480 +
  481 + gen_op_movl_T0_im((long) (dc->pc));
  482 + gen_movl_T0_reg(15);
  483 + target = (long) dc->pc + target;
  484 + dc->pc = dc->npc;
  485 + dc->npc = (uint8_t *) target;
  486 + }
  487 + goto jmp_insn;
  488 + case 2: /* FPU & Logical Operations */
  489 + {
  490 + unsigned int xop = GET_FIELD(insn, 7, 12);
  491 + if (xop == 0x3a) { /* generate trap */
  492 + int cond;
  493 + rs1 = GET_FIELD(insn, 13, 17);
  494 + gen_movl_reg_T0(rs1);
  495 + if (IS_IMM) {
  496 + gen_movl_imm_T1(GET_FIELD(insn, 25, 31));
  497 + } else {
  498 + rs2 = GET_FIELD(insn, 27, 31);
  499 + gen_movl_reg_T1(rs2);
  500 + }
  501 + gen_op_add_T1_T0();
  502 + save_state(dc);
  503 + cond = GET_FIELD(insn, 3, 6);
  504 + if (cond == 0x8) {
  505 + gen_op_trap_T0();
  506 + dc->is_br = 1;
  507 + goto jmp_insn;
  508 + } else {
  509 + gen_op_trapcc_T0();
  510 + }
  511 + } else if (xop == 0x28) {
  512 + rs1 = GET_FIELD(insn, 13, 17);
  513 + switch(rs1) {
  514 + case 0: /* rdy */
  515 + gen_op_rdy();
  516 + gen_movl_T0_reg(rd);
  517 + break;
  518 + default:
  519 + goto illegal_insn;
  520 + }
  521 + } else if (xop == 0x34 || xop == 0x35) { /* FPU Operations */
  522 + goto illegal_insn;
  523 + } else {
  524 + rs1 = GET_FIELD(insn, 13, 17);
  525 + gen_movl_reg_T0(rs1);
  526 + if (IS_IMM) { /* immediate */
  527 + rs2 = GET_FIELDs(insn, 19, 31);
  528 + gen_movl_imm_T1(rs2);
  529 + } else { /* register */
  530 + rs2 = GET_FIELD(insn, 27, 31);
  531 + gen_movl_reg_T1(rs2);
  532 + }
  533 + if (xop < 0x20) {
  534 + switch (xop & ~0x10) {
  535 + case 0x0:
  536 + if (xop & 0x10)
  537 + gen_op_add_T1_T0_cc();
  538 + else
  539 + gen_op_add_T1_T0();
  540 + break;
  541 + case 0x1:
  542 + gen_op_and_T1_T0();
  543 + if (xop & 0x10)
  544 + gen_op_logic_T0_cc();
  545 + break;
  546 + case 0x2:
  547 + gen_op_or_T1_T0();
  548 + if (xop & 0x10)
  549 + gen_op_logic_T0_cc();
  550 + break;
  551 + case 0x3:
  552 + gen_op_xor_T1_T0();
  553 + if (xop & 0x10)
  554 + gen_op_logic_T0_cc();
  555 + break;
  556 + case 0x4:
  557 + if (xop & 0x10)
  558 + gen_op_sub_T1_T0_cc();
  559 + else
  560 + gen_op_sub_T1_T0();
  561 + break;
  562 + case 0x5:
  563 + gen_op_andn_T1_T0();
  564 + if (xop & 0x10)
  565 + gen_op_logic_T0_cc();
  566 + break;
  567 + case 0x6:
  568 + gen_op_orn_T1_T0();
  569 + if (xop & 0x10)
  570 + gen_op_logic_T0_cc();
  571 + break;
  572 + case 0x7:
  573 + gen_op_xnor_T1_T0();
  574 + if (xop & 0x10)
  575 + gen_op_logic_T0_cc();
  576 + break;
  577 + case 0x8:
  578 + gen_op_addx_T1_T0();
  579 + if (xop & 0x10)
  580 + gen_op_set_flags();
  581 + break;
  582 + case 0xa:
  583 + gen_op_umul_T1_T0();
  584 + if (xop & 0x10)
  585 + gen_op_logic_T0_cc();
  586 + break;
  587 + case 0xb:
  588 + gen_op_smul_T1_T0();
  589 + if (xop & 0x10)
  590 + gen_op_logic_T0_cc();
  591 + break;
  592 + case 0xc:
  593 + gen_op_subx_T1_T0();
  594 + if (xop & 0x10)
  595 + gen_op_set_flags();
  596 + break;
  597 + case 0xe:
  598 + gen_op_udiv_T1_T0();
  599 + if (xop & 0x10)
  600 + gen_op_div_cc();
  601 + break;
  602 + case 0xf:
  603 + gen_op_sdiv_T1_T0();
  604 + if (xop & 0x10)
  605 + gen_op_div_cc();
  606 + break;
  607 + default:
  608 + goto illegal_insn;
  609 + }
  610 + gen_movl_T0_reg(rd);
  611 + } else {
  612 + switch (xop) {
  613 + case 0x24: /* mulscc */
  614 + gen_op_mulscc_T1_T0();
  615 + gen_movl_T0_reg(rd);
  616 + break;
  617 + case 0x25: /* SLL */
  618 + gen_op_sll();
  619 + gen_movl_T0_reg(rd);
  620 + break;
  621 + case 0x26:
  622 + gen_op_srl();
  623 + gen_movl_T0_reg(rd);
  624 + break;
  625 + case 0x27:
  626 + gen_op_sra();
  627 + gen_movl_T0_reg(rd);
  628 + break;
  629 + case 0x30:
  630 + {
  631 + gen_op_xor_T1_T0();
  632 + switch(rd) {
  633 + case 0:
  634 + gen_op_wry();
  635 + break;
  636 + default:
  637 + goto illegal_insn;
  638 + }
  639 + }
  640 + break;
  641 + case 0x38: /* jmpl */
  642 + {
  643 + gen_op_add_T1_T0();
  644 + gen_op_movl_npc_T0();
  645 + if (rd != 0) {
  646 + gen_op_movl_T0_im((long) (dc->pc));
  647 + gen_movl_T0_reg(rd);
  648 + }
  649 + dc->pc = dc->npc;
  650 + dc->npc = NULL;
  651 + }
  652 + goto jmp_insn;
  653 + case 0x3b: /* flush */
  654 + /* nothing to do */
  655 + break;
  656 + case 0x3c: /* save */
  657 + save_state(dc);
  658 + gen_op_add_T1_T0();
  659 + gen_op_save();
  660 + gen_movl_T0_reg(rd);
  661 + break;
  662 + case 0x3d: /* restore */
  663 + save_state(dc);
  664 + gen_op_add_T1_T0();
  665 + gen_op_restore();
  666 + gen_movl_T0_reg(rd);
  667 + break;
  668 + default:
  669 + goto illegal_insn;
  670 + }
  671 + }
  672 + }
  673 + break;
  674 + }
  675 + case 3: /* load/store instructions */
  676 + {
  677 + unsigned int xop = GET_FIELD(insn, 7, 12);
  678 + rs1 = GET_FIELD(insn, 13, 17);
  679 + gen_movl_reg_T0(rs1);
  680 + if (IS_IMM) { /* immediate */
  681 + rs2 = GET_FIELDs(insn, 19, 31);
  682 + gen_movl_imm_T1(rs2);
  683 + } else { /* register */
  684 + rs2 = GET_FIELD(insn, 27, 31);
  685 + gen_movl_reg_T1(rs2);
  686 + }
  687 + gen_op_add_T1_T0();
  688 + if (xop < 4 || xop > 7) {
  689 + switch (xop) {
  690 + case 0x0: /* load word */
  691 + gen_op_ld();
  692 + break;
  693 + case 0x1: /* load unsigned byte */
  694 + gen_op_ldub();
  695 + break;
  696 + case 0x2: /* load unsigned halfword */
  697 + gen_op_lduh();
  698 + break;
  699 + case 0x3: /* load double word */
  700 + gen_op_ldd();
  701 + gen_movl_T0_reg(rd + 1);
  702 + break;
  703 + case 0x9: /* load signed byte */
  704 + gen_op_ldsb();
  705 + break;
  706 + case 0xa: /* load signed halfword */
  707 + gen_op_ldsh();
  708 + break;
  709 + case 0xd: /* ldstub -- XXX: should be atomically */
  710 + gen_op_ldstub();
  711 + break;
  712 + case 0x0f: /* swap register with memory. Also atomically */
  713 + gen_op_swap();
  714 + break;
577 } 715 }
578 - case 3: /* load/store instructions */  
579 - {  
580 - unsigned int xop = GET_FIELD (insn, 7, 12);  
581 - rs1 = GET_FIELD (insn, 13, 17);  
582 - gen_movl_reg_T0 (rs1);  
583 - if (IS_IMM) { /* immediate */  
584 - rs2 = GET_FIELDs (insn, 20, 31);  
585 - gen_movl_imm_T1 (rs2);  
586 - } else { /* register */  
587 - rs2 = GET_FIELD (insn, 27, 31);  
588 - gen_movl_reg_T1 (rs2);  
589 - }  
590 - gen_op_add_T1_T0 ();  
591 - if (xop < 4 || xop > 7) {  
592 - switch (xop) {  
593 - case 0x0: /* load word */  
594 - gen_op_ld ();  
595 - break;  
596 - case 0x1: /* load unsigned byte */  
597 - gen_op_ldub ();  
598 - break;  
599 - case 0x2: /* load unsigned halfword */  
600 - gen_op_lduh ();  
601 - break;  
602 - case 0x3: /* load double word */  
603 - gen_op_ldd ();  
604 - gen_movl_T0_reg (rd+1);  
605 - break;  
606 - case 0x9: /* load signed byte */  
607 - gen_op_ldsb ();  
608 - break;  
609 - case 0xa: /* load signed halfword */  
610 - gen_op_ldsh ();  
611 - break;  
612 - case 0xd: /* ldstub -- XXX: should be atomically */  
613 - gen_op_ldstub ();  
614 - break;  
615 - case 0x0f: /* swap register with memory. Also atomically */  
616 - gen_op_swap ();  
617 - break;  
618 - }  
619 - gen_movl_T1_reg (rd);  
620 - } else if (xop < 8) {  
621 - gen_movl_reg_T1 (rd);  
622 - switch (xop) {  
623 - case 0x4:  
624 - gen_op_st ();  
625 - break;  
626 - case 0x5:  
627 - gen_op_stb ();  
628 - break;  
629 - case 0x6:  
630 - gen_op_sth ();  
631 - break;  
632 - case 0x7:  
633 - gen_op_st ();  
634 - gen_movl_reg_T1 (rd+1);  
635 - gen_op_st ();  
636 - break;  
637 - }  
638 - } 716 + gen_movl_T1_reg(rd);
  717 + } else if (xop < 8) {
  718 + gen_movl_reg_T1(rd);
  719 + switch (xop) {
  720 + case 0x4:
  721 + gen_op_st();
  722 + break;
  723 + case 0x5:
  724 + gen_op_stb();
  725 + break;
  726 + case 0x6:
  727 + gen_op_sth();
  728 + break;
  729 + case 0x7:
  730 + gen_movl_reg_T2(rd + 1);
  731 + gen_op_std();
  732 + break;
639 } 733 }
  734 + }
640 } 735 }
  736 + }
  737 + /* default case for non jump instructions */
  738 + if (dc->npc != NULL) {
  739 + dc->pc = dc->npc;
  740 + dc->npc = dc->npc + 4;
  741 + } else {
  742 + dc->pc = NULL;
  743 + gen_op_next_insn();
  744 + }
  745 + jmp_insn:;
  746 + return;
  747 + illegal_insn:
  748 + gen_op_jmp_im((uint32_t)dc->pc);
  749 + if (dc->npc != NULL)
  750 + gen_op_movl_npc_im((long) dc->npc);
  751 + gen_op_exception(TT_ILL_INSN);
  752 + dc->is_br = 1;
641 } 753 }
642 754
643 -static inline int gen_intermediate_code_internal (TranslationBlock *tb, int spc) 755 +static inline int gen_intermediate_code_internal(TranslationBlock * tb,
  756 + int spc)
644 { 757 {
645 - uint8_t *pc_start = (uint8_t *) tb->pc;  
646 - uint16_t *gen_opc_end;  
647 - DisasContext dc;  
648 -  
649 - memset (&dc, 0, sizeof (dc));  
650 - if (spc) {  
651 - printf ("SearchPC not yet supported\n");  
652 - exit (0);  
653 - }  
654 - dc.tb = tb;  
655 - dc.pc = pc_start;  
656 -  
657 - gen_opc_ptr = gen_opc_buf;  
658 - gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;  
659 - gen_opparam_ptr = gen_opparam_buf;  
660 -  
661 - do {  
662 - disas_sparc_insn (&dc);  
663 - } while (!dc.is_br && (gen_opc_ptr < gen_opc_end) &&  
664 - (dc.pc - pc_start) < (TARGET_PAGE_SIZE - 32));  
665 -  
666 - switch (dc.is_br) {  
667 - case DISAS_JUMP:  
668 - case DISAS_TB_JUMP:  
669 - gen_op_exit_tb ();  
670 - break;  
671 - }  
672 -  
673 - *gen_opc_ptr = INDEX_op_end; 758 + uint8_t *pc_start, *last_pc;
  759 + uint16_t *gen_opc_end;
  760 + DisasContext dc1, *dc = &dc1;
  761 +
  762 + memset(dc, 0, sizeof(DisasContext));
  763 + if (spc) {
  764 + printf("SearchPC not yet supported\n");
  765 + exit(0);
  766 + }
  767 + dc->tb = tb;
  768 + pc_start = (uint8_t *) tb->pc;
  769 + dc->pc = pc_start;
  770 + dc->npc = (uint8_t *) tb->cs_base;
  771 +
  772 + gen_opc_ptr = gen_opc_buf;
  773 + gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
  774 + gen_opparam_ptr = gen_opparam_buf;
  775 +
  776 + do {
  777 + last_pc = dc->pc;
  778 + disas_sparc_insn(dc);
  779 + if (dc->is_br)
  780 + break;
  781 + /* if the next PC is different, we abort now */
  782 + if (dc->pc != (last_pc + 4))
  783 + break;
  784 + } while ((gen_opc_ptr < gen_opc_end) &&
  785 + (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
  786 + if (dc->pc != NULL)
  787 + gen_op_jmp_im((long) dc->pc);
  788 + if (dc->npc != NULL)
  789 + gen_op_movl_npc_im((long) dc->npc);
  790 + gen_op_movl_T0_0();
  791 + gen_op_exit_tb();
  792 +
  793 + *gen_opc_ptr = INDEX_op_end;
674 #ifdef DEBUG_DISAS 794 #ifdef DEBUG_DISAS
675 - if (loglevel) {  
676 - fprintf (logfile, "--------------\n");  
677 - fprintf (logfile, "IN: %s\n", lookup_symbol (pc_start));  
678 - disas(logfile, pc_start, dc.pc - pc_start, 0, 0);  
679 - fprintf(logfile, "\n");  
680 - fprintf(logfile, "OP:\n");  
681 - dump_ops(gen_opc_buf, gen_opparam_buf);  
682 - fprintf(logfile, "\n");  
683 - } 795 + if (loglevel) {
  796 + fprintf(logfile, "--------------\n");
  797 + fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
  798 + disas(logfile, pc_start, last_pc + 4 - pc_start, 0, 0);
  799 + fprintf(logfile, "\n");
  800 + fprintf(logfile, "OP:\n");
  801 + dump_ops(gen_opc_buf, gen_opparam_buf);
  802 + fprintf(logfile, "\n");
  803 + }
684 #endif 804 #endif
685 805
686 - return 0; 806 + return 0;
687 } 807 }
688 808
689 -int gen_intermediate_code (CPUSPARCState *env, TranslationBlock *tb) 809 +int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
690 { 810 {
691 - return gen_intermediate_code_internal(tb, 0); 811 + return gen_intermediate_code_internal(tb, 0);
692 } 812 }
693 813
694 -int gen_intermediate_code_pc (CPUSPARCState *env, TranslationBlock *tb) 814 +int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
695 { 815 {
696 - return gen_intermediate_code_internal(tb, 1); 816 + return gen_intermediate_code_internal(tb, 1);
697 } 817 }
698 818
699 -void *mycpu;  
700 -  
701 -CPUSPARCState *cpu_sparc_init (void) 819 +CPUSPARCState *cpu_sparc_init(void)
702 { 820 {
703 - CPUSPARCState *env;  
704 -  
705 - cpu_exec_init ();  
706 -  
707 - if (!(env = malloc (sizeof(CPUSPARCState))))  
708 - return (NULL);  
709 - memset (env, 0, sizeof (*env));  
710 - if (!(env->regwptr = malloc (0x2000)))  
711 - return (NULL);  
712 - memset (env->regwptr, 0, 0x2000);  
713 - env->regwptr += 127;  
714 - env->user_mode_only = 1;  
715 - mycpu = env;  
716 - return (env); 821 + CPUSPARCState *env;
  822 +
  823 + cpu_exec_init();
  824 +
  825 + if (!(env = malloc(sizeof(CPUSPARCState))))
  826 + return (NULL);
  827 + memset(env, 0, sizeof(*env));
  828 + env->cwp = 0;
  829 + env->wim = 1;
  830 + env->regwptr = env->regbase + (env->cwp * 16);
  831 + env->user_mode_only = 1;
  832 + return (env);
717 } 833 }
718 834
719 #define GET_FLAG(a,b) ((env->psr & a)?b:'-') 835 #define GET_FLAG(a,b) ((env->psr & a)?b:'-')
720 836
721 -void cpu_sparc_dump_state (CPUSPARCState *env, FILE *f, int flags) 837 +void cpu_sparc_dump_state(CPUSPARCState * env, FILE * f, int flags)
722 { 838 {
723 - int i, x;  
724 -  
725 - fprintf (f, "@PC: %p\n", (void *) env->pc);  
726 - fprintf (f, "General Registers:\n");  
727 - for (i=0;i<4;i++)  
728 - fprintf (f, "%%g%c: %%%08x\t", i+'0', env->gregs[i]);  
729 - fprintf (f, "\n");  
730 - for (;i<8;i++)  
731 - fprintf (f, "%%g%c: %%%08x\t", i+'0', env->gregs[i]);  
732 - fprintf (f, "\nCurrent Register Window:\n");  
733 - for (x=0;x<3;x++) {  
734 - for (i=0;i<4;i++)  
735 - fprintf (f, "%%%c%d: %%%08x\t", (x==0?'o':(x==1?'l':'i')), i, env->regwptr[i+x*8]);  
736 - fprintf (f, "\n");  
737 - for (;i<8;i++)  
738 - fprintf (f, "%%%c%d: %%%08x\t", (x==0?'o':x==1?'l':'i'), i, env->regwptr[i+x*8]);  
739 - fprintf (f, "\n");  
740 - }  
741 - fprintf (f, "PSR: %x -> %c%c%c%c\n", env->psr,  
742 - GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),  
743 - GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C')); 839 + int i, x;
  840 +
  841 + fprintf(f, "pc: 0x%08x npc: 0x%08x\n", (int) env->pc, (int) env->npc);
  842 + fprintf(f, "General Registers:\n");
  843 + for (i = 0; i < 4; i++)
  844 + fprintf(f, "%%g%c: 0x%08x\t", i + '0', env->gregs[i]);
  845 + fprintf(f, "\n");
  846 + for (; i < 8; i++)
  847 + fprintf(f, "%%g%c: 0x%08x\t", i + '0', env->gregs[i]);
  848 + fprintf(f, "\nCurrent Register Window:\n");
  849 + for (x = 0; x < 3; x++) {
  850 + for (i = 0; i < 4; i++)
  851 + fprintf(f, "%%%c%d: 0x%08x\t",
  852 + (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
  853 + env->regwptr[i + x * 8]);
  854 + fprintf(f, "\n");
  855 + for (; i < 8; i++)
  856 + fprintf(f, "%%%c%d: 0x%08x\t",
  857 + (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
  858 + env->regwptr[i + x * 8]);
  859 + fprintf(f, "\n");
  860 + }
  861 + fprintf(f, "psr: 0x%08x -> %c%c%c%c wim: 0x%08x\n", env->psr | env->cwp,
  862 + GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
  863 + GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
  864 + env->wim);
744 } 865 }