Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ 50d3eeae

History | View | Annotate | Download (75.2 kB)

1 7a3f1944 bellard
/*
2 7a3f1944 bellard
   SPARC translation
3 7a3f1944 bellard

4 7a3f1944 bellard
   Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
5 3475187d bellard
   Copyright (C) 2003-2005 Fabrice Bellard
6 7a3f1944 bellard

7 7a3f1944 bellard
   This library is free software; you can redistribute it and/or
8 7a3f1944 bellard
   modify it under the terms of the GNU Lesser General Public
9 7a3f1944 bellard
   License as published by the Free Software Foundation; either
10 7a3f1944 bellard
   version 2 of the License, or (at your option) any later version.
11 7a3f1944 bellard

12 7a3f1944 bellard
   This library is distributed in the hope that it will be useful,
13 7a3f1944 bellard
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14 7a3f1944 bellard
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 7a3f1944 bellard
   Lesser General Public License for more details.
16 7a3f1944 bellard

17 7a3f1944 bellard
   You should have received a copy of the GNU Lesser General Public
18 7a3f1944 bellard
   License along with this library; if not, write to the Free Software
19 7a3f1944 bellard
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 7a3f1944 bellard
 */
21 7a3f1944 bellard
22 7a3f1944 bellard
/*
23 7a3f1944 bellard
   TODO-list:
24 7a3f1944 bellard

25 3475187d bellard
   Rest of V9 instructions, VIS instructions
26 bd497938 bellard
   NPC/PC static optimisations (use JUMP_TB when possible)
27 7a3f1944 bellard
   Optimize synthetic instructions
28 3475187d bellard
   Optional alignment check
29 3475187d bellard
   128-bit float
30 3475187d bellard
   Tagged add/sub
31 bd497938 bellard
*/
32 7a3f1944 bellard
33 7a3f1944 bellard
#include <stdarg.h>
34 7a3f1944 bellard
#include <stdlib.h>
35 7a3f1944 bellard
#include <stdio.h>
36 7a3f1944 bellard
#include <string.h>
37 7a3f1944 bellard
#include <inttypes.h>
38 7a3f1944 bellard
39 7a3f1944 bellard
#include "cpu.h"
40 7a3f1944 bellard
#include "exec-all.h"
41 7a3f1944 bellard
#include "disas.h"
42 7a3f1944 bellard
43 7a3f1944 bellard
#define DEBUG_DISAS
44 7a3f1944 bellard
45 72cbca10 bellard
#define DYNAMIC_PC  1 /* dynamic pc value */
46 72cbca10 bellard
#define JUMP_PC     2 /* dynamic pc value which takes only two values
47 72cbca10 bellard
                         according to jump_pc[T2] */
48 72cbca10 bellard
49 7a3f1944 bellard
typedef struct DisasContext {
50 72cbca10 bellard
    target_ulong pc;        /* current Program Counter: integer or DYNAMIC_PC */
51 72cbca10 bellard
    target_ulong npc;        /* next PC: integer or DYNAMIC_PC or JUMP_PC */
52 72cbca10 bellard
    target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
53 cf495bcf bellard
    int is_br;
54 e8af50a3 bellard
    int mem_idx;
55 a80dde08 bellard
    int fpu_enabled;
56 cf495bcf bellard
    struct TranslationBlock *tb;
57 7a3f1944 bellard
} DisasContext;
58 7a3f1944 bellard
59 7a3f1944 bellard
static uint16_t *gen_opc_ptr;
60 7a3f1944 bellard
static uint32_t *gen_opparam_ptr;
61 7a3f1944 bellard
extern FILE *logfile;
62 7a3f1944 bellard
extern int loglevel;
63 7a3f1944 bellard
64 7a3f1944 bellard
enum {
65 7a3f1944 bellard
#define DEF(s,n,copy_size) INDEX_op_ ## s,
66 7a3f1944 bellard
#include "opc.h"
67 7a3f1944 bellard
#undef DEF
68 cf495bcf bellard
    NB_OPS
69 7a3f1944 bellard
};
70 7a3f1944 bellard
71 7a3f1944 bellard
#include "gen-op.h"
72 7a3f1944 bellard
73 3475187d bellard
// This function uses non-native bit order
74 7a3f1944 bellard
#define GET_FIELD(X, FROM, TO) \
75 7a3f1944 bellard
  ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
76 7a3f1944 bellard
77 3475187d bellard
// This function uses the order in the manuals, i.e. bit 0 is 2^0
78 3475187d bellard
#define GET_FIELD_SP(X, FROM, TO) \
79 3475187d bellard
    GET_FIELD(X, 31 - (TO), 31 - (FROM))
80 3475187d bellard
81 3475187d bellard
#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
82 3475187d bellard
#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), 32 - ((b) - (a) + 1))
83 3475187d bellard
84 3475187d bellard
#ifdef TARGET_SPARC64
85 3475187d bellard
#define DFPREG(r) (((r & 1) << 6) | (r & 0x1e))
86 3475187d bellard
#else
87 3475187d bellard
#define DFPREG(r) (r)
88 3475187d bellard
#endif
89 3475187d bellard
90 83469015 bellard
#ifdef USE_DIRECT_JUMP
91 83469015 bellard
#define TBPARAM(x)
92 83469015 bellard
#else
93 83469015 bellard
#define TBPARAM(x) (long)(x)
94 83469015 bellard
#endif
95 83469015 bellard
96 3475187d bellard
static int sign_extend(int x, int len)
97 3475187d bellard
{
98 3475187d bellard
    len = 32 - len;
99 3475187d bellard
    return (x << len) >> len;
100 3475187d bellard
}
101 3475187d bellard
102 7a3f1944 bellard
#define IS_IMM (insn & (1<<13))
103 7a3f1944 bellard
104 cf495bcf bellard
static void disas_sparc_insn(DisasContext * dc);
105 7a3f1944 bellard
106 7a3f1944 bellard
static GenOpFunc *gen_op_movl_TN_reg[2][32] = {
107 cf495bcf bellard
    {
108 cf495bcf bellard
     gen_op_movl_g0_T0,
109 cf495bcf bellard
     gen_op_movl_g1_T0,
110 cf495bcf bellard
     gen_op_movl_g2_T0,
111 cf495bcf bellard
     gen_op_movl_g3_T0,
112 cf495bcf bellard
     gen_op_movl_g4_T0,
113 cf495bcf bellard
     gen_op_movl_g5_T0,
114 cf495bcf bellard
     gen_op_movl_g6_T0,
115 cf495bcf bellard
     gen_op_movl_g7_T0,
116 cf495bcf bellard
     gen_op_movl_o0_T0,
117 cf495bcf bellard
     gen_op_movl_o1_T0,
118 cf495bcf bellard
     gen_op_movl_o2_T0,
119 cf495bcf bellard
     gen_op_movl_o3_T0,
120 cf495bcf bellard
     gen_op_movl_o4_T0,
121 cf495bcf bellard
     gen_op_movl_o5_T0,
122 cf495bcf bellard
     gen_op_movl_o6_T0,
123 cf495bcf bellard
     gen_op_movl_o7_T0,
124 cf495bcf bellard
     gen_op_movl_l0_T0,
125 cf495bcf bellard
     gen_op_movl_l1_T0,
126 cf495bcf bellard
     gen_op_movl_l2_T0,
127 cf495bcf bellard
     gen_op_movl_l3_T0,
128 cf495bcf bellard
     gen_op_movl_l4_T0,
129 cf495bcf bellard
     gen_op_movl_l5_T0,
130 cf495bcf bellard
     gen_op_movl_l6_T0,
131 cf495bcf bellard
     gen_op_movl_l7_T0,
132 cf495bcf bellard
     gen_op_movl_i0_T0,
133 cf495bcf bellard
     gen_op_movl_i1_T0,
134 cf495bcf bellard
     gen_op_movl_i2_T0,
135 cf495bcf bellard
     gen_op_movl_i3_T0,
136 cf495bcf bellard
     gen_op_movl_i4_T0,
137 cf495bcf bellard
     gen_op_movl_i5_T0,
138 cf495bcf bellard
     gen_op_movl_i6_T0,
139 cf495bcf bellard
     gen_op_movl_i7_T0,
140 cf495bcf bellard
     },
141 cf495bcf bellard
    {
142 cf495bcf bellard
     gen_op_movl_g0_T1,
143 cf495bcf bellard
     gen_op_movl_g1_T1,
144 cf495bcf bellard
     gen_op_movl_g2_T1,
145 cf495bcf bellard
     gen_op_movl_g3_T1,
146 cf495bcf bellard
     gen_op_movl_g4_T1,
147 cf495bcf bellard
     gen_op_movl_g5_T1,
148 cf495bcf bellard
     gen_op_movl_g6_T1,
149 cf495bcf bellard
     gen_op_movl_g7_T1,
150 cf495bcf bellard
     gen_op_movl_o0_T1,
151 cf495bcf bellard
     gen_op_movl_o1_T1,
152 cf495bcf bellard
     gen_op_movl_o2_T1,
153 cf495bcf bellard
     gen_op_movl_o3_T1,
154 cf495bcf bellard
     gen_op_movl_o4_T1,
155 cf495bcf bellard
     gen_op_movl_o5_T1,
156 cf495bcf bellard
     gen_op_movl_o6_T1,
157 cf495bcf bellard
     gen_op_movl_o7_T1,
158 cf495bcf bellard
     gen_op_movl_l0_T1,
159 cf495bcf bellard
     gen_op_movl_l1_T1,
160 cf495bcf bellard
     gen_op_movl_l2_T1,
161 cf495bcf bellard
     gen_op_movl_l3_T1,
162 cf495bcf bellard
     gen_op_movl_l4_T1,
163 cf495bcf bellard
     gen_op_movl_l5_T1,
164 cf495bcf bellard
     gen_op_movl_l6_T1,
165 cf495bcf bellard
     gen_op_movl_l7_T1,
166 cf495bcf bellard
     gen_op_movl_i0_T1,
167 cf495bcf bellard
     gen_op_movl_i1_T1,
168 cf495bcf bellard
     gen_op_movl_i2_T1,
169 cf495bcf bellard
     gen_op_movl_i3_T1,
170 cf495bcf bellard
     gen_op_movl_i4_T1,
171 cf495bcf bellard
     gen_op_movl_i5_T1,
172 cf495bcf bellard
     gen_op_movl_i6_T1,
173 cf495bcf bellard
     gen_op_movl_i7_T1,
174 cf495bcf bellard
     }
175 7a3f1944 bellard
};
176 7a3f1944 bellard
177 7a3f1944 bellard
static GenOpFunc *gen_op_movl_reg_TN[3][32] = {
178 cf495bcf bellard
    {
179 cf495bcf bellard
     gen_op_movl_T0_g0,
180 cf495bcf bellard
     gen_op_movl_T0_g1,
181 cf495bcf bellard
     gen_op_movl_T0_g2,
182 cf495bcf bellard
     gen_op_movl_T0_g3,
183 cf495bcf bellard
     gen_op_movl_T0_g4,
184 cf495bcf bellard
     gen_op_movl_T0_g5,
185 cf495bcf bellard
     gen_op_movl_T0_g6,
186 cf495bcf bellard
     gen_op_movl_T0_g7,
187 cf495bcf bellard
     gen_op_movl_T0_o0,
188 cf495bcf bellard
     gen_op_movl_T0_o1,
189 cf495bcf bellard
     gen_op_movl_T0_o2,
190 cf495bcf bellard
     gen_op_movl_T0_o3,
191 cf495bcf bellard
     gen_op_movl_T0_o4,
192 cf495bcf bellard
     gen_op_movl_T0_o5,
193 cf495bcf bellard
     gen_op_movl_T0_o6,
194 cf495bcf bellard
     gen_op_movl_T0_o7,
195 cf495bcf bellard
     gen_op_movl_T0_l0,
196 cf495bcf bellard
     gen_op_movl_T0_l1,
197 cf495bcf bellard
     gen_op_movl_T0_l2,
198 cf495bcf bellard
     gen_op_movl_T0_l3,
199 cf495bcf bellard
     gen_op_movl_T0_l4,
200 cf495bcf bellard
     gen_op_movl_T0_l5,
201 cf495bcf bellard
     gen_op_movl_T0_l6,
202 cf495bcf bellard
     gen_op_movl_T0_l7,
203 cf495bcf bellard
     gen_op_movl_T0_i0,
204 cf495bcf bellard
     gen_op_movl_T0_i1,
205 cf495bcf bellard
     gen_op_movl_T0_i2,
206 cf495bcf bellard
     gen_op_movl_T0_i3,
207 cf495bcf bellard
     gen_op_movl_T0_i4,
208 cf495bcf bellard
     gen_op_movl_T0_i5,
209 cf495bcf bellard
     gen_op_movl_T0_i6,
210 cf495bcf bellard
     gen_op_movl_T0_i7,
211 cf495bcf bellard
     },
212 cf495bcf bellard
    {
213 cf495bcf bellard
     gen_op_movl_T1_g0,
214 cf495bcf bellard
     gen_op_movl_T1_g1,
215 cf495bcf bellard
     gen_op_movl_T1_g2,
216 cf495bcf bellard
     gen_op_movl_T1_g3,
217 cf495bcf bellard
     gen_op_movl_T1_g4,
218 cf495bcf bellard
     gen_op_movl_T1_g5,
219 cf495bcf bellard
     gen_op_movl_T1_g6,
220 cf495bcf bellard
     gen_op_movl_T1_g7,
221 cf495bcf bellard
     gen_op_movl_T1_o0,
222 cf495bcf bellard
     gen_op_movl_T1_o1,
223 cf495bcf bellard
     gen_op_movl_T1_o2,
224 cf495bcf bellard
     gen_op_movl_T1_o3,
225 cf495bcf bellard
     gen_op_movl_T1_o4,
226 cf495bcf bellard
     gen_op_movl_T1_o5,
227 cf495bcf bellard
     gen_op_movl_T1_o6,
228 cf495bcf bellard
     gen_op_movl_T1_o7,
229 cf495bcf bellard
     gen_op_movl_T1_l0,
230 cf495bcf bellard
     gen_op_movl_T1_l1,
231 cf495bcf bellard
     gen_op_movl_T1_l2,
232 cf495bcf bellard
     gen_op_movl_T1_l3,
233 cf495bcf bellard
     gen_op_movl_T1_l4,
234 cf495bcf bellard
     gen_op_movl_T1_l5,
235 cf495bcf bellard
     gen_op_movl_T1_l6,
236 cf495bcf bellard
     gen_op_movl_T1_l7,
237 cf495bcf bellard
     gen_op_movl_T1_i0,
238 cf495bcf bellard
     gen_op_movl_T1_i1,
239 cf495bcf bellard
     gen_op_movl_T1_i2,
240 cf495bcf bellard
     gen_op_movl_T1_i3,
241 cf495bcf bellard
     gen_op_movl_T1_i4,
242 cf495bcf bellard
     gen_op_movl_T1_i5,
243 cf495bcf bellard
     gen_op_movl_T1_i6,
244 cf495bcf bellard
     gen_op_movl_T1_i7,
245 cf495bcf bellard
     },
246 cf495bcf bellard
    {
247 cf495bcf bellard
     gen_op_movl_T2_g0,
248 cf495bcf bellard
     gen_op_movl_T2_g1,
249 cf495bcf bellard
     gen_op_movl_T2_g2,
250 cf495bcf bellard
     gen_op_movl_T2_g3,
251 cf495bcf bellard
     gen_op_movl_T2_g4,
252 cf495bcf bellard
     gen_op_movl_T2_g5,
253 cf495bcf bellard
     gen_op_movl_T2_g6,
254 cf495bcf bellard
     gen_op_movl_T2_g7,
255 cf495bcf bellard
     gen_op_movl_T2_o0,
256 cf495bcf bellard
     gen_op_movl_T2_o1,
257 cf495bcf bellard
     gen_op_movl_T2_o2,
258 cf495bcf bellard
     gen_op_movl_T2_o3,
259 cf495bcf bellard
     gen_op_movl_T2_o4,
260 cf495bcf bellard
     gen_op_movl_T2_o5,
261 cf495bcf bellard
     gen_op_movl_T2_o6,
262 cf495bcf bellard
     gen_op_movl_T2_o7,
263 cf495bcf bellard
     gen_op_movl_T2_l0,
264 cf495bcf bellard
     gen_op_movl_T2_l1,
265 cf495bcf bellard
     gen_op_movl_T2_l2,
266 cf495bcf bellard
     gen_op_movl_T2_l3,
267 cf495bcf bellard
     gen_op_movl_T2_l4,
268 cf495bcf bellard
     gen_op_movl_T2_l5,
269 cf495bcf bellard
     gen_op_movl_T2_l6,
270 cf495bcf bellard
     gen_op_movl_T2_l7,
271 cf495bcf bellard
     gen_op_movl_T2_i0,
272 cf495bcf bellard
     gen_op_movl_T2_i1,
273 cf495bcf bellard
     gen_op_movl_T2_i2,
274 cf495bcf bellard
     gen_op_movl_T2_i3,
275 cf495bcf bellard
     gen_op_movl_T2_i4,
276 cf495bcf bellard
     gen_op_movl_T2_i5,
277 cf495bcf bellard
     gen_op_movl_T2_i6,
278 cf495bcf bellard
     gen_op_movl_T2_i7,
279 cf495bcf bellard
     }
280 7a3f1944 bellard
};
281 7a3f1944 bellard
282 7a3f1944 bellard
static GenOpFunc1 *gen_op_movl_TN_im[3] = {
283 cf495bcf bellard
    gen_op_movl_T0_im,
284 cf495bcf bellard
    gen_op_movl_T1_im,
285 cf495bcf bellard
    gen_op_movl_T2_im
286 7a3f1944 bellard
};
287 7a3f1944 bellard
288 3475187d bellard
// Sign extending version
289 3475187d bellard
static GenOpFunc1 * const gen_op_movl_TN_sim[3] = {
290 3475187d bellard
    gen_op_movl_T0_sim,
291 3475187d bellard
    gen_op_movl_T1_sim,
292 3475187d bellard
    gen_op_movl_T2_sim
293 3475187d bellard
};
294 3475187d bellard
295 3475187d bellard
#ifdef TARGET_SPARC64
296 3475187d bellard
#define GEN32(func, NAME) \
297 3475187d bellard
static GenOpFunc *NAME ## _table [64] = {                                     \
298 3475187d bellard
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
299 3475187d bellard
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
300 3475187d bellard
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
301 3475187d bellard
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
302 3475187d bellard
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
303 3475187d bellard
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
304 3475187d bellard
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
305 3475187d bellard
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
306 3475187d bellard
NAME ## 32, 0, NAME ## 34, 0, NAME ## 36, 0, NAME ## 38, 0,                   \
307 3475187d bellard
NAME ## 40, 0, NAME ## 42, 0, NAME ## 44, 0, NAME ## 46, 0,                   \
308 3475187d bellard
NAME ## 48, 0, NAME ## 50, 0, NAME ## 52, 0, NAME ## 54, 0,                   \
309 3475187d bellard
NAME ## 56, 0, NAME ## 58, 0, NAME ## 60, 0, NAME ## 62, 0,                   \
310 3475187d bellard
};                                                                            \
311 3475187d bellard
static inline void func(int n)                                                \
312 3475187d bellard
{                                                                             \
313 3475187d bellard
    NAME ## _table[n]();                                                      \
314 3475187d bellard
}
315 3475187d bellard
#else
316 e8af50a3 bellard
#define GEN32(func, NAME) \
317 e8af50a3 bellard
static GenOpFunc *NAME ## _table [32] = {                                     \
318 e8af50a3 bellard
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
319 e8af50a3 bellard
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
320 e8af50a3 bellard
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
321 e8af50a3 bellard
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
322 e8af50a3 bellard
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
323 e8af50a3 bellard
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
324 e8af50a3 bellard
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
325 e8af50a3 bellard
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
326 e8af50a3 bellard
};                                                                            \
327 e8af50a3 bellard
static inline void func(int n)                                                \
328 e8af50a3 bellard
{                                                                             \
329 e8af50a3 bellard
    NAME ## _table[n]();                                                      \
330 e8af50a3 bellard
}
331 3475187d bellard
#endif
332 e8af50a3 bellard
333 e8af50a3 bellard
/* floating point registers moves */
334 e8af50a3 bellard
GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fprf);
335 e8af50a3 bellard
GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fprf);
336 e8af50a3 bellard
GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fprf);
337 e8af50a3 bellard
GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fprf);
338 e8af50a3 bellard
339 e8af50a3 bellard
GEN32(gen_op_load_fpr_DT0, gen_op_load_fpr_DT0_fprf);
340 e8af50a3 bellard
GEN32(gen_op_load_fpr_DT1, gen_op_load_fpr_DT1_fprf);
341 e8af50a3 bellard
GEN32(gen_op_store_DT0_fpr, gen_op_store_DT0_fpr_fprf);
342 e8af50a3 bellard
GEN32(gen_op_store_DT1_fpr, gen_op_store_DT1_fpr_fprf);
343 e8af50a3 bellard
344 3475187d bellard
#ifdef TARGET_SPARC64
345 3475187d bellard
// 'a' versions allowed to user depending on asi
346 3475187d bellard
#if defined(CONFIG_USER_ONLY)
347 3475187d bellard
#define supervisor(dc) 0
348 3475187d bellard
#define gen_op_ldst(name)        gen_op_##name##_raw()
349 3475187d bellard
#define OP_LD_TABLE(width)                                                \
350 3475187d bellard
    static void gen_op_##width##a(int insn, int is_ld, int size, int sign) \
