Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ 6b1575b7

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