128-bit float support for user mode
[qemu] / target-sparc / translate.c
1 /*
2    SPARC translation
3
4    Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
5    Copyright (C) 2003-2005 Fabrice Bellard
6
7    This library is free software; you can redistribute it and/or
8    modify it under the terms of the GNU Lesser General Public
9    License as published by the Free Software Foundation; either
10    version 2 of the License, or (at your option) any later version.
11
12    This library is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Lesser General Public License for more details.
16
17    You should have received a copy of the GNU Lesser General Public
18    License along with this library; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 /*
23    TODO-list:
24
25    Rest of V9 instructions, VIS instructions
26    NPC/PC static optimisations (use JUMP_TB when possible)
27    Optimize synthetic instructions
28 */
29
30 #include <stdarg.h>
31 #include <stdlib.h>
32 #include <stdio.h>
33 #include <string.h>
34 #include <inttypes.h>
35
36 #include "cpu.h"
37 #include "exec-all.h"
38 #include "disas.h"
39
40 #define DEBUG_DISAS
41
42 #define DYNAMIC_PC  1 /* dynamic pc value */
43 #define JUMP_PC     2 /* dynamic pc value which takes only two values
44                          according to jump_pc[T2] */
45
46 typedef struct DisasContext {
47     target_ulong pc;    /* current Program Counter: integer or DYNAMIC_PC */
48     target_ulong npc;   /* next PC: integer or DYNAMIC_PC or JUMP_PC */
49     target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
50     int is_br;
51     int mem_idx;
52     int fpu_enabled;
53     struct TranslationBlock *tb;
54 } DisasContext;
55
56 typedef struct sparc_def_t sparc_def_t;
57
58 struct sparc_def_t {
59     const unsigned char *name;
60     target_ulong iu_version;
61     uint32_t fpu_version;
62     uint32_t mmu_version;
63     uint32_t mmu_bm;
64 };
65
66 static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name);
67
68 static uint16_t *gen_opc_ptr;
69 static uint32_t *gen_opparam_ptr;
70 extern FILE *logfile;
71 extern int loglevel;
72
73 enum {
74 #define DEF(s,n,copy_size) INDEX_op_ ## s,
75 #include "opc.h"
76 #undef DEF
77     NB_OPS
78 };
79
80 #include "gen-op.h"
81
82 // This function uses non-native bit order
83 #define GET_FIELD(X, FROM, TO) \
84   ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
85
86 // This function uses the order in the manuals, i.e. bit 0 is 2^0
87 #define GET_FIELD_SP(X, FROM, TO) \
88     GET_FIELD(X, 31 - (TO), 31 - (FROM))
89
90 #define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
91 #define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
92
93 #ifdef TARGET_SPARC64
94 #define DFPREG(r) (((r & 1) << 5) | (r & 0x1e))
95 #define QFPREG(r) (((r & 1) << 5) | (r & 0x1c))
96 #else
97 #define DFPREG(r) (r & 0x1e)
98 #define QFPREG(r) (r & 0x1c)
99 #endif
100
101 #ifdef USE_DIRECT_JUMP
102 #define TBPARAM(x)
103 #else
104 #define TBPARAM(x) (long)(x)
105 #endif
106
107 static int sign_extend(int x, int len)
108 {
109     len = 32 - len;
110     return (x << len) >> len;
111 }
112
113 #define IS_IMM (insn & (1<<13))
114
115 static void disas_sparc_insn(DisasContext * dc);
116
117 static GenOpFunc * const gen_op_movl_TN_reg[2][32] = {
118     {
119      gen_op_movl_g0_T0,
120      gen_op_movl_g1_T0,
121      gen_op_movl_g2_T0,
122      gen_op_movl_g3_T0,
123      gen_op_movl_g4_T0,
124      gen_op_movl_g5_T0,
125      gen_op_movl_g6_T0,
126      gen_op_movl_g7_T0,
127      gen_op_movl_o0_T0,
128      gen_op_movl_o1_T0,
129      gen_op_movl_o2_T0,
130      gen_op_movl_o3_T0,
131      gen_op_movl_o4_T0,
132      gen_op_movl_o5_T0,
133      gen_op_movl_o6_T0,
134      gen_op_movl_o7_T0,
135      gen_op_movl_l0_T0,
136      gen_op_movl_l1_T0,
137      gen_op_movl_l2_T0,
138      gen_op_movl_l3_T0,
139      gen_op_movl_l4_T0,
140      gen_op_movl_l5_T0,
141      gen_op_movl_l6_T0,
142      gen_op_movl_l7_T0,
143      gen_op_movl_i0_T0,
144      gen_op_movl_i1_T0,
145      gen_op_movl_i2_T0,
146      gen_op_movl_i3_T0,
147      gen_op_movl_i4_T0,
148      gen_op_movl_i5_T0,
149      gen_op_movl_i6_T0,
150      gen_op_movl_i7_T0,
151      },
152     {
153      gen_op_movl_g0_T1,
154      gen_op_movl_g1_T1,
155      gen_op_movl_g2_T1,
156      gen_op_movl_g3_T1,
157      gen_op_movl_g4_T1,
158      gen_op_movl_g5_T1,
159      gen_op_movl_g6_T1,
160      gen_op_movl_g7_T1,
161      gen_op_movl_o0_T1,
162      gen_op_movl_o1_T1,
163      gen_op_movl_o2_T1,
164      gen_op_movl_o3_T1,
165      gen_op_movl_o4_T1,
166      gen_op_movl_o5_T1,
167      gen_op_movl_o6_T1,
168      gen_op_movl_o7_T1,
169      gen_op_movl_l0_T1,
170      gen_op_movl_l1_T1,
171      gen_op_movl_l2_T1,
172      gen_op_movl_l3_T1,
173      gen_op_movl_l4_T1,
174      gen_op_movl_l5_T1,
175      gen_op_movl_l6_T1,
176      gen_op_movl_l7_T1,
177      gen_op_movl_i0_T1,
178      gen_op_movl_i1_T1,
179      gen_op_movl_i2_T1,
180      gen_op_movl_i3_T1,
181      gen_op_movl_i4_T1,
182      gen_op_movl_i5_T1,
183      gen_op_movl_i6_T1,
184      gen_op_movl_i7_T1,
185      }
186 };
187
188 static GenOpFunc * const gen_op_movl_reg_TN[3][32] = {
189     {
190      gen_op_movl_T0_g0,
191      gen_op_movl_T0_g1,
192      gen_op_movl_T0_g2,
193      gen_op_movl_T0_g3,
194      gen_op_movl_T0_g4,
195      gen_op_movl_T0_g5,
196      gen_op_movl_T0_g6,
197      gen_op_movl_T0_g7,
198      gen_op_movl_T0_o0,
199      gen_op_movl_T0_o1,
200      gen_op_movl_T0_o2,
201      gen_op_movl_T0_o3,
202      gen_op_movl_T0_o4,
203      gen_op_movl_T0_o5,
204      gen_op_movl_T0_o6,
205      gen_op_movl_T0_o7,
206      gen_op_movl_T0_l0,
207      gen_op_movl_T0_l1,
208      gen_op_movl_T0_l2,
209      gen_op_movl_T0_l3,
210      gen_op_movl_T0_l4,
211      gen_op_movl_T0_l5,
212      gen_op_movl_T0_l6,
213      gen_op_movl_T0_l7,
214      gen_op_movl_T0_i0,
215      gen_op_movl_T0_i1,
216      gen_op_movl_T0_i2,
217      gen_op_movl_T0_i3,
218      gen_op_movl_T0_i4,
219      gen_op_movl_T0_i5,
220      gen_op_movl_T0_i6,
221      gen_op_movl_T0_i7,
222      },
223     {
224      gen_op_movl_T1_g0,
225      gen_op_movl_T1_g1,
226      gen_op_movl_T1_g2,
227      gen_op_movl_T1_g3,
228      gen_op_movl_T1_g4,
229      gen_op_movl_T1_g5,
230      gen_op_movl_T1_g6,
231      gen_op_movl_T1_g7,
232      gen_op_movl_T1_o0,
233      gen_op_movl_T1_o1,
234      gen_op_movl_T1_o2,
235      gen_op_movl_T1_o3,
236      gen_op_movl_T1_o4,
237      gen_op_movl_T1_o5,
238      gen_op_movl_T1_o6,
239      gen_op_movl_T1_o7,
240      gen_op_movl_T1_l0,
241      gen_op_movl_T1_l1,
242      gen_op_movl_T1_l2,
243      gen_op_movl_T1_l3,
244      gen_op_movl_T1_l4,
245      gen_op_movl_T1_l5,
246      gen_op_movl_T1_l6,
247      gen_op_movl_T1_l7,
248      gen_op_movl_T1_i0,
249      gen_op_movl_T1_i1,
250      gen_op_movl_T1_i2,
251      gen_op_movl_T1_i3,
252      gen_op_movl_T1_i4,
253      gen_op_movl_T1_i5,
254      gen_op_movl_T1_i6,
255      gen_op_movl_T1_i7,
256      },
257     {
258      gen_op_movl_T2_g0,
259      gen_op_movl_T2_g1,
260      gen_op_movl_T2_g2,
261      gen_op_movl_T2_g3,
262      gen_op_movl_T2_g4,
263      gen_op_movl_T2_g5,
264      gen_op_movl_T2_g6,
265      gen_op_movl_T2_g7,
266      gen_op_movl_T2_o0,
267      gen_op_movl_T2_o1,
268      gen_op_movl_T2_o2,
269      gen_op_movl_T2_o3,
270      gen_op_movl_T2_o4,
271      gen_op_movl_T2_o5,
272      gen_op_movl_T2_o6,
273      gen_op_movl_T2_o7,
274      gen_op_movl_T2_l0,
275      gen_op_movl_T2_l1,
276      gen_op_movl_T2_l2,
277      gen_op_movl_T2_l3,
278      gen_op_movl_T2_l4,
279      gen_op_movl_T2_l5,
280      gen_op_movl_T2_l6,
281      gen_op_movl_T2_l7,
282      gen_op_movl_T2_i0,
283      gen_op_movl_T2_i1,
284      gen_op_movl_T2_i2,
285      gen_op_movl_T2_i3,
286      gen_op_movl_T2_i4,
287      gen_op_movl_T2_i5,
288      gen_op_movl_T2_i6,
289      gen_op_movl_T2_i7,
290      }
291 };
292
293 static GenOpFunc1 * const gen_op_movl_TN_im[3] = {
294     gen_op_movl_T0_im,
295     gen_op_movl_T1_im,
296     gen_op_movl_T2_im
297 };
298
299 // Sign extending version
300 static GenOpFunc1 * const gen_op_movl_TN_sim[3] = {
301     gen_op_movl_T0_sim,
302     gen_op_movl_T1_sim,
303     gen_op_movl_T2_sim
304 };
305
306 #ifdef TARGET_SPARC64
307 #define GEN32(func, NAME) \
308 static GenOpFunc * const NAME ## _table [64] = {                              \
309 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
310 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
311 NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
312 NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
313 NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
314 NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
315 NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
316 NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
317 NAME ## 32, 0, NAME ## 34, 0, NAME ## 36, 0, NAME ## 38, 0,                   \
318 NAME ## 40, 0, NAME ## 42, 0, NAME ## 44, 0, NAME ## 46, 0,                   \
319 NAME ## 48, 0, NAME ## 50, 0, NAME ## 52, 0, NAME ## 54, 0,                   \
320 NAME ## 56, 0, NAME ## 58, 0, NAME ## 60, 0, NAME ## 62, 0,                   \
321 };                                                                            \
322 static inline void func(int n)                                                \
323 {                                                                             \
324     NAME ## _table[n]();                                                      \
325 }
326 #else
327 #define GEN32(func, NAME) \
328 static GenOpFunc *const NAME ## _table [32] = {                               \
329 NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
330 NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
331 NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
332 NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
333 NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
334 NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
335 NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
336 NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
337 };                                                                            \
338 static inline void func(int n)                                                \
339 {                                                                             \
340     NAME ## _table[n]();                                                      \
341 }
342 #endif
343
344 /* floating point registers moves */
345 GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fprf);
346 GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fprf);
347 GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fprf);
348 GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fprf);
349
350 GEN32(gen_op_load_fpr_DT0, gen_op_load_fpr_DT0_fprf);
351 GEN32(gen_op_load_fpr_DT1, gen_op_load_fpr_DT1_fprf);
352 GEN32(gen_op_store_DT0_fpr, gen_op_store_DT0_fpr_fprf);
353 GEN32(gen_op_store_DT1_fpr, gen_op_store_DT1_fpr_fprf);
354
355 #if defined(CONFIG_USER_ONLY)
356 GEN32(gen_op_load_fpr_QT0, gen_op_load_fpr_QT0_fprf);
357 GEN32(gen_op_load_fpr_QT1, gen_op_load_fpr_QT1_fprf);
358 GEN32(gen_op_store_QT0_fpr, gen_op_store_QT0_fpr_fprf);
359 GEN32(gen_op_store_QT1_fpr, gen_op_store_QT1_fpr_fprf);
360 #endif
361
362 /* moves */
363 #ifdef CONFIG_USER_ONLY
364 #define supervisor(dc) 0
365 #ifdef TARGET_SPARC64
366 #define hypervisor(dc) 0
367 #endif
368 #define gen_op_ldst(name)        gen_op_##name##_raw()
369 #else
370 #define supervisor(dc) (dc->mem_idx >= 1)
371 #ifdef TARGET_SPARC64
372 #define hypervisor(dc) (dc->mem_idx == 2)
373 #define OP_LD_TABLE(width)                                              \
374     static GenOpFunc * const gen_op_##width[] = {                       \
375         &gen_op_##width##_user,                                         \
376         &gen_op_##width##_kernel,                                       \
377         &gen_op_##width##_hypv,                                         \
378     };
379 #else
380 #define OP_LD_TABLE(width)                                              \
381     static GenOpFunc * const gen_op_##width[] = {                       \
382         &gen_op_##width##_user,                                         \
383         &gen_op_##width##_kernel,                                       \
384     };
385 #endif
386 #define gen_op_ldst(name)        (*gen_op_##name[dc->mem_idx])()
387 #endif
388
389 #ifndef CONFIG_USER_ONLY
390 OP_LD_TABLE(ld);
391 OP_LD_TABLE(st);
392 OP_LD_TABLE(ldub);
393 OP_LD_TABLE(lduh);
394 OP_LD_TABLE(ldsb);
395 OP_LD_TABLE(ldsh);
396 OP_LD_TABLE(stb);
397 OP_LD_TABLE(sth);
398 OP_LD_TABLE(std);
399 OP_LD_TABLE(ldstub);
400 OP_LD_TABLE(swap);
401 OP_LD_TABLE(ldd);
402 OP_LD_TABLE(stf);
403 OP_LD_TABLE(stdf);
404 OP_LD_TABLE(ldf);
405 OP_LD_TABLE(lddf);
406
407 #ifdef TARGET_SPARC64
408 OP_LD_TABLE(lduw);
409 OP_LD_TABLE(ldsw);
410 OP_LD_TABLE(ldx);
411 OP_LD_TABLE(stx);
412 #endif
413 #endif
414
415 /* asi moves */
416 #ifdef TARGET_SPARC64
417 static inline void gen_ld_asi(int insn, int size, int sign)
418 {
419     int asi, offset;
420
421     if (IS_IMM) {
422         offset = GET_FIELD(insn, 25, 31);
423         gen_op_ld_asi_reg(offset, size, sign);
424     } else {
425         asi = GET_FIELD(insn, 19, 26);
426         gen_op_ld_asi(asi, size, sign);
427     }
428 }
429
430 static inline void gen_st_asi(int insn, int size)
431 {
432     int asi, offset;
433
434     if (IS_IMM) {
435         offset = GET_FIELD(insn, 25, 31);
436         gen_op_st_asi_reg(offset, size);
437     } else {
438         asi = GET_FIELD(insn, 19, 26);
439         gen_op_st_asi(asi, size);
440     }
441 }
442
443 static inline void gen_ldf_asi(int insn, int size)
444 {
445     int asi, offset, rd;
446
447     rd = DFPREG(GET_FIELD(insn, 2, 6));
448     if (IS_IMM) {
449         offset = GET_FIELD(insn, 25, 31);
450         gen_op_ldf_asi_reg(offset, size, rd);
451     } else {
452         asi = GET_FIELD(insn, 19, 26);
453         gen_op_ldf_asi(asi, size, rd);
454     }
455 }
456
457 static inline void gen_stf_asi(int insn, int size)
458 {
459     int asi, offset, rd;
460
461     rd = DFPREG(GET_FIELD(insn, 2, 6));
462     if (IS_IMM) {
463         offset = GET_FIELD(insn, 25, 31);
464         gen_op_stf_asi_reg(offset, size, rd);
465     } else {
466         asi = GET_FIELD(insn, 19, 26);
467         gen_op_stf_asi(asi, size, rd);
468     }
469 }
470
471 static inline void gen_swap_asi(int insn)
472 {
473     int asi, offset;
474
475     if (IS_IMM) {
476         offset = GET_FIELD(insn, 25, 31);
477         gen_op_swap_asi_reg(offset);
478     } else {
479         asi = GET_FIELD(insn, 19, 26);
480         gen_op_swap_asi(asi);
481     }
482 }
483
484 static inline void gen_ldstub_asi(int insn)
485 {
486     int asi, offset;
487
488     if (IS_IMM) {
489         offset = GET_FIELD(insn, 25, 31);
490         gen_op_ldstub_asi_reg(offset);
491     } else {
492         asi = GET_FIELD(insn, 19, 26);
493         gen_op_ldstub_asi(asi);
494     }
495 }
496
497 static inline void gen_ldda_asi(int insn)
498 {
499     int asi, offset;
500
501     if (IS_IMM) {
502         offset = GET_FIELD(insn, 25, 31);
503         gen_op_ldda_asi_reg(offset);
504     } else {
505         asi = GET_FIELD(insn, 19, 26);
506         gen_op_ldda_asi(asi);
507     }
508 }
509
510 static inline void gen_stda_asi(int insn)
511 {
512     int asi, offset;
513
514     if (IS_IMM) {
515         offset = GET_FIELD(insn, 25, 31);
516         gen_op_stda_asi_reg(offset);
517     } else {
518         asi = GET_FIELD(insn, 19, 26);
519         gen_op_stda_asi(asi);
520     }
521 }
522
523 static inline void gen_cas_asi(int insn)
524 {
525     int asi, offset;
526
527     if (IS_IMM) {
528         offset = GET_FIELD(insn, 25, 31);
529         gen_op_cas_asi_reg(offset);
530     } else {
531         asi = GET_FIELD(insn, 19, 26);
532         gen_op_cas_asi(asi);
533     }
534 }
535
536 static inline void gen_casx_asi(int insn)
537 {
538     int asi, offset;
539
540     if (IS_IMM) {
541         offset = GET_FIELD(insn, 25, 31);
542         gen_op_casx_asi_reg(offset);
543     } else {
544         asi = GET_FIELD(insn, 19, 26);
545         gen_op_casx_asi(asi);
546     }
547 }
548
549 #elif !defined(CONFIG_USER_ONLY)
550
551 static inline void gen_ld_asi(int insn, int size, int sign)
552 {
553     int asi;
554
555     asi = GET_FIELD(insn, 19, 26);
556     gen_op_ld_asi(asi, size, sign);
557 }
558
559 static inline void gen_st_asi(int insn, int size)
560 {
561     int asi;
562
563     asi = GET_FIELD(insn, 19, 26);
564     gen_op_st_asi(asi, size);
565 }
566
567 static inline void gen_ldstub_asi(int insn)
568 {
569     int asi;
570
571     asi = GET_FIELD(insn, 19, 26);
572     gen_op_ldstub_asi(asi);
573 }
574
575 static inline void gen_swap_asi(int insn)
576 {
577     int asi;
578
579     asi = GET_FIELD(insn, 19, 26);
580     gen_op_swap_asi(asi);
581 }
582
583 static inline void gen_ldda_asi(int insn)
584 {
585     int asi;
586
587     asi = GET_FIELD(insn, 19, 26);
588     gen_op_ld_asi(asi, 8, 0);
589 }
590
591 static inline void gen_stda_asi(int insn)
592 {
593     int asi;
594
595     asi = GET_FIELD(insn, 19, 26);
596     gen_op_st_asi(asi, 8);
597 }
598 #endif
599
600 static inline void gen_movl_imm_TN(int reg, uint32_t imm)
601 {
602     gen_op_movl_TN_im[reg](imm);
603 }
604
605 static inline void gen_movl_imm_T1(uint32_t val)
606 {
607     gen_movl_imm_TN(1, val);
608 }
609
610 static inline void gen_movl_imm_T0(uint32_t val)
611 {
612     gen_movl_imm_TN(0, val);
613 }
614
615 static inline void gen_movl_simm_TN(int reg, int32_t imm)
616 {
617     gen_op_movl_TN_sim[reg](imm);
618 }
619
620 static inline void gen_movl_simm_T1(int32_t val)
621 {
622     gen_movl_simm_TN(1, val);
623 }
624
625 static inline void gen_movl_simm_T0(int32_t val)
626 {
627     gen_movl_simm_TN(0, val);
628 }
629
630 static inline void gen_movl_reg_TN(int reg, int t)
631 {
632     if (reg)
633         gen_op_movl_reg_TN[t][reg] ();
634     else
635         gen_movl_imm_TN(t, 0);
636 }
637
638 static inline void gen_movl_reg_T0(int reg)
639 {
640     gen_movl_reg_TN(reg, 0);
641 }
642
643 static inline void gen_movl_reg_T1(int reg)
644 {
645     gen_movl_reg_TN(reg, 1);
646 }
647
648 static inline void gen_movl_reg_T2(int reg)
649 {
650     gen_movl_reg_TN(reg, 2);
651 }
652
653 static inline void gen_movl_TN_reg(int reg, int t)
654 {
655     if (reg)
656         gen_op_movl_TN_reg[t][reg] ();
657 }
658
659 static inline void gen_movl_T0_reg(int reg)
660 {
661     gen_movl_TN_reg(reg, 0);
662 }
663
664 static inline void gen_movl_T1_reg(int reg)
665 {
666     gen_movl_TN_reg(reg, 1);
667 }
668
669 static inline void gen_jmp_im(target_ulong pc)
670 {
671 #ifdef TARGET_SPARC64
672     if (pc == (uint32_t)pc) {
673         gen_op_jmp_im(pc);
674     } else {
675         gen_op_jmp_im64(pc >> 32, pc);
676     }
677 #else
678     gen_op_jmp_im(pc);
679 #endif
680 }
681
682 static inline void gen_movl_npc_im(target_ulong npc)
683 {
684 #ifdef TARGET_SPARC64
685     if (npc == (uint32_t)npc) {
686         gen_op_movl_npc_im(npc);
687     } else {
688         gen_op_movq_npc_im64(npc >> 32, npc);
689     }
690 #else
691     gen_op_movl_npc_im(npc);
692 #endif
693 }
694
695 static inline void gen_goto_tb(DisasContext *s, int tb_num,
696                                target_ulong pc, target_ulong npc)
697 {
698     TranslationBlock *tb;
699
700     tb = s->tb;
701     if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
702         (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK))  {
703         /* jump to same page: we can use a direct jump */
704         if (tb_num == 0)
705             gen_op_goto_tb0(TBPARAM(tb));
706         else
707             gen_op_goto_tb1(TBPARAM(tb));
708         gen_jmp_im(pc);
709         gen_movl_npc_im(npc);
710         gen_op_movl_T0_im((long)tb + tb_num);
711         gen_op_exit_tb();
712     } else {
713         /* jump to another page: currently not optimized */
714         gen_jmp_im(pc);
715         gen_movl_npc_im(npc);
716         gen_op_movl_T0_0();
717         gen_op_exit_tb();
718     }
719 }
720
721 static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
722                                target_ulong pc2)
723 {
724     int l1;
725
726     l1 = gen_new_label();
727
728     gen_op_jz_T2_label(l1);
729
730     gen_goto_tb(dc, 0, pc1, pc1 + 4);
731
732     gen_set_label(l1);
733     gen_goto_tb(dc, 1, pc2, pc2 + 4);
734 }
735
736 static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
737                                 target_ulong pc2)
738 {
739     int l1;
740
741     l1 = gen_new_label();
742
743     gen_op_jz_T2_label(l1);
744
745     gen_goto_tb(dc, 0, pc2, pc1);
746
747     gen_set_label(l1);
748     gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
749 }
750
751 static inline void gen_branch(DisasContext *dc, target_ulong pc,
752                               target_ulong npc)
753 {
754     gen_goto_tb(dc, 0, pc, npc);
755 }
756
757 static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2)
758 {
759     int l1, l2;
760
761     l1 = gen_new_label();
762     l2 = gen_new_label();
763     gen_op_jz_T2_label(l1);
764
765     gen_movl_npc_im(npc1);
766     gen_op_jmp_label(l2);
767
768     gen_set_label(l1);
769     gen_movl_npc_im(npc2);
770     gen_set_label(l2);
771 }
772
773 /* call this function before using T2 as it may have been set for a jump */
774 static inline void flush_T2(DisasContext * dc)
775 {
776     if (dc->npc == JUMP_PC) {
777         gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
778         dc->npc = DYNAMIC_PC;
779     }
780 }
781
782 static inline void save_npc(DisasContext * dc)
783 {
784     if (dc->npc == JUMP_PC) {
785         gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
786         dc->npc = DYNAMIC_PC;
787     } else if (dc->npc != DYNAMIC_PC) {
788         gen_movl_npc_im(dc->npc);
789     }
790 }
791
792 static inline void save_state(DisasContext * dc)
793 {
794     gen_jmp_im(dc->pc);
795     save_npc(dc);
796 }
797
798 static inline void gen_mov_pc_npc(DisasContext * dc)
799 {
800     if (dc->npc == JUMP_PC) {
801         gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
802         gen_op_mov_pc_npc();
803         dc->pc = DYNAMIC_PC;
804     } else if (dc->npc == DYNAMIC_PC) {
805         gen_op_mov_pc_npc();
806         dc->pc = DYNAMIC_PC;
807     } else {
808         dc->pc = dc->npc;
809     }
810 }
811
812 static GenOpFunc * const gen_cond[2][16] = {
813     {
814         gen_op_eval_bn,
815         gen_op_eval_be,
816         gen_op_eval_ble,
817         gen_op_eval_bl,
818         gen_op_eval_bleu,
819         gen_op_eval_bcs,
820         gen_op_eval_bneg,
821         gen_op_eval_bvs,
822         gen_op_eval_ba,
823         gen_op_eval_bne,
824         gen_op_eval_bg,
825         gen_op_eval_bge,
826         gen_op_eval_bgu,
827         gen_op_eval_bcc,
828         gen_op_eval_bpos,
829         gen_op_eval_bvc,
830     },
831     {
832 #ifdef TARGET_SPARC64
833         gen_op_eval_bn,
834         gen_op_eval_xbe,
835         gen_op_eval_xble,
836         gen_op_eval_xbl,
837         gen_op_eval_xbleu,
838         gen_op_eval_xbcs,
839         gen_op_eval_xbneg,
840         gen_op_eval_xbvs,
841         gen_op_eval_ba,
842         gen_op_eval_xbne,
843         gen_op_eval_xbg,
844         gen_op_eval_xbge,
845         gen_op_eval_xbgu,
846         gen_op_eval_xbcc,
847         gen_op_eval_xbpos,
848         gen_op_eval_xbvc,
849 #endif
850     },
851 };
852
853 static GenOpFunc * const gen_fcond[4][16] = {
854     {
855         gen_op_eval_bn,
856         gen_op_eval_fbne,
857         gen_op_eval_fblg,
858         gen_op_eval_fbul,
859         gen_op_eval_fbl,
860         gen_op_eval_fbug,
861         gen_op_eval_fbg,
862         gen_op_eval_fbu,
863         gen_op_eval_ba,
864         gen_op_eval_fbe,
865         gen_op_eval_fbue,
866         gen_op_eval_fbge,
867         gen_op_eval_fbuge,
868         gen_op_eval_fble,
869         gen_op_eval_fbule,
870         gen_op_eval_fbo,
871     },
872 #ifdef TARGET_SPARC64
873     {
874         gen_op_eval_bn,
875         gen_op_eval_fbne_fcc1,
876         gen_op_eval_fblg_fcc1,
877         gen_op_eval_fbul_fcc1,
878         gen_op_eval_fbl_fcc1,
879         gen_op_eval_fbug_fcc1,
880         gen_op_eval_fbg_fcc1,
881         gen_op_eval_fbu_fcc1,
882         gen_op_eval_ba,
883         gen_op_eval_fbe_fcc1,
884         gen_op_eval_fbue_fcc1,
885         gen_op_eval_fbge_fcc1,
886         gen_op_eval_fbuge_fcc1,
887         gen_op_eval_fble_fcc1,
888         gen_op_eval_fbule_fcc1,
889         gen_op_eval_fbo_fcc1,
890     },
891     {
892         gen_op_eval_bn,
893         gen_op_eval_fbne_fcc2,
894         gen_op_eval_fblg_fcc2,
895         gen_op_eval_fbul_fcc2,
896         gen_op_eval_fbl_fcc2,
897         gen_op_eval_fbug_fcc2,
898         gen_op_eval_fbg_fcc2,
899         gen_op_eval_fbu_fcc2,
900         gen_op_eval_ba,
901         gen_op_eval_fbe_fcc2,
902         gen_op_eval_fbue_fcc2,
903         gen_op_eval_fbge_fcc2,
904         gen_op_eval_fbuge_fcc2,
905         gen_op_eval_fble_fcc2,
906         gen_op_eval_fbule_fcc2,
907         gen_op_eval_fbo_fcc2,
908     },
909     {
910         gen_op_eval_bn,
911         gen_op_eval_fbne_fcc3,
912         gen_op_eval_fblg_fcc3,
913         gen_op_eval_fbul_fcc3,
914         gen_op_eval_fbl_fcc3,
915         gen_op_eval_fbug_fcc3,
916         gen_op_eval_fbg_fcc3,
917         gen_op_eval_fbu_fcc3,
918         gen_op_eval_ba,
919         gen_op_eval_fbe_fcc3,
920         gen_op_eval_fbue_fcc3,
921         gen_op_eval_fbge_fcc3,
922         gen_op_eval_fbuge_fcc3,
923         gen_op_eval_fble_fcc3,
924         gen_op_eval_fbule_fcc3,
925         gen_op_eval_fbo_fcc3,
926     },
927 #else
928     {}, {}, {},
929 #endif
930 };
931
932 #ifdef TARGET_SPARC64
933 static void gen_cond_reg(int cond)
934 {
935         switch (cond) {
936         case 0x1:
937             gen_op_eval_brz();
938             break;
939         case 0x2:
940             gen_op_eval_brlez();
941             break;
942         case 0x3:
943             gen_op_eval_brlz();
944             break;
945         case 0x5:
946             gen_op_eval_brnz();
947             break;
948         case 0x6:
949             gen_op_eval_brgz();
950             break;
951         default:
952         case 0x7:
953             gen_op_eval_brgez();
954             break;
955         }
956 }
957 #endif
958
959 /* XXX: potentially incorrect if dynamic npc */
960 static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
961 {
962     unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
963     target_ulong target = dc->pc + offset;
964
965     if (cond == 0x0) {
966         /* unconditional not taken */
967         if (a) {
968             dc->pc = dc->npc + 4;
969             dc->npc = dc->pc + 4;
970         } else {
971             dc->pc = dc->npc;
972             dc->npc = dc->pc + 4;
973         }
974     } else if (cond == 0x8) {
975         /* unconditional taken */
976         if (a) {
977             dc->pc = target;
978             dc->npc = dc->pc + 4;
979         } else {
980             dc->pc = dc->npc;
981             dc->npc = target;
982         }
983     } else {
984         flush_T2(dc);
985         gen_cond[cc][cond]();
986         if (a) {
987             gen_branch_a(dc, target, dc->npc);
988             dc->is_br = 1;
989         } else {
990             dc->pc = dc->npc;
991             dc->jump_pc[0] = target;
992             dc->jump_pc[1] = dc->npc + 4;
993             dc->npc = JUMP_PC;
994         }
995     }
996 }
997
998 /* XXX: potentially incorrect if dynamic npc */
999 static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
1000 {
1001     unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1002     target_ulong target = dc->pc + offset;
1003
1004     if (cond == 0x0) {
1005         /* unconditional not taken */
1006         if (a) {
1007             dc->pc = dc->npc + 4;
1008             dc->npc = dc->pc + 4;
1009         } else {
1010             dc->pc = dc->npc;
1011             dc->npc = dc->pc + 4;
1012         }
1013     } else if (cond == 0x8) {
1014         /* unconditional taken */
1015         if (a) {
1016             dc->pc = target;
1017             dc->npc = dc->pc + 4;
1018         } else {
1019             dc->pc = dc->npc;
1020             dc->npc = target;
1021         }
1022     } else {
1023         flush_T2(dc);
1024         gen_fcond[cc][cond]();
1025         if (a) {
1026             gen_branch_a(dc, target, dc->npc);
1027             dc->is_br = 1;
1028         } else {
1029             dc->pc = dc->npc;
1030             dc->jump_pc[0] = target;
1031             dc->jump_pc[1] = dc->npc + 4;
1032             dc->npc = JUMP_PC;
1033         }
1034     }
1035 }
1036
1037 #ifdef TARGET_SPARC64
1038 /* XXX: potentially incorrect if dynamic npc */
1039 static void do_branch_reg(DisasContext * dc, int32_t offset, uint32_t insn)
1040 {
1041     unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1042     target_ulong target = dc->pc + offset;
1043
1044     flush_T2(dc);
1045     gen_cond_reg(cond);
1046     if (a) {
1047         gen_branch_a(dc, target, dc->npc);
1048         dc->is_br = 1;
1049     } else {
1050         dc->pc = dc->npc;
1051         dc->jump_pc[0] = target;
1052         dc->jump_pc[1] = dc->npc + 4;
1053         dc->npc = JUMP_PC;
1054     }
1055 }
1056
1057 static GenOpFunc * const gen_fcmps[4] = {
1058     gen_op_fcmps,
1059     gen_op_fcmps_fcc1,
1060     gen_op_fcmps_fcc2,
1061     gen_op_fcmps_fcc3,
1062 };
1063
1064 static GenOpFunc * const gen_fcmpd[4] = {
1065     gen_op_fcmpd,
1066     gen_op_fcmpd_fcc1,
1067     gen_op_fcmpd_fcc2,
1068     gen_op_fcmpd_fcc3,
1069 };
1070
1071 #if defined(CONFIG_USER_ONLY)
1072 static GenOpFunc * const gen_fcmpq[4] = {
1073     gen_op_fcmpq,
1074     gen_op_fcmpq_fcc1,
1075     gen_op_fcmpq_fcc2,
1076     gen_op_fcmpq_fcc3,
1077 };
1078 #endif
1079
1080 static GenOpFunc * const gen_fcmpes[4] = {
1081     gen_op_fcmpes,
1082     gen_op_fcmpes_fcc1,
1083     gen_op_fcmpes_fcc2,
1084     gen_op_fcmpes_fcc3,
1085 };
1086
1087 static GenOpFunc * const gen_fcmped[4] = {
1088     gen_op_fcmped,
1089     gen_op_fcmped_fcc1,
1090     gen_op_fcmped_fcc2,
1091     gen_op_fcmped_fcc3,
1092 };
1093
1094 #if defined(CONFIG_USER_ONLY)
1095 static GenOpFunc * const gen_fcmpeq[4] = {
1096     gen_op_fcmpeq,
1097     gen_op_fcmpeq_fcc1,
1098     gen_op_fcmpeq_fcc2,
1099     gen_op_fcmpeq_fcc3,
1100 };
1101 #endif
1102 #endif
1103
1104 static int gen_trap_ifnofpu(DisasContext * dc)
1105 {
1106 #if !defined(CONFIG_USER_ONLY)
1107     if (!dc->fpu_enabled) {
1108         save_state(dc);
1109         gen_op_exception(TT_NFPU_INSN);
1110         dc->is_br = 1;
1111         return 1;
1112     }
1113 #endif
1114     return 0;
1115 }
1116
1117 /* before an instruction, dc->pc must be static */
1118 static void disas_sparc_insn(DisasContext * dc)
1119 {
1120     unsigned int insn, opc, rs1, rs2, rd;
1121
1122     insn = ldl_code(dc->pc);
1123     opc = GET_FIELD(insn, 0, 1);
1124
1125     rd = GET_FIELD(insn, 2, 6);
1126     switch (opc) {
1127     case 0:                     /* branches/sethi */
1128         {
1129             unsigned int xop = GET_FIELD(insn, 7, 9);
1130             int32_t target;
1131             switch (xop) {
1132 #ifdef TARGET_SPARC64
1133             case 0x1:           /* V9 BPcc */
1134                 {
1135                     int cc;
1136
1137                     target = GET_FIELD_SP(insn, 0, 18);
1138                     target = sign_extend(target, 18);
1139                     target <<= 2;
1140                     cc = GET_FIELD_SP(insn, 20, 21);
1141                     if (cc == 0)
1142                         do_branch(dc, target, insn, 0);
1143                     else if (cc == 2)
1144                         do_branch(dc, target, insn, 1);
1145                     else
1146                         goto illegal_insn;
1147                     goto jmp_insn;
1148                 }
1149             case 0x3:           /* V9 BPr */
1150                 {
1151                     target = GET_FIELD_SP(insn, 0, 13) |
1152                         (GET_FIELD_SP(insn, 20, 21) << 14);
1153                     target = sign_extend(target, 16);
1154                     target <<= 2;
1155                     rs1 = GET_FIELD(insn, 13, 17);
1156                     gen_movl_reg_T0(rs1);
1157                     do_branch_reg(dc, target, insn);
1158                     goto jmp_insn;
1159                 }
1160             case 0x5:           /* V9 FBPcc */
1161                 {
1162                     int cc = GET_FIELD_SP(insn, 20, 21);
1163                     if (gen_trap_ifnofpu(dc))
1164                         goto jmp_insn;
1165                     target = GET_FIELD_SP(insn, 0, 18);
1166                     target = sign_extend(target, 19);
1167                     target <<= 2;
1168                     do_fbranch(dc, target, insn, cc);
1169                     goto jmp_insn;
1170                 }
1171 #else
1172             case 0x7:           /* CBN+x */
1173                 {
1174                     goto ncp_insn;
1175                 }
1176 #endif
1177             case 0x2:           /* BN+x */
1178                 {
1179                     target = GET_FIELD(insn, 10, 31);
1180                     target = sign_extend(target, 22);
1181                     target <<= 2;
1182                     do_branch(dc, target, insn, 0);
1183                     goto jmp_insn;
1184                 }
1185             case 0x6:           /* FBN+x */
1186                 {
1187                     if (gen_trap_ifnofpu(dc))
1188                         goto jmp_insn;
1189                     target = GET_FIELD(insn, 10, 31);
1190                     target = sign_extend(target, 22);
1191                     target <<= 2;
1192                     do_fbranch(dc, target, insn, 0);
1193                     goto jmp_insn;
1194                 }
1195             case 0x4:           /* SETHI */
1196 #define OPTIM
1197 #if defined(OPTIM)
1198                 if (rd) { // nop
1199 #endif
1200                     uint32_t value = GET_FIELD(insn, 10, 31);
1201                     gen_movl_imm_T0(value << 10);
1202                     gen_movl_T0_reg(rd);
1203 #if defined(OPTIM)
1204                 }
1205 #endif
1206                 break;
1207             case 0x0:           /* UNIMPL */
1208             default:
1209                 goto illegal_insn;
1210             }
1211             break;
1212         }
1213         break;
1214     case 1:
1215         /*CALL*/ {
1216             target_long target = GET_FIELDs(insn, 2, 31) << 2;
1217
1218 #ifdef TARGET_SPARC64
1219             if (dc->pc == (uint32_t)dc->pc) {
1220                 gen_op_movl_T0_im(dc->pc);
1221             } else {
1222                 gen_op_movq_T0_im64(dc->pc >> 32, dc->pc);
1223             }
1224 #else
1225             gen_op_movl_T0_im(dc->pc);
1226 #endif
1227             gen_movl_T0_reg(15);
1228             target += dc->pc;
1229             gen_mov_pc_npc(dc);
1230             dc->npc = target;
1231         }
1232         goto jmp_insn;
1233     case 2:                     /* FPU & Logical Operations */
1234         {
1235             unsigned int xop = GET_FIELD(insn, 7, 12);
1236             if (xop == 0x3a) {  /* generate trap */
1237                 int cond;
1238
1239                 rs1 = GET_FIELD(insn, 13, 17);
1240                 gen_movl_reg_T0(rs1);
1241                 if (IS_IMM) {
1242                     rs2 = GET_FIELD(insn, 25, 31);
1243 #if defined(OPTIM)
1244                     if (rs2 != 0) {
1245 #endif
1246                         gen_movl_simm_T1(rs2);
1247                         gen_op_add_T1_T0();
1248 #if defined(OPTIM)
1249                     }
1250 #endif
1251                 } else {
1252                     rs2 = GET_FIELD(insn, 27, 31);
1253 #if defined(OPTIM)
1254                     if (rs2 != 0) {
1255 #endif
1256                         gen_movl_reg_T1(rs2);
1257                         gen_op_add_T1_T0();
1258 #if defined(OPTIM)
1259                     }
1260 #endif
1261                 }
1262                 cond = GET_FIELD(insn, 3, 6);
1263                 if (cond == 0x8) {
1264                     save_state(dc);
1265                     gen_op_trap_T0();
1266                 } else if (cond != 0) {
1267 #ifdef TARGET_SPARC64
1268                     /* V9 icc/xcc */
1269                     int cc = GET_FIELD_SP(insn, 11, 12);
1270                     flush_T2(dc);
1271                     save_state(dc);
1272                     if (cc == 0)
1273                         gen_cond[0][cond]();
1274                     else if (cc == 2)
1275                         gen_cond[1][cond]();
1276                     else
1277                         goto illegal_insn;
1278 #else
1279                     flush_T2(dc);
1280                     save_state(dc);
1281                     gen_cond[0][cond]();
1282 #endif
1283                     gen_op_trapcc_T0();
1284                 }
1285                 gen_op_next_insn();
1286                 gen_op_movl_T0_0();
1287                 gen_op_exit_tb();
1288                 dc->is_br = 1;
1289                 goto jmp_insn;
1290             } else if (xop == 0x28) {
1291                 rs1 = GET_FIELD(insn, 13, 17);
1292                 switch(rs1) {
1293                 case 0: /* rdy */
1294 #ifndef TARGET_SPARC64
1295                 case 0x01 ... 0x0e: /* undefined in the SPARCv8
1296                                        manual, rdy on the microSPARC
1297                                        II */
1298                 case 0x0f:          /* stbar in the SPARCv8 manual,
1299                                        rdy on the microSPARC II */
1300                 case 0x10 ... 0x1f: /* implementation-dependent in the
1301                                        SPARCv8 manual, rdy on the
1302                                        microSPARC II */
1303 #endif
1304                     gen_op_movtl_T0_env(offsetof(CPUSPARCState, y));
1305                     gen_movl_T0_reg(rd);
1306                     break;
1307 #ifdef TARGET_SPARC64
1308                 case 0x2: /* V9 rdccr */
1309                     gen_op_rdccr();
1310                     gen_movl_T0_reg(rd);
1311                     break;
1312                 case 0x3: /* V9 rdasi */
1313                     gen_op_movl_T0_env(offsetof(CPUSPARCState, asi));
1314                     gen_movl_T0_reg(rd);
1315                     break;
1316                 case 0x4: /* V9 rdtick */
1317                     gen_op_rdtick();
1318                     gen_movl_T0_reg(rd);
1319                     break;
1320                 case 0x5: /* V9 rdpc */
1321                     if (dc->pc == (uint32_t)dc->pc) {
1322                         gen_op_movl_T0_im(dc->pc);
1323                     } else {
1324                         gen_op_movq_T0_im64(dc->pc >> 32, dc->pc);
1325                     }
1326                     gen_movl_T0_reg(rd);
1327                     break;
1328                 case 0x6: /* V9 rdfprs */
1329                     gen_op_movl_T0_env(offsetof(CPUSPARCState, fprs));
1330                     gen_movl_T0_reg(rd);
1331                     break;
1332                 case 0xf: /* V9 membar */
1333                     break; /* no effect */
1334                 case 0x13: /* Graphics Status */
1335                     if (gen_trap_ifnofpu(dc))
1336                         goto jmp_insn;
1337                     gen_op_movtl_T0_env(offsetof(CPUSPARCState, gsr));
1338                     gen_movl_T0_reg(rd);
1339                     break;
1340                 case 0x17: /* Tick compare */
1341                     gen_op_movtl_T0_env(offsetof(CPUSPARCState, tick_cmpr));
1342                     gen_movl_T0_reg(rd);
1343                     break;
1344                 case 0x18: /* System tick */
1345                     gen_op_rdstick();
1346                     gen_movl_T0_reg(rd);
1347                     break;
1348                 case 0x19: /* System tick compare */
1349                     gen_op_movtl_T0_env(offsetof(CPUSPARCState, stick_cmpr));
1350                     gen_movl_T0_reg(rd);
1351                     break;
1352                 case 0x10: /* Performance Control */
1353                 case 0x11: /* Performance Instrumentation Counter */
1354                 case 0x12: /* Dispatch Control */
1355                 case 0x14: /* Softint set, WO */
1356                 case 0x15: /* Softint clear, WO */
1357                 case 0x16: /* Softint write */
1358 #endif
1359                 default:
1360                     goto illegal_insn;
1361                 }
1362 #if !defined(CONFIG_USER_ONLY)
1363             } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
1364 #ifndef TARGET_SPARC64
1365                 if (!supervisor(dc))
1366                     goto priv_insn;
1367                 gen_op_rdpsr();
1368 #else
1369                 if (!hypervisor(dc))
1370                     goto priv_insn;
1371                 rs1 = GET_FIELD(insn, 13, 17);
1372                 switch (rs1) {
1373                 case 0: // hpstate
1374                     // gen_op_rdhpstate();
1375                     break;
1376                 case 1: // htstate
1377                     // gen_op_rdhtstate();
1378                     break;
1379                 case 3: // hintp
1380                     gen_op_movl_T0_env(offsetof(CPUSPARCState, hintp));
1381                     break;
1382                 case 5: // htba
1383                     gen_op_movl_T0_env(offsetof(CPUSPARCState, htba));
1384                     break;
1385                 case 6: // hver
1386                     gen_op_movl_T0_env(offsetof(CPUSPARCState, hver));
1387                     break;
1388                 case 31: // hstick_cmpr
1389                     gen_op_movl_env_T0(offsetof(CPUSPARCState, hstick_cmpr));
1390                     break;
1391                 default:
1392                     goto illegal_insn;
1393                 }
1394 #endif
1395                 gen_movl_T0_reg(rd);
1396                 break;
1397             } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
1398                 if (!supervisor(dc))
1399                     goto priv_insn;
1400 #ifdef TARGET_SPARC64
1401                 rs1 = GET_FIELD(insn, 13, 17);
1402                 switch (rs1) {
1403                 case 0: // tpc
1404                     gen_op_rdtpc();
1405                     break;
1406                 case 1: // tnpc
1407                     gen_op_rdtnpc();
1408                     break;
1409                 case 2: // tstate
1410                     gen_op_rdtstate();
1411                     break;
1412                 case 3: // tt
1413                     gen_op_rdtt();
1414                     break;
1415                 case 4: // tick
1416                     gen_op_rdtick();
1417                     break;
1418                 case 5: // tba
1419                     gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
1420                     break;
1421                 case 6: // pstate
1422                     gen_op_rdpstate();
1423                     break;
1424                 case 7: // tl
1425                     gen_op_movl_T0_env(offsetof(CPUSPARCState, tl));
1426                     break;
1427                 case 8: // pil
1428                     gen_op_movl_T0_env(offsetof(CPUSPARCState, psrpil));
1429                     break;
1430                 case 9: // cwp
1431                     gen_op_rdcwp();
1432                     break;
1433                 case 10: // cansave
1434                     gen_op_movl_T0_env(offsetof(CPUSPARCState, cansave));
1435                     break;
1436                 case 11: // canrestore
1437                     gen_op_movl_T0_env(offsetof(CPUSPARCState, canrestore));
1438                     break;
1439                 case 12: // cleanwin
1440                     gen_op_movl_T0_env(offsetof(CPUSPARCState, cleanwin));
1441                     break;
1442                 case 13: // otherwin
1443                     gen_op_movl_T0_env(offsetof(CPUSPARCState, otherwin));
1444                     break;
1445                 case 14: // wstate
1446                     gen_op_movl_T0_env(offsetof(CPUSPARCState, wstate));
1447                     break;
1448                 case 16: // UA2005 gl
1449                     gen_op_movl_T0_env(offsetof(CPUSPARCState, gl));
1450                     break;
1451                 case 26: // UA2005 strand status
1452                     if (!hypervisor(dc))
1453                         goto priv_insn;
1454                     gen_op_movl_T0_env(offsetof(CPUSPARCState, ssr));
1455                     break;
1456                 case 31: // ver
1457                     gen_op_movtl_T0_env(offsetof(CPUSPARCState, version));
1458                     break;
1459                 case 15: // fq
1460                 default:
1461                     goto illegal_insn;
1462                 }
1463 #else
1464                 gen_op_movl_T0_env(offsetof(CPUSPARCState, wim));
1465 #endif
1466                 gen_movl_T0_reg(rd);
1467                 break;
1468             } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
1469 #ifdef TARGET_SPARC64
1470                 gen_op_flushw();
1471 #else
1472                 if (!supervisor(dc))
1473                     goto priv_insn;
1474                 gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
1475                 gen_movl_T0_reg(rd);
1476 #endif
1477                 break;
1478 #endif
1479             } else if (xop == 0x34) {   /* FPU Operations */
1480                 if (gen_trap_ifnofpu(dc))
1481                     goto jmp_insn;
1482                 gen_op_clear_ieee_excp_and_FTT();
1483                 rs1 = GET_FIELD(insn, 13, 17);
1484                 rs2 = GET_FIELD(insn, 27, 31);
1485                 xop = GET_FIELD(insn, 18, 26);
1486                 switch (xop) {
1487                     case 0x1: /* fmovs */
1488                         gen_op_load_fpr_FT0(rs2);
1489                         gen_op_store_FT0_fpr(rd);
1490                         break;
1491                     case 0x5: /* fnegs */
1492                         gen_op_load_fpr_FT1(rs2);
1493                         gen_op_fnegs();
1494                         gen_op_store_FT0_fpr(rd);
1495                         break;
1496                     case 0x9: /* fabss */
1497                         gen_op_load_fpr_FT1(rs2);
1498                         gen_op_fabss();
1499                         gen_op_store_FT0_fpr(rd);
1500                         break;
1501                     case 0x29: /* fsqrts */
1502                         gen_op_load_fpr_FT1(rs2);
1503                         gen_op_fsqrts();
1504                         gen_op_store_FT0_fpr(rd);
1505                         break;
1506                     case 0x2a: /* fsqrtd */
1507                         gen_op_load_fpr_DT1(DFPREG(rs2));
1508                         gen_op_fsqrtd();
1509                         gen_op_store_DT0_fpr(DFPREG(rd));
1510                         break;
1511                     case 0x2b: /* fsqrtq */
1512 #if defined(CONFIG_USER_ONLY)
1513                         gen_op_load_fpr_QT1(QFPREG(rs2));
1514                         gen_op_fsqrtq();
1515                         gen_op_store_QT0_fpr(QFPREG(rd));
1516                         break;
1517 #else
1518                         goto nfpu_insn;
1519 #endif
1520                     case 0x41:
1521                         gen_op_load_fpr_FT0(rs1);
1522                         gen_op_load_fpr_FT1(rs2);
1523                         gen_op_fadds();
1524                         gen_op_store_FT0_fpr(rd);
1525                         break;
1526                     case 0x42:
1527                         gen_op_load_fpr_DT0(DFPREG(rs1));
1528                         gen_op_load_fpr_DT1(DFPREG(rs2));
1529                         gen_op_faddd();
1530                         gen_op_store_DT0_fpr(DFPREG(rd));
1531                         break;
1532                     case 0x43: /* faddq */
1533 #if defined(CONFIG_USER_ONLY)
1534                         gen_op_load_fpr_QT0(QFPREG(rs1));
1535                         gen_op_load_fpr_QT1(QFPREG(rs2));
1536                         gen_op_faddq();
1537                         gen_op_store_QT0_fpr(QFPREG(rd));
1538                         break;
1539 #else
1540                         goto nfpu_insn;
1541 #endif
1542                     case 0x45:
1543                         gen_op_load_fpr_FT0(rs1);
1544                         gen_op_load_fpr_FT1(rs2);
1545                         gen_op_fsubs();
1546                         gen_op_store_FT0_fpr(rd);
1547                         break;
1548                     case 0x46:
1549                         gen_op_load_fpr_DT0(DFPREG(rs1));
1550                         gen_op_load_fpr_DT1(DFPREG(rs2));
1551                         gen_op_fsubd();
1552                         gen_op_store_DT0_fpr(DFPREG(rd));
1553                         break;
1554                     case 0x47: /* fsubq */
1555 #if defined(CONFIG_USER_ONLY)
1556                         gen_op_load_fpr_QT0(QFPREG(rs1));
1557                         gen_op_load_fpr_QT1(QFPREG(rs2));
1558                         gen_op_fsubq();
1559                         gen_op_store_QT0_fpr(QFPREG(rd));
1560                         break;
1561 #else
1562                         goto nfpu_insn;
1563 #endif
1564                     case 0x49:
1565                         gen_op_load_fpr_FT0(rs1);
1566                         gen_op_load_fpr_FT1(rs2);
1567                         gen_op_fmuls();
1568                         gen_op_store_FT0_fpr(rd);
1569                         break;
1570                     case 0x4a:
1571                         gen_op_load_fpr_DT0(DFPREG(rs1));
1572                         gen_op_load_fpr_DT1(DFPREG(rs2));
1573                         gen_op_fmuld();
1574                         gen_op_store_DT0_fpr(rd);
1575                         break;
1576                     case 0x4b: /* fmulq */
1577 #if defined(CONFIG_USER_ONLY)
1578                         gen_op_load_fpr_QT0(QFPREG(rs1));
1579                         gen_op_load_fpr_QT1(QFPREG(rs2));
1580                         gen_op_fmulq();
1581                         gen_op_store_QT0_fpr(QFPREG(rd));
1582                         break;
1583 #else
1584                         goto nfpu_insn;
1585 #endif
1586                     case 0x4d:
1587                         gen_op_load_fpr_FT0(rs1);
1588                         gen_op_load_fpr_FT1(rs2);
1589                         gen_op_fdivs();
1590                         gen_op_store_FT0_fpr(rd);
1591                         break;
1592                     case 0x4e:
1593                         gen_op_load_fpr_DT0(DFPREG(rs1));
1594                         gen_op_load_fpr_DT1(DFPREG(rs2));
1595                         gen_op_fdivd();
1596                         gen_op_store_DT0_fpr(DFPREG(rd));
1597                         break;
1598                     case 0x4f: /* fdivq */
1599 #if defined(CONFIG_USER_ONLY)
1600                         gen_op_load_fpr_QT0(QFPREG(rs1));
1601                         gen_op_load_fpr_QT1(QFPREG(rs2));
1602                         gen_op_fdivq();
1603                         gen_op_store_QT0_fpr(QFPREG(rd));
1604                         break;
1605 #else
1606                         goto nfpu_insn;
1607 #endif
1608                     case 0x69:
1609                         gen_op_load_fpr_FT0(rs1);
1610                         gen_op_load_fpr_FT1(rs2);
1611                         gen_op_fsmuld();
1612                         gen_op_store_DT0_fpr(DFPREG(rd));
1613                         break;
1614                     case 0x6e: /* fdmulq */
1615 #if defined(CONFIG_USER_ONLY)
1616                         gen_op_load_fpr_DT0(DFPREG(rs1));
1617                         gen_op_load_fpr_DT1(DFPREG(rs2));
1618                         gen_op_fdmulq();
1619                         gen_op_store_QT0_fpr(QFPREG(rd));
1620                         break;
1621 #else
1622                         goto nfpu_insn;
1623 #endif
1624                     case 0xc4:
1625                         gen_op_load_fpr_FT1(rs2);
1626                         gen_op_fitos();
1627                         gen_op_store_FT0_fpr(rd);
1628                         break;
1629                     case 0xc6:
1630                         gen_op_load_fpr_DT1(DFPREG(rs2));
1631                         gen_op_fdtos();
1632                         gen_op_store_FT0_fpr(rd);
1633                         break;
1634                     case 0xc7: /* fqtos */
1635 #if defined(CONFIG_USER_ONLY)
1636                         gen_op_load_fpr_QT1(QFPREG(rs2));
1637                         gen_op_fqtos();
1638                         gen_op_store_FT0_fpr(rd);
1639                         break;
1640 #else
1641                         goto nfpu_insn;
1642 #endif
1643                     case 0xc8:
1644                         gen_op_load_fpr_FT1(rs2);
1645                         gen_op_fitod();
1646                         gen_op_store_DT0_fpr(DFPREG(rd));
1647                         break;
1648                     case 0xc9:
1649                         gen_op_load_fpr_FT1(rs2);
1650                         gen_op_fstod();
1651                         gen_op_store_DT0_fpr(DFPREG(rd));
1652                         break;
1653                     case 0xcb: /* fqtod */
1654 #if defined(CONFIG_USER_ONLY)
1655                         gen_op_load_fpr_QT1(QFPREG(rs2));
1656                         gen_op_fqtod();
1657                         gen_op_store_DT0_fpr(DFPREG(rd));
1658                         break;
1659 #else
1660                         goto nfpu_insn;
1661 #endif
1662                     case 0xcc: /* fitoq */
1663 #if defined(CONFIG_USER_ONLY)
1664                         gen_op_load_fpr_FT1(rs2);
1665                         gen_op_fitoq();
1666                         gen_op_store_QT0_fpr(QFPREG(rd));
1667                         break;
1668 #else
1669                         goto nfpu_insn;
1670 #endif
1671                     case 0xcd: /* fstoq */
1672 #if defined(CONFIG_USER_ONLY)
1673                         gen_op_load_fpr_FT1(rs2);
1674                         gen_op_fstoq();
1675                         gen_op_store_QT0_fpr(QFPREG(rd));
1676                         break;
1677 #else
1678                         goto nfpu_insn;
1679 #endif
1680                     case 0xce: /* fdtoq */
1681 #if defined(CONFIG_USER_ONLY)
1682                         gen_op_load_fpr_DT1(DFPREG(rs2));
1683                         gen_op_fdtoq();
1684                         gen_op_store_QT0_fpr(QFPREG(rd));
1685                         break;
1686 #else
1687                         goto nfpu_insn;
1688 #endif
1689                     case 0xd1:
1690                         gen_op_load_fpr_FT1(rs2);
1691                         gen_op_fstoi();
1692                         gen_op_store_FT0_fpr(rd);
1693                         break;
1694                     case 0xd2:
1695                         gen_op_load_fpr_DT1(rs2);
1696                         gen_op_fdtoi();
1697                         gen_op_store_FT0_fpr(rd);
1698                         break;
1699                     case 0xd3: /* fqtoi */
1700 #if defined(CONFIG_USER_ONLY)
1701                         gen_op_load_fpr_QT1(QFPREG(rs2));
1702                         gen_op_fqtoi();
1703                         gen_op_store_FT0_fpr(rd);
1704                         break;
1705 #else
1706                         goto nfpu_insn;
1707 #endif
1708 #ifdef TARGET_SPARC64
1709                     case 0x2: /* V9 fmovd */
1710                         gen_op_load_fpr_DT0(DFPREG(rs2));
1711                         gen_op_store_DT0_fpr(DFPREG(rd));
1712                         break;
1713                     case 0x3: /* V9 fmovq */
1714 #if defined(CONFIG_USER_ONLY)
1715                         gen_op_load_fpr_QT0(QFPREG(rs2));
1716                         gen_op_store_QT0_fpr(QFPREG(rd));
1717                         break;
1718 #else
1719                         goto nfpu_insn;
1720 #endif
1721                     case 0x6: /* V9 fnegd */
1722                         gen_op_load_fpr_DT1(DFPREG(rs2));
1723                         gen_op_fnegd();
1724                         gen_op_store_DT0_fpr(DFPREG(rd));
1725                         break;
1726                     case 0x7: /* V9 fnegq */
1727 #if defined(CONFIG_USER_ONLY)
1728                         gen_op_load_fpr_QT1(QFPREG(rs2));
1729                         gen_op_fnegq();
1730                         gen_op_store_QT0_fpr(QFPREG(rd));
1731                         break;
1732 #else
1733                         goto nfpu_insn;
1734 #endif
1735                     case 0xa: /* V9 fabsd */
1736                         gen_op_load_fpr_DT1(DFPREG(rs2));
1737                         gen_op_fabsd();
1738                         gen_op_store_DT0_fpr(DFPREG(rd));
1739                         break;
1740                     case 0xb: /* V9 fabsq */
1741 #if defined(CONFIG_USER_ONLY)
1742                         gen_op_load_fpr_QT1(QFPREG(rs2));
1743                         gen_op_fabsq();
1744                         gen_op_store_QT0_fpr(QFPREG(rd));
1745                         break;
1746 #else
1747                         goto nfpu_insn;
1748 #endif
1749                     case 0x81: /* V9 fstox */
1750                         gen_op_load_fpr_FT1(rs2);
1751                         gen_op_fstox();
1752                         gen_op_store_DT0_fpr(DFPREG(rd));
1753                         break;
1754                     case 0x82: /* V9 fdtox */
1755                         gen_op_load_fpr_DT1(DFPREG(rs2));
1756                         gen_op_fdtox();
1757                         gen_op_store_DT0_fpr(DFPREG(rd));
1758                         break;
1759                     case 0x83: /* V9 fqtox */
1760 #if defined(CONFIG_USER_ONLY)
1761                         gen_op_load_fpr_QT1(QFPREG(rs2));
1762                         gen_op_fqtox();
1763                         gen_op_store_DT0_fpr(DFPREG(rd));
1764                         break;
1765 #else
1766                         goto nfpu_insn;
1767 #endif
1768                     case 0x84: /* V9 fxtos */
1769                         gen_op_load_fpr_DT1(DFPREG(rs2));
1770                         gen_op_fxtos();
1771                         gen_op_store_FT0_fpr(rd);
1772                         break;
1773                     case 0x88: /* V9 fxtod */
1774                         gen_op_load_fpr_DT1(DFPREG(rs2));
1775                         gen_op_fxtod();
1776                         gen_op_store_DT0_fpr(DFPREG(rd));
1777                         break;
1778                     case 0x8c: /* V9 fxtoq */
1779 #if defined(CONFIG_USER_ONLY)
1780                         gen_op_load_fpr_DT1(DFPREG(rs2));
1781                         gen_op_fxtoq();
1782                         gen_op_store_QT0_fpr(QFPREG(rd));
1783                         break;
1784 #else
1785                         goto nfpu_insn;
1786 #endif
1787 #endif
1788                     default:
1789                         goto illegal_insn;
1790                 }
1791             } else if (xop == 0x35) {   /* FPU Operations */
1792 #ifdef TARGET_SPARC64
1793                 int cond;
1794 #endif
1795                 if (gen_trap_ifnofpu(dc))
1796                     goto jmp_insn;
1797                 gen_op_clear_ieee_excp_and_FTT();
1798                 rs1 = GET_FIELD(insn, 13, 17);
1799                 rs2 = GET_FIELD(insn, 27, 31);
1800                 xop = GET_FIELD(insn, 18, 26);
1801 #ifdef TARGET_SPARC64
1802                 if ((xop & 0x11f) == 0x005) { // V9 fmovsr
1803                     cond = GET_FIELD_SP(insn, 14, 17);
1804                     gen_op_load_fpr_FT0(rd);
1805                     gen_op_load_fpr_FT1(rs2);
1806                     rs1 = GET_FIELD(insn, 13, 17);
1807                     gen_movl_reg_T0(rs1);
1808                     flush_T2(dc);
1809                     gen_cond_reg(cond);
1810                     gen_op_fmovs_cc();
1811                     gen_op_store_FT0_fpr(rd);
1812                     break;
1813                 } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
1814                     cond = GET_FIELD_SP(insn, 14, 17);
1815                     gen_op_load_fpr_DT0(rd);
1816                     gen_op_load_fpr_DT1(rs2);
1817                     flush_T2(dc);
1818                     rs1 = GET_FIELD(insn, 13, 17);
1819                     gen_movl_reg_T0(rs1);
1820                     gen_cond_reg(cond);
1821                     gen_op_fmovs_cc();
1822                     gen_op_store_DT0_fpr(rd);
1823                     break;
1824                 } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
1825 #if defined(CONFIG_USER_ONLY)
1826                     cond = GET_FIELD_SP(insn, 14, 17);
1827                     gen_op_load_fpr_QT0(QFPREG(rd));
1828                     gen_op_load_fpr_QT1(QFPREG(rs2));
1829                     flush_T2(dc);
1830                     rs1 = GET_FIELD(insn, 13, 17);
1831                     gen_movl_reg_T0(rs1);
1832                     gen_cond_reg(cond);
1833                     gen_op_fmovq_cc();
1834                     gen_op_store_QT0_fpr(QFPREG(rd));
1835                     break;
1836 #else
1837                     goto nfpu_insn;
1838 #endif
1839                 }
1840 #endif
1841                 switch (xop) {
1842 #ifdef TARGET_SPARC64
1843                     case 0x001: /* V9 fmovscc %fcc0 */
1844                         cond = GET_FIELD_SP(insn, 14, 17);
1845                         gen_op_load_fpr_FT0(rd);
1846                         gen_op_load_fpr_FT1(rs2);
1847                         flush_T2(dc);
1848                         gen_fcond[0][cond]();
1849                         gen_op_fmovs_cc();
1850                         gen_op_store_FT0_fpr(rd);
1851                         break;
1852                     case 0x002: /* V9 fmovdcc %fcc0 */
1853                         cond = GET_FIELD_SP(insn, 14, 17);
1854                         gen_op_load_fpr_DT0(rd);
1855                         gen_op_load_fpr_DT1(rs2);
1856                         flush_T2(dc);
1857                         gen_fcond[0][cond]();
1858                         gen_op_fmovd_cc();
1859                         gen_op_store_DT0_fpr(rd);
1860                         break;
1861                     case 0x003: /* V9 fmovqcc %fcc0 */
1862 #if defined(CONFIG_USER_ONLY)
1863                         cond = GET_FIELD_SP(insn, 14, 17);
1864                         gen_op_load_fpr_QT0(QFPREG(rd));
1865                         gen_op_load_fpr_QT1(QFPREG(rs2));
1866                         flush_T2(dc);
1867                         gen_fcond[0][cond]();
1868                         gen_op_fmovq_cc();
1869                         gen_op_store_QT0_fpr(QFPREG(rd));
1870                         break;
1871 #else
1872                         goto nfpu_insn;
1873 #endif
1874                     case 0x041: /* V9 fmovscc %fcc1 */
1875                         cond = GET_FIELD_SP(insn, 14, 17);
1876                         gen_op_load_fpr_FT0(rd);
1877                         gen_op_load_fpr_FT1(rs2);
1878                         flush_T2(dc);
1879                         gen_fcond[1][cond]();
1880                         gen_op_fmovs_cc();
1881                         gen_op_store_FT0_fpr(rd);
1882                         break;
1883                     case 0x042: /* V9 fmovdcc %fcc1 */
1884                         cond = GET_FIELD_SP(insn, 14, 17);
1885                         gen_op_load_fpr_DT0(rd);
1886                         gen_op_load_fpr_DT1(rs2);
1887                         flush_T2(dc);
1888                         gen_fcond[1][cond]();
1889                         gen_op_fmovd_cc();
1890                         gen_op_store_DT0_fpr(rd);
1891                         break;
1892                     case 0x043: /* V9 fmovqcc %fcc1 */
1893 #if defined(CONFIG_USER_ONLY)
1894                         cond = GET_FIELD_SP(insn, 14, 17);
1895                         gen_op_load_fpr_QT0(QFPREG(rd));
1896                         gen_op_load_fpr_QT1(QFPREG(rs2));
1897                         flush_T2(dc);
1898                         gen_fcond[1][cond]();
1899                         gen_op_fmovq_cc();
1900                         gen_op_store_QT0_fpr(QFPREG(rd));
1901                         break;
1902 #else
1903                         goto nfpu_insn;
1904 #endif
1905                     case 0x081: /* V9 fmovscc %fcc2 */
1906                         cond = GET_FIELD_SP(insn, 14, 17);
1907                         gen_op_load_fpr_FT0(rd);
1908                         gen_op_load_fpr_FT1(rs2);
1909                         flush_T2(dc);
1910                         gen_fcond[2][cond]();
1911                         gen_op_fmovs_cc();
1912                         gen_op_store_FT0_fpr(rd);
1913                         break;
1914                     case 0x082: /* V9 fmovdcc %fcc2 */
1915                         cond = GET_FIELD_SP(insn, 14, 17);
1916                         gen_op_load_fpr_DT0(rd);
1917                         gen_op_load_fpr_DT1(rs2);
1918                         flush_T2(dc);
1919                         gen_fcond[2][cond]();
1920                         gen_op_fmovd_cc();
1921                         gen_op_store_DT0_fpr(rd);
1922                         break;
1923                     case 0x083: /* V9 fmovqcc %fcc2 */
1924 #if defined(CONFIG_USER_ONLY)
1925                         cond = GET_FIELD_SP(insn, 14, 17);
1926                         gen_op_load_fpr_QT0(rd);
1927                         gen_op_load_fpr_QT1(rs2);
1928                         flush_T2(dc);
1929                         gen_fcond[2][cond]();
1930                         gen_op_fmovq_cc();
1931                         gen_op_store_QT0_fpr(rd);
1932                         break;
1933 #else
1934                         goto nfpu_insn;
1935 #endif
1936                     case 0x0c1: /* V9 fmovscc %fcc3 */
1937                         cond = GET_FIELD_SP(insn, 14, 17);
1938                         gen_op_load_fpr_FT0(rd);
1939                         gen_op_load_fpr_FT1(rs2);
1940                         flush_T2(dc);
1941                         gen_fcond[3][cond]();
1942                         gen_op_fmovs_cc();
1943                         gen_op_store_FT0_fpr(rd);
1944                         break;
1945                     case 0x0c2: /* V9 fmovdcc %fcc3 */
1946                         cond = GET_FIELD_SP(insn, 14, 17);
1947                         gen_op_load_fpr_DT0(rd);
1948                         gen_op_load_fpr_DT1(rs2);
1949                         flush_T2(dc);
1950                         gen_fcond[3][cond]();
1951                         gen_op_fmovd_cc();
1952                         gen_op_store_DT0_fpr(rd);
1953                         break;
1954                     case 0x0c3: /* V9 fmovqcc %fcc3 */
1955 #if defined(CONFIG_USER_ONLY)
1956                         cond = GET_FIELD_SP(insn, 14, 17);
1957                         gen_op_load_fpr_QT0(QFPREG(rd));
1958                         gen_op_load_fpr_QT1(QFPREG(rs2));
1959                         flush_T2(dc);
1960                         gen_fcond[3][cond]();
1961                         gen_op_fmovq_cc();
1962                         gen_op_store_QT0_fpr(QFPREG(rd));
1963                         break;
1964 #else
1965                         goto nfpu_insn;
1966 #endif
1967                     case 0x101: /* V9 fmovscc %icc */
1968                         cond = GET_FIELD_SP(insn, 14, 17);
1969                         gen_op_load_fpr_FT0(rd);
1970                         gen_op_load_fpr_FT1(rs2);
1971                         flush_T2(dc);
1972                         gen_cond[0][cond]();
1973                         gen_op_fmovs_cc();
1974                         gen_op_store_FT0_fpr(rd);
1975                         break;
1976                     case 0x102: /* V9 fmovdcc %icc */
1977                         cond = GET_FIELD_SP(insn, 14, 17);
1978                         gen_op_load_fpr_DT0(rd);
1979                         gen_op_load_fpr_DT1(rs2);
1980                         flush_T2(dc);
1981                         gen_cond[0][cond]();
1982                         gen_op_fmovd_cc();
1983                         gen_op_store_DT0_fpr(rd);
1984                         break;
1985                     case 0x103: /* V9 fmovqcc %icc */
1986 #if defined(CONFIG_USER_ONLY)
1987                         cond = GET_FIELD_SP(insn, 14, 17);
1988                         gen_op_load_fpr_QT0(rd);
1989                         gen_op_load_fpr_QT1(rs2);
1990                         flush_T2(dc);
1991                         gen_cond[0][cond]();
1992                         gen_op_fmovq_cc();
1993                         gen_op_store_QT0_fpr(rd);
1994                         break;
1995 #else
1996                         goto nfpu_insn;
1997 #endif
1998                     case 0x181: /* V9 fmovscc %xcc */
1999                         cond = GET_FIELD_SP(insn, 14, 17);
2000                         gen_op_load_fpr_FT0(rd);
2001                         gen_op_load_fpr_FT1(rs2);
2002                         flush_T2(dc);
2003                         gen_cond[1][cond]();
2004                         gen_op_fmovs_cc();
2005                         gen_op_store_FT0_fpr(rd);
2006                         break;
2007                     case 0x182: /* V9 fmovdcc %xcc */
2008                         cond = GET_FIELD_SP(insn, 14, 17);
2009                         gen_op_load_fpr_DT0(rd);
2010                         gen_op_load_fpr_DT1(rs2);
2011                         flush_T2(dc);
2012                         gen_cond[1][cond]();
2013                         gen_op_fmovd_cc();
2014                         gen_op_store_DT0_fpr(rd);
2015                         break;
2016                     case 0x183: /* V9 fmovqcc %xcc */
2017 #if defined(CONFIG_USER_ONLY)
2018                         cond = GET_FIELD_SP(insn, 14, 17);
2019                         gen_op_load_fpr_QT0(rd);
2020                         gen_op_load_fpr_QT1(rs2);
2021                         flush_T2(dc);
2022                         gen_cond[1][cond]();
2023                         gen_op_fmovq_cc();
2024                         gen_op_store_QT0_fpr(rd);
2025                         break;
2026 #else
2027                         goto nfpu_insn;
2028 #endif
2029 #endif
2030                     case 0x51: /* fcmps, V9 %fcc */
2031                         gen_op_load_fpr_FT0(rs1);
2032                         gen_op_load_fpr_FT1(rs2);
2033 #ifdef TARGET_SPARC64
2034                         gen_fcmps[rd & 3]();
2035 #else
2036                         gen_op_fcmps();
2037 #endif
2038                         break;
2039                     case 0x52: /* fcmpd, V9 %fcc */
2040                         gen_op_load_fpr_DT0(DFPREG(rs1));
2041                         gen_op_load_fpr_DT1(DFPREG(rs2));
2042 #ifdef TARGET_SPARC64
2043                         gen_fcmpd[rd & 3]();
2044 #else
2045                         gen_op_fcmpd();
2046 #endif
2047                         break;
2048                     case 0x53: /* fcmpq, V9 %fcc */
2049 #if defined(CONFIG_USER_ONLY)
2050                         gen_op_load_fpr_QT0(QFPREG(rs1));
2051                         gen_op_load_fpr_QT1(QFPREG(rs2));
2052 #ifdef TARGET_SPARC64
2053                         gen_fcmpq[rd & 3]();
2054 #else
2055                         gen_op_fcmpq();
2056 #endif
2057                         break;
2058 #else /* !defined(CONFIG_USER_ONLY) */
2059                         goto nfpu_insn;
2060 #endif
2061                     case 0x55: /* fcmpes, V9 %fcc */
2062                         gen_op_load_fpr_FT0(rs1);
2063                         gen_op_load_fpr_FT1(rs2);
2064 #ifdef TARGET_SPARC64
2065                         gen_fcmpes[rd & 3]();
2066 #else
2067                         gen_op_fcmpes();
2068 #endif
2069                         break;
2070                     case 0x56: /* fcmped, V9 %fcc */
2071                         gen_op_load_fpr_DT0(DFPREG(rs1));
2072                         gen_op_load_fpr_DT1(DFPREG(rs2));
2073 #ifdef TARGET_SPARC64
2074                         gen_fcmped[rd & 3]();
2075 #else
2076                         gen_op_fcmped();
2077 #endif
2078                         break;
2079                     case 0x57: /* fcmpeq, V9 %fcc */
2080 #if defined(CONFIG_USER_ONLY)
2081                         gen_op_load_fpr_QT0(QFPREG(rs1));
2082                         gen_op_load_fpr_QT1(QFPREG(rs2));
2083 #ifdef TARGET_SPARC64
2084                         gen_fcmpeq[rd & 3]();
2085 #else
2086                         gen_op_fcmpeq();
2087 #endif
2088                         break;
2089 #else/* !defined(CONFIG_USER_ONLY) */
2090                         goto nfpu_insn;
2091 #endif
2092                     default:
2093                         goto illegal_insn;
2094                 }
2095 #if defined(OPTIM)
2096             } else if (xop == 0x2) {
2097                 // clr/mov shortcut
2098
2099                 rs1 = GET_FIELD(insn, 13, 17);
2100                 if (rs1 == 0) {
2101                     // or %g0, x, y -> mov T1, x; mov y, T1
2102                     if (IS_IMM) {       /* immediate */
2103                         rs2 = GET_FIELDs(insn, 19, 31);
2104                         gen_movl_simm_T1(rs2);
2105                     } else {            /* register */
2106                         rs2 = GET_FIELD(insn, 27, 31);
2107                         gen_movl_reg_T1(rs2);
2108                     }
2109                     gen_movl_T1_reg(rd);
2110                 } else {
2111                     gen_movl_reg_T0(rs1);
2112                     if (IS_IMM) {       /* immediate */
2113                         // or x, #0, y -> mov T1, x; mov y, T1
2114                         rs2 = GET_FIELDs(insn, 19, 31);
2115                         if (rs2 != 0) {
2116                             gen_movl_simm_T1(rs2);
2117                             gen_op_or_T1_T0();
2118                         }
2119                     } else {            /* register */
2120                         // or x, %g0, y -> mov T1, x; mov y, T1
2121                         rs2 = GET_FIELD(insn, 27, 31);
2122                         if (rs2 != 0) {
2123                             gen_movl_reg_T1(rs2);
2124                             gen_op_or_T1_T0();
2125                         }
2126                     }
2127                     gen_movl_T0_reg(rd);
2128                 }
2129 #endif
2130 #ifdef TARGET_SPARC64
2131             } else if (xop == 0x25) { /* sll, V9 sllx */
2132                 rs1 = GET_FIELD(insn, 13, 17);
2133                 gen_movl_reg_T0(rs1);
2134                 if (IS_IMM) {   /* immediate */
2135                     rs2 = GET_FIELDs(insn, 20, 31);
2136                     gen_movl_simm_T1(rs2);
2137                 } else {                /* register */
2138                     rs2 = GET_FIELD(insn, 27, 31);
2139                     gen_movl_reg_T1(rs2);
2140                 }
2141                 if (insn & (1 << 12))
2142                     gen_op_sllx();
2143                 else
2144                     gen_op_sll();
2145                 gen_movl_T0_reg(rd);
2146             } else if (xop == 0x26) { /* srl, V9 srlx */
2147                 rs1 = GET_FIELD(insn, 13, 17);
2148                 gen_movl_reg_T0(rs1);
2149                 if (IS_IMM) {   /* immediate */
2150                     rs2 = GET_FIELDs(insn, 20, 31);
2151                     gen_movl_simm_T1(rs2);
2152                 } else {                /* register */
2153                     rs2 = GET_FIELD(insn, 27, 31);
2154                     gen_movl_reg_T1(rs2);
2155                 }
2156                 if (insn & (1 << 12))
2157                     gen_op_srlx();
2158                 else
2159                     gen_op_srl();
2160                 gen_movl_T0_reg(rd);
2161             } else if (xop == 0x27) { /* sra, V9 srax */
2162                 rs1 = GET_FIELD(insn, 13, 17);
2163                 gen_movl_reg_T0(rs1);
2164                 if (IS_IMM) {   /* immediate */
2165                     rs2 = GET_FIELDs(insn, 20, 31);
2166                     gen_movl_simm_T1(rs2);
2167                 } else {                /* register */
2168                     rs2 = GET_FIELD(insn, 27, 31);
2169                     gen_movl_reg_T1(rs2);
2170                 }
2171                 if (insn & (1 << 12))
2172                     gen_op_srax();
2173                 else
2174                     gen_op_sra();
2175                 gen_movl_T0_reg(rd);
2176 #endif
2177             } else if (xop < 0x36) {
2178                 rs1 = GET_FIELD(insn, 13, 17);
2179                 gen_movl_reg_T0(rs1);
2180                 if (IS_IMM) {   /* immediate */
2181                     rs2 = GET_FIELDs(insn, 19, 31);
2182                     gen_movl_simm_T1(rs2);
2183                 } else {                /* register */
2184                     rs2 = GET_FIELD(insn, 27, 31);
2185                     gen_movl_reg_T1(rs2);
2186                 }
2187                 if (xop < 0x20) {
2188                     switch (xop & ~0x10) {
2189                     case 0x0:
2190                         if (xop & 0x10)
2191                             gen_op_add_T1_T0_cc();
2192                         else
2193                             gen_op_add_T1_T0();
2194                         break;
2195                     case 0x1:
2196                         gen_op_and_T1_T0();
2197                         if (xop & 0x10)
2198                             gen_op_logic_T0_cc();
2199                         break;
2200                     case 0x2:
2201                         gen_op_or_T1_T0();
2202                         if (xop & 0x10)
2203                             gen_op_logic_T0_cc();
2204                         break;
2205                     case 0x3:
2206                         gen_op_xor_T1_T0();
2207                         if (xop & 0x10)
2208                             gen_op_logic_T0_cc();
2209                         break;
2210                     case 0x4:
2211                         if (xop & 0x10)
2212                             gen_op_sub_T1_T0_cc();
2213                         else
2214                             gen_op_sub_T1_T0();
2215                         break;
2216                     case 0x5:
2217                         gen_op_andn_T1_T0();
2218                         if (xop & 0x10)
2219                             gen_op_logic_T0_cc();
2220                         break;
2221                     case 0x6:
2222                         gen_op_orn_T1_T0();
2223                         if (xop & 0x10)
2224                             gen_op_logic_T0_cc();
2225                         break;
2226                     case 0x7:
2227                         gen_op_xnor_T1_T0();
2228                         if (xop & 0x10)
2229                             gen_op_logic_T0_cc();
2230                         break;
2231                     case 0x8:
2232                         if (xop & 0x10)
2233                             gen_op_addx_T1_T0_cc();
2234                         else
2235                             gen_op_addx_T1_T0();
2236                         break;
2237 #ifdef TARGET_SPARC64
2238                     case 0x9: /* V9 mulx */
2239                         gen_op_mulx_T1_T0();
2240                         break;
2241 #endif
2242                     case 0xa:
2243                         gen_op_umul_T1_T0();
2244                         if (xop & 0x10)
2245                             gen_op_logic_T0_cc();
2246                         break;
2247                     case 0xb:
2248                         gen_op_smul_T1_T0();
2249                         if (xop & 0x10)
2250                             gen_op_logic_T0_cc();
2251                         break;
2252                     case 0xc:
2253                         if (xop & 0x10)
2254                             gen_op_subx_T1_T0_cc();
2255                         else
2256                             gen_op_subx_T1_T0();
2257                         break;
2258 #ifdef TARGET_SPARC64
2259                     case 0xd: /* V9 udivx */
2260                         gen_op_udivx_T1_T0();
2261                         break;
2262 #endif
2263                     case 0xe:
2264                         gen_op_udiv_T1_T0();
2265                         if (xop & 0x10)
2266                             gen_op_div_cc();
2267                         break;
2268                     case 0xf:
2269                         gen_op_sdiv_T1_T0();
2270                         if (xop & 0x10)
2271                             gen_op_div_cc();
2272                         break;
2273                     default:
2274                         goto illegal_insn;
2275                     }
2276                     gen_movl_T0_reg(rd);
2277                 } else {
2278                     switch (xop) {
2279                     case 0x20: /* taddcc */
2280                         gen_op_tadd_T1_T0_cc();
2281                         gen_movl_T0_reg(rd);
2282                         break;
2283                     case 0x21: /* tsubcc */
2284                         gen_op_tsub_T1_T0_cc();
2285                         gen_movl_T0_reg(rd);
2286                         break;
2287                     case 0x22: /* taddcctv */
2288                         save_state(dc);
2289                         gen_op_tadd_T1_T0_ccTV();
2290                         gen_movl_T0_reg(rd);
2291                         break;
2292                     case 0x23: /* tsubcctv */
2293                         save_state(dc);
2294                         gen_op_tsub_T1_T0_ccTV();
2295                         gen_movl_T0_reg(rd);
2296                         break;
2297                     case 0x24: /* mulscc */
2298                         gen_op_mulscc_T1_T0();
2299                         gen_movl_T0_reg(rd);
2300                         break;
2301 #ifndef TARGET_SPARC64
2302                     case 0x25:  /* sll */
2303                         gen_op_sll();
2304                         gen_movl_T0_reg(rd);
2305                         break;
2306                     case 0x26:  /* srl */
2307                         gen_op_srl();
2308                         gen_movl_T0_reg(rd);
2309                         break;
2310                     case 0x27:  /* sra */
2311                         gen_op_sra();
2312                         gen_movl_T0_reg(rd);
2313                         break;
2314 #endif
2315                     case 0x30:
2316                         {
2317                             switch(rd) {
2318                             case 0: /* wry */
2319                                 gen_op_xor_T1_T0();
2320                                 gen_op_movtl_env_T0(offsetof(CPUSPARCState, y));
2321                                 break;
2322 #ifndef TARGET_SPARC64
2323                             case 0x01 ... 0x0f: /* undefined in the
2324                                                    SPARCv8 manual, nop
2325                                                    on the microSPARC
2326                                                    II */
2327                             case 0x10 ... 0x1f: /* implementation-dependent
2328                                                    in the SPARCv8
2329                                                    manual, nop on the
2330                                                    microSPARC II */
2331                                 break;
2332 #else
2333                             case 0x2: /* V9 wrccr */
2334                                 gen_op_xor_T1_T0();
2335                                 gen_op_wrccr();
2336                                 break;
2337                             case 0x3: /* V9 wrasi */
2338                                 gen_op_xor_T1_T0();
2339                                 gen_op_movl_env_T0(offsetof(CPUSPARCState, asi));
2340                                 break;
2341                             case 0x6: /* V9 wrfprs */
2342                                 gen_op_xor_T1_T0();
2343                                 gen_op_movl_env_T0(offsetof(CPUSPARCState, fprs));
2344                                 save_state(dc);
2345                                 gen_op_next_insn();
2346                                 gen_op_movl_T0_0();
2347                                 gen_op_exit_tb();
2348                                 dc->is_br = 1;
2349                                 break;
2350                             case 0xf: /* V9 sir, nop if user */
2351 #if !defined(CONFIG_USER_ONLY)
2352                                 if (supervisor(dc))
2353                                     gen_op_sir();
2354 #endif
2355                                 break;
2356                             case 0x13: /* Graphics Status */
2357                                 if (gen_trap_ifnofpu(dc))
2358                                     goto jmp_insn;
2359                                 gen_op_xor_T1_T0();
2360                                 gen_op_movtl_env_T0(offsetof(CPUSPARCState, gsr));
2361                                 break;
2362                             case 0x17: /* Tick compare */
2363 #if !defined(CONFIG_USER_ONLY)
2364                                 if (!supervisor(dc))
2365                                     goto illegal_insn;
2366 #endif
2367                                 gen_op_xor_T1_T0();
2368                                 gen_op_movtl_env_T0(offsetof(CPUSPARCState, tick_cmpr));
2369                                 gen_op_wrtick_cmpr();
2370                                 break;
2371                             case 0x18: /* System tick */
2372 #if !defined(CONFIG_USER_ONLY)
2373                                 if (!supervisor(dc))
2374                                     goto illegal_insn;
2375 #endif
2376                                 gen_op_xor_T1_T0();
2377                                 gen_op_wrstick();
2378                                 break;
2379                             case 0x19: /* System tick compare */
2380 #if !defined(CONFIG_USER_ONLY)
2381                                 if (!supervisor(dc))
2382                                     goto illegal_insn;
2383 #endif
2384                                 gen_op_xor_T1_T0();
2385                                 gen_op_movtl_env_T0(offsetof(CPUSPARCState, stick_cmpr));
2386                                 gen_op_wrstick_cmpr();
2387                                 break;
2388
2389                             case 0x10: /* Performance Control */
2390                             case 0x11: /* Performance Instrumentation Counter */
2391                             case 0x12: /* Dispatch Control */
2392                             case 0x14: /* Softint set */
2393                             case 0x15: /* Softint clear */
2394                             case 0x16: /* Softint write */
2395 #endif
2396                             default:
2397                                 goto illegal_insn;
2398                             }
2399                         }
2400                         break;
2401 #if !defined(CONFIG_USER_ONLY)
2402                     case 0x31: /* wrpsr, V9 saved, restored */
2403                         {
2404                             if (!supervisor(dc))
2405                                 goto priv_insn;
2406 #ifdef TARGET_SPARC64
2407                             switch (rd) {
2408                             case 0:
2409                                 gen_op_saved();
2410                                 break;
2411                             case 1:
2412                                 gen_op_restored();
2413                                 break;
2414                             case 2: /* UA2005 allclean */
2415                             case 3: /* UA2005 otherw */
2416                             case 4: /* UA2005 normalw */
2417                             case 5: /* UA2005 invalw */
2418                                 // XXX
2419                             default:
2420                                 goto illegal_insn;
2421                             }
2422 #else
2423                             gen_op_xor_T1_T0();
2424                             gen_op_wrpsr();
2425                             save_state(dc);
2426                             gen_op_next_insn();
2427                             gen_op_movl_T0_0();
2428                             gen_op_exit_tb();
2429                             dc->is_br = 1;
2430 #endif
2431                         }
2432                         break;
2433                     case 0x32: /* wrwim, V9 wrpr */
2434                         {
2435                             if (!supervisor(dc))
2436                                 goto priv_insn;
2437                             gen_op_xor_T1_T0();
2438 #ifdef TARGET_SPARC64
2439                             switch (rd) {
2440                             case 0: // tpc
2441                                 gen_op_wrtpc();
2442                                 break;
2443                             case 1: // tnpc
2444                                 gen_op_wrtnpc();
2445                                 break;
2446                             case 2: // tstate
2447                                 gen_op_wrtstate();
2448                                 break;
2449                             case 3: // tt
2450                                 gen_op_wrtt();
2451                                 break;
2452                             case 4: // tick
2453                                 gen_op_wrtick();
2454                                 break;
2455                             case 5: // tba
2456                                 gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
2457                                 break;
2458                             case 6: // pstate
2459                                 gen_op_wrpstate();
2460                                 save_state(dc);
2461                                 gen_op_next_insn();
2462                                 gen_op_movl_T0_0();
2463                                 gen_op_exit_tb();
2464                                 dc->is_br = 1;
2465                                 break;
2466                             case 7: // tl
2467                                 gen_op_movl_env_T0(offsetof(CPUSPARCState, tl));
2468                                 break;
2469                             case 8: // pil
2470                                 gen_op_movl_env_T0(offsetof(CPUSPARCState, psrpil));
2471                                 break;
2472                             case 9: // cwp
2473                                 gen_op_wrcwp();
2474                                 break;
2475                             case 10: // cansave
2476                                 gen_op_movl_env_T0(offsetof(CPUSPARCState, cansave));
2477                                 break;
2478                             case 11: // canrestore
2479                                 gen_op_movl_env_T0(offsetof(CPUSPARCState, canrestore));
2480                                 break;
2481                             case 12: // cleanwin
2482                                 gen_op_movl_env_T0(offsetof(CPUSPARCState, cleanwin));
2483                                 break;
2484                             case 13: // otherwin
2485                                 gen_op_movl_env_T0(offsetof(CPUSPARCState, otherwin));
2486                                 break;
2487                             case 14: // wstate
2488                                 gen_op_movl_env_T0(offsetof(CPUSPARCState, wstate));
2489                                 break;
2490                             case 16: // UA2005 gl
2491                                 gen_op_movl_env_T0(offsetof(CPUSPARCState, gl));
2492                                 break;
2493                             case 26: // UA2005 strand status
2494                                 if (!hypervisor(dc))
2495                                     goto priv_insn;
2496                                 gen_op_movl_env_T0(offsetof(CPUSPARCState, ssr));
2497                                 break;
2498                             default:
2499                                 goto illegal_insn;
2500                             }
2501 #else
2502                             gen_op_wrwim();
2503 #endif
2504                         }
2505                         break;
2506                     case 0x33: /* wrtbr, UA2005 wrhpr */
2507                         {
2508 #ifndef TARGET_SPARC64
2509                             if (!supervisor(dc))
2510                                 goto priv_insn;
2511                             gen_op_xor_T1_T0();
2512                             gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
2513 #else
2514                             if (!hypervisor(dc))
2515                                 goto priv_insn;
2516                             gen_op_xor_T1_T0();
2517                             switch (rd) {
2518                             case 0: // hpstate
2519                                 // XXX gen_op_wrhpstate();
2520                                 save_state(dc);
2521                                 gen_op_next_insn();
2522                                 gen_op_movl_T0_0();
2523                                 gen_op_exit_tb();
2524                                 dc->is_br = 1;
2525                                 break;
2526                             case 1: // htstate
2527                                 // XXX gen_op_wrhtstate();
2528                                 break;
2529                             case 3: // hintp
2530                                 gen_op_movl_env_T0(offsetof(CPUSPARCState, hintp));
2531                                 break;
2532                             case 5: // htba
2533                                 gen_op_movl_env_T0(offsetof(CPUSPARCState, htba));
2534                                 break;
2535                             case 31: // hstick_cmpr
2536                                 gen_op_movtl_env_T0(offsetof(CPUSPARCState, hstick_cmpr));
2537                                 gen_op_wrhstick_cmpr();
2538                                 break;
2539                             case 6: // hver readonly
2540                             default:
2541                                 goto illegal_insn;
2542                             }
2543 #endif
2544                         }
2545                         break;
2546 #endif
2547 #ifdef TARGET_SPARC64
2548                     case 0x2c: /* V9 movcc */
2549                         {
2550                             int cc = GET_FIELD_SP(insn, 11, 12);
2551                             int cond = GET_FIELD_SP(insn, 14, 17);
2552                             if (IS_IMM) {       /* immediate */
2553                                 rs2 = GET_FIELD_SPs(insn, 0, 10);
2554                                 gen_movl_simm_T1(rs2);
2555                             }
2556                             else {
2557                                 rs2 = GET_FIELD_SP(insn, 0, 4);
2558                                 gen_movl_reg_T1(rs2);
2559                             }
2560                             gen_movl_reg_T0(rd);
2561                             flush_T2(dc);
2562                             if (insn & (1 << 18)) {
2563                                 if (cc == 0)
2564                                     gen_cond[0][cond]();
2565                                 else if (cc == 2)
2566                                     gen_cond[1][cond]();
2567                                 else
2568                                     goto illegal_insn;
2569                             } else {
2570                                 gen_fcond[cc][cond]();
2571                             }
2572                             gen_op_mov_cc();
2573                             gen_movl_T0_reg(rd);
2574                             break;
2575                         }
2576                     case 0x2d: /* V9 sdivx */
2577                         gen_op_sdivx_T1_T0();
2578                         gen_movl_T0_reg(rd);
2579                         break;
2580                     case 0x2e: /* V9 popc */
2581                         {
2582                             if (IS_IMM) {       /* immediate */
2583                                 rs2 = GET_FIELD_SPs(insn, 0, 12);
2584                                 gen_movl_simm_T1(rs2);
2585                                 // XXX optimize: popc(constant)
2586                             }
2587                             else {
2588                                 rs2 = GET_FIELD_SP(insn, 0, 4);
2589                                 gen_movl_reg_T1(rs2);
2590                             }
2591                             gen_op_popc();
2592                             gen_movl_T0_reg(rd);
2593                         }
2594                     case 0x2f: /* V9 movr */
2595                         {
2596                             int cond = GET_FIELD_SP(insn, 10, 12);
2597                             rs1 = GET_FIELD(insn, 13, 17);
2598                             flush_T2(dc);
2599                             gen_movl_reg_T0(rs1);
2600                             gen_cond_reg(cond);
2601                             if (IS_IMM) {       /* immediate */
2602                                 rs2 = GET_FIELD_SPs(insn, 0, 9);
2603                                 gen_movl_simm_T1(rs2);
2604                             }
2605                             else {
2606                                 rs2 = GET_FIELD_SP(insn, 0, 4);
2607                                 gen_movl_reg_T1(rs2);
2608                             }
2609                             gen_movl_reg_T0(rd);
2610                             gen_op_mov_cc();
2611                             gen_movl_T0_reg(rd);
2612                             break;
2613                         }
2614 #endif
2615                     default:
2616                         goto illegal_insn;
2617                     }
2618                 }
2619             } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
2620 #ifdef TARGET_SPARC64
2621                 int opf = GET_FIELD_SP(insn, 5, 13);
2622                 rs1 = GET_FIELD(insn, 13, 17);
2623                 rs2 = GET_FIELD(insn, 27, 31);
2624                 if (gen_trap_ifnofpu(dc))
2625                     goto jmp_insn;
2626
2627                 switch (opf) {
2628                 case 0x000: /* VIS I edge8cc */
2629                 case 0x001: /* VIS II edge8n */
2630                 case 0x002: /* VIS I edge8lcc */
2631                 case 0x003: /* VIS II edge8ln */
2632                 case 0x004: /* VIS I edge16cc */
2633                 case 0x005: /* VIS II edge16n */
2634                 case 0x006: /* VIS I edge16lcc */
2635                 case 0x007: /* VIS II edge16ln */
2636                 case 0x008: /* VIS I edge32cc */
2637                 case 0x009: /* VIS II edge32n */
2638                 case 0x00a: /* VIS I edge32lcc */
2639                 case 0x00b: /* VIS II edge32ln */
2640                     // XXX
2641                     goto illegal_insn;
2642                 case 0x010: /* VIS I array8 */
2643                     gen_movl_reg_T0(rs1);
2644                     gen_movl_reg_T1(rs2);
2645                     gen_op_array8();
2646                     gen_movl_T0_reg(rd);
2647                     break;
2648                 case 0x012: /* VIS I array16 */
2649                     gen_movl_reg_T0(rs1);
2650                     gen_movl_reg_T1(rs2);
2651                     gen_op_array16();
2652                     gen_movl_T0_reg(rd);
2653                     break;
2654                 case 0x014: /* VIS I array32 */
2655                     gen_movl_reg_T0(rs1);
2656                     gen_movl_reg_T1(rs2);
2657                     gen_op_array32();
2658                     gen_movl_T0_reg(rd);
2659                     break;
2660                 case 0x018: /* VIS I alignaddr */
2661                     gen_movl_reg_T0(rs1);
2662                     gen_movl_reg_T1(rs2);
2663                     gen_op_alignaddr();
2664                     gen_movl_T0_reg(rd);
2665                     break;
2666                 case 0x019: /* VIS II bmask */
2667                 case 0x01a: /* VIS I alignaddrl */
2668                     // XXX
2669                     goto illegal_insn;
2670                 case 0x020: /* VIS I fcmple16 */
2671                     gen_op_load_fpr_DT0(rs1);
2672                     gen_op_load_fpr_DT1(rs2);
2673                     gen_op_fcmple16();
2674                     gen_op_store_DT0_fpr(rd);
2675                     break;
2676                 case 0x022: /* VIS I fcmpne16 */
2677                     gen_op_load_fpr_DT0(rs1);
2678                     gen_op_load_fpr_DT1(rs2);
2679                     gen_op_fcmpne16();
2680                     gen_op_store_DT0_fpr(rd);
2681                     break;
2682                 case 0x024: /* VIS I fcmple32 */
2683                     gen_op_load_fpr_DT0(rs1);
2684                     gen_op_load_fpr_DT1(rs2);
2685                     gen_op_fcmple32();
2686                     gen_op_store_DT0_fpr(rd);
2687                     break;
2688                 case 0x026: /* VIS I fcmpne32 */
2689                     gen_op_load_fpr_DT0(rs1);
2690                     gen_op_load_fpr_DT1(rs2);
2691                     gen_op_fcmpne32();
2692                     gen_op_store_DT0_fpr(rd);
2693                     break;
2694                 case 0x028: /* VIS I fcmpgt16 */
2695                     gen_op_load_fpr_DT0(rs1);
2696                     gen_op_load_fpr_DT1(rs2);
2697                     gen_op_fcmpgt16();
2698                     gen_op_store_DT0_fpr(rd);
2699                     break;
2700                 case 0x02a: /* VIS I fcmpeq16 */
2701                     gen_op_load_fpr_DT0(rs1);
2702                     gen_op_load_fpr_DT1(rs2);
2703                     gen_op_fcmpeq16();
2704                     gen_op_store_DT0_fpr(rd);
2705                     break;
2706                 case 0x02c: /* VIS I fcmpgt32 */
2707                     gen_op_load_fpr_DT0(rs1);
2708                     gen_op_load_fpr_DT1(rs2);
2709                     gen_op_fcmpgt32();
2710                     gen_op_store_DT0_fpr(rd);
2711                     break;
2712                 case 0x02e: /* VIS I fcmpeq32 */
2713                     gen_op_load_fpr_DT0(rs1);
2714                     gen_op_load_fpr_DT1(rs2);
2715                     gen_op_fcmpeq32();
2716                     gen_op_store_DT0_fpr(rd);
2717                     break;
2718                 case 0x031: /* VIS I fmul8x16 */
2719                     gen_op_load_fpr_DT0(rs1);
2720                     gen_op_load_fpr_DT1(rs2);
2721                     gen_op_fmul8x16();
2722                     gen_op_store_DT0_fpr(rd);
2723                     break;
2724                 case 0x033: /* VIS I fmul8x16au */
2725                     gen_op_load_fpr_DT0(rs1);
2726                     gen_op_load_fpr_DT1(rs2);
2727                     gen_op_fmul8x16au();
2728                     gen_op_store_DT0_fpr(rd);
2729                     break;
2730                 case 0x035: /* VIS I fmul8x16al */
2731                     gen_op_load_fpr_DT0(rs1);
2732                     gen_op_load_fpr_DT1(rs2);
2733                     gen_op_fmul8x16al();
2734                     gen_op_store_DT0_fpr(rd);
2735                     break;
2736                 case 0x036: /* VIS I fmul8sux16 */
2737                     gen_op_load_fpr_DT0(rs1);
2738                     gen_op_load_fpr_DT1(rs2);
2739                     gen_op_fmul8sux16();
2740                     gen_op_store_DT0_fpr(rd);
2741                     break;
2742                 case 0x037: /* VIS I fmul8ulx16 */
2743                     gen_op_load_fpr_DT0(rs1);
2744                     gen_op_load_fpr_DT1(rs2);
2745                     gen_op_fmul8ulx16();
2746                     gen_op_store_DT0_fpr(rd);
2747                     break;
2748                 case 0x038: /* VIS I fmuld8sux16 */
2749                     gen_op_load_fpr_DT0(rs1);
2750                     gen_op_load_fpr_DT1(rs2);
2751                     gen_op_fmuld8sux16();
2752                     gen_op_store_DT0_fpr(rd);
2753                     break;
2754                 case 0x039: /* VIS I fmuld8ulx16 */
2755                     gen_op_load_fpr_DT0(rs1);
2756                     gen_op_load_fpr_DT1(rs2);
2757                     gen_op_fmuld8ulx16();
2758                     gen_op_store_DT0_fpr(rd);
2759                     break;
2760                 case 0x03a: /* VIS I fpack32 */
2761                 case 0x03b: /* VIS I fpack16 */
2762                 case 0x03d: /* VIS I fpackfix */
2763                 case 0x03e: /* VIS I pdist */
2764                     // XXX
2765                     goto illegal_insn;
2766                 case 0x048: /* VIS I faligndata */
2767                     gen_op_load_fpr_DT0(rs1);
2768                     gen_op_load_fpr_DT1(rs2);
2769                     gen_op_faligndata();
2770                     gen_op_store_DT0_fpr(rd);
2771                     break;
2772                 case 0x04b: /* VIS I fpmerge */
2773                     gen_op_load_fpr_DT0(rs1);
2774                     gen_op_load_fpr_DT1(rs2);
2775                     gen_op_fpmerge();
2776                     gen_op_store_DT0_fpr(rd);
2777                     break;
2778                 case 0x04c: /* VIS II bshuffle */
2779                     // XXX
2780                     goto illegal_insn;
2781                 case 0x04d: /* VIS I fexpand */
2782                     gen_op_load_fpr_DT0(rs1);
2783                     gen_op_load_fpr_DT1(rs2);
2784                     gen_op_fexpand();
2785                     gen_op_store_DT0_fpr(rd);
2786                     break;
2787                 case 0x050: /* VIS I fpadd16 */
2788                     gen_op_load_fpr_DT0(rs1);
2789                     gen_op_load_fpr_DT1(rs2);
2790                     gen_op_fpadd16();
2791                     gen_op_store_DT0_fpr(rd);
2792                     break;
2793                 case 0x051: /* VIS I fpadd16s */
2794                     gen_op_load_fpr_FT0(rs1);
2795                     gen_op_load_fpr_FT1(rs2);
2796                     gen_op_fpadd16s();
2797                     gen_op_store_FT0_fpr(rd);
2798                     break;
2799                 case 0x052: /* VIS I fpadd32 */
2800                     gen_op_load_fpr_DT0(rs1);
2801                     gen_op_load_fpr_DT1(rs2);
2802                     gen_op_fpadd32();
2803                     gen_op_store_DT0_fpr(rd);
2804                     break;
2805                 case 0x053: /* VIS I fpadd32s */
2806                     gen_op_load_fpr_FT0(rs1);
2807                     gen_op_load_fpr_FT1(rs2);
2808                     gen_op_fpadd32s();
2809                     gen_op_store_FT0_fpr(rd);
2810                     break;
2811                 case 0x054: /* VIS I fpsub16 */
2812                     gen_op_load_fpr_DT0(rs1);
2813                     gen_op_load_fpr_DT1(rs2);
2814                     gen_op_fpsub16();
2815                     gen_op_store_DT0_fpr(rd);
2816                     break;
2817                 case 0x055: /* VIS I fpsub16s */
2818                     gen_op_load_fpr_FT0(rs1);
2819                     gen_op_load_fpr_FT1(rs2);
2820                     gen_op_fpsub16s();
2821                     gen_op_store_FT0_fpr(rd);
2822                     break;
2823                 case 0x056: /* VIS I fpsub32 */
2824                     gen_op_load_fpr_DT0(rs1);
2825                     gen_op_load_fpr_DT1(rs2);
2826                     gen_op_fpadd32();
2827                     gen_op_store_DT0_fpr(rd);
2828                     break;
2829                 case 0x057: /* VIS I fpsub32s */
2830                     gen_op_load_fpr_FT0(rs1);
2831                     gen_op_load_fpr_FT1(rs2);
2832                     gen_op_fpsub32s();
2833                     gen_op_store_FT0_fpr(rd);
2834                     break;
2835                 case 0x060: /* VIS I fzero */
2836                     gen_op_movl_DT0_0();
2837                     gen_op_store_DT0_fpr(rd);
2838                     break;
2839                 case 0x061: /* VIS I fzeros */
2840                     gen_op_movl_FT0_0();
2841                     gen_op_store_FT0_fpr(rd);
2842                     break;
2843                 case 0x062: /* VIS I fnor */
2844                     gen_op_load_fpr_DT0(rs1);
2845                     gen_op_load_fpr_DT1(rs2);
2846                     gen_op_fnor();
2847                     gen_op_store_DT0_fpr(rd);
2848                     break;
2849                 case 0x063: /* VIS I fnors */
2850                     gen_op_load_fpr_FT0(rs1);
2851                     gen_op_load_fpr_FT1(rs2);
2852                     gen_op_fnors();
2853                     gen_op_store_FT0_fpr(rd);
2854                     break;
2855                 case 0x064: /* VIS I fandnot2 */
2856                     gen_op_load_fpr_DT1(rs1);
2857                     gen_op_load_fpr_DT0(rs2);
2858                     gen_op_fandnot();
2859                     gen_op_store_DT0_fpr(rd);
2860                     break;
2861                 case 0x065: /* VIS I fandnot2s */
2862                     gen_op_load_fpr_FT1(rs1);
2863                     gen_op_load_fpr_FT0(rs2);
2864                     gen_op_fandnots();
2865                     gen_op_store_FT0_fpr(rd);
2866                     break;
2867                 case 0x066: /* VIS I fnot2 */
2868                     gen_op_load_fpr_DT1(rs2);
2869                     gen_op_fnot();
2870                     gen_op_store_DT0_fpr(rd);
2871                     break;
2872                 case 0x067: /* VIS I fnot2s */
2873                     gen_op_load_fpr_FT1(rs2);
2874                     gen_op_fnot();
2875                     gen_op_store_FT0_fpr(rd);
2876                     break;
2877                 case 0x068: /* VIS I fandnot1 */
2878                     gen_op_load_fpr_DT0(rs1);
2879                     gen_op_load_fpr_DT1(rs2);
2880                     gen_op_fandnot();
2881                     gen_op_store_DT0_fpr(rd);
2882                     break;
2883                 case 0x069: /* VIS I fandnot1s */
2884                     gen_op_load_fpr_FT0(rs1);
2885                     gen_op_load_fpr_FT1(rs2);
2886                     gen_op_fandnots();
2887                     gen_op_store_FT0_fpr(rd);
2888                     break;
2889                 case 0x06a: /* VIS I fnot1 */
2890                     gen_op_load_fpr_DT1(rs1);
2891                     gen_op_fnot();
2892                     gen_op_store_DT0_fpr(rd);
2893                     break;
2894                 case 0x06b: /* VIS I fnot1s */
2895                     gen_op_load_fpr_FT1(rs1);
2896                     gen_op_fnot();
2897                     gen_op_store_FT0_fpr(rd);
2898                     break;
2899                 case 0x06c: /* VIS I fxor */
2900                     gen_op_load_fpr_DT0(rs1);
2901                     gen_op_load_fpr_DT1(rs2);
2902                     gen_op_fxor();
2903                     gen_op_store_DT0_fpr(rd);
2904                     break;
2905                 case 0x06d: /* VIS I fxors */
2906                     gen_op_load_fpr_FT0(rs1);
2907                     gen_op_load_fpr_FT1(rs2);
2908                     gen_op_fxors();
2909                     gen_op_store_FT0_fpr(rd);
2910                     break;
2911                 case 0x06e: /* VIS I fnand */
2912                     gen_op_load_fpr_DT0(rs1);
2913                     gen_op_load_fpr_DT1(rs2);
2914                     gen_op_fnand();
2915                     gen_op_store_DT0_fpr(rd);
2916                     break;
2917                 case 0x06f: /* VIS I fnands */
2918                     gen_op_load_fpr_FT0(rs1);
2919                     gen_op_load_fpr_FT1(rs2);
2920                     gen_op_fnands();
2921                     gen_op_store_FT0_fpr(rd);
2922                     break;
2923                 case 0x070: /* VIS I fand */
2924                     gen_op_load_fpr_DT0(rs1);
2925                     gen_op_load_fpr_DT1(rs2);
2926                     gen_op_fand();
2927                     gen_op_store_DT0_fpr(rd);
2928                     break;
2929                 case 0x071: /* VIS I fands */
2930                     gen_op_load_fpr_FT0(rs1);
2931                     gen_op_load_fpr_FT1(rs2);
2932                     gen_op_fands();
2933                     gen_op_store_FT0_fpr(rd);
2934                     break;
2935                 case 0x072: /* VIS I fxnor */
2936                     gen_op_load_fpr_DT0(rs1);
2937                     gen_op_load_fpr_DT1(rs2);
2938                     gen_op_fxnor();
2939                     gen_op_store_DT0_fpr(rd);
2940                     break;
2941                 case 0x073: /* VIS I fxnors */
2942                     gen_op_load_fpr_FT0(rs1);
2943                     gen_op_load_fpr_FT1(rs2);
2944                     gen_op_fxnors();
2945                     gen_op_store_FT0_fpr(rd);
2946                     break;
2947                 case 0x074: /* VIS I fsrc1 */
2948                     gen_op_load_fpr_DT0(rs1);
2949                     gen_op_store_DT0_fpr(rd);
2950                     break;
2951                 case 0x075: /* VIS I fsrc1s */
2952                     gen_op_load_fpr_FT0(rs1);
2953                     gen_op_store_FT0_fpr(rd);
2954                     break;
2955                 case 0x076: /* VIS I fornot2 */
2956                     gen_op_load_fpr_DT1(rs1);
2957                     gen_op_load_fpr_DT0(rs2);
2958                     gen_op_fornot();
2959                     gen_op_store_DT0_fpr(rd);
2960                     break;
2961                 case 0x077: /* VIS I fornot2s */
2962                     gen_op_load_fpr_FT1(rs1);
2963                     gen_op_load_fpr_FT0(rs2);
2964                     gen_op_fornots();
2965                     gen_op_store_FT0_fpr(rd);
2966                     break;
2967                 case 0x078: /* VIS I fsrc2 */
2968                     gen_op_load_fpr_DT0(rs2);
2969                     gen_op_store_DT0_fpr(rd);
2970                     break;
2971                 case 0x079: /* VIS I fsrc2s */
2972                     gen_op_load_fpr_FT0(rs2);
2973                     gen_op_store_FT0_fpr(rd);
2974                     break;
2975                 case 0x07a: /* VIS I fornot1 */
2976                     gen_op_load_fpr_DT0(rs1);
2977                     gen_op_load_fpr_DT1(rs2);
2978                     gen_op_fornot();
2979                     gen_op_store_DT0_fpr(rd);
2980                     break;
2981                 case 0x07b: /* VIS I fornot1s */
2982                     gen_op_load_fpr_FT0(rs1);
2983                     gen_op_load_fpr_FT1(rs2);
2984                     gen_op_fornots();
2985                     gen_op_store_FT0_fpr(rd);
2986                     break;
2987                 case 0x07c: /* VIS I for */
2988                     gen_op_load_fpr_DT0(rs1);
2989                     gen_op_load_fpr_DT1(rs2);
2990                     gen_op_for();
2991                     gen_op_store_DT0_fpr(rd);
2992                     break;
2993                 case 0x07d: /* VIS I fors */
2994                     gen_op_load_fpr_FT0(rs1);
2995                     gen_op_load_fpr_FT1(rs2);
2996                     gen_op_fors();
2997                     gen_op_store_FT0_fpr(rd);
2998                     break;
2999                 case 0x07e: /* VIS I fone */
3000                     gen_op_movl_DT0_1();
3001                     gen_op_store_DT0_fpr(rd);
3002                     break;
3003                 case 0x07f: /* VIS I fones */
3004                     gen_op_movl_FT0_1();
3005                     gen_op_store_FT0_fpr(rd);
3006                     break;
3007                 case 0x080: /* VIS I shutdown */
3008                 case 0x081: /* VIS II siam */
3009                     // XXX
3010                     goto illegal_insn;
3011                 default:
3012                     goto illegal_insn;
3013                 }
3014 #else
3015                 goto ncp_insn;
3016 #endif
3017             } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
3018 #ifdef TARGET_SPARC64
3019                 goto illegal_insn;
3020 #else
3021                 goto ncp_insn;
3022 #endif
3023 #ifdef TARGET_SPARC64
3024             } else if (xop == 0x39) { /* V9 return */
3025                 rs1 = GET_FIELD(insn, 13, 17);
3026                 save_state(dc);
3027                 gen_movl_reg_T0(rs1);
3028                 if (IS_IMM) {   /* immediate */
3029                     rs2 = GET_FIELDs(insn, 19, 31);
3030 #if defined(OPTIM)
3031                     if (rs2) {
3032 #endif
3033                         gen_movl_simm_T1(rs2);
3034                         gen_op_add_T1_T0();
3035 #if defined(OPTIM)
3036                     }
3037 #endif
3038                 } else {                /* register */
3039                     rs2 = GET_FIELD(insn, 27, 31);
3040 #if defined(OPTIM)
3041                     if (rs2) {
3042 #endif
3043                         gen_movl_reg_T1(rs2);
3044                         gen_op_add_T1_T0();
3045 #if defined(OPTIM)
3046                     }
3047 #endif
3048                 }
3049                 gen_op_restore();
3050                 gen_mov_pc_npc(dc);
3051                 gen_op_check_align_T0_3();
3052                 gen_op_movl_npc_T0();
3053                 dc->npc = DYNAMIC_PC;
3054                 goto jmp_insn;
3055 #endif
3056             } else {
3057                 rs1 = GET_FIELD(insn, 13, 17);
3058                 gen_movl_reg_T0(rs1);
3059                 if (IS_IMM) {   /* immediate */
3060                     rs2 = GET_FIELDs(insn, 19, 31);
3061 #if defined(OPTIM)
3062                     if (rs2) {
3063 #endif
3064                         gen_movl_simm_T1(rs2);
3065                         gen_op_add_T1_T0();
3066 #if defined(OPTIM)
3067                     }
3068 #endif
3069                 } else {                /* register */
3070                     rs2 = GET_FIELD(insn, 27, 31);
3071 #if defined(OPTIM)
3072                     if (rs2) {
3073 #endif
3074                         gen_movl_reg_T1(rs2);
3075                         gen_op_add_T1_T0();
3076 #if defined(OPTIM)
3077                     }
3078 #endif
3079                 }
3080                 switch (xop) {
3081                 case 0x38:      /* jmpl */
3082                     {
3083                         if (rd != 0) {
3084 #ifdef TARGET_SPARC64
3085                             if (dc->pc == (uint32_t)dc->pc) {
3086                                 gen_op_movl_T1_im(dc->pc);
3087                             } else {
3088                                 gen_op_movq_T1_im64(dc->pc >> 32, dc->pc);
3089                             }
3090 #else
3091                             gen_op_movl_T1_im(dc->pc);
3092 #endif
3093                             gen_movl_T1_reg(rd);
3094                         }
3095                         gen_mov_pc_npc(dc);
3096                         gen_op_check_align_T0_3();
3097                         gen_op_movl_npc_T0();
3098                         dc->npc = DYNAMIC_PC;
3099                     }
3100                     goto jmp_insn;
3101 #if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
3102                 case 0x39:      /* rett, V9 return */
3103                     {
3104                         if (!supervisor(dc))
3105                             goto priv_insn;
3106                         gen_mov_pc_npc(dc);
3107                         gen_op_check_align_T0_3();
3108                         gen_op_movl_npc_T0();
3109                         dc->npc = DYNAMIC_PC;
3110                         gen_op_rett();
3111                     }
3112                     goto jmp_insn;
3113 #endif
3114                 case 0x3b: /* flush */
3115                     gen_op_flush_T0();
3116                     break;
3117                 case 0x3c:      /* save */
3118                     save_state(dc);
3119                     gen_op_save();
3120                     gen_movl_T0_reg(rd);
3121                     break;
3122                 case 0x3d:      /* restore */
3123                     save_state(dc);
3124                     gen_op_restore();
3125                     gen_movl_T0_reg(rd);
3126                     break;
3127 #if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
3128                 case 0x3e:      /* V9 done/retry */
3129                     {
3130                         switch (rd) {
3131                         case 0:
3132                             if (!supervisor(dc))
3133                                 goto priv_insn;
3134                             dc->npc = DYNAMIC_PC;
3135                             dc->pc = DYNAMIC_PC;
3136                             gen_op_done();
3137                             goto jmp_insn;
3138                         case 1:
3139                             if (!supervisor(dc))
3140                                 goto priv_insn;
3141                             dc->npc = DYNAMIC_PC;
3142                             dc->pc = DYNAMIC_PC;
3143                             gen_op_retry();
3144                             goto jmp_insn;
3145                         default:
3146                             goto illegal_insn;
3147                         }
3148                     }
3149                     break;
3150 #endif
3151                 default:
3152                     goto illegal_insn;
3153                 }
3154             }
3155             break;
3156         }
3157         break;
3158     case 3:                     /* load/store instructions */
3159         {
3160             unsigned int xop = GET_FIELD(insn, 7, 12);
3161             rs1 = GET_FIELD(insn, 13, 17);
3162             save_state(dc);
3163             gen_movl_reg_T0(rs1);
3164             if (xop == 0x3c || xop == 0x3e)
3165             {
3166                 rs2 = GET_FIELD(insn, 27, 31);
3167                 gen_movl_reg_T1(rs2);
3168             }
3169             else if (IS_IMM) {       /* immediate */
3170                 rs2 = GET_FIELDs(insn, 19, 31);
3171 #if defined(OPTIM)
3172                 if (rs2 != 0) {
3173 #endif
3174                     gen_movl_simm_T1(rs2);
3175                     gen_op_add_T1_T0();
3176 #if defined(OPTIM)
3177                 }
3178 #endif
3179             } else {            /* register */
3180                 rs2 = GET_FIELD(insn, 27, 31);
3181 #if defined(OPTIM)
3182                 if (rs2 != 0) {
3183 #endif
3184                     gen_movl_reg_T1(rs2);
3185                     gen_op_add_T1_T0();
3186 #if defined(OPTIM)
3187                 }
3188 #endif
3189             }
3190             if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
3191                 (xop > 0x17 && xop <= 0x1d ) ||
3192                 (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
3193                 switch (xop) {
3194                 case 0x0:       /* load word */
3195                     gen_op_check_align_T0_3();
3196 #ifndef TARGET_SPARC64
3197                     gen_op_ldst(ld);
3198 #else
3199                     gen_op_ldst(lduw);
3200 #endif
3201                     break;
3202                 case 0x1:       /* load unsigned byte */
3203                     gen_op_ldst(ldub);
3204                     break;
3205                 case 0x2:       /* load unsigned halfword */
3206                     gen_op_check_align_T0_1();
3207                     gen_op_ldst(lduh);
3208                     break;
3209                 case 0x3:       /* load double word */
3210                     if (rd & 1)
3211                         goto illegal_insn;
3212                     gen_op_check_align_T0_7();
3213                     gen_op_ldst(ldd);
3214                     gen_movl_T0_reg(rd + 1);
3215                     break;
3216                 case 0x9:       /* load signed byte */
3217                     gen_op_ldst(ldsb);
3218                     break;
3219                 case 0xa:       /* load signed halfword */
3220                     gen_op_check_align_T0_1();
3221                     gen_op_ldst(ldsh);
3222                     break;
3223                 case 0xd:       /* ldstub -- XXX: should be atomically */
3224                     gen_op_ldst(ldstub);
3225                     break;
3226                 case 0x0f:      /* swap register with memory. Also atomically */
3227                     gen_op_check_align_T0_3();
3228                     gen_movl_reg_T1(rd);
3229                     gen_op_ldst(swap);
3230                     break;
3231 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
3232                 case 0x10:      /* load word alternate */
3233 #ifndef TARGET_SPARC64
3234                     if (IS_IMM)
3235                         goto illegal_insn;
3236                     if (!supervisor(dc))
3237                         goto priv_insn;
3238 #endif
3239                     gen_op_check_align_T0_3();
3240                     gen_ld_asi(insn, 4, 0);
3241                     break;
3242                 case 0x11:      /* load unsigned byte alternate */
3243 #ifndef TARGET_SPARC64
3244                     if (IS_IMM)
3245                         goto illegal_insn;
3246                     if (!supervisor(dc))
3247                         goto priv_insn;
3248 #endif
3249                     gen_ld_asi(insn, 1, 0);
3250                     break;
3251                 case 0x12:      /* load unsigned halfword alternate */
3252 #ifndef TARGET_SPARC64
3253                     if (IS_IMM)
3254                         goto illegal_insn;
3255                     if (!supervisor(dc))
3256                         goto priv_insn;
3257 #endif
3258                     gen_op_check_align_T0_1();
3259                     gen_ld_asi(insn, 2, 0);
3260                     break;
3261                 case 0x13:      /* load double word alternate */
3262 #ifndef TARGET_SPARC64
3263                     if (IS_IMM)
3264                         goto illegal_insn;
3265                     if (!supervisor(dc))
3266                         goto priv_insn;
3267 #endif
3268                     if (rd & 1)
3269                         goto illegal_insn;
3270                     gen_op_check_align_T0_7();
3271                     gen_ldda_asi(insn);
3272                     gen_movl_T0_reg(rd + 1);
3273                     break;
3274                 case 0x19:      /* load signed byte alternate */
3275 #ifndef TARGET_SPARC64
3276                     if (IS_IMM)
3277                         goto illegal_insn;
3278                     if (!supervisor(dc))
3279                         goto priv_insn;
3280 #endif
3281                     gen_ld_asi(insn, 1, 1);
3282                     break;
3283                 case 0x1a:      /* load signed halfword alternate */
3284 #ifndef TARGET_SPARC64
3285                     if (IS_IMM)
3286                         goto illegal_insn;
3287                     if (!supervisor(dc))
3288                         goto priv_insn;
3289 #endif
3290                     gen_op_check_align_T0_1();
3291                     gen_ld_asi(insn, 2, 1);
3292                     break;
3293                 case 0x1d:      /* ldstuba -- XXX: should be atomically */
3294 #ifndef TARGET_SPARC64
3295                     if (IS_IMM)
3296                         goto illegal_insn;
3297                     if (!supervisor(dc))
3298                         goto priv_insn;
3299 #endif
3300                     gen_ldstub_asi(insn);
3301                     break;
3302                 case 0x1f:      /* swap reg with alt. memory. Also atomically */
3303 #ifndef TARGET_SPARC64
3304                     if (IS_IMM)
3305                         goto illegal_insn;
3306                     if (!supervisor(dc))
3307                         goto priv_insn;
3308 #endif
3309                     gen_op_check_align_T0_3();
3310                     gen_movl_reg_T1(rd);
3311                     gen_swap_asi(insn);
3312                     break;
3313
3314 #ifndef TARGET_SPARC64
3315                 case 0x30: /* ldc */
3316                 case 0x31: /* ldcsr */
3317                 case 0x33: /* lddc */
3318                     goto ncp_insn;
3319 #endif
3320 #endif
3321 #ifdef TARGET_SPARC64
3322                 case 0x08: /* V9 ldsw */
3323                     gen_op_check_align_T0_3();
3324                     gen_op_ldst(ldsw);
3325                     break;
3326                 case 0x0b: /* V9 ldx */
3327                     gen_op_check_align_T0_7();
3328                     gen_op_ldst(ldx);
3329                     break;
3330                 case 0x18: /* V9 ldswa */
3331                     gen_op_check_align_T0_3();
3332                     gen_ld_asi(insn, 4, 1);
3333                     break;
3334                 case 0x1b: /* V9 ldxa */
3335                     gen_op_check_align_T0_7();
3336                     gen_ld_asi(insn, 8, 0);
3337                     break;
3338                 case 0x2d: /* V9 prefetch, no effect */
3339                     goto skip_move;
3340                 case 0x30: /* V9 ldfa */
3341                     gen_op_check_align_T0_3();
3342                     gen_ldf_asi(insn, 4);
3343                     goto skip_move;
3344                 case 0x33: /* V9 lddfa */
3345                     gen_op_check_align_T0_3();
3346                     gen_ldf_asi(insn, 8);
3347                     goto skip_move;
3348                 case 0x3d: /* V9 prefetcha, no effect */
3349                     goto skip_move;
3350                 case 0x32: /* V9 ldqfa */
3351 #if defined(CONFIG_USER_ONLY)
3352                     gen_op_check_align_T0_3();
3353                     gen_ldf_asi(insn, 16);
3354                     goto skip_move;
3355 #else
3356                     goto nfpu_insn;
3357 #endif
3358 #endif
3359                 default:
3360                     goto illegal_insn;
3361                 }
3362                 gen_movl_T1_reg(rd);
3363 #ifdef TARGET_SPARC64
3364             skip_move: ;
3365 #endif
3366             } else if (xop >= 0x20 && xop < 0x24) {
3367                 if (gen_trap_ifnofpu(dc))
3368                     goto jmp_insn;
3369                 switch (xop) {
3370                 case 0x20:      /* load fpreg */
3371                     gen_op_check_align_T0_3();
3372                     gen_op_ldst(ldf);
3373                     gen_op_store_FT0_fpr(rd);
3374                     break;
3375                 case 0x21:      /* load fsr */
3376                     gen_op_check_align_T0_3();
3377                     gen_op_ldst(ldf);
3378                     gen_op_ldfsr();
3379                     break;
3380                 case 0x22:      /* load quad fpreg */
3381 #if defined(CONFIG_USER_ONLY)
3382                     gen_op_check_align_T0_7();
3383                     gen_op_ldst(ldqf);
3384                     gen_op_store_QT0_fpr(QFPREG(rd));
3385                     break;
3386 #else
3387                     goto nfpu_insn;
3388 #endif
3389                 case 0x23:      /* load double fpreg */
3390                     gen_op_check_align_T0_7();
3391                     gen_op_ldst(lddf);
3392                     gen_op_store_DT0_fpr(DFPREG(rd));
3393                     break;
3394                 default:
3395                     goto illegal_insn;
3396                 }
3397             } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) || \
3398                        xop == 0xe || xop == 0x1e) {
3399                 gen_movl_reg_T1(rd);
3400                 switch (xop) {
3401                 case 0x4:
3402                     gen_op_check_align_T0_3();
3403                     gen_op_ldst(st);
3404                     break;
3405                 case 0x5:
3406                     gen_op_ldst(stb);
3407                     break;
3408                 case 0x6:
3409                     gen_op_check_align_T0_1();
3410                     gen_op_ldst(sth);
3411                     break;
3412                 case 0x7:
3413                     if (rd & 1)
3414                         goto illegal_insn;
3415                     gen_op_check_align_T0_7();
3416                     flush_T2(dc);
3417                     gen_movl_reg_T2(rd + 1);
3418                     gen_op_ldst(std);
3419                     break;
3420 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
3421                 case 0x14:
3422 #ifndef TARGET_SPARC64
3423                     if (IS_IMM)
3424                         goto illegal_insn;
3425                     if (!supervisor(dc))
3426                         goto priv_insn;
3427 #endif
3428                     gen_op_check_align_T0_3();
3429                     gen_st_asi(insn, 4);
3430                     break;
3431                 case 0x15:
3432 #ifndef TARGET_SPARC64
3433                     if (IS_IMM)
3434                         goto illegal_insn;
3435                     if (!supervisor(dc))
3436                         goto priv_insn;
3437 #endif
3438                     gen_st_asi(insn, 1);
3439                     break;
3440                 case 0x16:
3441 #ifndef TARGET_SPARC64
3442                     if (IS_IMM)
3443                         goto illegal_insn;
3444                     if (!supervisor(dc))
3445                         goto priv_insn;
3446 #endif
3447                     gen_op_check_align_T0_1();
3448                     gen_st_asi(insn, 2);
3449                     break;
3450                 case 0x17:
3451 #ifndef TARGET_SPARC64
3452                     if (IS_IMM)
3453                         goto illegal_insn;
3454                     if (!supervisor(dc))
3455                         goto priv_insn;
3456 #endif
3457                     if (rd & 1)
3458                         goto illegal_insn;
3459                     gen_op_check_align_T0_7();
3460                     flush_T2(dc);
3461                     gen_movl_reg_T2(rd + 1);
3462                     gen_stda_asi(insn);
3463                     break;
3464 #endif
3465 #ifdef TARGET_SPARC64
3466                 case 0x0e: /* V9 stx */
3467                     gen_op_check_align_T0_7();
3468                     gen_op_ldst(stx);
3469                     break;
3470                 case 0x1e: /* V9 stxa */
3471                     gen_op_check_align_T0_7();
3472                     gen_st_asi(insn, 8);
3473                     break;
3474 #endif
3475                 default:
3476                     goto illegal_insn;
3477                 }
3478             } else if (xop > 0x23 && xop < 0x28) {
3479                 if (gen_trap_ifnofpu(dc))
3480                     goto jmp_insn;
3481                 switch (xop) {
3482                 case 0x24:
3483                     gen_op_check_align_T0_3();
3484                     gen_op_load_fpr_FT0(rd);
3485                     gen_op_ldst(stf);
3486                     break;
3487                 case 0x25: /* stfsr, V9 stxfsr */
3488 #ifdef CONFIG_USER_ONLY
3489                     gen_op_check_align_T0_3();
3490 #endif
3491                     gen_op_stfsr();
3492                     gen_op_ldst(stf);
3493                     break;
3494                 case 0x26:
3495 #ifdef TARGET_SPARC64
3496 #if defined(CONFIG_USER_ONLY)
3497                     /* V9 stqf, store quad fpreg */
3498                     gen_op_check_align_T0_7();
3499                     gen_op_load_fpr_QT0(QFPREG(rd));
3500                     gen_op_ldst(stqf);
3501                     break;
3502 #else
3503                     goto nfpu_insn;
3504 #endif
3505 #else /* !TARGET_SPARC64 */
3506                     /* stdfq, store floating point queue */
3507 #if defined(CONFIG_USER_ONLY)
3508                     goto illegal_insn;
3509 #else
3510                     if (!supervisor(dc))
3511                         goto priv_insn;
3512                     if (gen_trap_ifnofpu(dc))
3513                         goto jmp_insn;
3514                     goto nfq_insn;
3515 #endif
3516 #endif
3517                 case 0x27:
3518                     gen_op_check_align_T0_7();
3519                     gen_op_load_fpr_DT0(DFPREG(rd));
3520                     gen_op_ldst(stdf);
3521                     break;
3522                 default:
3523                     goto illegal_insn;
3524                 }
3525             } else if (xop > 0x33 && xop < 0x3f) {
3526                 switch (xop) {
3527 #ifdef TARGET_SPARC64
3528                 case 0x34: /* V9 stfa */
3529                     gen_op_check_align_T0_3();
3530                     gen_op_load_fpr_FT0(rd);
3531                     gen_stf_asi(insn, 4);
3532                     break;
3533                 case 0x36: /* V9 stqfa */
3534 #if defined(CONFIG_USER_ONLY)
3535                     gen_op_check_align_T0_7();
3536                     gen_op_load_fpr_QT0(QFPREG(rd));
3537                     gen_stf_asi(insn, 16);
3538                     break;
3539 #else
3540                     goto nfpu_insn;
3541 #endif
3542                 case 0x37: /* V9 stdfa */
3543                     gen_op_check_align_T0_3();
3544                     gen_op_load_fpr_DT0(DFPREG(rd));
3545                     gen_stf_asi(insn, 8);
3546                     break;
3547                 case 0x3c: /* V9 casa */
3548                     gen_op_check_align_T0_3();
3549                     flush_T2(dc);
3550                     gen_movl_reg_T2(rd);
3551                     gen_cas_asi(insn);
3552                     gen_movl_T1_reg(rd);
3553                     break;
3554                 case 0x3e: /* V9 casxa */
3555                     gen_op_check_align_T0_7();
3556                     flush_T2(dc);
3557                     gen_movl_reg_T2(rd);
3558                     gen_casx_asi(insn);
3559                     gen_movl_T1_reg(rd);
3560                     break;
3561 #else
3562                 case 0x34: /* stc */
3563                 case 0x35: /* stcsr */
3564                 case 0x36: /* stdcq */
3565                 case 0x37: /* stdc */
3566                     goto ncp_insn;
3567 #endif
3568                 default:
3569                     goto illegal_insn;
3570                 }
3571             }
3572             else
3573                 goto illegal_insn;
3574         }
3575         break;
3576     }
3577     /* default case for non jump instructions */
3578     if (dc->npc == DYNAMIC_PC) {
3579         dc->pc = DYNAMIC_PC;
3580         gen_op_next_insn();
3581     } else if (dc->npc == JUMP_PC) {
3582         /* we can do a static jump */
3583         gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1]);
3584         dc->is_br = 1;
3585     } else {
3586         dc->pc = dc->npc;
3587         dc->npc = dc->npc + 4;
3588     }
3589  jmp_insn:
3590     return;
3591  illegal_insn:
3592     save_state(dc);
3593     gen_op_exception(TT_ILL_INSN);
3594     dc->is_br = 1;
3595     return;
3596 #if !defined(CONFIG_USER_ONLY)
3597  priv_insn:
3598     save_state(dc);
3599     gen_op_exception(TT_PRIV_INSN);
3600     dc->is_br = 1;
3601     return;
3602  nfpu_insn:
3603     save_state(dc);
3604     gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
3605     dc->is_br = 1;
3606     return;
3607 #ifndef TARGET_SPARC64
3608  nfq_insn:
3609     save_state(dc);
3610     gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
3611     dc->is_br = 1;
3612     return;
3613 #endif
3614 #endif
3615 #ifndef TARGET_SPARC64
3616  ncp_insn:
3617     save_state(dc);
3618     gen_op_exception(TT_NCP_INSN);
3619     dc->is_br = 1;
3620     return;
3621 #endif
3622 }
3623
3624 static inline int gen_intermediate_code_internal(TranslationBlock * tb,
3625                                                  int spc, CPUSPARCState *env)
3626 {
3627     target_ulong pc_start, last_pc;
3628     uint16_t *gen_opc_end;
3629     DisasContext dc1, *dc = &dc1;
3630     int j, lj = -1;
3631
3632     memset(dc, 0, sizeof(DisasContext));
3633     dc->tb = tb;
3634     pc_start = tb->pc;
3635     dc->pc = pc_start;
3636     last_pc = dc->pc;
3637     dc->npc = (target_ulong) tb->cs_base;
3638     dc->mem_idx = cpu_mmu_index(env);
3639     dc->fpu_enabled = cpu_fpu_enabled(env);
3640     gen_opc_ptr = gen_opc_buf;
3641     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
3642     gen_opparam_ptr = gen_opparam_buf;
3643     nb_gen_labels = 0;
3644
3645     do {
3646         if (env->nb_breakpoints > 0) {
3647             for(j = 0; j < env->nb_breakpoints; j++) {
3648                 if (env->breakpoints[j] == dc->pc) {
3649                     if (dc->pc != pc_start)
3650                         save_state(dc);
3651                     gen_op_debug();
3652                     gen_op_movl_T0_0();
3653                     gen_op_exit_tb();
3654                     dc->is_br = 1;
3655                     goto exit_gen_loop;
3656                 }
3657             }
3658         }
3659         if (spc) {
3660             if (loglevel > 0)
3661                 fprintf(logfile, "Search PC...\n");
3662             j = gen_opc_ptr - gen_opc_buf;
3663             if (lj < j) {
3664                 lj++;
3665                 while (lj < j)
3666                     gen_opc_instr_start[lj++] = 0;
3667                 gen_opc_pc[lj] = dc->pc;
3668                 gen_opc_npc[lj] = dc->npc;
3669                 gen_opc_instr_start[lj] = 1;
3670             }
3671         }
3672         last_pc = dc->pc;
3673         disas_sparc_insn(dc);
3674
3675         if (dc->is_br)
3676             break;
3677         /* if the next PC is different, we abort now */
3678         if (dc->pc != (last_pc + 4))
3679             break;
3680         /* if we reach a page boundary, we stop generation so that the
3681            PC of a TT_TFAULT exception is always in the right page */
3682         if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
3683             break;
3684         /* if single step mode, we generate only one instruction and
3685            generate an exception */
3686         if (env->singlestep_enabled) {
3687             gen_jmp_im(dc->pc);
3688             gen_op_movl_T0_0();
3689             gen_op_exit_tb();
3690             break;
3691         }
3692     } while ((gen_opc_ptr < gen_opc_end) &&
3693              (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
3694
3695  exit_gen_loop:
3696     if (!dc->is_br) {
3697         if (dc->pc != DYNAMIC_PC &&
3698             (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
3699             /* static PC and NPC: we can use direct chaining */
3700             gen_branch(dc, dc->pc, dc->npc);
3701         } else {
3702             if (dc->pc != DYNAMIC_PC)
3703                 gen_jmp_im(dc->pc);
3704             save_npc(dc);
3705             gen_op_movl_T0_0();
3706             gen_op_exit_tb();
3707         }
3708     }
3709     *gen_opc_ptr = INDEX_op_end;
3710     if (spc) {
3711         j = gen_opc_ptr - gen_opc_buf;
3712         lj++;
3713         while (lj <= j)
3714             gen_opc_instr_start[lj++] = 0;
3715 #if 0
3716         if (loglevel > 0) {
3717             page_dump(logfile);
3718         }
3719 #endif
3720         gen_opc_jump_pc[0] = dc->jump_pc[0];
3721         gen_opc_jump_pc[1] = dc->jump_pc[1];
3722     } else {
3723         tb->size = last_pc + 4 - pc_start;
3724     }
3725 #ifdef DEBUG_DISAS
3726     if (loglevel & CPU_LOG_TB_IN_ASM) {
3727         fprintf(logfile, "--------------\n");
3728         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
3729         target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
3730         fprintf(logfile, "\n");
3731         if (loglevel & CPU_LOG_TB_OP) {
3732             fprintf(logfile, "OP:\n");
3733             dump_ops(gen_opc_buf, gen_opparam_buf);
3734             fprintf(logfile, "\n");
3735         }
3736     }
3737 #endif
3738     return 0;
3739 }
3740
3741 int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
3742 {
3743     return gen_intermediate_code_internal(tb, 0, env);
3744 }
3745
3746 int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
3747 {
3748     return gen_intermediate_code_internal(tb, 1, env);
3749 }
3750
3751 extern int ram_size;
3752
3753 void cpu_reset(CPUSPARCState *env)
3754 {
3755     tlb_flush(env, 1);
3756     env->cwp = 0;
3757     env->wim = 1;
3758     env->regwptr = env->regbase + (env->cwp * 16);
3759 #if defined(CONFIG_USER_ONLY)
3760     env->user_mode_only = 1;
3761 #ifdef TARGET_SPARC64
3762     env->cleanwin = NWINDOWS - 2;
3763     env->cansave = NWINDOWS - 2;
3764     env->pstate = PS_RMO | PS_PEF | PS_IE;
3765     env->asi = 0x82; // Primary no-fault
3766 #endif
3767 #else
3768     env->psret = 0;
3769     env->psrs = 1;
3770     env->psrps = 1;
3771 #ifdef TARGET_SPARC64
3772     env->pstate = PS_PRIV;
3773     env->hpstate = HS_PRIV;
3774     env->pc = 0x1fff0000000ULL;
3775 #else
3776     env->pc = 0;
3777     env->mmuregs[0] &= ~(MMU_E | MMU_NF);
3778     env->mmuregs[0] |= env->mmu_bm;
3779 #endif
3780     env->npc = env->pc + 4;
3781 #endif
3782 }
3783
3784 CPUSPARCState *cpu_sparc_init(const char *cpu_model)
3785 {
3786     CPUSPARCState *env;
3787     const sparc_def_t *def;
3788
3789     def = cpu_sparc_find_by_name(cpu_model);
3790     if (!def)
3791         return NULL;
3792
3793     env = qemu_mallocz(sizeof(CPUSPARCState));
3794     if (!env)
3795         return NULL;
3796     cpu_exec_init(env);
3797     env->version = def->iu_version;
3798     env->fsr = def->fpu_version;
3799 #if !defined(TARGET_SPARC64)
3800     env->mmu_bm = def->mmu_bm;
3801     env->mmuregs[0] |= def->mmu_version;
3802     cpu_sparc_set_id(env, 0);
3803 #endif
3804     cpu_reset(env);
3805     
3806     return env;
3807 }
3808
3809 void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
3810 {
3811 #if !defined(TARGET_SPARC64)
3812     env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
3813 #endif
3814 }
3815
3816 static const sparc_def_t sparc_defs[] = {
3817 #ifdef TARGET_SPARC64
3818     {
3819         .name = "Fujitsu Sparc64",
3820         .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)
3821                        | (MAXTL << 8) | (NWINDOWS - 1)),
3822         .fpu_version = 0x00000000,
3823         .mmu_version = 0,
3824     },
3825     {
3826         .name = "Fujitsu Sparc64 III",
3827         .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)
3828                        | (MAXTL << 8) | (NWINDOWS - 1)),
3829         .fpu_version = 0x00000000,
3830         .mmu_version = 0,
3831     },
3832     {
3833         .name = "Fujitsu Sparc64 IV",
3834         .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)
3835                        | (MAXTL << 8) | (NWINDOWS - 1)),
3836         .fpu_version = 0x00000000,
3837         .mmu_version = 0,
3838     },
3839     {
3840         .name = "Fujitsu Sparc64 V",
3841         .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)
3842                        | (MAXTL << 8) | (NWINDOWS - 1)),
3843         .fpu_version = 0x00000000,
3844         .mmu_version = 0,
3845     },
3846     {
3847         .name = "TI UltraSparc I",
3848         .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)
3849                        | (MAXTL << 8) | (NWINDOWS - 1)),
3850         .fpu_version = 0x00000000,
3851         .mmu_version = 0,
3852     },
3853     {
3854         .name = "TI UltraSparc II",
3855         .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)
3856                        | (MAXTL << 8) | (NWINDOWS - 1)),
3857         .fpu_version = 0x00000000,
3858         .mmu_version = 0,
3859     },
3860     {
3861         .name = "TI UltraSparc IIi",
3862         .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)
3863                        | (MAXTL << 8) | (NWINDOWS - 1)),
3864         .fpu_version = 0x00000000,
3865         .mmu_version = 0,
3866     },
3867     {
3868         .name = "TI UltraSparc IIe",
3869         .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)
3870                        | (MAXTL << 8) | (NWINDOWS - 1)),
3871         .fpu_version = 0x00000000,
3872         .mmu_version = 0,
3873     },
3874     {
3875         .name = "Sun UltraSparc III",
3876         .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)
3877                        | (MAXTL << 8) | (NWINDOWS - 1)),
3878         .fpu_version = 0x00000000,
3879         .mmu_version = 0,
3880     },
3881     {
3882         .name = "Sun UltraSparc III Cu",
3883         .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)
3884                        | (MAXTL << 8) | (NWINDOWS - 1)),
3885         .fpu_version = 0x00000000,
3886         .mmu_version = 0,
3887     },
3888     {
3889         .name = "Sun UltraSparc IIIi",
3890         .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)
3891                        | (MAXTL << 8) | (NWINDOWS - 1)),
3892         .fpu_version = 0x00000000,
3893         .mmu_version = 0,
3894     },
3895     {
3896         .name = "Sun UltraSparc IV",
3897         .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)
3898                        | (MAXTL << 8) | (NWINDOWS - 1)),
3899         .fpu_version = 0x00000000,
3900         .mmu_version = 0,
3901     },
3902     {
3903         .name = "Sun UltraSparc IV+",
3904         .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)
3905                        | (MAXTL << 8) | (NWINDOWS - 1)),
3906         .fpu_version = 0x00000000,
3907         .mmu_version = 0,
3908     },
3909     {
3910         .name = "Sun UltraSparc IIIi+",
3911         .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)
3912                        | (MAXTL << 8) | (NWINDOWS - 1)),
3913         .fpu_version = 0x00000000,
3914         .mmu_version = 0,
3915     },
3916     {
3917         .name = "NEC UltraSparc I",
3918         .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)
3919                        | (MAXTL << 8) | (NWINDOWS - 1)),
3920         .fpu_version = 0x00000000,
3921         .mmu_version = 0,
3922     },
3923 #else
3924     {
3925         .name = "Fujitsu MB86900",
3926         .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
3927         .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
3928         .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
3929         .mmu_bm = 0x00004000,
3930     },
3931     {
3932         .name = "Fujitsu MB86904",
3933         .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
3934         .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
3935         .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
3936         .mmu_bm = 0x00004000,
3937     },
3938     {
3939         .name = "Fujitsu MB86907",
3940         .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
3941         .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
3942         .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
3943         .mmu_bm = 0x00004000,
3944     },
3945     {
3946         .name = "LSI L64811",
3947         .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
3948         .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
3949         .mmu_version = 0x10 << 24,
3950         .mmu_bm = 0x00004000,
3951     },
3952     {
3953         .name = "Cypress CY7C601",
3954         .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
3955         .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
3956         .mmu_version = 0x10 << 24,
3957         .mmu_bm = 0x00004000,
3958     },
3959     {
3960         .name = "Cypress CY7C611",
3961         .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
3962         .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
3963         .mmu_version = 0x10 << 24,
3964         .mmu_bm = 0x00004000,
3965     },
3966     {
3967         .name = "TI SuperSparc II",
3968         .iu_version = 0x40000000,
3969         .fpu_version = 0 << 17,
3970         .mmu_version = 0x04000000,
3971         .mmu_bm = 0x00002000,
3972     },
3973     {
3974         .name = "TI MicroSparc I",
3975         .iu_version = 0x41000000,
3976         .fpu_version = 4 << 17,
3977         .mmu_version = 0x41000000,
3978         .mmu_bm = 0x00004000,
3979     },
3980     {
3981         .name = "TI MicroSparc II",
3982         .iu_version = 0x42000000,
3983         .fpu_version = 4 << 17,
3984         .mmu_version = 0x02000000,
3985         .mmu_bm = 0x00004000,
3986     },
3987     {
3988         .name = "TI MicroSparc IIep",
3989         .iu_version = 0x42000000,
3990         .fpu_version = 4 << 17,
3991         .mmu_version = 0x04000000,
3992         .mmu_bm = 0x00004000,
3993     },
3994     {
3995         .name = "TI SuperSparc 51",
3996         .iu_version = 0x43000000,
3997         .fpu_version = 0 << 17,
3998         .mmu_version = 0x04000000,
3999         .mmu_bm = 0x00002000,
4000     },
4001     {
4002         .name = "TI SuperSparc 61",
4003         .iu_version = 0x44000000,
4004         .fpu_version = 0 << 17,
4005         .mmu_version = 0x04000000,
4006         .mmu_bm = 0x00002000,
4007     },
4008     {
4009         .name = "Ross RT625",
4010         .iu_version = 0x1e000000,
4011         .fpu_version = 1 << 17,
4012         .mmu_version = 0x1e000000,
4013         .mmu_bm = 0x00004000,
4014     },
4015     {
4016         .name = "Ross RT620",
4017         .iu_version = 0x1f000000,
4018         .fpu_version = 1 << 17,
4019         .mmu_version = 0x1f000000,
4020         .mmu_bm = 0x00004000,
4021     },
4022     {
4023         .name = "BIT B5010",
4024         .iu_version = 0x20000000,
4025         .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
4026         .mmu_version = 0x20000000,
4027         .mmu_bm = 0x00004000,
4028     },
4029     {
4030         .name = "Matsushita MN10501",
4031         .iu_version = 0x50000000,
4032         .fpu_version = 0 << 17,
4033         .mmu_version = 0x50000000,
4034         .mmu_bm = 0x00004000,
4035     },
4036     {
4037         .name = "Weitek W8601",
4038         .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
4039         .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
4040         .mmu_version = 0x10 << 24,
4041         .mmu_bm = 0x00004000,
4042     },
4043     {
4044         .name = "LEON2",
4045         .iu_version = 0xf2000000,
4046         .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
4047         .mmu_version = 0xf2000000,
4048         .mmu_bm = 0x00004000,
4049     },
4050     {
4051         .name = "LEON3",
4052         .iu_version = 0xf3000000,
4053         .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
4054         .mmu_version = 0xf3000000,
4055         .mmu_bm = 0x00004000,
4056     },
4057 #endif
4058 };
4059
4060 static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name)
4061 {
4062     unsigned int i;
4063
4064     for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
4065         if (strcasecmp(name, sparc_defs[i].name) == 0) {
4066             return &sparc_defs[i];
4067         }
4068     }
4069     return NULL;
4070 }
4071
4072 void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
4073 {
4074     unsigned int i;
4075
4076     for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
4077         (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x\n",
4078                        sparc_defs[i].name,
4079                        sparc_defs[i].iu_version,
4080                        sparc_defs[i].fpu_version,
4081                        sparc_defs[i].mmu_version);
4082     }
4083 }
4084
4085 #define GET_FLAG(a,b) ((env->psr & a)?b:'-')
4086
4087 void cpu_dump_state(CPUState *env, FILE *f,
4088                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
4089                     int flags)
4090 {
4091     int i, x;
4092
4093     cpu_fprintf(f, "pc: " TARGET_FMT_lx "  npc: " TARGET_FMT_lx "\n", env->pc, env->npc);
4094     cpu_fprintf(f, "General Registers:\n");
4095     for (i = 0; i < 4; i++)
4096         cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
4097     cpu_fprintf(f, "\n");
4098     for (; i < 8; i++)
4099         cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
4100     cpu_fprintf(f, "\nCurrent Register Window:\n");
4101     for (x = 0; x < 3; x++) {
4102         for (i = 0; i < 4; i++)
4103             cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
4104                     (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
4105                     env->regwptr[i + x * 8]);
4106         cpu_fprintf(f, "\n");
4107         for (; i < 8; i++)
4108             cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
4109                     (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
4110                     env->regwptr[i + x * 8]);
4111         cpu_fprintf(f, "\n");
4112     }
4113     cpu_fprintf(f, "\nFloating Point Registers:\n");
4114     for (i = 0; i < 32; i++) {
4115         if ((i & 3) == 0)
4116             cpu_fprintf(f, "%%f%02d:", i);
4117         cpu_fprintf(f, " %016lf", env->fpr[i]);
4118         if ((i & 3) == 3)
4119             cpu_fprintf(f, "\n");
4120     }
4121 #ifdef TARGET_SPARC64
4122     cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d fprs: %d\n",
4123                 env->pstate, GET_CCR(env), env->asi, env->tl, env->fprs);
4124     cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d cleanwin %d cwp %d\n",
4125                 env->cansave, env->canrestore, env->otherwin, env->wstate,
4126                 env->cleanwin, NWINDOWS - 1 - env->cwp);
4127 #else
4128     cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n", GET_PSR(env),
4129             GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
4130             GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
4131             env->psrs?'S':'-', env->psrps?'P':'-',
4132             env->psret?'E':'-', env->wim);
4133 #endif
4134     cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env));
4135 }
4136
4137 #if defined(CONFIG_USER_ONLY)
4138 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
4139 {
4140     return addr;
4141 }
4142
4143 #else
4144 extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
4145                                  int *access_index, target_ulong address, int rw,
4146                                  int mmu_idx);
4147
4148 target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
4149 {
4150     target_phys_addr_t phys_addr;
4151     int prot, access_index;
4152
4153     if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2, 0) != 0)
4154         if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 0, 0) != 0)
4155             return -1;
4156     if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED)
4157         return -1;
4158     return phys_addr;
4159 }
4160 #endif
4161
4162 void helper_flush(target_ulong addr)
4163 {
4164     addr &= ~7;
4165     tb_invalidate_page_range(addr, addr + 8);
4166 }