351 3475187d bellard
    {                                                                        \
352 3475187d bellard
        int asi, offset;                                                \
353 3475187d bellard
                                                                        \
354 3475187d bellard
        if (IS_IMM) {                                                        \
355 3475187d bellard
            offset = GET_FIELD(insn, 25, 31);                                \
356 3475187d bellard
            if (is_ld)                                                        \
357 3475187d bellard
                gen_op_ld_asi_reg(offset, size, sign);                        \
358 3475187d bellard
            else                                                        \
359 3475187d bellard
                gen_op_st_asi_reg(offset, size, sign);                        \
360 3475187d bellard
            return;                                                        \
361 3475187d bellard
        }                                                                \
362 3475187d bellard
        asi = GET_FIELD(insn, 19, 26);                                        \
363 3475187d bellard
        switch (asi) {                                                        \
364 3475187d bellard
        case 0x80: /* Primary address space */                                \
365 3475187d bellard
            gen_op_##width##_raw();                                        \
366 3475187d bellard
            break;                                                        \
367 725cb90b bellard
        case 0x82: /* Primary address space, non-faulting load */       \
368 725cb90b bellard
            gen_op_##width##_raw();                                        \
369 725cb90b bellard
            break;                                                        \
370 3475187d bellard
        default:                                                        \
371 3475187d bellard
            break;                                                        \
372 3475187d bellard
        }                                                                \
373 3475187d bellard
    }
374 3475187d bellard
375 3475187d bellard
#else
376 3475187d bellard
#define gen_op_ldst(name)        (*gen_op_##name[dc->mem_idx])()
377 3475187d bellard
#define OP_LD_TABLE(width)                                                \
378 3475187d bellard
    static GenOpFunc *gen_op_##width[] = {                                \
379 3475187d bellard
        &gen_op_##width##_user,                                                \
380 3475187d bellard
        &gen_op_##width##_kernel,                                        \
381 3475187d bellard
    };                                                                        \
382 3475187d bellard
                                                                        \
383 3475187d bellard
    static void gen_op_##width##a(int insn, int is_ld, int size, int sign) \
384 3475187d bellard
    {                                                                        \
385 3475187d bellard
        int asi, offset;                                                \
386 3475187d bellard
                                                                        \
387 3475187d bellard
        if (IS_IMM) {                                                        \
388 3475187d bellard
            offset = GET_FIELD(insn, 25, 31);                                \
389 3475187d bellard
            if (is_ld)                                                        \
390 3475187d bellard
                gen_op_ld_asi_reg(offset, size, sign);                        \
391 3475187d bellard
            else                                                        \
392 3475187d bellard
                gen_op_st_asi_reg(offset, size, sign);                        \
393 3475187d bellard
            return;                                                        \
394 3475187d bellard
        }                                                                \
395 3475187d bellard
        asi = GET_FIELD(insn, 19, 26);                                        \
396 3475187d bellard
        if (is_ld)                                                        \
397 3475187d bellard
            gen_op_ld_asi(asi, size, sign);                                \
398 3475187d bellard
        else                                                                \
399 3475187d bellard
            gen_op_st_asi(asi, size, sign);                                \
400 3475187d bellard
    }
401 3475187d bellard
402 3475187d bellard
#define supervisor(dc) (dc->mem_idx == 1)
403 3475187d bellard
#endif
404 3475187d bellard
#else
405 e8af50a3 bellard
#if defined(CONFIG_USER_ONLY)
406 e8af50a3 bellard
#define gen_op_ldst(name)        gen_op_##name##_raw()
407 0fa85d43 bellard
#define OP_LD_TABLE(width)
408 e8af50a3 bellard
#define supervisor(dc) 0
409 e8af50a3 bellard
#else
410 e8af50a3 bellard
#define gen_op_ldst(name)        (*gen_op_##name[dc->mem_idx])()
411 e8af50a3 bellard
#define OP_LD_TABLE(width)                                                      \
412 e8af50a3 bellard
static GenOpFunc *gen_op_##width[] = {                                        \
413 e8af50a3 bellard
    &gen_op_##width##_user,                                                   \
414 e8af50a3 bellard
    &gen_op_##width##_kernel,                                                 \
415 e8af50a3 bellard
};                                                                            \
416 e8af50a3 bellard
                                                                              \
417 e8af50a3 bellard
static void gen_op_##width##a(int insn, int is_ld, int size, int sign)        \
418 e8af50a3 bellard
{                                                                             \
419 e8af50a3 bellard
    int asi;                                                                  \
420 e8af50a3 bellard
                                                                              \
421 e8af50a3 bellard
    asi = GET_FIELD(insn, 19, 26);                                            \
422 e8af50a3 bellard
    switch (asi) {                                                            \
423 e8af50a3 bellard
        case 10: /* User data access */                                       \
424 e8af50a3 bellard
            gen_op_##width##_user();                                          \
425 e8af50a3 bellard
            break;                                                            \
426 e8af50a3 bellard
        case 11: /* Supervisor data access */                                 \
427 e8af50a3 bellard
            gen_op_##width##_kernel();                                        \
428 e8af50a3 bellard
            break;                                                            \
429 e8af50a3 bellard
        case 0x20 ... 0x2f: /* MMU passthrough */                              \
430 e8af50a3 bellard
            if (is_ld)                                                        \
431 e8af50a3 bellard
                gen_op_ld_asi(asi, size, sign);                                      \
432 e8af50a3 bellard
            else                                                              \
433 e8af50a3 bellard
                gen_op_st_asi(asi, size, sign);                                      \
434 e8af50a3 bellard
            break;                                                            \
435 e8af50a3 bellard
        default:                                                              \
436 e8af50a3 bellard
            if (is_ld)                                                        \
437 e8af50a3 bellard
                gen_op_ld_asi(asi, size, sign);                                      \
438 e8af50a3 bellard
            else                                                              \
439 e8af50a3 bellard
                gen_op_st_asi(asi, size, sign);                                      \
440 e8af50a3 bellard
            break;                                                            \
441 e8af50a3 bellard
    }                                                                         \
442 e8af50a3 bellard
}
443 e8af50a3 bellard
444 e8af50a3 bellard
#define supervisor(dc) (dc->mem_idx == 1)
445 e8af50a3 bellard
#endif
446 3475187d bellard
#endif
447 e8af50a3 bellard
448 e8af50a3 bellard
OP_LD_TABLE(ld);
449 e8af50a3 bellard
OP_LD_TABLE(st);
450 e8af50a3 bellard
OP_LD_TABLE(ldub);
451 e8af50a3 bellard
OP_LD_TABLE(lduh);
452 e8af50a3 bellard
OP_LD_TABLE(ldsb);
453 e8af50a3 bellard
OP_LD_TABLE(ldsh);
454 e8af50a3 bellard
OP_LD_TABLE(stb);
455 e8af50a3 bellard
OP_LD_TABLE(sth);
456 e8af50a3 bellard
OP_LD_TABLE(std);
457 e8af50a3 bellard
OP_LD_TABLE(ldstub);
458 e8af50a3 bellard
OP_LD_TABLE(swap);
459 e8af50a3 bellard
OP_LD_TABLE(ldd);
460 e8af50a3 bellard
OP_LD_TABLE(stf);
461 e8af50a3 bellard
OP_LD_TABLE(stdf);
462 e8af50a3 bellard
OP_LD_TABLE(ldf);
463 e8af50a3 bellard
OP_LD_TABLE(lddf);
464 e8af50a3 bellard
465 3475187d bellard
#ifdef TARGET_SPARC64
466 3475187d bellard
OP_LD_TABLE(ldsw);
467 3475187d bellard
OP_LD_TABLE(ldx);
468 3475187d bellard
OP_LD_TABLE(stx);
469 3475187d bellard
OP_LD_TABLE(cas);
470 3475187d bellard
OP_LD_TABLE(casx);
471 3475187d bellard
#endif
472 3475187d bellard
473 3475187d bellard
static inline void gen_movl_imm_TN(int reg, uint32_t imm)
474 7a3f1944 bellard
{
475 83469015 bellard
    gen_op_movl_TN_im[reg](imm);
476 7a3f1944 bellard
}
477 7a3f1944 bellard
478 3475187d bellard
static inline void gen_movl_imm_T1(uint32_t val)
479 7a3f1944 bellard
{
480 cf495bcf bellard
    gen_movl_imm_TN(1, val);
481 7a3f1944 bellard
}
482 7a3f1944 bellard
483 3475187d bellard
static inline void gen_movl_imm_T0(uint32_t val)
484 7a3f1944 bellard
{
485 cf495bcf bellard
    gen_movl_imm_TN(0, val);
486 7a3f1944 bellard
}
487 7a3f1944 bellard
488 3475187d bellard
static inline void gen_movl_simm_TN(int reg, int32_t imm)
489 3475187d bellard
{
490 3475187d bellard
    gen_op_movl_TN_sim[reg](imm);
491 3475187d bellard
}
492 3475187d bellard
493 3475187d bellard
static inline void gen_movl_simm_T1(int32_t val)
494 3475187d bellard
{
495 3475187d bellard
    gen_movl_simm_TN(1, val);
496 3475187d bellard
}
497 3475187d bellard
498 3475187d bellard
static inline void gen_movl_simm_T0(int32_t val)
499 3475187d bellard
{
500 3475187d bellard
    gen_movl_simm_TN(0, val);
501 3475187d bellard
}
502 3475187d bellard
503 cf495bcf bellard
static inline void gen_movl_reg_TN(int reg, int t)
504 7a3f1944 bellard
{
505 cf495bcf bellard
    if (reg)
506 cf495bcf bellard
        gen_op_movl_reg_TN[t][reg] ();
507 cf495bcf bellard
    else
508 cf495bcf bellard
        gen_movl_imm_TN(t, 0);
509 7a3f1944 bellard
}
510 7a3f1944 bellard
511 cf495bcf bellard
static inline void gen_movl_reg_T0(int reg)
512 7a3f1944 bellard
{
513 cf495bcf bellard
    gen_movl_reg_TN(reg, 0);
514 7a3f1944 bellard
}
515 7a3f1944 bellard
516 cf495bcf bellard
static inline void gen_movl_reg_T1(int reg)
517 7a3f1944 bellard
{
518 cf495bcf bellard
    gen_movl_reg_TN(reg, 1);
519 7a3f1944 bellard
}
520 7a3f1944 bellard
521 cf495bcf bellard
static inline void gen_movl_reg_T2(int reg)
522 7a3f1944 bellard
{
523 cf495bcf bellard
    gen_movl_reg_TN(reg, 2);
524 7a3f1944 bellard
}
525 7a3f1944 bellard
526 cf495bcf bellard
static inline void gen_movl_TN_reg(int reg, int t)
527 7a3f1944 bellard
{
528 cf495bcf bellard
    if (reg)
529 cf495bcf bellard
        gen_op_movl_TN_reg[t][reg] ();
530 7a3f1944 bellard
}
531 7a3f1944 bellard
532 cf495bcf bellard
static inline void gen_movl_T0_reg(int reg)
533 7a3f1944 bellard
{
534 cf495bcf bellard
    gen_movl_TN_reg(reg, 0);
535 7a3f1944 bellard
}
536 7a3f1944 bellard
537 cf495bcf bellard
static inline void gen_movl_T1_reg(int reg)
538 7a3f1944 bellard
{
539 cf495bcf bellard
    gen_movl_TN_reg(reg, 1);
540 7a3f1944 bellard
}
541 7a3f1944 bellard
542 3475187d bellard
static inline void gen_jmp_im(target_ulong pc)
543 3475187d bellard
{
544 3475187d bellard
#ifdef TARGET_SPARC64
545 3475187d bellard
    if (pc == (uint32_t)pc) {
546 3475187d bellard
        gen_op_jmp_im(pc);
547 3475187d bellard
    } else {
548 3475187d bellard
        gen_op_jmp_im64(pc >> 32, pc);
549 3475187d bellard
    }
550 3475187d bellard
#else
551 3475187d bellard
    gen_op_jmp_im(pc);
552 3475187d bellard
#endif
553 3475187d bellard
}
554 3475187d bellard
555 3475187d bellard
static inline void gen_movl_npc_im(target_ulong npc)
556 3475187d bellard
{
557 3475187d bellard
#ifdef TARGET_SPARC64
558 3475187d bellard
    if (npc == (uint32_t)npc) {
559 3475187d bellard
        gen_op_movl_npc_im(npc);
560 3475187d bellard
    } else {
561 3475187d bellard
        gen_op_movq_npc_im64(npc >> 32, npc);
562 3475187d bellard
    }
563 3475187d bellard
#else
564 3475187d bellard
    gen_op_movl_npc_im(npc);
565 3475187d bellard
#endif
566 3475187d bellard
}
567 3475187d bellard
568 6e256c93 bellard
static inline void gen_goto_tb(DisasContext *s, int tb_num, 
569 6e256c93 bellard
                               target_ulong pc, target_ulong npc)
570 6e256c93 bellard
{
571 6e256c93 bellard
    TranslationBlock *tb;
572 6e256c93 bellard
573 6e256c93 bellard
    tb = s->tb;
574 6e256c93 bellard
    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
575 6e256c93 bellard
        (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK))  {
576 6e256c93 bellard
        /* jump to same page: we can use a direct jump */
577 6e256c93 bellard
        if (tb_num == 0)
578 6e256c93 bellard
            gen_op_goto_tb0(TBPARAM(tb));
579 6e256c93 bellard
        else
580 6e256c93 bellard
            gen_op_goto_tb1(TBPARAM(tb));
581 6e256c93 bellard
        gen_jmp_im(pc);
582 6e256c93 bellard
        gen_movl_npc_im(npc);
583 6e256c93 bellard
        gen_op_movl_T0_im((long)tb + tb_num);
584 6e256c93 bellard
        gen_op_exit_tb();
585 6e256c93 bellard
    } else {
586 6e256c93 bellard
        /* jump to another page: currently not optimized */
587 6e256c93 bellard
        gen_jmp_im(pc);
588 6e256c93 bellard
        gen_movl_npc_im(npc);
589 6e256c93 bellard
        gen_op_movl_T0_0();
590 6e256c93 bellard
        gen_op_exit_tb();
591 6e256c93 bellard
    }
592 6e256c93 bellard
}
593 6e256c93 bellard
594 83469015 bellard
static inline void gen_branch2(DisasContext *dc, long tb, target_ulong pc1, target_ulong pc2)
595 83469015 bellard
{
596 83469015 bellard
    int l1;
597 83469015 bellard
598 83469015 bellard
    l1 = gen_new_label();
599 83469015 bellard
600 83469015 bellard
    gen_op_jz_T2_label(l1);
601 83469015 bellard
602 6e256c93 bellard
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
603 83469015 bellard
604 83469015 bellard
    gen_set_label(l1);
605 6e256c93 bellard
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
606 83469015 bellard
}
607 83469015 bellard
608 83469015 bellard
static inline void gen_branch_a(DisasContext *dc, long tb, target_ulong pc1, target_ulong pc2)
609 83469015 bellard
{
610 83469015 bellard
    int l1;
611 83469015 bellard
612 83469015 bellard
    l1 = gen_new_label();
613 83469015 bellard
614 83469015 bellard
    gen_op_jz_T2_label(l1);
615 83469015 bellard
616 6e256c93 bellard
    gen_goto_tb(dc, 0, pc2, pc1);
617 83469015 bellard
618 83469015 bellard
    gen_set_label(l1);
619 6e256c93 bellard
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
620 83469015 bellard
}
621 83469015 bellard
622 83469015 bellard
static inline void gen_branch(DisasContext *dc, long tb, target_ulong pc, target_ulong npc)
623 83469015 bellard
{
624 6e256c93 bellard
    gen_goto_tb(dc, 0, pc, npc);
625 83469015 bellard
}
626 83469015 bellard
627 83469015 bellard
static inline void gen_generic_branch(DisasContext *dc, target_ulong npc1, target_ulong npc2)
628 83469015 bellard
{
629 83469015 bellard
    int l1, l2;
630 83469015 bellard
631 83469015 bellard
    l1 = gen_new_label();
632 83469015 bellard
    l2 = gen_new_label();
633 83469015 bellard
    gen_op_jz_T2_label(l1);
634 83469015 bellard
635 83469015 bellard
    gen_movl_npc_im(npc1);
636 83469015 bellard
    gen_op_jmp_label(l2);
637 83469015 bellard
638 83469015 bellard
    gen_set_label(l1);
639 83469015 bellard
    gen_movl_npc_im(npc2);
640 83469015 bellard
    gen_set_label(l2);
641 83469015 bellard
}
642 83469015 bellard
643 83469015 bellard
/* call this function before using T2 as it may have been set for a jump */
644 83469015 bellard
static inline void flush_T2(DisasContext * dc)
645 83469015 bellard
{
646 83469015 bellard
    if (dc->npc == JUMP_PC) {
647 83469015 bellard
        gen_generic_branch(dc, dc->jump_pc[0], dc->jump_pc[1]);
648 83469015 bellard
        dc->npc = DYNAMIC_PC;
649 83469015 bellard
    }
650 83469015 bellard
}
651 83469015 bellard
652 72cbca10 bellard
static inline void save_npc(DisasContext * dc)
653 72cbca10 bellard
{
654 72cbca10 bellard
    if (dc->npc == JUMP_PC) {
655 83469015 bellard
        gen_generic_branch(dc, dc->jump_pc[0], dc->jump_pc[1]);
656 72cbca10 bellard
        dc->npc = DYNAMIC_PC;
657 72cbca10 bellard
    } else if (dc->npc != DYNAMIC_PC) {
658 3475187d bellard
        gen_movl_npc_im(dc->npc);
659 72cbca10 bellard
    }
660 72cbca10 bellard
}
661 72cbca10 bellard
662 72cbca10 bellard
static inline void save_state(DisasContext * dc)
663 72cbca10 bellard
{
664 3475187d bellard
    gen_jmp_im(dc->pc);
665 72cbca10 bellard
    save_npc(dc);
666 72cbca10 bellard
}
667 72cbca10 bellard
668 0bee699e bellard
static inline void gen_mov_pc_npc(DisasContext * dc)
669 0bee699e bellard
{
670 0bee699e bellard
    if (dc->npc == JUMP_PC) {
671 83469015 bellard
        gen_generic_branch(dc, dc->jump_pc[0], dc->jump_pc[1]);
672 0bee699e bellard
        gen_op_mov_pc_npc();
673 0bee699e bellard
        dc->pc = DYNAMIC_PC;
674 0bee699e bellard
    } else if (dc->npc == DYNAMIC_PC) {
675 0bee699e bellard
        gen_op_mov_pc_npc();
676 0bee699e bellard
        dc->pc = DYNAMIC_PC;
677 0bee699e bellard
    } else {
678 0bee699e bellard
        dc->pc = dc->npc;
679 0bee699e bellard
    }
680 0bee699e bellard
}
681 0bee699e bellard
682 3475187d bellard
static GenOpFunc * const gen_cond[2][16] = {
683 3475187d bellard
    {
684 3475187d bellard
        gen_op_eval_ba,
685 3475187d bellard
        gen_op_eval_be,
686 3475187d bellard
        gen_op_eval_ble,
687 3475187d bellard
        gen_op_eval_bl,
688 3475187d bellard
        gen_op_eval_bleu,
689 3475187d bellard
        gen_op_eval_bcs,
690 3475187d bellard
        gen_op_eval_bneg,
691 3475187d bellard
        gen_op_eval_bvs,
692 3475187d bellard
        gen_op_eval_bn,
693 3475187d bellard
        gen_op_eval_bne,
694 3475187d bellard
        gen_op_eval_bg,
695 3475187d bellard
        gen_op_eval_bge,
696 3475187d bellard
        gen_op_eval_bgu,
697 3475187d bellard
        gen_op_eval_bcc,
698 3475187d bellard
        gen_op_eval_bpos,
699 3475187d bellard
        gen_op_eval_bvc,
700 3475187d bellard
    },
701 3475187d bellard
    {
702 3475187d bellard
#ifdef TARGET_SPARC64
703 3475187d bellard
        gen_op_eval_ba,
704 3475187d bellard
        gen_op_eval_xbe,
705 3475187d bellard
        gen_op_eval_xble,
706 3475187d bellard
        gen_op_eval_xbl,
707 3475187d bellard
        gen_op_eval_xbleu,
708 3475187d bellard
        gen_op_eval_xbcs,
709 3475187d bellard
        gen_op_eval_xbneg,
710 3475187d bellard
        gen_op_eval_xbvs,
711 3475187d bellard
        gen_op_eval_bn,
712 3475187d bellard
        gen_op_eval_xbne,
713 3475187d bellard
        gen_op_eval_xbg,
714 3475187d bellard
        gen_op_eval_xbge,
715 3475187d bellard
        gen_op_eval_xbgu,
716 3475187d bellard
        gen_op_eval_xbcc,
717 3475187d bellard
        gen_op_eval_xbpos,
718 3475187d bellard
        gen_op_eval_xbvc,
719 3475187d bellard
#endif
720 3475187d bellard
    },
721 3475187d bellard
};
722 3475187d bellard
723 3475187d bellard
static GenOpFunc * const gen_fcond[4][16] = {
724 3475187d bellard
    {
725 3475187d bellard
        gen_op_eval_ba,
726 3475187d bellard
        gen_op_eval_fbne,
727 3475187d bellard
        gen_op_eval_fblg,
728 3475187d bellard
        gen_op_eval_fbul,
729 3475187d bellard
        gen_op_eval_fbl,
730 3475187d bellard
        gen_op_eval_fbug,
731 3475187d bellard
        gen_op_eval_fbg,
732 3475187d bellard
        gen_op_eval_fbu,
733 3475187d bellard
        gen_op_eval_bn,
734 3475187d bellard
        gen_op_eval_fbe,
735 3475187d bellard
        gen_op_eval_fbue,
736 3475187d bellard
        gen_op_eval_fbge,
737 3475187d bellard
        gen_op_eval_fbuge,
738 3475187d bellard
        gen_op_eval_fble,
739 3475187d bellard
        gen_op_eval_fbule,
740 3475187d bellard
        gen_op_eval_fbo,
741 3475187d bellard
    },
742 3475187d bellard
#ifdef TARGET_SPARC64
743 3475187d bellard
    {
744 3475187d bellard
        gen_op_eval_ba,
745 3475187d bellard
        gen_op_eval_fbne_fcc1,
746 3475187d bellard
        gen_op_eval_fblg_fcc1,
747 3475187d bellard
        gen_op_eval_fbul_fcc1,
748 3475187d bellard
        gen_op_eval_fbl_fcc1,
749 3475187d bellard
        gen_op_eval_fbug_fcc1,
750 3475187d bellard
        gen_op_eval_fbg_fcc1,
751 3475187d bellard
        gen_op_eval_fbu_fcc1,
752 3475187d bellard
        gen_op_eval_bn,
753 3475187d bellard
        gen_op_eval_fbe_fcc1,
754 3475187d bellard
        gen_op_eval_fbue_fcc1,
755 3475187d bellard
        gen_op_eval_fbge_fcc1,
756 3475187d bellard
        gen_op_eval_fbuge_fcc1,
757 3475187d bellard
        gen_op_eval_fble_fcc1,
758 3475187d bellard
        gen_op_eval_fbule_fcc1,
759 3475187d bellard
        gen_op_eval_fbo_fcc1,
760 3475187d bellard
    },
761 3475187d bellard
    {
762 3475187d bellard
        gen_op_eval_ba,
763 3475187d bellard
        gen_op_eval_fbne_fcc2,
764 3475187d bellard
        gen_op_eval_fblg_fcc2,
765 3475187d bellard
        gen_op_eval_fbul_fcc2,
766 3475187d bellard
        gen_op_eval_fbl_fcc2,
767 3475187d bellard
        gen_op_eval_fbug_fcc2,
768 3475187d bellard
        gen_op_eval_fbg_fcc2,
769 3475187d bellard
        gen_op_eval_fbu_fcc2,
770 3475187d bellard
        gen_op_eval_bn,
771 3475187d bellard
        gen_op_eval_fbe_fcc2,
772 3475187d bellard
        gen_op_eval_fbue_fcc2,
773 3475187d bellard
        gen_op_eval_fbge_fcc2,
774 3475187d bellard
        gen_op_eval_fbuge_fcc2,
775 3475187d bellard
        gen_op_eval_fble_fcc2,
776 3475187d bellard
        gen_op_eval_fbule_fcc2,
777 3475187d bellard
        gen_op_eval_fbo_fcc2,
778 3475187d bellard
    },
779 3475187d bellard
    {
780 3475187d bellard
        gen_op_eval_ba,
781 3475187d bellard
        gen_op_eval_fbne_fcc3,
782 3475187d bellard
        gen_op_eval_fblg_fcc3,
783 3475187d bellard
        gen_op_eval_fbul_fcc3,
784 3475187d bellard
        gen_op_eval_fbl_fcc3,
785 3475187d bellard
        gen_op_eval_fbug_fcc3,
786 3475187d bellard
        gen_op_eval_fbg_fcc3,
787 3475187d bellard
        gen_op_eval_fbu_fcc3,
788 3475187d bellard
        gen_op_eval_bn,
789 3475187d bellard
        gen_op_eval_fbe_fcc3,
790 3475187d bellard
        gen_op_eval_fbue_fcc3,
791 3475187d bellard
        gen_op_eval_fbge_fcc3,
792 3475187d bellard
        gen_op_eval_fbuge_fcc3,
793 3475187d bellard
        gen_op_eval_fble_fcc3,
794 3475187d bellard
        gen_op_eval_fbule_fcc3,
795 3475187d bellard
        gen_op_eval_fbo_fcc3,
796 3475187d bellard
    },
797 3475187d bellard
#else
798 3475187d bellard
    {}, {}, {},
799 3475187d bellard
#endif
800 3475187d bellard
};
801 7a3f1944 bellard
802 3475187d bellard
#ifdef TARGET_SPARC64
803 3475187d bellard
static void gen_cond_reg(int cond)
804 e8af50a3 bellard
{
805 e8af50a3 bellard
        switch (cond) {
806 e8af50a3 bellard
        case 0x1:
807 3475187d bellard
            gen_op_eval_brz();
808 e8af50a3 bellard
            break;
809 e8af50a3 bellard
        case 0x2:
810 3475187d bellard
            gen_op_eval_brlez();
811 e8af50a3 bellard
            break;
812 e8af50a3 bellard
        case 0x3:
813 3475187d bellard
            gen_op_eval_brlz();
814 e8af50a3 bellard
            break;
815 e8af50a3 bellard
        case 0x5:
816 3475187d bellard
            gen_op_eval_brnz();
817 e8af50a3 bellard
            break;
818 e8af50a3 bellard
        case 0x6:
819 3475187d bellard
            gen_op_eval_brgz();
820 e8af50a3 bellard
            break;
821 e8af50a3 bellard
        default:
822 3475187d bellard
        case 0x7:
823 3475187d bellard
            gen_op_eval_brgez();
824 e8af50a3 bellard
            break;
825 e8af50a3 bellard
        }
826 e8af50a3 bellard
}
827 3475187d bellard
#endif
828 cf495bcf bellard
829 0bee699e bellard
/* XXX: potentially incorrect if dynamic npc */
830 3475187d bellard
static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
831 7a3f1944 bellard
{
832 cf495bcf bellard
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
833 af7bf89b bellard
    target_ulong target = dc->pc + offset;
834 3475187d bellard
        
835 cf495bcf bellard
    if (cond == 0x0) {
836 cf495bcf bellard
        /* unconditional not taken */
837 cf495bcf bellard
        if (a) {
838 0bee699e bellard
            dc->pc = dc->npc + 4; 
839 cf495bcf bellard
            dc->npc = dc->pc + 4;
840 cf495bcf bellard
        } else {
841 cf495bcf bellard
            dc->pc = dc->npc;
842 cf495bcf bellard
            dc->npc = dc->pc + 4;
843 cf495bcf bellard
        }
844 cf495bcf bellard
    } else if (cond == 0x8) {
845 cf495bcf bellard
        /* unconditional taken */
846 cf495bcf bellard
        if (a) {
847 72cbca10 bellard
            dc->pc = target;
848 cf495bcf bellard
            dc->npc = dc->pc + 4;
849 cf495bcf bellard
        } else {
850 cf495bcf bellard
            dc->pc = dc->npc;
851 72cbca10 bellard
            dc->npc = target;
852 cf495bcf bellard
        }
853 cf495bcf bellard
    } else {
854 72cbca10 bellard
        flush_T2(dc);
855 3475187d bellard
        gen_cond[cc][cond]();
856 cf495bcf bellard
        if (a) {
857 83469015 bellard
            gen_branch_a(dc, (long)dc->tb, target, dc->npc);
858 cf495bcf bellard
            dc->is_br = 1;
859 cf495bcf bellard
        } else {
860 cf495bcf bellard
            dc->pc = dc->npc;
861 72cbca10 bellard
            dc->jump_pc[0] = target;
862 72cbca10 bellard
            dc->jump_pc[1] = dc->npc + 4;
863 72cbca10 bellard
            dc->npc = JUMP_PC;
864 cf495bcf bellard
        }
865 cf495bcf bellard
    }
866 7a3f1944 bellard
}
867 7a3f1944 bellard
868 0bee699e bellard
/* XXX: potentially incorrect if dynamic npc */
869 3475187d bellard
static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
870 e8af50a3 bellard
{
871 e8af50a3 bellard
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
872 af7bf89b bellard
    target_ulong target = dc->pc + offset;
873 af7bf89b bellard
874 e8af50a3 bellard
    if (cond == 0x0) {
875 e8af50a3 bellard
        /* unconditional not taken */
876 e8af50a3 bellard
        if (a) {
877 e8af50a3 bellard
            dc->pc = dc->npc + 4;
878 e8af50a3 bellard
            dc->npc = dc->pc + 4;
879 e8af50a3 bellard
        } else {
880 e8af50a3 bellard
            dc->pc = dc->npc;
881 e8af50a3 bellard
            dc->npc = dc->pc + 4;
882 e8af50a3 bellard
        }
883 e8af50a3 bellard
    } else if (cond == 0x8) {
884 e8af50a3 bellard
        /* unconditional taken */
885 e8af50a3 bellard
        if (a) {
886 e8af50a3 bellard
            dc->pc = target;
887 e8af50a3 bellard
            dc->npc = dc->pc + 4;
888 e8af50a3 bellard
        } else {
889 e8af50a3 bellard
            dc->pc = dc->npc;
890 e8af50a3 bellard
            dc->npc = target;
891 e8af50a3 bellard
        }
892 e8af50a3 bellard
    } else {
893 e8af50a3 bellard
        flush_T2(dc);
894 3475187d bellard
        gen_fcond[cc][cond]();
895 e8af50a3 bellard
        if (a) {
896 83469015 bellard
            gen_branch_a(dc, (long)dc->tb, target, dc->npc);
897 e8af50a3 bellard
            dc->is_br = 1;
898 e8af50a3 bellard
        } else {
899 e8af50a3 bellard
            dc->pc = dc->npc;
900 e8af50a3 bellard
            dc->jump_pc[0] = target;
901 e8af50a3 bellard
            dc->jump_pc[1] = dc->npc + 4;
902 e8af50a3 bellard
            dc->npc = JUMP_PC;
903 e8af50a3 bellard
        }
904 e8af50a3 bellard
    }
905 e8af50a3 bellard
}
906 e8af50a3 bellard
907 3475187d bellard
#ifdef TARGET_SPARC64
908 3475187d bellard
/* XXX: potentially incorrect if dynamic npc */
909 3475187d bellard
static void do_branch_reg(DisasContext * dc, int32_t offset, uint32_t insn)
910 7a3f1944 bellard
{
911 3475187d bellard
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
912 3475187d bellard
    target_ulong target = dc->pc + offset;
913 3475187d bellard
914 3475187d bellard
    flush_T2(dc);
915 3475187d bellard
    gen_cond_reg(cond);
916 3475187d bellard
    if (a) {
917 83469015 bellard
        gen_branch_a(dc, (long)dc->tb, target, dc->npc);
918 3475187d bellard
        dc->is_br = 1;
919 3475187d bellard
    } else {
920 3475187d bellard
        dc->pc = dc->npc;
921 3475187d bellard
        dc->jump_pc[0] = target;
922 3475187d bellard
        dc->jump_pc[1] = dc->npc + 4;
923 3475187d bellard
        dc->npc = JUMP_PC;
924 3475187d bellard
    }
925 7a3f1944 bellard
}
926 7a3f1944 bellard
927 3475187d bellard
static GenOpFunc * const gen_fcmps[4] = {
928 3475187d bellard
    gen_op_fcmps,
929 3475187d bellard
    gen_op_fcmps_fcc1,
930 3475187d bellard
    gen_op_fcmps_fcc2,
931 3475187d bellard
    gen_op_fcmps_fcc3,
932 3475187d bellard
};
933 3475187d bellard
934 3475187d bellard
static GenOpFunc * const gen_fcmpd[4] = {
935 3475187d bellard
    gen_op_fcmpd,
936 3475187d bellard
    gen_op_fcmpd_fcc1,
937 3475187d bellard
    gen_op_fcmpd_fcc2,
938 3475187d bellard
    gen_op_fcmpd_fcc3,
939 3475187d bellard
};
940 3475187d bellard
#endif
941 3475187d bellard
942 a80dde08 bellard
static int gen_trap_ifnofpu(DisasContext * dc)
943 a80dde08 bellard
{
944 a80dde08 bellard
#if !defined(CONFIG_USER_ONLY)
945 a80dde08 bellard
    if (!dc->fpu_enabled) {
946 a80dde08 bellard
        save_state(dc);
947 a80dde08 bellard
        gen_op_exception(TT_NFPU_INSN);
948 a80dde08 bellard
        dc->is_br = 1;
949 a80dde08 bellard
        return 1;
950 a80dde08 bellard
    }
951 a80dde08 bellard
#endif
952 a80dde08 bellard
    return 0;
953 a80dde08 bellard
}
954 a80dde08 bellard
955 0bee699e bellard
/* before an instruction, dc->pc must be static */
956 cf495bcf bellard
static void disas_sparc_insn(DisasContext * dc)
957 cf495bcf bellard
{
958 cf495bcf bellard
    unsigned int insn, opc, rs1, rs2, rd;
959 7a3f1944 bellard
960 0fa85d43 bellard
    insn = ldl_code(dc->pc);
961 cf495bcf bellard
    opc = GET_FIELD(insn, 0, 1);
962 7a3f1944 bellard
963 cf495bcf bellard
    rd = GET_FIELD(insn, 2, 6);
964 cf495bcf bellard
    switch (opc) {
965 cf495bcf bellard
    case 0:                        /* branches/sethi */
966 cf495bcf bellard
        {
967 cf495bcf bellard
            unsigned int xop = GET_FIELD(insn, 7, 9);
968 af7bf89b bellard
            int32_t target;
969 cf495bcf bellard
            switch (xop) {
970 3475187d bellard
#ifdef TARGET_SPARC64
971 af7bf89b bellard
            case 0x1:                /* V9 BPcc */
972 3475187d bellard
                {
973 3475187d bellard
                    int cc;
974 3475187d bellard
975 3475187d bellard
                    target = GET_FIELD_SP(insn, 0, 18);
976 3475187d bellard
                    target = sign_extend(target, 18);
977 ee6c0b51 bellard
                    target <<= 2;
978 3475187d bellard
                    cc = GET_FIELD_SP(insn, 20, 21);
979 3475187d bellard
                    if (cc == 0)
980 3475187d bellard
                        do_branch(dc, target, insn, 0);
981 3475187d bellard
                    else if (cc == 2)
982 3475187d bellard
                        do_branch(dc, target, insn, 1);
983 3475187d bellard
                    else
984 3475187d bellard
                        goto illegal_insn;
985 3475187d bellard
                    goto jmp_insn;
986 3475187d bellard
                }
987 af7bf89b bellard
            case 0x3:                /* V9 BPr */
988 3475187d bellard
                {
989 3475187d bellard
                    target = GET_FIELD_SP(insn, 0, 13) | 
990 13846e70 bellard
                        (GET_FIELD_SP(insn, 20, 21) << 14);
991 3475187d bellard
                    target = sign_extend(target, 16);
992 ee6c0b51 bellard
                    target <<= 2;
993 3475187d bellard
                    rs1 = GET_FIELD(insn, 13, 17);
994 83469015 bellard
                    gen_movl_reg_T0(rs1);
995 3475187d bellard
                    do_branch_reg(dc, target, insn);
996 3475187d bellard
                    goto jmp_insn;
997 3475187d bellard
                }
998 af7bf89b bellard
            case 0x5:                /* V9 FBPcc */
999 3475187d bellard
                {
1000 3475187d bellard
                    int cc = GET_FIELD_SP(insn, 20, 21);
1001 a80dde08 bellard
                    if (gen_trap_ifnofpu(dc))
1002 a80dde08 bellard
                        goto jmp_insn;
1003 3475187d bellard
                    target = GET_FIELD_SP(insn, 0, 18);
1004 3475187d bellard
                    target = sign_extend(target, 19);
1005 ee6c0b51 bellard
                    target <<= 2;
1006 3475187d bellard
                    do_fbranch(dc, target, insn, cc);
1007 3475187d bellard
                    goto jmp_insn;
1008 3475187d bellard
                }
1009 3475187d bellard
#endif
1010 cf495bcf bellard
            case 0x2:                /* BN+x */
1011 7a3f1944 bellard
                {
1012 3475187d bellard
                    target = GET_FIELD(insn, 10, 31);
1013 cf495bcf bellard
                    target = sign_extend(target, 22);
1014 ee6c0b51 bellard
                    target <<= 2;
1015 3475187d bellard
                    do_branch(dc, target, insn, 0);
1016 cf495bcf bellard
                    goto jmp_insn;
1017 7a3f1944 bellard
                }
1018 e8af50a3 bellard
            case 0x6:                /* FBN+x */
1019 e8af50a3 bellard
                {
1020 a80dde08 bellard
                    if (gen_trap_ifnofpu(dc))
1021 a80dde08 bellard
                        goto jmp_insn;
1022 3475187d bellard
                    target = GET_FIELD(insn, 10, 31);
1023 e8af50a3 bellard
                    target = sign_extend(target, 22);
1024 ee6c0b51 bellard
                    target <<= 2;
1025 3475187d bellard
                    do_fbranch(dc, target, insn, 0);
1026 e8af50a3 bellard
                    goto jmp_insn;
1027 e8af50a3 bellard
                }
1028 cf495bcf bellard
            case 0x4:                /* SETHI */
1029 e80cfcfc bellard
#define OPTIM
1030 e80cfcfc bellard
#if defined(OPTIM)
1031 e80cfcfc bellard
                if (rd) { // nop
1032 e80cfcfc bellard
#endif
1033 3475187d bellard
                    uint32_t value = GET_FIELD(insn, 10, 31);
1034 3475187d bellard
                    gen_movl_imm_T0(value << 10);
1035 e80cfcfc bellard
                    gen_movl_T0_reg(rd);
1036 e80cfcfc bellard
#if defined(OPTIM)
1037 e80cfcfc bellard
                }
1038 e80cfcfc bellard
#endif
1039 cf495bcf bellard
                break;
1040 3475187d bellard
            case 0x0:                /* UNIMPL */
1041 3475187d bellard
            default:
1042 3475187d bellard
                goto illegal_insn;
1043 cf495bcf bellard
            }
1044 cf495bcf bellard
            break;
1045 cf495bcf bellard
        }
1046 af7bf89b bellard
        break;
1047 cf495bcf bellard
    case 1:
1048 cf495bcf bellard
        /*CALL*/ {
1049 af7bf89b bellard
            target_long target = GET_FIELDs(insn, 2, 31) << 2;
1050 cf495bcf bellard
1051 83469015 bellard
#ifdef TARGET_SPARC64
1052 83469015 bellard
            if (dc->pc == (uint32_t)dc->pc) {
1053 83469015 bellard
                gen_op_movl_T0_im(dc->pc);
1054 83469015 bellard
            } else {
1055 83469015 bellard
                gen_op_movq_T0_im64(dc->pc >> 32, dc->pc);
1056 83469015 bellard
            }
1057 83469015 bellard
#else
1058 af7bf89b bellard
            gen_op_movl_T0_im(dc->pc);
1059 83469015 bellard
#endif
1060 cf495bcf bellard
            gen_movl_T0_reg(15);
1061 af7bf89b bellard
            target += dc->pc;
1062 0bee699e bellard
            gen_mov_pc_npc(dc);
1063 72cbca10 bellard
            dc->npc = target;
1064 cf495bcf bellard
        }
1065 cf495bcf bellard
        goto jmp_insn;
1066 cf495bcf bellard
    case 2:                        /* FPU & Logical Operations */
1067 cf495bcf bellard
        {
1068 cf495bcf bellard
            unsigned int xop = GET_FIELD(insn, 7, 12);
1069 cf495bcf bellard
            if (xop == 0x3a) {        /* generate trap */
1070 cf495bcf bellard
                int cond;
1071 3475187d bellard
1072 cf495bcf bellard
                rs1 = GET_FIELD(insn, 13, 17);
1073 cf495bcf bellard
                gen_movl_reg_T0(rs1);
1074 cf495bcf bellard
                if (IS_IMM) {
1075 e8af50a3 bellard
                    rs2 = GET_FIELD(insn, 25, 31);
1076 e80cfcfc bellard
#if defined(OPTIM)
1077 e8af50a3 bellard
                    if (rs2 != 0) {
1078 e80cfcfc bellard
#endif
1079 3475187d bellard
                        gen_movl_simm_T1(rs2);
1080 e80cfcfc bellard
                        gen_op_add_T1_T0();
1081 e80cfcfc bellard
#if defined(OPTIM)
1082 e8af50a3 bellard
                    }
1083 e80cfcfc bellard
#endif
1084 cf495bcf bellard
                } else {
1085 cf495bcf bellard
                    rs2 = GET_FIELD(insn, 27, 31);
1086 e80cfcfc bellard
#if defined(OPTIM)
1087 e80cfcfc bellard
                    if (rs2 != 0) {
1088 e80cfcfc bellard
#endif
1089 e80cfcfc bellard
                        gen_movl_reg_T1(rs2);
1090 e80cfcfc bellard
                        gen_op_add_T1_T0();
1091 e80cfcfc bellard
#if defined(OPTIM)
1092 e80cfcfc bellard
                    }
1093 e80cfcfc bellard
#endif
1094 cf495bcf bellard
                }
1095 cf495bcf bellard
                cond = GET_FIELD(insn, 3, 6);
1096 cf495bcf bellard
                if (cond == 0x8) {
1097 a80dde08 bellard
                    save_state(dc);
1098 cf495bcf bellard
                    gen_op_trap_T0();
1099 af7bf89b bellard
                } else if (cond != 0) {
1100 3475187d bellard
#ifdef TARGET_SPARC64
1101 3475187d bellard
                    /* V9 icc/xcc */
1102 3475187d bellard
                    int cc = GET_FIELD_SP(insn, 11, 12);
1103 a80dde08 bellard
                    flush_T2(dc);
1104 a80dde08 bellard
                    save_state(dc);
1105 3475187d bellard
                    if (cc == 0)
1106 3475187d bellard
                        gen_cond[0][cond]();
1107 3475187d bellard
                    else if (cc == 2)
1108 3475187d bellard
                        gen_cond[1][cond]();
1109 3475187d bellard
                    else
1110 3475187d bellard
                        goto illegal_insn;
1111 3475187d bellard
#else
1112 a80dde08 bellard
                    flush_T2(dc);
1113 a80dde08 bellard
                    save_state(dc);
1114 3475187d bellard
                    gen_cond[0][cond]();
1115 3475187d bellard
#endif
1116 cf495bcf bellard
                    gen_op_trapcc_T0();
1117 cf495bcf bellard
                }
1118 a80dde08 bellard
                gen_op_next_insn();
1119 a80dde08 bellard
                gen_op_movl_T0_0();
1120 a80dde08 bellard
                gen_op_exit_tb();
1121 a80dde08 bellard
                dc->is_br = 1;
1122 a80dde08 bellard
                goto jmp_insn;
1123 cf495bcf bellard
            } else if (xop == 0x28) {
1124 cf495bcf bellard
                rs1 = GET_FIELD(insn, 13, 17);
1125 cf495bcf bellard
                switch(rs1) {
1126 cf495bcf bellard
                case 0: /* rdy */
1127 3475187d bellard
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, y));
1128 cf495bcf bellard
                    gen_movl_T0_reg(rd);
1129 cf495bcf bellard
                    break;
1130 af7bf89b bellard
                case 15: /* stbar / V9 membar */
1131 e8af50a3 bellard
                    break; /* no effect? */
1132 3475187d bellard
#ifdef TARGET_SPARC64
1133 af7bf89b bellard
                case 0x2: /* V9 rdccr */
1134 3475187d bellard
                    gen_op_rdccr();
1135 3475187d bellard
                    gen_movl_T0_reg(rd);
1136 3475187d bellard
                    break;
1137 af7bf89b bellard
                case 0x3: /* V9 rdasi */
1138 3475187d bellard
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, asi));
1139 3475187d bellard
                    gen_movl_T0_reg(rd);
1140 3475187d bellard
                    break;
1141 af7bf89b bellard
                case 0x4: /* V9 rdtick */
1142 3475187d bellard
                    gen_op_rdtick();
1143 3475187d bellard
                    gen_movl_T0_reg(rd);
1144 3475187d bellard
                    break;
1145 af7bf89b bellard
                case 0x5: /* V9 rdpc */
1146 ded3ab80 pbrook
                    if (dc->pc == (uint32_t)dc->pc) {
1147 ded3ab80 pbrook
                        gen_op_movl_T0_im(dc->pc);
1148 ded3ab80 pbrook
                    } else {
1149 ded3ab80 pbrook
                        gen_op_movq_T0_im64(dc->pc >> 32, dc->pc);
1150 ded3ab80 pbrook
                    }
1151 3475187d bellard
                    gen_movl_T0_reg(rd);
1152 3475187d bellard
                    break;
1153 af7bf89b bellard
                case 0x6: /* V9 rdfprs */
1154 3475187d bellard
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, fprs));
1155 3475187d bellard
                    gen_movl_T0_reg(rd);
1156 3475187d bellard
                    break;
1157 725cb90b bellard
                case 0x13: /* Graphics Status */
1158 725cb90b bellard
                    if (gen_trap_ifnofpu(dc))
1159 725cb90b bellard
                        goto jmp_insn;
1160 725cb90b bellard
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, gsr));
1161 725cb90b bellard
                    gen_movl_T0_reg(rd);
1162 725cb90b bellard
                    break;
1163 83469015 bellard
                case 0x17: /* Tick compare */
1164 83469015 bellard
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, tick_cmpr));
1165 83469015 bellard
                    gen_movl_T0_reg(rd);
1166 83469015 bellard
                    break;
1167 83469015 bellard
                case 0x18: /* System tick */
1168 83469015 bellard
                    gen_op_rdtick(); // XXX
1169 83469015 bellard
                    gen_movl_T0_reg(rd);
1170 83469015 bellard
                    break;
1171 83469015 bellard
                case 0x19: /* System tick compare */
1172 83469015 bellard
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, stick_cmpr));
1173 83469015 bellard
                    gen_movl_T0_reg(rd);
1174 83469015 bellard
                    break;
1175 83469015 bellard
                case 0x10: /* Performance Control */
1176 83469015 bellard
                case 0x11: /* Performance Instrumentation Counter */
1177 83469015 bellard
                case 0x12: /* Dispatch Control */
1178 83469015 bellard
                case 0x14: /* Softint set, WO */
1179 83469015 bellard
                case 0x15: /* Softint clear, WO */
1180 83469015 bellard
                case 0x16: /* Softint write */
1181 3475187d bellard
#endif
1182 3475187d bellard
                default:
1183 cf495bcf bellard
                    goto illegal_insn;
1184 cf495bcf bellard
                }
1185 e8af50a3 bellard
#if !defined(CONFIG_USER_ONLY)
1186 3475187d bellard
#ifndef TARGET_SPARC64
1187 3475187d bellard
            } else if (xop == 0x29) { /* rdpsr / V9 unimp */
1188 e8af50a3 bellard
                if (!supervisor(dc))
1189 e8af50a3 bellard
                    goto priv_insn;
1190 e8af50a3 bellard
                gen_op_rdpsr();
1191 e8af50a3 bellard
                gen_movl_T0_reg(rd);
1192 e8af50a3 bellard
                break;
1193 3475187d bellard
#endif
1194 3475187d bellard
            } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
1195 e8af50a3 bellard
                if (!supervisor(dc))
1196 e8af50a3 bellard
                    goto priv_insn;
1197 3475187d bellard
#ifdef TARGET_SPARC64
1198 3475187d bellard
                rs1 = GET_FIELD(insn, 13, 17);
1199 3475187d bellard
                switch (rs1) {
1200 3475187d bellard
                case 0: // tpc
1201 3475187d bellard
                    gen_op_rdtpc();
1202 3475187d bellard
                    break;
1203 3475187d bellard
                case 1: // tnpc
1204 3475187d bellard
                    gen_op_rdtnpc();
1205 3475187d bellard
                    break;
1206 3475187d bellard
                case 2: // tstate
1207 3475187d bellard
                    gen_op_rdtstate();
1208 3475187d bellard
                    break;
1209 3475187d bellard
                case 3: // tt
1210 3475187d bellard
                    gen_op_rdtt();
1211 3475187d bellard
                    break;
1212 3475187d bellard
                case 4: // tick
1213 3475187d bellard
                    gen_op_rdtick();
1214 3475187d bellard
                    break;
1215 3475187d bellard
                case 5: // tba
1216 3475187d bellard
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
1217 3475187d bellard
                    break;
1218 3475187d bellard
                case 6: // pstate
1219 3475187d bellard
                    gen_op_rdpstate();
1220 3475187d bellard
                    break;
1221 3475187d bellard
                case 7: // tl
1222 3475187d bellard
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, tl));
1223 3475187d bellard
                    break;
1224 3475187d bellard
                case 8: // pil
1225 3475187d bellard
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, psrpil));
1226 3475187d bellard
                    break;
1227 3475187d bellard
                case 9: // cwp
1228 3475187d bellard
                    gen_op_rdcwp();
1229 3475187d bellard
                    break;
1230 3475187d bellard
                case 10: // cansave
1231 3475187d bellard
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, cansave));
1232 3475187d bellard
                    break;
1233 3475187d bellard
                case 11: // canrestore
1234 3475187d bellard
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, canrestore));
1235 3475187d bellard
                    break;
1236 3475187d bellard
                case 12: // cleanwin
1237 3475187d bellard
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, cleanwin));
1238 3475187d bellard
                    break;
1239 3475187d bellard
                case 13: // otherwin
1240 3475187d bellard
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, otherwin));
1241 3475187d bellard
                    break;
1242 3475187d bellard
                case 14: // wstate
1243 3475187d bellard
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, wstate));
1244 3475187d bellard
                    break;
1245 3475187d bellard
                case 31: // ver
1246 3475187d bellard
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, version));
1247 3475187d bellard
                    break;
1248 3475187d bellard
                case 15: // fq
1249 3475187d bellard
                default:
1250 3475187d bellard
                    goto illegal_insn;
1251 3475187d bellard
                }
1252 3475187d bellard
#else
1253 3475187d bellard
                gen_op_movl_T0_env(offsetof(CPUSPARCState, wim));
1254 3475187d bellard
#endif
1255 e8af50a3 bellard
                gen_movl_T0_reg(rd);
1256 e8af50a3 bellard
                break;
1257 3475187d bellard
            } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
1258 3475187d bellard
#ifdef TARGET_SPARC64
1259 3475187d bellard
                gen_op_flushw();
1260 3475187d bellard
#else
1261 e8af50a3 bellard
                if (!supervisor(dc))
1262 e8af50a3 bellard
                    goto priv_insn;
1263 3475187d bellard
                gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
1264 e8af50a3 bellard
                gen_movl_T0_reg(rd);
1265 3475187d bellard
#endif
1266 e8af50a3 bellard
                break;
1267 e8af50a3 bellard
#endif
1268 e80cfcfc bellard
            } else if (xop == 0x34) {        /* FPU Operations */
1269 a80dde08 bellard
                if (gen_trap_ifnofpu(dc))
1270 a80dde08 bellard
                    goto jmp_insn;
1271 e8af50a3 bellard
                rs1 = GET_FIELD(insn, 13, 17);
1272 e8af50a3 bellard
                rs2 = GET_FIELD(insn, 27, 31);
1273 e8af50a3 bellard
                xop = GET_FIELD(insn, 18, 26);
1274 e8af50a3 bellard
                switch (xop) {
1275 e8af50a3 bellard
                    case 0x1: /* fmovs */
1276 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs2);
1277 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1278 e8af50a3 bellard
                        break;
1279 e8af50a3 bellard
                    case 0x5: /* fnegs */
1280 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1281 e8af50a3 bellard
                        gen_op_fnegs();
1282 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1283 e8af50a3 bellard
                        break;
1284 e8af50a3 bellard
                    case 0x9: /* fabss */
1285 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1286 e8af50a3 bellard
                        gen_op_fabss();
1287 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1288 e8af50a3 bellard
                        break;
1289 e8af50a3 bellard
                    case 0x29: /* fsqrts */
1290 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1291 e8af50a3 bellard
                        gen_op_fsqrts();
1292 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1293 e8af50a3 bellard
                        break;
1294 e8af50a3 bellard
                    case 0x2a: /* fsqrtd */
1295 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1296 e8af50a3 bellard
                        gen_op_fsqrtd();
1297 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1298 e8af50a3 bellard
                        break;
1299 e80cfcfc bellard
                    case 0x2b: /* fsqrtq */
1300 e80cfcfc bellard
                        goto nfpu_insn;
1301 e8af50a3 bellard
                    case 0x41:
1302 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs1);
1303 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1304 e8af50a3 bellard
                        gen_op_fadds();
1305 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1306 e8af50a3 bellard
                        break;
1307 e8af50a3 bellard
                    case 0x42:
1308 3475187d bellard
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1309 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1310 e8af50a3 bellard
                        gen_op_faddd();
1311 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1312 e8af50a3 bellard
                        break;
1313 e80cfcfc bellard
                    case 0x43: /* faddq */
1314 e80cfcfc bellard
                        goto nfpu_insn;
1315 e8af50a3 bellard
                    case 0x45:
1316 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs1);
1317 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1318 e8af50a3 bellard
                        gen_op_fsubs();
1319 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1320 e8af50a3 bellard
                        break;
1321 e8af50a3 bellard
                    case 0x46:
1322 3475187d bellard
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1323 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1324 e8af50a3 bellard
                        gen_op_fsubd();
1325 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1326 e8af50a3 bellard
                        break;
1327 e80cfcfc bellard
                    case 0x47: /* fsubq */
1328 e80cfcfc bellard
                        goto nfpu_insn;
1329 e8af50a3 bellard
                    case 0x49:
1330 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs1);
1331 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1332 e8af50a3 bellard
                        gen_op_fmuls();
1333 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1334 e8af50a3 bellard
                        break;
1335 e8af50a3 bellard
                    case 0x4a:
1336 3475187d bellard
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1337 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1338 e8af50a3 bellard
                        gen_op_fmuld();
1339 e8af50a3 bellard
                        gen_op_store_DT0_fpr(rd);
1340 e8af50a3 bellard
                        break;
1341 e80cfcfc bellard
                    case 0x4b: /* fmulq */
1342 e80cfcfc bellard
                        goto nfpu_insn;
1343 e8af50a3 bellard
                    case 0x4d:
1344 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs1);
1345 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1346 e8af50a3 bellard
                        gen_op_fdivs();
1347 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1348 e8af50a3 bellard
                        break;
1349 e8af50a3 bellard
                    case 0x4e:
1350 3475187d bellard
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1351 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1352 e8af50a3 bellard
                        gen_op_fdivd();
1353 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1354 e8af50a3 bellard
                        break;
1355 e80cfcfc bellard
                    case 0x4f: /* fdivq */
1356 e80cfcfc bellard
                        goto nfpu_insn;
1357 e8af50a3 bellard
                    case 0x69:
1358 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs1);
1359 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1360 e8af50a3 bellard
                        gen_op_fsmuld();
1361 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1362 e8af50a3 bellard
                        break;
1363 e80cfcfc bellard
                    case 0x6e: /* fdmulq */
1364 e80cfcfc bellard
                        goto nfpu_insn;
1365 e8af50a3 bellard
                    case 0xc4:
1366 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1367 e8af50a3 bellard
                        gen_op_fitos();
1368 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1369 e8af50a3 bellard
                        break;
1370 e8af50a3 bellard
                    case 0xc6:
1371 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1372 e8af50a3 bellard
                        gen_op_fdtos();
1373 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1374 e8af50a3 bellard
                        break;
1375 e80cfcfc bellard
                    case 0xc7: /* fqtos */
1376 e80cfcfc bellard
                        goto nfpu_insn;
1377 e8af50a3 bellard
                    case 0xc8:
1378 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1379 e8af50a3 bellard
                        gen_op_fitod();
1380 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1381 e8af50a3 bellard
                        break;
1382 e8af50a3 bellard
                    case 0xc9:
1383 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1384 e8af50a3 bellard
                        gen_op_fstod();
1385 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1386 e8af50a3 bellard
                        break;
1387 e80cfcfc bellard
                    case 0xcb: /* fqtod */
1388 e80cfcfc bellard
                        goto nfpu_insn;
1389 e80cfcfc bellard
                    case 0xcc: /* fitoq */
1390 e80cfcfc bellard
                        goto nfpu_insn;
1391 e80cfcfc bellard
                    case 0xcd: /* fstoq */
1392 e80cfcfc bellard
                        goto nfpu_insn;
1393 e80cfcfc bellard
                    case 0xce: /* fdtoq */
1394 e80cfcfc bellard
                        goto nfpu_insn;
1395 e8af50a3 bellard
                    case 0xd1:
1396 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1397 e8af50a3 bellard
                        gen_op_fstoi();
1398 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1399 e8af50a3 bellard
                        break;
1400 e8af50a3 bellard
                    case 0xd2:
1401 e8af50a3 bellard
                        gen_op_load_fpr_DT1(rs2);
1402 e8af50a3 bellard
                        gen_op_fdtoi();
1403 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1404 e8af50a3 bellard
                        break;
1405 e80cfcfc bellard
                    case 0xd3: /* fqtoi */
1406 e80cfcfc bellard
                        goto nfpu_insn;
1407 3475187d bellard
#ifdef TARGET_SPARC64
1408 af7bf89b bellard
                    case 0x2: /* V9 fmovd */
1409 3475187d bellard
                        gen_op_load_fpr_DT0(DFPREG(rs2));
1410 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1411 3475187d bellard
                        break;
1412 af7bf89b bellard
                    case 0x6: /* V9 fnegd */
1413 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1414 3475187d bellard
                        gen_op_fnegd();
1415 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1416 3475187d bellard
                        break;
1417 af7bf89b bellard
                    case 0xa: /* V9 fabsd */
1418 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1419 3475187d bellard
                        gen_op_fabsd();
1420 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1421 3475187d bellard
                        break;
1422 af7bf89b bellard
                    case 0x81: /* V9 fstox */
1423 3475187d bellard
                        gen_op_load_fpr_FT1(rs2);
1424 3475187d bellard
                        gen_op_fstox();
1425 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1426 3475187d bellard
                        break;
1427 af7bf89b bellard
                    case 0x82: /* V9 fdtox */
1428 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1429 3475187d bellard
                        gen_op_fdtox();
1430 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1431 3475187d bellard
                        break;
1432 af7bf89b bellard
                    case 0x84: /* V9 fxtos */
1433 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1434 3475187d bellard
                        gen_op_fxtos();
1435 3475187d bellard
                        gen_op_store_FT0_fpr(rd);
1436 3475187d bellard
                        break;
1437 af7bf89b bellard
                    case 0x88: /* V9 fxtod */
1438 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1439 3475187d bellard
                        gen_op_fxtod();
1440 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1441 3475187d bellard
                        break;
1442 af7bf89b bellard
                    case 0x3: /* V9 fmovq */
1443 af7bf89b bellard
                    case 0x7: /* V9 fnegq */
1444 af7bf89b bellard
                    case 0xb: /* V9 fabsq */
1445 af7bf89b bellard
                    case 0x83: /* V9 fqtox */
1446 af7bf89b bellard
                    case 0x8c: /* V9 fxtoq */
1447 3475187d bellard
                        goto nfpu_insn;
1448 3475187d bellard
#endif
1449 3475187d bellard
                    default:
1450 e8af50a3 bellard
                        goto illegal_insn;
1451 e8af50a3 bellard
                }
1452 e80cfcfc bellard
            } else if (xop == 0x35) {        /* FPU Operations */
1453 3475187d bellard
#ifdef TARGET_SPARC64
1454 3475187d bellard
                int cond;
1455 3475187d bellard
#endif
1456 a80dde08 bellard
                if (gen_trap_ifnofpu(dc))
1457 a80dde08 bellard
                    goto jmp_insn;
1458 cf495bcf bellard
                rs1 = GET_FIELD(insn, 13, 17);
1459 e80cfcfc bellard
                rs2 = GET_FIELD(insn, 27, 31);
1460 e80cfcfc bellard
                xop = GET_FIELD(insn, 18, 26);
1461 3475187d bellard
#ifdef TARGET_SPARC64
1462 3475187d bellard
                if ((xop & 0x11f) == 0x005) { // V9 fmovsr
1463 3475187d bellard
                    cond = GET_FIELD_SP(insn, 14, 17);
1464 3475187d bellard
                    gen_op_load_fpr_FT0(rd);
1465 3475187d bellard
                    gen_op_load_fpr_FT1(rs2);
1466 3475187d bellard
                    rs1 = GET_FIELD(insn, 13, 17);
1467 3475187d bellard
                    gen_movl_reg_T0(rs1);
1468 3475187d bellard
                    flush_T2(dc);
1469 3475187d bellard
                    gen_cond_reg(cond);
1470 3475187d bellard
                    gen_op_fmovs_cc();
1471 3475187d bellard
                    gen_op_store_FT0_fpr(rd);
1472 3475187d bellard
                    break;
1473 3475187d bellard
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
1474 3475187d bellard
                    cond = GET_FIELD_SP(insn, 14, 17);
1475 3475187d bellard
                    gen_op_load_fpr_DT0(rd);
1476 3475187d bellard
                    gen_op_load_fpr_DT1(rs2);
1477 3475187d bellard
                    flush_T2(dc);
1478 3475187d bellard
                    rs1 = GET_FIELD(insn, 13, 17);
1479 3475187d bellard
                    gen_movl_reg_T0(rs1);
1480 3475187d bellard
                    gen_cond_reg(cond);
1481 3475187d bellard
                    gen_op_fmovs_cc();
1482 3475187d bellard
                    gen_op_store_DT0_fpr(rd);
1483 3475187d bellard
                    break;
1484 3475187d bellard
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
1485 3475187d bellard
                    goto nfpu_insn;
1486 3475187d bellard
                }
1487 3475187d bellard
#endif
1488 e80cfcfc bellard
                switch (xop) {
1489 3475187d bellard
#ifdef TARGET_SPARC64
1490 3475187d bellard
                    case 0x001: /* V9 fmovscc %fcc0 */
1491 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1492 3475187d bellard
                        gen_op_load_fpr_FT0(rd);
1493 3475187d bellard
                        gen_op_load_fpr_FT1(rs2);
1494 3475187d bellard
                        flush_T2(dc);
1495 3475187d bellard
                        gen_fcond[0][cond]();
1496 3475187d bellard
                        gen_op_fmovs_cc();
1497 3475187d bellard
                        gen_op_store_FT0_fpr(rd);
1498 3475187d bellard
                        break;
1499 3475187d bellard
                    case 0x002: /* V9 fmovdcc %fcc0 */
1500 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1501 3475187d bellard
                        gen_op_load_fpr_DT0(rd);
1502 3475187d bellard
                        gen_op_load_fpr_DT1(rs2);
1503 3475187d bellard
                        flush_T2(dc);
1504 3475187d bellard
                        gen_fcond[0][cond]();
1505 3475187d bellard
                        gen_op_fmovd_cc();
1506 3475187d bellard
                        gen_op_store_DT0_fpr(rd);
1507 3475187d bellard
                        break;
1508 3475187d bellard
                    case 0x003: /* V9 fmovqcc %fcc0 */
1509 3475187d bellard
                        goto nfpu_insn;
1510 3475187d bellard
                    case 0x041: /* V9 fmovscc %fcc1 */
1511 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1512 3475187d bellard
                        gen_op_load_fpr_FT0(rd);
1513 3475187d bellard
                        gen_op_load_fpr_FT1(rs2);
1514 3475187d bellard
                        flush_T2(dc);
1515 3475187d bellard
                        gen_fcond[1][cond]();
1516 3475187d bellard
                        gen_op_fmovs_cc();
1517 3475187d bellard
                        gen_op_store_FT0_fpr(rd);
1518 3475187d bellard
                        break;
1519 3475187d bellard
                    case 0x042: /* V9 fmovdcc %fcc1 */
1520 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1521 3475187d bellard
                        gen_op_load_fpr_DT0(rd);
1522 3475187d bellard
                        gen_op_load_fpr_DT1(rs2);
1523 3475187d bellard
                        flush_T2(dc);
1524 3475187d bellard
                        gen_fcond[1][cond]();
1525 3475187d bellard
                        gen_op_fmovd_cc();
1526 3475187d bellard
                        gen_op_store_DT0_fpr(rd);
1527 3475187d bellard
                        break;
1528 3475187d bellard
                    case 0x043: /* V9 fmovqcc %fcc1 */
1529 3475187d bellard
                        goto nfpu_insn;
1530 3475187d bellard
                    case 0x081: /* V9 fmovscc %fcc2 */
1531 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1532 3475187d bellard
                        gen_op_load_fpr_FT0(rd);
1533 3475187d bellard
                        gen_op_load_fpr_FT1(rs2);
1534 3475187d bellard
                        flush_T2(dc);
1535 3475187d bellard
                        gen_fcond[2][cond]();
1536 3475187d bellard
                        gen_op_fmovs_cc();
1537 3475187d bellard
                        gen_op_store_FT0_fpr(rd);
1538 3475187d bellard
                        break;
1539 3475187d bellard
                    case 0x082: /* V9 fmovdcc %fcc2 */
1540 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1541 3475187d bellard
                        gen_op_load_fpr_DT0(rd);
1542 3475187d bellard
                        gen_op_load_fpr_DT1(rs2);
1543 3475187d bellard
                        flush_T2(dc);
1544 3475187d bellard
                        gen_fcond[2][cond]();
1545 3475187d bellard
                        gen_op_fmovd_cc();
1546 3475187d bellard
                        gen_op_store_DT0_fpr(rd);
1547 3475187d bellard
                        break;
1548 3475187d bellard
                    case 0x083: /* V9 fmovqcc %fcc2 */
1549 3475187d bellard
                        goto nfpu_insn;
1550 3475187d bellard
                    case 0x0c1: /* V9 fmovscc %fcc3 */
1551 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1552 3475187d bellard
                        gen_op_load_fpr_FT0(rd);
1553 3475187d bellard
                        gen_op_load_fpr_FT1(rs2);
1554 3475187d bellard
                        flush_T2(dc);
1555 3475187d bellard
                        gen_fcond[3][cond]();
1556 3475187d bellard
                        gen_op_fmovs_cc();
1557 3475187d bellard
                        gen_op_store_FT0_fpr(rd);
1558 3475187d bellard
                        break;
1559 3475187d bellard
                    case 0x0c2: /* V9 fmovdcc %fcc3 */
1560 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1561 3475187d bellard
                        gen_op_load_fpr_DT0(rd);
1562 3475187d bellard
                        gen_op_load_fpr_DT1(rs2);
1563 3475187d bellard
                        flush_T2(dc);
1564 3475187d bellard
                        gen_fcond[3][cond]();
1565 3475187d bellard
                        gen_op_fmovd_cc();
1566 3475187d bellard
                        gen_op_store_DT0_fpr(rd);
1567 3475187d bellard
                        break;
1568 3475187d bellard
                    case 0x0c3: /* V9 fmovqcc %fcc3 */
1569 3475187d bellard
                        goto nfpu_insn;
1570 3475187d bellard
                    case 0x101: /* V9 fmovscc %icc */
1571 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1572 3475187d bellard
                        gen_op_load_fpr_FT0(rd);
1573 3475187d bellard
                        gen_op_load_fpr_FT1(rs2);
1574 3475187d bellard
                        flush_T2(dc);
1575 3475187d bellard
                        gen_cond[0][cond]();
1576 3475187d bellard
                        gen_op_fmovs_cc();
1577 3475187d bellard
                        gen_op_store_FT0_fpr(rd);
1578 3475187d bellard
                        break;
1579 3475187d bellard
                    case 0x102: /* V9 fmovdcc %icc */
1580 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1581 3475187d bellard
                        gen_op_load_fpr_DT0(rd);
1582 3475187d bellard
                        gen_op_load_fpr_DT1(rs2);
1583 3475187d bellard
                        flush_T2(dc);
1584 3475187d bellard
                        gen_cond[0][cond]();
1585 3475187d bellard
                        gen_op_fmovd_cc();
1586 3475187d bellard
                        gen_op_store_DT0_fpr(rd);
1587 3475187d bellard
                        break;
1588 3475187d bellard
                    case 0x103: /* V9 fmovqcc %icc */
1589 3475187d bellard
                        goto nfpu_insn;
1590 3475187d bellard
                    case 0x181: /* V9 fmovscc %xcc */
1591 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1592 3475187d bellard
                        gen_op_load_fpr_FT0(rd);
1593 3475187d bellard
                        gen_op_load_fpr_FT1(rs2);
1594 3475187d bellard
                        flush_T2(dc);
1595 3475187d bellard
                        gen_cond[1][cond]();
1596 3475187d bellard
                        gen_op_fmovs_cc();
1597 3475187d bellard
                        gen_op_store_FT0_fpr(rd);
1598 3475187d bellard
                        break;
1599 3475187d bellard
                    case 0x182: /* V9 fmovdcc %xcc */
1600 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1601 3475187d bellard
                        gen_op_load_fpr_DT0(rd);
1602 3475187d bellard
                        gen_op_load_fpr_DT1(rs2);
1603 3475187d bellard
                        flush_T2(dc);
1604 3475187d bellard
                        gen_cond[1][cond]();
1605 3475187d bellard
                        gen_op_fmovd_cc();
1606 3475187d bellard
                        gen_op_store_DT0_fpr(rd);
1607 3475187d bellard
                        break;
1608 3475187d bellard
                    case 0x183: /* V9 fmovqcc %xcc */
1609 3475187d bellard
                        goto nfpu_insn;
1610 3475187d bellard
#endif
1611 3475187d bellard
                    case 0x51: /* V9 %fcc */
1612 e80cfcfc bellard
                        gen_op_load_fpr_FT0(rs1);
1613 e80cfcfc bellard
                        gen_op_load_fpr_FT1(rs2);
1614 3475187d bellard
#ifdef TARGET_SPARC64
1615 3475187d bellard
                        gen_fcmps[rd & 3]();
1616 3475187d bellard
#else
1617 e80cfcfc bellard
                        gen_op_fcmps();
1618 3475187d bellard
#endif
1619 e80cfcfc bellard
                        break;
1620 3475187d bellard
                    case 0x52: /* V9 %fcc */
1621 3475187d bellard
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1622 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1623 3475187d bellard
#ifdef TARGET_SPARC64
1624 3475187d bellard
                        gen_fcmpd[rd & 3]();
1625 3475187d bellard
#else
1626 e80cfcfc bellard
                        gen_op_fcmpd();
1627 3475187d bellard
#endif
1628 e80cfcfc bellard
                        break;
1629 e80cfcfc bellard
                    case 0x53: /* fcmpq */
1630 e80cfcfc bellard
                        goto nfpu_insn;
1631 3475187d bellard
                    case 0x55: /* fcmpes, V9 %fcc */
1632 e80cfcfc bellard
                        gen_op_load_fpr_FT0(rs1);
1633 e80cfcfc bellard
                        gen_op_load_fpr_FT1(rs2);
1634 3475187d bellard
#ifdef TARGET_SPARC64
1635 3475187d bellard
                        gen_fcmps[rd & 3]();
1636 3475187d bellard
#else
1637 e80cfcfc bellard
                        gen_op_fcmps(); /* XXX should trap if qNaN or sNaN  */
1638 3475187d bellard
#endif
1639 e80cfcfc bellard
                        break;
1640 3475187d bellard
                    case 0x56: /* fcmped, V9 %fcc */
1641 3475187d bellard
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1642 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1643 3475187d bellard
#ifdef TARGET_SPARC64
1644 3475187d bellard
                        gen_fcmpd[rd & 3]();
1645 3475187d bellard
#else
1646 e80cfcfc bellard
                        gen_op_fcmpd(); /* XXX should trap if qNaN or sNaN  */
1647 3475187d bellard
#endif
1648 e80cfcfc bellard
                        break;
1649 e80cfcfc bellard
                    case 0x57: /* fcmpeq */
1650 e80cfcfc bellard
                        goto nfpu_insn;
1651 e80cfcfc bellard
                    default:
1652 e80cfcfc bellard
                        goto illegal_insn;
1653 e80cfcfc bellard
                }
1654 e80cfcfc bellard
#if defined(OPTIM)
1655 e80cfcfc bellard
            } else if (xop == 0x2) {
1656 e80cfcfc bellard
                // clr/mov shortcut
1657 e80cfcfc bellard
1658 e80cfcfc bellard
                rs1 = GET_FIELD(insn, 13, 17);
1659 e80cfcfc bellard
                if (rs1 == 0) {
1660 e80cfcfc bellard
                    // or %g0, x, y -> mov T1, x; mov y, T1
1661 e80cfcfc bellard
                    if (IS_IMM) {        /* immediate */
1662 e80cfcfc bellard
                        rs2 = GET_FIELDs(insn, 19, 31);
1663 3475187d bellard
                        gen_movl_simm_T1(rs2);
1664 e80cfcfc bellard
                    } else {                /* register */
1665 e80cfcfc bellard
                        rs2 = GET_FIELD(insn, 27, 31);
1666 e80cfcfc bellard
                        gen_movl_reg_T1(rs2);
1667 e80cfcfc bellard
                    }
1668 e80cfcfc bellard
                    gen_movl_T1_reg(rd);
1669 e80cfcfc bellard
                } else {
1670 e80cfcfc bellard
                    gen_movl_reg_T0(rs1);
1671 e80cfcfc bellard
                    if (IS_IMM) {        /* immediate */
1672 e80cfcfc bellard
                        // or x, #0, y -> mov T1, x; mov y, T1
1673 e80cfcfc bellard
                        rs2 = GET_FIELDs(insn, 19, 31);
1674 e80cfcfc bellard
                        if (rs2 != 0) {
1675 3475187d bellard
                            gen_movl_simm_T1(rs2);
1676 e80cfcfc bellard
                            gen_op_or_T1_T0();
1677 e80cfcfc bellard
                        }
1678 e80cfcfc bellard
                    } else {                /* register */
1679 e80cfcfc bellard
                        // or x, %g0, y -> mov T1, x; mov y, T1
1680 e80cfcfc bellard
                        rs2 = GET_FIELD(insn, 27, 31);
1681 e80cfcfc bellard
                        if (rs2 != 0) {
1682 e80cfcfc bellard
                            gen_movl_reg_T1(rs2);
1683 e80cfcfc bellard
                            gen_op_or_T1_T0();
1684 e80cfcfc bellard
                        }
1685 e80cfcfc bellard
                    }
1686 e80cfcfc bellard
                    gen_movl_T0_reg(rd);
1687 e80cfcfc bellard
                }
1688 e80cfcfc bellard
#endif
1689 83469015 bellard
#ifdef TARGET_SPARC64
1690 83469015 bellard
            } else if (xop == 0x25) { /* sll, V9 sllx ( == sll) */
1691 83469015 bellard
                rs1 = GET_FIELD(insn, 13, 17);
1692 83469015 bellard
                gen_movl_reg_T0(rs1);
1693 83469015 bellard
                if (IS_IMM) {        /* immediate */
1694 83469015 bellard
                    rs2 = GET_FIELDs(insn, 20, 31);
1695 83469015 bellard
                    gen_movl_simm_T1(rs2);
1696 83469015 bellard
                } else {                /* register */
1697 83469015 bellard
                    rs2 = GET_FIELD(insn, 27, 31);
1698 83469015 bellard
                    gen_movl_reg_T1(rs2);
1699 83469015 bellard
                }
1700 83469015 bellard
                gen_op_sll();
1701 83469015 bellard
                gen_movl_T0_reg(rd);
1702 83469015 bellard
            } else if (xop == 0x26) { /* srl, V9 srlx */
1703 83469015 bellard
                rs1 = GET_FIELD(insn, 13, 17);
1704 83469015 bellard
                gen_movl_reg_T0(rs1);
1705 83469015 bellard
                if (IS_IMM) {        /* immediate */
1706 83469015 bellard
                    rs2 = GET_FIELDs(insn, 20, 31);
1707 83469015 bellard
                    gen_movl_simm_T1(rs2);
1708 83469015 bellard
                } else {                /* register */
1709 83469015 bellard
                    rs2 = GET_FIELD(insn, 27, 31);
1710 83469015 bellard
                    gen_movl_reg_T1(rs2);
1711 83469015 bellard
                }
1712 83469015 bellard
                if (insn & (1 << 12))
1713 83469015 bellard
                    gen_op_srlx();
1714 83469015 bellard
                else
1715 83469015 bellard
                    gen_op_srl();
1716 83469015 bellard
                gen_movl_T0_reg(rd);
1717 83469015 bellard
            } else if (xop == 0x27) { /* sra, V9 srax */
1718 83469015 bellard
                rs1 = GET_FIELD(insn, 13, 17);
1719 83469015 bellard
                gen_movl_reg_T0(rs1);
1720 83469015 bellard
                if (IS_IMM) {        /* immediate */
1721 83469015 bellard
                    rs2 = GET_FIELDs(insn, 20, 31);
1722 83469015 bellard
                    gen_movl_simm_T1(rs2);
1723 83469015 bellard
                } else {                /* register */
1724 83469015 bellard
                    rs2 = GET_FIELD(insn, 27, 31);
1725 83469015 bellard
                    gen_movl_reg_T1(rs2);
1726 83469015 bellard
                }
1727 83469015 bellard
                if (insn & (1 << 12))
1728 83469015 bellard
                    gen_op_srax();
1729 83469015 bellard
                else
1730 83469015 bellard
                    gen_op_sra();
1731 83469015 bellard
                gen_movl_T0_reg(rd);
1732 83469015 bellard
#endif
1733 e80cfcfc bellard
            } else if (xop < 0x38) {
1734 e80cfcfc bellard
                rs1 = GET_FIELD(insn, 13, 17);
1735 e80cfcfc bellard
                gen_movl_reg_T0(rs1);
1736 e80cfcfc bellard
                if (IS_IMM) {        /* immediate */
1737 cf495bcf bellard
                    rs2 = GET_FIELDs(insn, 19, 31);
1738 3475187d bellard
                    gen_movl_simm_T1(rs2);
1739 cf495bcf bellard
                } else {                /* register */
1740 cf495bcf bellard
                    rs2 = GET_FIELD(insn, 27, 31);
1741 cf495bcf bellard
                    gen_movl_reg_T1(rs2);
1742 cf495bcf bellard
                }
1743 cf495bcf bellard
                if (xop < 0x20) {
1744 cf495bcf bellard
                    switch (xop & ~0x10) {
1745 cf495bcf bellard
                    case 0x0:
1746 cf495bcf bellard
                        if (xop & 0x10)
1747 cf495bcf bellard
                            gen_op_add_T1_T0_cc();
1748 cf495bcf bellard
                        else
1749 cf495bcf bellard
                            gen_op_add_T1_T0();
1750 cf495bcf bellard
                        break;
1751 cf495bcf bellard
                    case 0x1:
1752 cf495bcf bellard
                        gen_op_and_T1_T0();
1753 cf495bcf bellard
                        if (xop & 0x10)
1754 cf495bcf bellard
                            gen_op_logic_T0_cc();
1755 cf495bcf bellard
                        break;
1756 cf495bcf bellard
                    case 0x2:
1757 e80cfcfc bellard
                        gen_op_or_T1_T0();
1758 e80cfcfc bellard
                        if (xop & 0x10)
1759 e80cfcfc bellard
                            gen_op_logic_T0_cc();
1760 e80cfcfc bellard
                        break;
1761 cf495bcf bellard
                    case 0x3:
1762 cf495bcf bellard
                        gen_op_xor_T1_T0();
1763 cf495bcf bellard
                        if (xop & 0x10)
1764 cf495bcf bellard
                            gen_op_logic_T0_cc();
1765 cf495bcf bellard
                        break;
1766 cf495bcf bellard
                    case 0x4:
1767 cf495bcf bellard
                        if (xop & 0x10)
1768 cf495bcf bellard
                            gen_op_sub_T1_T0_cc();
1769 cf495bcf bellard
                        else
1770 cf495bcf bellard
                            gen_op_sub_T1_T0();
1771 cf495bcf bellard
                        break;
1772 cf495bcf bellard
                    case 0x5:
1773 cf495bcf bellard
                        gen_op_andn_T1_T0();
1774 cf495bcf bellard
                        if (xop & 0x10)
1775 cf495bcf bellard
                            gen_op_logic_T0_cc();
1776 cf495bcf bellard
                        break;
1777 cf495bcf bellard
                    case 0x6:
1778 cf495bcf bellard
                        gen_op_orn_T1_T0();
1779 cf495bcf bellard
                        if (xop & 0x10)
1780 cf495bcf bellard
                            gen_op_logic_T0_cc();
1781 cf495bcf bellard
                        break;
1782 cf495bcf bellard
                    case 0x7:
1783 cf495bcf bellard
                        gen_op_xnor_T1_T0();
1784 cf495bcf bellard
                        if (xop & 0x10)
1785 cf495bcf bellard
                            gen_op_logic_T0_cc();
1786 cf495bcf bellard
                        break;
1787 cf495bcf bellard
                    case 0x8:
1788 cf495bcf bellard
                        if (xop & 0x10)
1789 af7bf89b bellard
                            gen_op_addx_T1_T0_cc();
1790 af7bf89b bellard
                        else
1791 af7bf89b bellard
                            gen_op_addx_T1_T0();
1792 cf495bcf bellard
                        break;
1793 ded3ab80 pbrook
#ifdef TARGET_SPARC64
1794 ded3ab80 pbrook
                    case 0x9: /* V9 mulx */
1795 ded3ab80 pbrook
                        gen_op_mulx_T1_T0();
1796 ded3ab80 pbrook
                        break;
1797 ded3ab80 pbrook
#endif
1798 cf495bcf bellard
                    case 0xa:
1799 cf495bcf bellard
                        gen_op_umul_T1_T0();
1800 cf495bcf bellard
                        if (xop & 0x10)
1801 cf495bcf bellard
                            gen_op_logic_T0_cc();
1802 cf495bcf bellard
                        break;
1803 cf495bcf bellard
                    case 0xb:
1804 cf495bcf bellard
                        gen_op_smul_T1_T0();
1805 cf495bcf bellard
                        if (xop & 0x10)
1806 cf495bcf bellard
                            gen_op_logic_T0_cc();
1807 cf495bcf bellard
                        break;
1808 cf495bcf bellard
                    case 0xc:
1809 cf495bcf bellard
                        if (xop & 0x10)
1810 af7bf89b bellard
                            gen_op_subx_T1_T0_cc();
1811 af7bf89b bellard
                        else
1812 af7bf89b bellard
                            gen_op_subx_T1_T0();
1813 cf495bcf bellard
                        break;
1814 ded3ab80 pbrook
#ifdef TARGET_SPARC64
1815 ded3ab80 pbrook
                    case 0xd: /* V9 udivx */
1816 ded3ab80 pbrook
                        gen_op_udivx_T1_T0();
1817 ded3ab80 pbrook
                        break;
1818 ded3ab80 pbrook
#endif
1819 cf495bcf bellard
                    case 0xe:
1820 cf495bcf bellard
                        gen_op_udiv_T1_T0();
1821 cf495bcf bellard
                        if (xop & 0x10)
1822 cf495bcf bellard
                            gen_op_div_cc();
1823 cf495bcf bellard
                        break;
1824 cf495bcf bellard
                    case 0xf:
1825 cf495bcf bellard
                        gen_op_sdiv_T1_T0();
1826 cf495bcf bellard
                        if (xop & 0x10)
1827 cf495bcf bellard
                            gen_op_div_cc();
1828 cf495bcf bellard
                        break;
1829 cf495bcf bellard
                    default:
1830 cf495bcf bellard
                        goto illegal_insn;
1831 cf495bcf bellard
                    }
1832 e80cfcfc bellard
                    gen_movl_T0_reg(rd);
1833 cf495bcf bellard
                } else {
1834 cf495bcf bellard
                    switch (xop) {
1835 e80cfcfc bellard
                    case 0x20: /* taddcc */
1836 e80cfcfc bellard
                    case 0x21: /* tsubcc */
1837 e80cfcfc bellard
                    case 0x22: /* taddcctv */
1838 e80cfcfc bellard
                    case 0x23: /* tsubcctv */
1839 e80cfcfc bellard
                        goto illegal_insn;
1840 cf495bcf bellard
                    case 0x24: /* mulscc */
1841 cf495bcf bellard
                        gen_op_mulscc_T1_T0();
1842 cf495bcf bellard
                        gen_movl_T0_reg(rd);
1843 cf495bcf bellard
                        break;
1844 83469015 bellard
#ifndef TARGET_SPARC64
1845 83469015 bellard
                    case 0x25:        /* sll */
1846 3475187d bellard
                        gen_op_sll();
1847 cf495bcf bellard
                        gen_movl_T0_reg(rd);
1848 cf495bcf bellard
                        break;
1849 83469015 bellard
                    case 0x26:  /* srl */
1850 3475187d bellard
                        gen_op_srl();
1851 cf495bcf bellard
                        gen_movl_T0_reg(rd);
1852 cf495bcf bellard
                        break;
1853 83469015 bellard
                    case 0x27:  /* sra */
1854 3475187d bellard
                        gen_op_sra();
1855 cf495bcf bellard
                        gen_movl_T0_reg(rd);
1856 cf495bcf bellard
                        break;
1857 83469015 bellard
#endif
1858 cf495bcf bellard
                    case 0x30:
1859 cf495bcf bellard
                        {
1860 cf495bcf bellard
                            switch(rd) {
1861 3475187d bellard
                            case 0: /* wry */
1862 3475187d bellard
                                gen_op_xor_T1_T0();
1863 3475187d bellard
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, y));
1864 cf495bcf bellard
                                break;
1865 3475187d bellard
#ifdef TARGET_SPARC64
1866 af7bf89b bellard
                            case 0x2: /* V9 wrccr */
1867 3475187d bellard
                                gen_op_wrccr();
1868 3475187d bellard
                                break;
1869 af7bf89b bellard
                            case 0x3: /* V9 wrasi */
1870 3475187d bellard
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, asi));
1871 3475187d bellard
                                break;
1872 af7bf89b bellard
                            case 0x6: /* V9 wrfprs */
1873 3475187d bellard
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, fprs));
1874 3475187d bellard
                                break;
1875 3475187d bellard
                            case 0xf: /* V9 sir, nop if user */
1876 3475187d bellard
#if !defined(CONFIG_USER_ONLY)
1877 3475187d bellard
                                if (supervisor(dc))
1878 3475187d bellard
                                    gen_op_sir();
1879 3475187d bellard
#endif
1880 3475187d bellard
                                break;
1881 725cb90b bellard
                            case 0x13: /* Graphics Status */
1882 725cb90b bellard
                                if (gen_trap_ifnofpu(dc))
1883 725cb90b bellard
                                    goto jmp_insn;
1884 725cb90b bellard
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, gsr));
1885 725cb90b bellard
                                break;
1886 83469015 bellard
                            case 0x17: /* Tick compare */
1887 83469015 bellard
#if !defined(CONFIG_USER_ONLY)
1888 83469015 bellard
                                if (!supervisor(dc))
1889 83469015 bellard
                                    goto illegal_insn;
1890 83469015 bellard
#endif
1891 83469015 bellard
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, tick_cmpr));
1892 83469015 bellard
                                break;
1893 83469015 bellard
                            case 0x18: /* System tick */
1894 83469015 bellard
#if !defined(CONFIG_USER_ONLY)
1895 83469015 bellard
                                if (!supervisor(dc))
1896 83469015 bellard
                                    goto illegal_insn;
1897 83469015 bellard
#endif
1898 83469015 bellard
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, stick_cmpr));
1899 83469015 bellard
                                break;
1900 83469015 bellard
                            case 0x19: /* System tick compare */
1901 83469015 bellard
#if !defined(CONFIG_USER_ONLY)
1902 83469015 bellard
                                if (!supervisor(dc))
1903 83469015 bellard
                                    goto illegal_insn;
1904 3475187d bellard
#endif
1905 83469015 bellard
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, stick_cmpr));
1906 83469015 bellard
                                break;
1907 83469015 bellard
1908 3475187d bellard
                            case 0x10: /* Performance Control */
1909 3475187d bellard
                            case 0x11: /* Performance Instrumentation Counter */
1910 3475187d bellard
                            case 0x12: /* Dispatch Control */
1911 3475187d bellard
                            case 0x14: /* Softint set */
1912 3475187d bellard
                            case 0x15: /* Softint clear */
1913 3475187d bellard
                            case 0x16: /* Softint write */
1914 83469015 bellard
#endif
1915 3475187d bellard
                            default:
1916 cf495bcf bellard
                                goto illegal_insn;
1917 cf495bcf bellard
                            }
1918 cf495bcf bellard
                        }
1919 cf495bcf bellard
                        break;
1920 e8af50a3 bellard
#if !defined(CONFIG_USER_ONLY)
1921 af7bf89b bellard
                    case 0x31: /* wrpsr, V9 saved, restored */
1922 e8af50a3 bellard
                        {
1923 e8af50a3 bellard
                            if (!supervisor(dc))
1924 e8af50a3 bellard
                                goto priv_insn;
1925 3475187d bellard
#ifdef TARGET_SPARC64
1926 3475187d bellard
                            switch (rd) {
1927 3475187d bellard
                            case 0:
1928 3475187d bellard
                                gen_op_saved();
1929 3475187d bellard
                                break;
1930 3475187d bellard
                            case 1:
1931 3475187d bellard
                                gen_op_restored();
1932 3475187d bellard
                                break;
1933 3475187d bellard
                            default:
1934 3475187d bellard
                                goto illegal_insn;
1935 3475187d bellard
                            }
1936 3475187d bellard
#else
1937 e8af50a3 bellard
                            gen_op_xor_T1_T0();
1938 e8af50a3 bellard
                            gen_op_wrpsr();
1939 9e61bde5 bellard
                            save_state(dc);
1940 9e61bde5 bellard
                            gen_op_next_insn();
1941 9e61bde5 bellard
                            gen_op_movl_T0_0();
1942 9e61bde5 bellard
                            gen_op_exit_tb();
1943 9e61bde5 bellard
                            dc->is_br = 1;
1944 3475187d bellard
#endif
1945 e8af50a3 bellard
                        }
1946 e8af50a3 bellard
                        break;
1947 af7bf89b bellard
                    case 0x32: /* wrwim, V9 wrpr */
1948 e8af50a3 bellard
                        {
1949 e8af50a3 bellard
                            if (!supervisor(dc))
1950 e8af50a3 bellard
                                goto priv_insn;
1951 e8af50a3 bellard
                            gen_op_xor_T1_T0();
1952 3475187d bellard
#ifdef TARGET_SPARC64
1953 3475187d bellard
                            switch (rd) {
1954 3475187d bellard
                            case 0: // tpc
1955 3475187d bellard
                                gen_op_wrtpc();
1956 3475187d bellard
                                break;
1957 3475187d bellard
                            case 1: // tnpc
1958 3475187d bellard
                                gen_op_wrtnpc();
1959 3475187d bellard
                                break;
1960 3475187d bellard
                            case 2: // tstate
1961 3475187d bellard
                                gen_op_wrtstate();
1962 3475187d bellard
                                break;
1963 3475187d bellard
                            case 3: // tt
1964 3475187d bellard
                                gen_op_wrtt();
1965 3475187d bellard
                                break;
1966 3475187d bellard
                            case 4: // tick
1967 3475187d bellard
                                gen_op_wrtick();
1968 3475187d bellard
                                break;
1969 3475187d bellard
                            case 5: // tba
1970 83469015 bellard
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
1971 3475187d bellard
                                break;
1972 3475187d bellard
                            case 6: // pstate
1973 3475187d bellard
                                gen_op_wrpstate();
1974 ded3ab80 pbrook
                                save_state(dc);
1975 ded3ab80 pbrook
                                gen_op_next_insn();
1976 ded3ab80 pbrook
                                gen_op_movl_T0_0();
1977 ded3ab80 pbrook
                                gen_op_exit_tb();
1978 ded3ab80 pbrook
                                dc->is_br = 1;
1979 3475187d bellard
                                break;
1980 3475187d bellard
                            case 7: // tl
1981 3475187d bellard
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, tl));
1982 3475187d bellard
                                break;
1983 3475187d bellard
                            case 8: // pil
1984 3475187d bellard
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, psrpil));
1985 3475187d bellard
                                break;
1986 3475187d bellard
                            case 9: // cwp
1987 3475187d bellard
                                gen_op_wrcwp();
1988 3475187d bellard
                                break;
1989 3475187d bellard
                            case 10: // cansave
1990 3475187d bellard
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, cansave));
1991 3475187d bellard
                                break;
1992 3475187d bellard
                            case 11: // canrestore
1993 3475187d bellard
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, canrestore));
1994 3475187d bellard
                                break;
1995 3475187d bellard
                            case 12: // cleanwin
1996 3475187d bellard
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, cleanwin));
1997 3475187d bellard
                                break;
1998 3475187d bellard
                            case 13: // otherwin
1999 3475187d bellard
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, otherwin));
2000 3475187d bellard
                                break;
2001 3475187d bellard
                            case 14: // wstate
2002 3475187d bellard
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, wstate));
2003 3475187d bellard
                                break;
2004 3475187d bellard
                            default:
2005 3475187d bellard
                                goto illegal_insn;
2006 3475187d bellard
                            }
2007 3475187d bellard
#else
2008 c688a6eb bellard
                            gen_op_wrwim();
2009 3475187d bellard
#endif
2010 e8af50a3 bellard
                        }
2011 e8af50a3 bellard
                        break;
2012 3475187d bellard
#ifndef TARGET_SPARC64
2013 3475187d bellard
                    case 0x33: /* wrtbr, V9 unimp */
2014 e8af50a3 bellard
                        {
2015 e8af50a3 bellard
                            if (!supervisor(dc))
2016 e8af50a3 bellard
                                goto priv_insn;
2017 e8af50a3 bellard
                            gen_op_xor_T1_T0();
2018 3475187d bellard
                            gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
2019 e8af50a3 bellard
                        }
2020 e8af50a3 bellard
                        break;
2021 e8af50a3 bellard
#endif
2022 3475187d bellard
#endif
2023 3475187d bellard
#ifdef TARGET_SPARC64
2024 af7bf89b bellard
                    case 0x2c: /* V9 movcc */
2025 3475187d bellard
                        {
2026 3475187d bellard
                            int cc = GET_FIELD_SP(insn, 11, 12);
2027 3475187d bellard
                            int cond = GET_FIELD_SP(insn, 14, 17);
2028 3475187d bellard
                            if (IS_IMM) {        /* immediate */
2029 3475187d bellard
                                rs2 = GET_FIELD_SPs(insn, 0, 10);
2030 3475187d bellard
                                gen_movl_simm_T1(rs2);
2031 3475187d bellard
                            }
2032 3475187d bellard
                            else {
2033 3475187d bellard
                                rs2 = GET_FIELD_SP(insn, 0, 4);
2034 3475187d bellard
                                gen_movl_reg_T1(rs2);
2035 3475187d bellard
                            }
2036 3475187d bellard
                            gen_movl_reg_T0(rd);
2037 3475187d bellard
                            flush_T2(dc);
2038 3475187d bellard
                            if (insn & (1 << 18)) {
2039 3475187d bellard
                                if (cc == 0)
2040 3475187d bellard
                                    gen_cond[0][cond]();
2041 3475187d bellard
                                else if (cc == 2)
2042 3475187d bellard
                                    gen_cond[1][cond]();
2043 3475187d bellard
                                else
2044 3475187d bellard
                                    goto illegal_insn;
2045 3475187d bellard
                            } else {
2046 3475187d bellard
                                gen_fcond[cc][cond]();
2047 3475187d bellard
                            }
2048 3475187d bellard
                            gen_op_mov_cc();
2049 3475187d bellard
                            gen_movl_T0_reg(rd);
2050 3475187d bellard
                            break;
2051 3475187d bellard
                        }
2052 af7bf89b bellard
                    case 0x2d: /* V9 sdivx */
2053 3475187d bellard
                        gen_op_sdivx_T1_T0();
2054 3475187d bellard
                        gen_movl_T0_reg(rd);
2055 3475187d bellard
                        break;
2056 af7bf89b bellard
                    case 0x2e: /* V9 popc */
2057 3475187d bellard
                        {
2058 3475187d bellard
                            if (IS_IMM) {        /* immediate */
2059 3475187d bellard
                                rs2 = GET_FIELD_SPs(insn, 0, 12);
2060 3475187d bellard
                                gen_movl_simm_T1(rs2);
2061 3475187d bellard
                                // XXX optimize: popc(constant)
2062 3475187d bellard
                            }
2063 3475187d bellard
                            else {
2064 3475187d bellard
                                rs2 = GET_FIELD_SP(insn, 0, 4);
2065 3475187d bellard
                                gen_movl_reg_T1(rs2);
2066 3475187d bellard
                            }
2067 3475187d bellard
                            gen_op_popc();
2068 3475187d bellard
                            gen_movl_T0_reg(rd);
2069 3475187d bellard
                        }
2070 af7bf89b bellard
                    case 0x2f: /* V9 movr */
2071 3475187d bellard
                        {
2072 3475187d bellard
                            int cond = GET_FIELD_SP(insn, 10, 12);
2073 3475187d bellard
                            rs1 = GET_FIELD(insn, 13, 17);
2074 3475187d bellard
                            flush_T2(dc);
2075 3475187d bellard
                            gen_movl_reg_T0(rs1);
2076 3475187d bellard
                            gen_cond_reg(cond);
2077 3475187d bellard
                            if (IS_IMM) {        /* immediate */
2078 3475187d bellard
                                rs2 = GET_FIELD_SPs(insn, 0, 10);
2079 3475187d bellard
                                gen_movl_simm_T1(rs2);
2080 3475187d bellard
                            }
2081 3475187d bellard
                            else {
2082 3475187d bellard
                                rs2 = GET_FIELD_SP(insn, 0, 4);
2083 3475187d bellard
                                gen_movl_reg_T1(rs2);
2084 3475187d bellard
                            }
2085 3475187d bellard
                            gen_movl_reg_T0(rd);
2086 3475187d bellard
                            gen_op_mov_cc();
2087 3475187d bellard
                            gen_movl_T0_reg(rd);
2088 3475187d bellard
                            break;
2089 3475187d bellard
                        }
2090 3475187d bellard
                    case 0x36: /* UltraSparc shutdown, VIS */
2091 3475187d bellard
                        {
2092 725cb90b bellard
                            int opf = GET_FIELD_SP(insn, 5, 13);
2093 725cb90b bellard
                            rs1 = GET_FIELD(insn, 13, 17);
2094 725cb90b bellard
                            rs2 = GET_FIELD(insn, 27, 31);
2095 725cb90b bellard
2096 725cb90b bellard
                            switch (opf) {
2097 725cb90b bellard
                            case 0x018: /* VIS I alignaddr */
2098 725cb90b bellard
                                if (gen_trap_ifnofpu(dc))
2099 725cb90b bellard
                                    goto jmp_insn;
2100 725cb90b bellard
                                gen_movl_reg_T0(rs1);
2101 725cb90b bellard
                                gen_movl_reg_T1(rs2);
2102 725cb90b bellard
                                gen_op_alignaddr();
2103 725cb90b bellard
                                gen_movl_T0_reg(rd);
2104 725cb90b bellard
                                break;
2105 725cb90b bellard
                            case 0x01a: /* VIS I alignaddrl */
2106 725cb90b bellard
                                if (gen_trap_ifnofpu(dc))
2107 725cb90b bellard
                                    goto jmp_insn;
2108 725cb90b bellard
                                // XXX
2109 725cb90b bellard
                                break;
2110 725cb90b bellard
                            case 0x048: /* VIS I faligndata */
2111 725cb90b bellard
                                if (gen_trap_ifnofpu(dc))
2112 725cb90b bellard
                                    goto jmp_insn;
2113 725cb90b bellard
                                gen_op_load_fpr_DT0(rs1);
2114 725cb90b bellard
                                gen_op_load_fpr_DT1(rs2);
2115 725cb90b bellard
                                gen_op_faligndata();
2116 725cb90b bellard
                                gen_op_store_DT0_fpr(rd);
2117 725cb90b bellard
                                break;
2118 725cb90b bellard
                            default:
2119 725cb90b bellard
                                goto illegal_insn;
2120 725cb90b bellard
                            }
2121 725cb90b bellard
                            break;
2122 3475187d bellard
                        }
2123 3475187d bellard
#endif
2124 3475187d bellard
                    default:
2125 e80cfcfc bellard
                        goto illegal_insn;
2126 e80cfcfc bellard
                    }
2127 e80cfcfc bellard
                }
2128 3475187d bellard
#ifdef TARGET_SPARC64
2129 3475187d bellard
            } else if (xop == 0x39) { /* V9 return */
2130 3475187d bellard
                rs1 = GET_FIELD(insn, 13, 17);
2131 3475187d bellard
                gen_movl_reg_T0(rs1);
2132 3475187d bellard
                if (IS_IMM) {        /* immediate */
2133 3475187d bellard
                    rs2 = GET_FIELDs(insn, 19, 31);
2134 3475187d bellard
#if defined(OPTIM)
2135 3475187d bellard
                    if (rs2) {
2136 3475187d bellard
#endif
2137 3475187d bellard
                        gen_movl_simm_T1(rs2);
2138 3475187d bellard
                        gen_op_add_T1_T0();
2139 3475187d bellard
#if defined(OPTIM)
2140 3475187d bellard
                    }
2141 3475187d bellard
#endif
2142 3475187d bellard
                } else {                /* register */
2143 3475187d bellard
                    rs2 = GET_FIELD(insn, 27, 31);
2144 3475187d bellard
#if defined(OPTIM)
2145 3475187d bellard
                    if (rs2) {
2146 3475187d bellard
#endif
2147 3475187d bellard
                        gen_movl_reg_T1(rs2);
2148 3475187d bellard
                        gen_op_add_T1_T0();
2149 3475187d bellard
#if defined(OPTIM)
2150 3475187d bellard
                    }
2151 3475187d bellard
#endif
2152 3475187d bellard
                }
2153 83469015 bellard
                gen_op_restore();
2154 3475187d bellard
                gen_mov_pc_npc(dc);
2155 3475187d bellard
                gen_op_movl_npc_T0();
2156 3475187d bellard
                dc->npc = DYNAMIC_PC;
2157 3475187d bellard
                goto jmp_insn;
2158 3475187d bellard
#endif
2159 e80cfcfc bellard
            } else {
2160 e80cfcfc bellard
                rs1 = GET_FIELD(insn, 13, 17);
2161 e80cfcfc bellard
                gen_movl_reg_T0(rs1);
2162 e80cfcfc bellard
                if (IS_IMM) {        /* immediate */
2163 e80cfcfc bellard
                    rs2 = GET_FIELDs(insn, 19, 31);
2164 e80cfcfc bellard
#if defined(OPTIM)
2165 e80cfcfc bellard
                    if (rs2) {
2166 e8af50a3 bellard
#endif
2167 3475187d bellard
                        gen_movl_simm_T1(rs2);
2168 e80cfcfc bellard
                        gen_op_add_T1_T0();
2169 e80cfcfc bellard
#if defined(OPTIM)
2170 e80cfcfc bellard
                    }
2171 e8af50a3 bellard
#endif
2172 e80cfcfc bellard
                } else {                /* register */
2173 e80cfcfc bellard
                    rs2 = GET_FIELD(insn, 27, 31);
2174 e80cfcfc bellard
#if defined(OPTIM)
2175 e80cfcfc bellard
                    if (rs2) {
2176 e80cfcfc bellard
#endif
2177 e80cfcfc bellard
                        gen_movl_reg_T1(rs2);
2178 e80cfcfc bellard
                        gen_op_add_T1_T0();
2179 e80cfcfc bellard
#if defined(OPTIM)
2180 e80cfcfc bellard
                    }
2181 e8af50a3 bellard
#endif
2182 cf495bcf bellard
                }
2183 e80cfcfc bellard
                switch (xop) {
2184 e80cfcfc bellard
                case 0x38:        /* jmpl */
2185 e80cfcfc bellard
                    {
2186 e80cfcfc bellard
                        if (rd != 0) {
2187 ded3ab80 pbrook
#ifdef TARGET_SPARC64
2188 ded3ab80 pbrook
                            if (dc->pc == (uint32_t)dc->pc) {
2189 ded3ab80 pbrook
                                gen_op_movl_T1_im(dc->pc);
2190 ded3ab80 pbrook
                            } else {
2191 ded3ab80 pbrook
                                gen_op_movq_T1_im64(dc->pc >> 32, dc->pc);
2192 ded3ab80 pbrook
                            }
2193 ded3ab80 pbrook
#else
2194 0bee699e bellard
                            gen_op_movl_T1_im(dc->pc);
2195 ded3ab80 pbrook
#endif
2196 0bee699e bellard
                            gen_movl_T1_reg(rd);
2197 e80cfcfc bellard
                        }
2198 0bee699e bellard
                        gen_mov_pc_npc(dc);
2199 0bee699e bellard
                        gen_op_movl_npc_T0();
2200 e80cfcfc bellard
                        dc->npc = DYNAMIC_PC;
2201 e80cfcfc bellard
                    }
2202 e80cfcfc bellard
                    goto jmp_insn;
2203 3475187d bellard
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
2204 af7bf89b bellard
                case 0x39:        /* rett, V9 return */
2205 e80cfcfc bellard
                    {
2206 e80cfcfc bellard
                        if (!supervisor(dc))
2207 e80cfcfc bellard
                            goto priv_insn;
2208 0bee699e bellard
                        gen_mov_pc_npc(dc);
2209 e80cfcfc bellard
                        gen_op_movl_npc_T0();
2210 0bee699e bellard
                        dc->npc = DYNAMIC_PC;
2211 e80cfcfc bellard
                        gen_op_rett();
2212 e80cfcfc bellard
                    }
2213 0bee699e bellard
                    goto jmp_insn;
2214 e80cfcfc bellard
#endif
2215 e80cfcfc bellard
                case 0x3b: /* flush */
2216 e80cfcfc bellard
                    gen_op_flush_T0();
2217 e80cfcfc bellard
                    break;
2218 e80cfcfc bellard
                case 0x3c:        /* save */
2219 e80cfcfc bellard
                    save_state(dc);
2220 e80cfcfc bellard
                    gen_op_save();
2221 e80cfcfc bellard
                    gen_movl_T0_reg(rd);
2222 e80cfcfc bellard
                    break;
2223 e80cfcfc bellard
                case 0x3d:        /* restore */
2224 e80cfcfc bellard
                    save_state(dc);
2225 e80cfcfc bellard
                    gen_op_restore();
2226 e80cfcfc bellard
                    gen_movl_T0_reg(rd);
2227 e80cfcfc bellard
                    break;
2228 3475187d bellard
#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
2229 af7bf89b bellard
                case 0x3e:      /* V9 done/retry */
2230 3475187d bellard
                    {
2231 3475187d bellard
                        switch (rd) {
2232 3475187d bellard
                        case 0:
2233 3475187d bellard
                            if (!supervisor(dc))
2234 3475187d bellard
                                goto priv_insn;
2235 83469015 bellard
                            dc->npc = DYNAMIC_PC;
2236 83469015 bellard
                            dc->pc = DYNAMIC_PC;
2237 3475187d bellard
                            gen_op_done();
2238 83469015 bellard
                            goto jmp_insn;
2239 3475187d bellard
                        case 1:
2240 3475187d bellard
                            if (!supervisor(dc))
2241 3475187d bellard
                                goto priv_insn;
2242 83469015 bellard
                            dc->npc = DYNAMIC_PC;
2243 83469015 bellard
                            dc->pc = DYNAMIC_PC;
2244 3475187d bellard
                            gen_op_retry();
2245 83469015 bellard
                            goto jmp_insn;
2246 3475187d bellard
                        default:
2247 3475187d bellard
                            goto illegal_insn;
2248 3475187d bellard
                        }
2249 3475187d bellard
                    }
2250 3475187d bellard
                    break;
2251 3475187d bellard
#endif
2252 3475187d bellard
                default:
2253 e80cfcfc bellard
                    goto illegal_insn;
2254 e80cfcfc bellard
                }
2255 cf495bcf bellard
            }
2256 cf495bcf bellard
            break;
2257 cf495bcf bellard
        }
2258 af7bf89b bellard
        break;
2259 cf495bcf bellard
    case 3:                        /* load/store instructions */
2260 cf495bcf bellard
        {
2261 cf495bcf bellard
            unsigned int xop = GET_FIELD(insn, 7, 12);
2262 cf495bcf bellard
            rs1 = GET_FIELD(insn, 13, 17);
2263 cf495bcf bellard
            gen_movl_reg_T0(rs1);
2264 cf495bcf bellard
            if (IS_IMM) {        /* immediate */
2265 cf495bcf bellard
                rs2 = GET_FIELDs(insn, 19, 31);
2266 e80cfcfc bellard
#if defined(OPTIM)
2267 e8af50a3 bellard
                if (rs2 != 0) {
2268 e80cfcfc bellard
#endif
2269 3475187d bellard
                    gen_movl_simm_T1(rs2);
2270 e8af50a3 bellard
                    gen_op_add_T1_T0();
2271 e80cfcfc bellard
#if defined(OPTIM)
2272 e8af50a3 bellard
                }
2273 e80cfcfc bellard
#endif
2274 cf495bcf bellard
            } else {                /* register */
2275 cf495bcf bellard
                rs2 = GET_FIELD(insn, 27, 31);
2276 e80cfcfc bellard
#if defined(OPTIM)
2277 e80cfcfc bellard
                if (rs2 != 0) {
2278 e80cfcfc bellard
#endif
2279 e80cfcfc bellard
                    gen_movl_reg_T1(rs2);
2280 e80cfcfc bellard
                    gen_op_add_T1_T0();
2281 e80cfcfc bellard
#if defined(OPTIM)
2282 e80cfcfc bellard
                }
2283 e80cfcfc bellard
#endif
2284 cf495bcf bellard
            }
2285 3475187d bellard
            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) || \
2286 3475187d bellard
                    (xop > 0x17 && xop < 0x1d ) || \
2287 3475187d bellard
                    (xop > 0x2c && xop < 0x33) || xop == 0x1f) {
2288 cf495bcf bellard
                switch (xop) {
2289 cf495bcf bellard
                case 0x0:        /* load word */
2290 e8af50a3 bellard
                    gen_op_ldst(ld);
2291 cf495bcf bellard
                    break;
2292 cf495bcf bellard
                case 0x1:        /* load unsigned byte */
2293 e8af50a3 bellard
                    gen_op_ldst(ldub);
2294 cf495bcf bellard
                    break;
2295 cf495bcf bellard
                case 0x2:        /* load unsigned halfword */
2296 e8af50a3 bellard
                    gen_op_ldst(lduh);
2297 cf495bcf bellard
                    break;
2298 cf495bcf bellard
                case 0x3:        /* load double word */
2299 e8af50a3 bellard
                    gen_op_ldst(ldd);
2300 cf495bcf bellard
                    gen_movl_T0_reg(rd + 1);
2301 cf495bcf bellard
                    break;
2302 cf495bcf bellard
                case 0x9:        /* load signed byte */
2303 e8af50a3 bellard
                    gen_op_ldst(ldsb);
2304 cf495bcf bellard
                    break;
2305 cf495bcf bellard
                case 0xa:        /* load signed halfword */
2306 e8af50a3 bellard
                    gen_op_ldst(ldsh);
2307 cf495bcf bellard
                    break;
2308 cf495bcf bellard
                case 0xd:        /* ldstub -- XXX: should be atomically */
2309 e8af50a3 bellard
                    gen_op_ldst(ldstub);
2310 cf495bcf bellard
                    break;
2311 cf495bcf bellard
                case 0x0f:        /* swap register with memory. Also atomically */
2312 e80cfcfc bellard
                    gen_movl_reg_T1(rd);
2313 e8af50a3 bellard
                    gen_op_ldst(swap);
2314 e8af50a3 bellard
                    break;
2315 3475187d bellard
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
2316 e8af50a3 bellard
                case 0x10:        /* load word alternate */
2317 3475187d bellard
#ifndef TARGET_SPARC64
2318 e8af50a3 bellard
                    if (!supervisor(dc))
2319 e8af50a3 bellard
                        goto priv_insn;
2320 3475187d bellard
#endif
2321 e8af50a3 bellard
                    gen_op_lda(insn, 1, 4, 0);
2322 e8af50a3 bellard
                    break;
2323 e8af50a3 bellard
                case 0x11:        /* load unsigned byte alternate */
2324 3475187d bellard
#ifndef TARGET_SPARC64
2325 e8af50a3 bellard
                    if (!supervisor(dc))
2326 e8af50a3 bellard
                        goto priv_insn;
2327 3475187d bellard
#endif
2328 e8af50a3 bellard
                    gen_op_lduba(insn, 1, 1, 0);
2329 e8af50a3 bellard
                    break;
2330 e8af50a3 bellard
                case 0x12:        /* load unsigned halfword alternate */
2331 3475187d bellard
#ifndef TARGET_SPARC64
2332 e8af50a3 bellard
                    if (!supervisor(dc))
2333 e8af50a3 bellard
                        goto priv_insn;
2334 3475187d bellard
#endif
2335 e8af50a3 bellard
                    gen_op_lduha(insn, 1, 2, 0);
2336 e8af50a3 bellard
                    break;
2337 e8af50a3 bellard
                case 0x13:        /* load double word alternate */
2338 3475187d bellard
#ifndef TARGET_SPARC64
2339 e8af50a3 bellard
                    if (!supervisor(dc))
2340 e8af50a3 bellard
                        goto priv_insn;
2341 3475187d bellard
#endif
2342 e8af50a3 bellard
                    gen_op_ldda(insn, 1, 8, 0);
2343 e8af50a3 bellard
                    gen_movl_T0_reg(rd + 1);
2344 e8af50a3 bellard
                    break;
2345 e8af50a3 bellard
                case 0x19:        /* load signed byte alternate */
2346 3475187d bellard
#ifndef TARGET_SPARC64
2347 e8af50a3 bellard
                    if (!supervisor(dc))
2348 e8af50a3 bellard
                        goto priv_insn;
2349 3475187d bellard
#endif
2350 e8af50a3 bellard
                    gen_op_ldsba(insn, 1, 1, 1);
2351 e8af50a3 bellard
                    break;
2352 e8af50a3 bellard
                case 0x1a:        /* load signed halfword alternate */
2353 3475187d bellard
#ifndef TARGET_SPARC64
2354 e8af50a3 bellard
                    if (!supervisor(dc))
2355 e8af50a3 bellard
                        goto priv_insn;
2356 3475187d bellard
#endif
2357 e8af50a3 bellard
                    gen_op_ldsha(insn, 1, 2 ,1);
2358 e8af50a3 bellard
                    break;
2359 e8af50a3 bellard
                case 0x1d:        /* ldstuba -- XXX: should be atomically */
2360 3475187d bellard
#ifndef TARGET_SPARC64
2361 e8af50a3 bellard
                    if (!supervisor(dc))
2362 e8af50a3 bellard
                        goto priv_insn;
2363 3475187d bellard
#endif
2364 e8af50a3 bellard
                    gen_op_ldstuba(insn, 1, 1, 0);
2365 e8af50a3 bellard
                    break;
2366 e8af50a3 bellard
                case 0x1f:        /* swap reg with alt. memory. Also atomically */
2367 3475187d bellard
#ifndef TARGET_SPARC64
2368 e8af50a3 bellard
                    if (!supervisor(dc))
2369 e8af50a3 bellard
                        goto priv_insn;
2370 3475187d bellard
#endif
2371 e80cfcfc bellard
                    gen_movl_reg_T1(rd);
2372 e8af50a3 bellard
                    gen_op_swapa(insn, 1, 4, 0);
2373 cf495bcf bellard
                    break;
2374 3475187d bellard
2375 3475187d bellard
#ifndef TARGET_SPARC64
2376 0fa85d43 bellard
                    /* avoid warnings */
2377 0fa85d43 bellard
                    (void) &gen_op_stfa;
2378 0fa85d43 bellard
                    (void) &gen_op_stdfa;
2379 0fa85d43 bellard
                    (void) &gen_op_ldfa;
2380 0fa85d43 bellard
                    (void) &gen_op_lddfa;
2381 3475187d bellard
#else
2382 3475187d bellard
#if !defined(CONFIG_USER_ONLY)
2383 3475187d bellard
                    (void) &gen_op_cas;
2384 3475187d bellard
                    (void) &gen_op_casx;
2385 e80cfcfc bellard
#endif
2386 3475187d bellard
#endif
2387 3475187d bellard
#endif
2388 3475187d bellard
#ifdef TARGET_SPARC64
2389 af7bf89b bellard
                case 0x08: /* V9 ldsw */
2390 3475187d bellard
                    gen_op_ldst(ldsw);
2391 3475187d bellard
                    break;
2392 af7bf89b bellard
                case 0x0b: /* V9 ldx */
2393 3475187d bellard
                    gen_op_ldst(ldx);
2394 3475187d bellard
                    break;
2395 af7bf89b bellard
                case 0x18: /* V9 ldswa */
2396 3475187d bellard
                    gen_op_ldswa(insn, 1, 4, 1);
2397 3475187d bellard
                    break;
2398 af7bf89b bellard
                case 0x1b: /* V9 ldxa */
2399 3475187d bellard
                    gen_op_ldxa(insn, 1, 8, 0);
2400 3475187d bellard
                    break;
2401 3475187d bellard
                case 0x2d: /* V9 prefetch, no effect */
2402 3475187d bellard
                    goto skip_move;
2403 af7bf89b bellard
                case 0x30: /* V9 ldfa */
2404 3475187d bellard
                    gen_op_ldfa(insn, 1, 8, 0); // XXX
2405 3475187d bellard
                    break;
2406 af7bf89b bellard
                case 0x33: /* V9 lddfa */
2407 3475187d bellard
                    gen_op_lddfa(insn, 1, 8, 0); // XXX
2408 af7bf89b bellard
2409 3475187d bellard
                    break;
2410 3475187d bellard
                case 0x3d: /* V9 prefetcha, no effect */
2411 3475187d bellard
                    goto skip_move;
2412 af7bf89b bellard
                case 0x32: /* V9 ldqfa */
2413 3475187d bellard
                    goto nfpu_insn;
2414 3475187d bellard
#endif
2415 3475187d bellard
                default:
2416 e80cfcfc bellard
                    goto illegal_insn;
2417 7a3f1944 bellard
                }
2418 cf495bcf bellard
                gen_movl_T1_reg(rd);
2419 3475187d bellard
#ifdef TARGET_SPARC64
2420 3475187d bellard
            skip_move: ;
2421 3475187d bellard
#endif
2422 e8af50a3 bellard
            } else if (xop >= 0x20 && xop < 0x24) {
2423 a80dde08 bellard
                if (gen_trap_ifnofpu(dc))
2424 a80dde08 bellard
                    goto jmp_insn;
2425 e8af50a3 bellard
                switch (xop) {
2426 e8af50a3 bellard
                case 0x20:        /* load fpreg */
2427 e8af50a3 bellard
                    gen_op_ldst(ldf);
2428 e8af50a3 bellard
                    gen_op_store_FT0_fpr(rd);
2429 e8af50a3 bellard
                    break;
2430 e8af50a3 bellard
                case 0x21:        /* load fsr */
2431 9e61bde5 bellard
                    gen_op_ldst(ldf);
2432 e8af50a3 bellard
                    gen_op_ldfsr();
2433 e8af50a3 bellard
                    break;
2434 af7bf89b bellard
                case 0x22:      /* load quad fpreg */
2435 af7bf89b bellard
                    goto nfpu_insn;
2436 e8af50a3 bellard
                case 0x23:        /* load double fpreg */
2437 e8af50a3 bellard
                    gen_op_ldst(lddf);
2438 3475187d bellard
                    gen_op_store_DT0_fpr(DFPREG(rd));
2439 e8af50a3 bellard
                    break;
2440 e80cfcfc bellard
                default:
2441 e80cfcfc bellard
                    goto illegal_insn;
2442 e8af50a3 bellard
                }
2443 3475187d bellard
            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) || \
2444 3475187d bellard
                       xop == 0xe || xop == 0x1e) {
2445 cf495bcf bellard
                gen_movl_reg_T1(rd);
2446 cf495bcf bellard
                switch (xop) {
2447 cf495bcf bellard
                case 0x4:
2448 e8af50a3 bellard
                    gen_op_ldst(st);
2449 cf495bcf bellard
                    break;
2450 cf495bcf bellard
                case 0x5:
2451 e8af50a3 bellard
                    gen_op_ldst(stb);
2452 cf495bcf bellard
                    break;
2453 cf495bcf bellard
                case 0x6:
2454 e8af50a3 bellard
                    gen_op_ldst(sth);
2455 cf495bcf bellard
                    break;
2456 cf495bcf bellard
                case 0x7:
2457 72cbca10 bellard
                    flush_T2(dc);
2458 cf495bcf bellard
                    gen_movl_reg_T2(rd + 1);
2459 e8af50a3 bellard
                    gen_op_ldst(std);
2460 e8af50a3 bellard
                    break;
2461 3475187d bellard
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
2462 e8af50a3 bellard
                case 0x14:
2463 3475187d bellard
#ifndef TARGET_SPARC64
2464 e8af50a3 bellard
                    if (!supervisor(dc))
2465 e8af50a3 bellard
                        goto priv_insn;
2466 3475187d bellard
#endif
2467 e8af50a3 bellard
                    gen_op_sta(insn, 0, 4, 0);
2468 d39c0b99 bellard
                    break;
2469 e8af50a3 bellard
                case 0x15:
2470 3475187d bellard
#ifndef TARGET_SPARC64
2471 e8af50a3 bellard
                    if (!supervisor(dc))
2472 e8af50a3 bellard
                        goto priv_insn;
2473 3475187d bellard
#endif
2474 e8af50a3 bellard
                    gen_op_stba(insn, 0, 1, 0);
2475 d39c0b99 bellard
                    break;
2476 e8af50a3 bellard
                case 0x16:
2477 3475187d bellard
#ifndef TARGET_SPARC64
2478 e8af50a3 bellard
                    if (!supervisor(dc))
2479 e8af50a3 bellard
                        goto priv_insn;
2480 3475187d bellard
#endif
2481 e8af50a3 bellard
                    gen_op_stha(insn, 0, 2, 0);
2482 d39c0b99 bellard
                    break;
2483 e8af50a3 bellard
                case 0x17:
2484 3475187d bellard
#ifndef TARGET_SPARC64
2485 e8af50a3 bellard
                    if (!supervisor(dc))
2486 e8af50a3 bellard
                        goto priv_insn;
2487 3475187d bellard
#endif
2488 e8af50a3 bellard
                    flush_T2(dc);
2489 e8af50a3 bellard
                    gen_movl_reg_T2(rd + 1);
2490 e8af50a3 bellard
                    gen_op_stda(insn, 0, 8, 0);
2491 d39c0b99 bellard
                    break;
2492 e80cfcfc bellard
#endif
2493 3475187d bellard
#ifdef TARGET_SPARC64
2494 af7bf89b bellard
                case 0x0e: /* V9 stx */
2495 3475187d bellard
                    gen_op_ldst(stx);
2496 3475187d bellard
                    break;
2497 af7bf89b bellard
                case 0x1e: /* V9 stxa */
2498 3475187d bellard
                    gen_op_stxa(insn, 0, 8, 0); // XXX
2499 3475187d bellard
                    break;
2500 3475187d bellard
#endif
2501 3475187d bellard
                default:
2502 e80cfcfc bellard
                    goto illegal_insn;
2503 7a3f1944 bellard
                }
2504 e8af50a3 bellard
            } else if (xop > 0x23 && xop < 0x28) {
2505 a80dde08 bellard
                if (gen_trap_ifnofpu(dc))
2506 a80dde08 bellard
                    goto jmp_insn;
2507 e8af50a3 bellard
                switch (xop) {
2508 e8af50a3 bellard
                case 0x24:
2509 e8af50a3 bellard
                    gen_op_load_fpr_FT0(rd);
2510 e8af50a3 bellard
                    gen_op_ldst(stf);
2511 e8af50a3 bellard
                    break;
2512 af7bf89b bellard
                case 0x25: /* stfsr, V9 stxfsr */
2513 e8af50a3 bellard
                    gen_op_stfsr();
2514 9e61bde5 bellard
                    gen_op_ldst(stf);
2515 e8af50a3 bellard
                    break;
2516 af7bf89b bellard
                case 0x26: /* stdfq */
2517 af7bf89b bellard
                    goto nfpu_insn;
2518 e8af50a3 bellard
                case 0x27:
2519 3475187d bellard
                    gen_op_load_fpr_DT0(DFPREG(rd));
2520 e8af50a3 bellard
                    gen_op_ldst(stdf);
2521 e8af50a3 bellard
                    break;
2522 e80cfcfc bellard
                default:
2523 3475187d bellard
                    goto illegal_insn;
2524 3475187d bellard
                }
2525 3475187d bellard
            } else if (xop > 0x33 && xop < 0x3f) {
2526 3475187d bellard
#ifdef TARGET_SPARC64
2527 3475187d bellard
                switch (xop) {
2528 af7bf89b bellard
                case 0x34: /* V9 stfa */
2529 3475187d bellard
                    gen_op_stfa(insn, 0, 0, 0); // XXX
2530 3475187d bellard
                    break;
2531 af7bf89b bellard
                case 0x37: /* V9 stdfa */
2532 3475187d bellard
                    gen_op_stdfa(insn, 0, 0, 0); // XXX
2533 3475187d bellard
                    break;
2534 af7bf89b bellard
                case 0x3c: /* V9 casa */
2535 3475187d bellard
                    gen_op_casa(insn, 0, 4, 0); // XXX
2536 3475187d bellard
                    break;
2537 af7bf89b bellard
                case 0x3e: /* V9 casxa */
2538 3475187d bellard
                    gen_op_casxa(insn, 0, 8, 0); // XXX
2539 3475187d bellard
                    break;
2540 af7bf89b bellard
                case 0x36: /* V9 stqfa */
2541 3475187d bellard
                    goto nfpu_insn;
2542 3475187d bellard
                default:
2543 e80cfcfc bellard
                    goto illegal_insn;
2544 e8af50a3 bellard
                }
2545 3475187d bellard
#else
2546 e80cfcfc bellard
                goto illegal_insn;
2547 3475187d bellard
#endif
2548 e8af50a3 bellard
            }
2549 e80cfcfc bellard
            else
2550 e80cfcfc bellard
                goto illegal_insn;
2551 7a3f1944 bellard
        }
2552 af7bf89b bellard
        break;
2553 cf495bcf bellard
    }
2554 cf495bcf bellard
    /* default case for non jump instructions */
2555 72cbca10 bellard
    if (dc->npc == DYNAMIC_PC) {
2556 72cbca10 bellard
        dc->pc = DYNAMIC_PC;
2557 72cbca10 bellard
        gen_op_next_insn();
2558 72cbca10 bellard
    } else if (dc->npc == JUMP_PC) {
2559 72cbca10 bellard
        /* we can do a static jump */
2560 83469015 bellard
        gen_branch2(dc, (long)dc->tb, dc->jump_pc[0], dc->jump_pc[1]);
2561 72cbca10 bellard
        dc->is_br = 1;
2562 72cbca10 bellard
    } else {
2563 cf495bcf bellard
        dc->pc = dc->npc;
2564 cf495bcf bellard
        dc->npc = dc->npc + 4;
2565 cf495bcf bellard
    }
2566 e80cfcfc bellard
 jmp_insn:
2567 cf495bcf bellard
    return;
2568 cf495bcf bellard
 illegal_insn:
2569 72cbca10 bellard
    save_state(dc);
2570 cf495bcf bellard
    gen_op_exception(TT_ILL_INSN);
2571 cf495bcf bellard
    dc->is_br = 1;
2572 e8af50a3 bellard
    return;
2573 e80cfcfc bellard
#if !defined(CONFIG_USER_ONLY)
2574 e8af50a3 bellard
 priv_insn:
2575 e8af50a3 bellard
    save_state(dc);
2576 e8af50a3 bellard
    gen_op_exception(TT_PRIV_INSN);
2577 e8af50a3 bellard
    dc->is_br = 1;
2578 e80cfcfc bellard
    return;
2579 e80cfcfc bellard
#endif
2580 e80cfcfc bellard
 nfpu_insn:
2581 e80cfcfc bellard
    save_state(dc);
2582 e80cfcfc bellard
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
2583 e80cfcfc bellard
    dc->is_br = 1;
2584 7a3f1944 bellard
}
2585 7a3f1944 bellard
2586 cf495bcf bellard
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
2587 e8af50a3 bellard
                                                 int spc, CPUSPARCState *env)
2588 7a3f1944 bellard
{
2589 72cbca10 bellard
    target_ulong pc_start, last_pc;
2590 cf495bcf bellard
    uint16_t *gen_opc_end;
2591 cf495bcf bellard
    DisasContext dc1, *dc = &dc1;
2592 e8af50a3 bellard
    int j, lj = -1;
2593 cf495bcf bellard
2594 cf495bcf bellard
    memset(dc, 0, sizeof(DisasContext));
2595 cf495bcf bellard
    dc->tb = tb;
2596 72cbca10 bellard
    pc_start = tb->pc;
2597 cf495bcf bellard
    dc->pc = pc_start;
2598 e80cfcfc bellard
    last_pc = dc->pc;
2599 72cbca10 bellard
    dc->npc = (target_ulong) tb->cs_base;
2600 e8af50a3 bellard
#if defined(CONFIG_USER_ONLY)
2601 e8af50a3 bellard
    dc->mem_idx = 0;
2602 a80dde08 bellard
    dc->fpu_enabled = 1;
2603 e8af50a3 bellard
#else
2604 e8af50a3 bellard
    dc->mem_idx = ((env->psrs) != 0);
2605 a80dde08 bellard
#ifdef TARGET_SPARC64
2606 a80dde08 bellard
    dc->fpu_enabled = (((env->pstate & PS_PEF) != 0) && ((env->fprs & FPRS_FEF) != 0));
2607 a80dde08 bellard
#else
2608 a80dde08 bellard
    dc->fpu_enabled = ((env->psref) != 0);
2609 a80dde08 bellard
#endif
2610 e8af50a3 bellard
#endif
2611 cf495bcf bellard
    gen_opc_ptr = gen_opc_buf;
2612 cf495bcf bellard
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2613 cf495bcf bellard
    gen_opparam_ptr = gen_opparam_buf;
2614 83469015 bellard
    nb_gen_labels = 0;
2615 cf495bcf bellard
2616 cf495bcf bellard
    do {
2617 e8af50a3 bellard
        if (env->nb_breakpoints > 0) {
2618 e8af50a3 bellard
            for(j = 0; j < env->nb_breakpoints; j++) {
2619 e8af50a3 bellard
                if (env->breakpoints[j] == dc->pc) {
2620 e80cfcfc bellard
                    if (dc->pc != pc_start)
2621 e80cfcfc bellard
                        save_state(dc);
2622 e80cfcfc bellard
                    gen_op_debug();
2623 e80cfcfc bellard
                    gen_op_movl_T0_0();
2624 e80cfcfc bellard
                    gen_op_exit_tb();
2625 e80cfcfc bellard
                    dc->is_br = 1;
2626 e80cfcfc bellard
                    goto exit_gen_loop;
2627 e8af50a3 bellard
                }
2628 e8af50a3 bellard
            }
2629 e8af50a3 bellard
        }
2630 e8af50a3 bellard
        if (spc) {
2631 e8af50a3 bellard
            if (loglevel > 0)
2632 e8af50a3 bellard
                fprintf(logfile, "Search PC...\n");
2633 e8af50a3 bellard
            j = gen_opc_ptr - gen_opc_buf;
2634 e8af50a3 bellard
            if (lj < j) {
2635 e8af50a3 bellard
                lj++;
2636 e8af50a3 bellard
                while (lj < j)
2637 e8af50a3 bellard
                    gen_opc_instr_start[lj++] = 0;
2638 e8af50a3 bellard
                gen_opc_pc[lj] = dc->pc;
2639 e8af50a3 bellard
                gen_opc_npc[lj] = dc->npc;
2640 e8af50a3 bellard
                gen_opc_instr_start[lj] = 1;
2641 e8af50a3 bellard
            }
2642 e8af50a3 bellard
        }
2643 cf495bcf bellard
        last_pc = dc->pc;
2644 cf495bcf bellard
        disas_sparc_insn(dc);
2645 3475187d bellard
2646 cf495bcf bellard
        if (dc->is_br)
2647 cf495bcf bellard
            break;
2648 cf495bcf bellard
        /* if the next PC is different, we abort now */
2649 cf495bcf bellard
        if (dc->pc != (last_pc + 4))
2650 cf495bcf bellard
            break;
2651 d39c0b99 bellard
        /* if we reach a page boundary, we stop generation so that the
2652 d39c0b99 bellard
           PC of a TT_TFAULT exception is always in the right page */
2653 d39c0b99 bellard
        if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
2654 d39c0b99 bellard
            break;
2655 e80cfcfc bellard
        /* if single step mode, we generate only one instruction and
2656 e80cfcfc bellard
           generate an exception */
2657 e80cfcfc bellard
        if (env->singlestep_enabled) {
2658 3475187d bellard
            gen_jmp_im(dc->pc);
2659 e80cfcfc bellard
            gen_op_movl_T0_0();
2660 e80cfcfc bellard
            gen_op_exit_tb();
2661 e80cfcfc bellard
            break;
2662 e80cfcfc bellard
        }
2663 cf495bcf bellard
    } while ((gen_opc_ptr < gen_opc_end) &&
2664 cf495bcf bellard
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
2665 e80cfcfc bellard
2666 e80cfcfc bellard
 exit_gen_loop:
2667 72cbca10 bellard
    if (!dc->is_br) {
2668 72cbca10 bellard
        if (dc->pc != DYNAMIC_PC && 
2669 72cbca10 bellard
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
2670 72cbca10 bellard
            /* static PC and NPC: we can use direct chaining */
2671 83469015 bellard
            gen_branch(dc, (long)tb, dc->pc, dc->npc);
2672 72cbca10 bellard
        } else {
2673 72cbca10 bellard
            if (dc->pc != DYNAMIC_PC)
2674 3475187d bellard
                gen_jmp_im(dc->pc);
2675 72cbca10 bellard
            save_npc(dc);
2676 72cbca10 bellard
            gen_op_movl_T0_0();
2677 72cbca10 bellard
            gen_op_exit_tb();
2678 72cbca10 bellard
        }
2679 72cbca10 bellard
    }
2680 cf495bcf bellard
    *gen_opc_ptr = INDEX_op_end;
2681 e8af50a3 bellard
    if (spc) {
2682 e8af50a3 bellard
        j = gen_opc_ptr - gen_opc_buf;
2683 e8af50a3 bellard
        lj++;
2684 e8af50a3 bellard
        while (lj <= j)
2685 e8af50a3 bellard
            gen_opc_instr_start[lj++] = 0;
2686 e8af50a3 bellard
        tb->size = 0;
2687 e8af50a3 bellard
#if 0
2688 e8af50a3 bellard
        if (loglevel > 0) {
2689 e8af50a3 bellard
            page_dump(logfile);
2690 e8af50a3 bellard
        }
2691 e8af50a3 bellard
#endif
2692 c3278b7b bellard
        gen_opc_jump_pc[0] = dc->jump_pc[0];
2693 c3278b7b bellard
        gen_opc_jump_pc[1] = dc->jump_pc[1];
2694 e8af50a3 bellard
    } else {
2695 e80cfcfc bellard
        tb->size = last_pc + 4 - pc_start;
2696 e8af50a3 bellard
    }
2697 7a3f1944 bellard
#ifdef DEBUG_DISAS
2698 e19e89a5 bellard
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2699 cf495bcf bellard
        fprintf(logfile, "--------------\n");
2700 0fa85d43 bellard
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
2701 0fa85d43 bellard
        target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
2702 cf495bcf bellard
        fprintf(logfile, "\n");
2703 e19e89a5 bellard
        if (loglevel & CPU_LOG_TB_OP) {
2704 e19e89a5 bellard
            fprintf(logfile, "OP:\n");
2705 e19e89a5 bellard
            dump_ops(gen_opc_buf, gen_opparam_buf);
2706 e19e89a5 bellard
            fprintf(logfile, "\n");
2707 e19e89a5 bellard
        }
2708 cf495bcf bellard
    }
2709 7a3f1944 bellard
#endif
2710 cf495bcf bellard
    return 0;
2711 7a3f1944 bellard
}
2712 7a3f1944 bellard
2713 cf495bcf bellard
int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
2714 7a3f1944 bellard
{
2715 e8af50a3 bellard
    return gen_intermediate_code_internal(tb, 0, env);
2716 7a3f1944 bellard
}
2717 7a3f1944 bellard
2718 cf495bcf bellard
int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
2719 7a3f1944 bellard
{
2720 e8af50a3 bellard
    return gen_intermediate_code_internal(tb, 1, env);
2721 7a3f1944 bellard
}
2722 7a3f1944 bellard
2723 e80cfcfc bellard
extern int ram_size;
2724 cf495bcf bellard
2725 e80cfcfc bellard
void cpu_reset(CPUSPARCState *env)
2726 e80cfcfc bellard
{
2727 cf495bcf bellard
    memset(env, 0, sizeof(*env));
2728 bb05683b bellard
    tlb_flush(env, 1);
2729 cf495bcf bellard
    env->cwp = 0;
2730 cf495bcf bellard
    env->wim = 1;
2731 cf495bcf bellard
    env->regwptr = env->regbase + (env->cwp * 16);
2732 e8af50a3 bellard
#if defined(CONFIG_USER_ONLY)
2733 cf495bcf bellard
    env->user_mode_only = 1;
2734 5ef54116 bellard
#ifdef TARGET_SPARC64
2735 5ef54116 bellard
    env->cleanwin = NWINDOWS - 1;
2736 5ef54116 bellard
    env->cansave = NWINDOWS - 1;
2737 5ef54116 bellard
#endif
2738 e8af50a3 bellard
#else
2739 e8af50a3 bellard
    env->psrs = 1;
2740 0bee699e bellard
    env->psrps = 1;
2741 e80cfcfc bellard
    env->gregs[1] = ram_size;
2742 3475187d bellard
#ifdef TARGET_SPARC64
2743 83469015 bellard
    env->pstate = PS_PRIV;
2744 3475187d bellard
    env->version = GET_VER(env);
2745 83469015 bellard
    env->pc = 0x1fff0000000ULL;
2746 3475187d bellard
#else
2747 3475187d bellard
    env->mmuregs[0] = (0x04 << 24); /* Impl 0, ver 4, MMU disabled */
2748 83469015 bellard
    env->pc = 0xffd00000;
2749 3475187d bellard
#endif
2750 83469015 bellard
    env->npc = env->pc + 4;
2751 e8af50a3 bellard
#endif
2752 e80cfcfc bellard
}
2753 e80cfcfc bellard
2754 e80cfcfc bellard
CPUSPARCState *cpu_sparc_init(void)
2755 e80cfcfc bellard
{
2756 e80cfcfc bellard
    CPUSPARCState *env;
2757 e80cfcfc bellard
2758 c68ea704 bellard
    env = qemu_mallocz(sizeof(CPUSPARCState));
2759 c68ea704 bellard
    if (!env)
2760 c68ea704 bellard
        return NULL;
2761 c68ea704 bellard
    cpu_exec_init(env);
2762 e80cfcfc bellard
    cpu_reset(env);
2763 cf495bcf bellard
    return (env);
2764 7a3f1944 bellard
}
2765 7a3f1944 bellard
2766 7a3f1944 bellard
#define GET_FLAG(a,b) ((env->psr & a)?b:'-')
2767 7a3f1944 bellard
2768 7fe48483 bellard
void cpu_dump_state(CPUState *env, FILE *f, 
2769 7fe48483 bellard
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
2770 7fe48483 bellard
                    int flags)
2771 7a3f1944 bellard
{
2772 cf495bcf bellard
    int i, x;
2773 cf495bcf bellard
2774 af7bf89b bellard
    cpu_fprintf(f, "pc: " TARGET_FMT_lx "  npc: " TARGET_FMT_lx "\n", env->pc, env->npc);
2775 7fe48483 bellard
    cpu_fprintf(f, "General Registers:\n");
2776 cf495bcf bellard
    for (i = 0; i < 4; i++)
2777 af7bf89b bellard
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
2778 7fe48483 bellard
    cpu_fprintf(f, "\n");
2779 cf495bcf bellard
    for (; i < 8; i++)
2780 af7bf89b bellard
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
2781 7fe48483 bellard
    cpu_fprintf(f, "\nCurrent Register Window:\n");
2782 cf495bcf bellard
    for (x = 0; x < 3; x++) {
2783 cf495bcf bellard
        for (i = 0; i < 4; i++)
2784 af7bf89b bellard
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
2785 cf495bcf bellard
                    (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
2786 cf495bcf bellard
                    env->regwptr[i + x * 8]);
2787 7fe48483 bellard
        cpu_fprintf(f, "\n");
2788 cf495bcf bellard
        for (; i < 8; i++)
2789 af7bf89b bellard
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
2790 cf495bcf bellard
                    (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
2791 cf495bcf bellard
                    env->regwptr[i + x * 8]);
2792 7fe48483 bellard
        cpu_fprintf(f, "\n");
2793 cf495bcf bellard
    }
2794 7fe48483 bellard
    cpu_fprintf(f, "\nFloating Point Registers:\n");
2795 e8af50a3 bellard
    for (i = 0; i < 32; i++) {
2796 e8af50a3 bellard
        if ((i & 3) == 0)
2797 7fe48483 bellard
            cpu_fprintf(f, "%%f%02d:", i);
2798 7fe48483 bellard
        cpu_fprintf(f, " %016lf", env->fpr[i]);
2799 e8af50a3 bellard
        if ((i & 3) == 3)
2800 7fe48483 bellard
            cpu_fprintf(f, "\n");
2801 e8af50a3 bellard
    }
2802 ded3ab80 pbrook
#ifdef TARGET_SPARC64
2803 ded3ab80 pbrook
    cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d\n",
2804 ded3ab80 pbrook
                env->pstate, GET_CCR(env), env->asi, env->tl);
2805 ded3ab80 pbrook
    cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d cleanwin %d cwp %d\n",
2806 ded3ab80 pbrook
                env->cansave, env->canrestore, env->otherwin, env->wstate,
2807 ded3ab80 pbrook
                env->cleanwin, NWINDOWS - 1 - env->cwp);
2808 ded3ab80 pbrook
#else
2809 7fe48483 bellard
    cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n", GET_PSR(env),
2810 cf495bcf bellard
            GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
2811 cf495bcf bellard
            GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
2812 e8af50a3 bellard
            env->psrs?'S':'-', env->psrps?'P':'-', 
2813 e8af50a3 bellard
            env->psret?'E':'-', env->wim);
2814 ded3ab80 pbrook
#endif
2815 3475187d bellard
    cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env));
2816 7a3f1944 bellard
}
2817 edfcbd99 bellard
2818 e80cfcfc bellard
#if defined(CONFIG_USER_ONLY)
2819 d785e6be bellard
target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
2820 edfcbd99 bellard
{
2821 edfcbd99 bellard
    return addr;
2822 edfcbd99 bellard
}
2823 658138bc bellard
2824 e80cfcfc bellard
#else
2825 af7bf89b bellard
extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
2826 af7bf89b bellard
                                 int *access_index, target_ulong address, int rw,
2827 0fa85d43 bellard
                                 int is_user);
2828 0fa85d43 bellard
2829 d785e6be bellard
target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
2830 e80cfcfc bellard
{
2831 af7bf89b bellard
    target_phys_addr_t phys_addr;
2832 e80cfcfc bellard
    int prot, access_index;
2833 e80cfcfc bellard
2834 e80cfcfc bellard
    if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2, 0) != 0)
2835 6b1575b7 bellard
        if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 0, 0) != 0)
2836 6b1575b7 bellard
            return -1;
2837 e80cfcfc bellard
    return phys_addr;
2838 e80cfcfc bellard
}
2839 e80cfcfc bellard
#endif
2840 e80cfcfc bellard
2841 658138bc bellard
void helper_flush(target_ulong addr)
2842 658138bc bellard
{
2843 658138bc bellard
    addr &= ~7;
2844 658138bc bellard
    tb_invalidate_page_range(addr, addr + 8);
2845 658138bc bellard
}