Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ c5d6edc3

History | View | Annotate | Download (71.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 <<= 2;
960 3475187d bellard
                    target = sign_extend(target, 18);
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 3475187d bellard
                        (GET_FIELD_SP(insn, 20, 21) >> 7);
974 3475187d bellard
                    target <<= 2;
975 3475187d bellard
                    target = sign_extend(target, 16);
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 <<= 2;
990 3475187d bellard
                    target = sign_extend(target, 19);
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 <<= 2;
999 cf495bcf bellard
                    target = sign_extend(target, 22);
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 <<= 2;
1011 e8af50a3 bellard
                    target = sign_extend(target, 22);
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 3475187d bellard
                    gen_op_movl_T0_im(dc->pc);
1127 3475187d bellard
                    gen_movl_T0_reg(rd);
1128 3475187d bellard
                    break;
1129 af7bf89b bellard
                case 0x6: /* V9 rdfprs */
1130 3475187d bellard
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, fprs));
1131 3475187d bellard
                    gen_movl_T0_reg(rd);
1132 3475187d bellard
                    break;
1133 83469015 bellard
                case 0x17: /* Tick compare */
1134 83469015 bellard
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, tick_cmpr));
1135 83469015 bellard
                    gen_movl_T0_reg(rd);
1136 83469015 bellard
                    break;
1137 83469015 bellard
                case 0x18: /* System tick */
1138 83469015 bellard
                    gen_op_rdtick(); // XXX
1139 83469015 bellard
                    gen_movl_T0_reg(rd);
1140 83469015 bellard
                    break;
1141 83469015 bellard
                case 0x19: /* System tick compare */
1142 83469015 bellard
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, stick_cmpr));
1143 83469015 bellard
                    gen_movl_T0_reg(rd);
1144 83469015 bellard
                    break;
1145 83469015 bellard
                case 0x10: /* Performance Control */
1146 83469015 bellard
                case 0x11: /* Performance Instrumentation Counter */
1147 83469015 bellard
                case 0x12: /* Dispatch Control */
1148 83469015 bellard
                case 0x13: /* Graphics Status */
1149 83469015 bellard
                case 0x14: /* Softint set, WO */
1150 83469015 bellard
                case 0x15: /* Softint clear, WO */
1151 83469015 bellard
                case 0x16: /* Softint write */
1152 3475187d bellard
#endif
1153 3475187d bellard
                default:
1154 cf495bcf bellard
                    goto illegal_insn;
1155 cf495bcf bellard
                }
1156 e8af50a3 bellard
#if !defined(CONFIG_USER_ONLY)
1157 3475187d bellard
#ifndef TARGET_SPARC64
1158 3475187d bellard
            } else if (xop == 0x29) { /* rdpsr / V9 unimp */
1159 e8af50a3 bellard
                if (!supervisor(dc))
1160 e8af50a3 bellard
                    goto priv_insn;
1161 e8af50a3 bellard
                gen_op_rdpsr();
1162 e8af50a3 bellard
                gen_movl_T0_reg(rd);
1163 e8af50a3 bellard
                break;
1164 3475187d bellard
#endif
1165 3475187d bellard
            } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
1166 e8af50a3 bellard
                if (!supervisor(dc))
1167 e8af50a3 bellard
                    goto priv_insn;
1168 3475187d bellard
#ifdef TARGET_SPARC64
1169 3475187d bellard
                rs1 = GET_FIELD(insn, 13, 17);
1170 3475187d bellard
                switch (rs1) {
1171 3475187d bellard
                case 0: // tpc
1172 3475187d bellard
                    gen_op_rdtpc();
1173 3475187d bellard
                    break;
1174 3475187d bellard
                case 1: // tnpc
1175 3475187d bellard
                    gen_op_rdtnpc();
1176 3475187d bellard
                    break;
1177 3475187d bellard
                case 2: // tstate
1178 3475187d bellard
                    gen_op_rdtstate();
1179 3475187d bellard
                    break;
1180 3475187d bellard
                case 3: // tt
1181 3475187d bellard
                    gen_op_rdtt();
1182 3475187d bellard
                    break;
1183 3475187d bellard
                case 4: // tick
1184 3475187d bellard
                    gen_op_rdtick();
1185 3475187d bellard
                    break;
1186 3475187d bellard
                case 5: // tba
1187 3475187d bellard
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
1188 3475187d bellard
                    break;
1189 3475187d bellard
                case 6: // pstate
1190 3475187d bellard
                    gen_op_rdpstate();
1191 3475187d bellard
                    break;
1192 3475187d bellard
                case 7: // tl
1193 3475187d bellard
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, tl));
1194 3475187d bellard
                    break;
1195 3475187d bellard
                case 8: // pil
1196 3475187d bellard
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, psrpil));
1197 3475187d bellard
                    break;
1198 3475187d bellard
                case 9: // cwp
1199 3475187d bellard
                    gen_op_rdcwp();
1200 3475187d bellard
                    break;
1201 3475187d bellard
                case 10: // cansave
1202 3475187d bellard
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, cansave));
1203 3475187d bellard
                    break;
1204 3475187d bellard
                case 11: // canrestore
1205 3475187d bellard
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, canrestore));
1206 3475187d bellard
                    break;
1207 3475187d bellard
                case 12: // cleanwin
1208 3475187d bellard
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, cleanwin));
1209 3475187d bellard
                    break;
1210 3475187d bellard
                case 13: // otherwin
1211 3475187d bellard
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, otherwin));
1212 3475187d bellard
                    break;
1213 3475187d bellard
                case 14: // wstate
1214 3475187d bellard
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, wstate));
1215 3475187d bellard
                    break;
1216 3475187d bellard
                case 31: // ver
1217 3475187d bellard
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, version));
1218 3475187d bellard
                    break;
1219 3475187d bellard
                case 15: // fq
1220 3475187d bellard
                default:
1221 3475187d bellard
                    goto illegal_insn;
1222 3475187d bellard
                }
1223 3475187d bellard
#else
1224 3475187d bellard
                gen_op_movl_T0_env(offsetof(CPUSPARCState, wim));
1225 3475187d bellard
#endif
1226 e8af50a3 bellard
                gen_movl_T0_reg(rd);
1227 e8af50a3 bellard
                break;
1228 3475187d bellard
            } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
1229 3475187d bellard
#ifdef TARGET_SPARC64
1230 3475187d bellard
                gen_op_flushw();
1231 3475187d bellard
#else
1232 e8af50a3 bellard
                if (!supervisor(dc))
1233 e8af50a3 bellard
                    goto priv_insn;
1234 3475187d bellard
                gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
1235 e8af50a3 bellard
                gen_movl_T0_reg(rd);
1236 3475187d bellard
#endif
1237 e8af50a3 bellard
                break;
1238 e8af50a3 bellard
#endif
1239 e80cfcfc bellard
            } else if (xop == 0x34) {        /* FPU Operations */
1240 e80cfcfc bellard
#if !defined(CONFIG_USER_ONLY)
1241 55e4f664 bellard
                save_state(dc);
1242 e80cfcfc bellard
                gen_op_trap_ifnofpu();
1243 e80cfcfc bellard
#endif
1244 e8af50a3 bellard
                rs1 = GET_FIELD(insn, 13, 17);
1245 e8af50a3 bellard
                rs2 = GET_FIELD(insn, 27, 31);
1246 e8af50a3 bellard
                xop = GET_FIELD(insn, 18, 26);
1247 e8af50a3 bellard
                switch (xop) {
1248 e8af50a3 bellard
                    case 0x1: /* fmovs */
1249 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs2);
1250 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1251 e8af50a3 bellard
                        break;
1252 e8af50a3 bellard
                    case 0x5: /* fnegs */
1253 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1254 e8af50a3 bellard
                        gen_op_fnegs();
1255 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1256 e8af50a3 bellard
                        break;
1257 e8af50a3 bellard
                    case 0x9: /* fabss */
1258 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1259 e8af50a3 bellard
                        gen_op_fabss();
1260 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1261 e8af50a3 bellard
                        break;
1262 e8af50a3 bellard
                    case 0x29: /* fsqrts */
1263 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1264 e8af50a3 bellard
                        gen_op_fsqrts();
1265 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1266 e8af50a3 bellard
                        break;
1267 e8af50a3 bellard
                    case 0x2a: /* fsqrtd */
1268 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1269 e8af50a3 bellard
                        gen_op_fsqrtd();
1270 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1271 e8af50a3 bellard
                        break;
1272 e80cfcfc bellard
                    case 0x2b: /* fsqrtq */
1273 e80cfcfc bellard
                        goto nfpu_insn;
1274 e8af50a3 bellard
                    case 0x41:
1275 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs1);
1276 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1277 e8af50a3 bellard
                        gen_op_fadds();
1278 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1279 e8af50a3 bellard
                        break;
1280 e8af50a3 bellard
                    case 0x42:
1281 3475187d bellard
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1282 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1283 e8af50a3 bellard
                        gen_op_faddd();
1284 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1285 e8af50a3 bellard
                        break;
1286 e80cfcfc bellard
                    case 0x43: /* faddq */
1287 e80cfcfc bellard
                        goto nfpu_insn;
1288 e8af50a3 bellard
                    case 0x45:
1289 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs1);
1290 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1291 e8af50a3 bellard
                        gen_op_fsubs();
1292 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1293 e8af50a3 bellard
                        break;
1294 e8af50a3 bellard
                    case 0x46:
1295 3475187d bellard
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1296 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1297 e8af50a3 bellard
                        gen_op_fsubd();
1298 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1299 e8af50a3 bellard
                        break;
1300 e80cfcfc bellard
                    case 0x47: /* fsubq */
1301 e80cfcfc bellard
                        goto nfpu_insn;
1302 e8af50a3 bellard
                    case 0x49:
1303 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs1);
1304 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1305 e8af50a3 bellard
                        gen_op_fmuls();
1306 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1307 e8af50a3 bellard
                        break;
1308 e8af50a3 bellard
                    case 0x4a:
1309 3475187d bellard
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1310 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1311 e8af50a3 bellard
                        gen_op_fmuld();
1312 e8af50a3 bellard
                        gen_op_store_DT0_fpr(rd);
1313 e8af50a3 bellard
                        break;
1314 e80cfcfc bellard
                    case 0x4b: /* fmulq */
1315 e80cfcfc bellard
                        goto nfpu_insn;
1316 e8af50a3 bellard
                    case 0x4d:
1317 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs1);
1318 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1319 e8af50a3 bellard
                        gen_op_fdivs();
1320 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1321 e8af50a3 bellard
                        break;
1322 e8af50a3 bellard
                    case 0x4e:
1323 3475187d bellard
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1324 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1325 e8af50a3 bellard
                        gen_op_fdivd();
1326 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1327 e8af50a3 bellard
                        break;
1328 e80cfcfc bellard
                    case 0x4f: /* fdivq */
1329 e80cfcfc bellard
                        goto nfpu_insn;
1330 e8af50a3 bellard
                    case 0x69:
1331 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs1);
1332 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1333 e8af50a3 bellard
                        gen_op_fsmuld();
1334 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1335 e8af50a3 bellard
                        break;
1336 e80cfcfc bellard
                    case 0x6e: /* fdmulq */
1337 e80cfcfc bellard
                        goto nfpu_insn;
1338 e8af50a3 bellard
                    case 0xc4:
1339 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1340 e8af50a3 bellard
                        gen_op_fitos();
1341 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1342 e8af50a3 bellard
                        break;
1343 e8af50a3 bellard
                    case 0xc6:
1344 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1345 e8af50a3 bellard
                        gen_op_fdtos();
1346 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1347 e8af50a3 bellard
                        break;
1348 e80cfcfc bellard
                    case 0xc7: /* fqtos */
1349 e80cfcfc bellard
                        goto nfpu_insn;
1350 e8af50a3 bellard
                    case 0xc8:
1351 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1352 e8af50a3 bellard
                        gen_op_fitod();
1353 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1354 e8af50a3 bellard
                        break;
1355 e8af50a3 bellard
                    case 0xc9:
1356 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1357 e8af50a3 bellard
                        gen_op_fstod();
1358 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1359 e8af50a3 bellard
                        break;
1360 e80cfcfc bellard
                    case 0xcb: /* fqtod */
1361 e80cfcfc bellard
                        goto nfpu_insn;
1362 e80cfcfc bellard
                    case 0xcc: /* fitoq */
1363 e80cfcfc bellard
                        goto nfpu_insn;
1364 e80cfcfc bellard
                    case 0xcd: /* fstoq */
1365 e80cfcfc bellard
                        goto nfpu_insn;
1366 e80cfcfc bellard
                    case 0xce: /* fdtoq */
1367 e80cfcfc bellard
                        goto nfpu_insn;
1368 e8af50a3 bellard
                    case 0xd1:
1369 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
1370 e8af50a3 bellard
                        gen_op_fstoi();
1371 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1372 e8af50a3 bellard
                        break;
1373 e8af50a3 bellard
                    case 0xd2:
1374 e8af50a3 bellard
                        gen_op_load_fpr_DT1(rs2);
1375 e8af50a3 bellard
                        gen_op_fdtoi();
1376 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
1377 e8af50a3 bellard
                        break;
1378 e80cfcfc bellard
                    case 0xd3: /* fqtoi */
1379 e80cfcfc bellard
                        goto nfpu_insn;
1380 3475187d bellard
#ifdef TARGET_SPARC64
1381 af7bf89b bellard
                    case 0x2: /* V9 fmovd */
1382 3475187d bellard
                        gen_op_load_fpr_DT0(DFPREG(rs2));
1383 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1384 3475187d bellard
                        break;
1385 af7bf89b bellard
                    case 0x6: /* V9 fnegd */
1386 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1387 3475187d bellard
                        gen_op_fnegd();
1388 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1389 3475187d bellard
                        break;
1390 af7bf89b bellard
                    case 0xa: /* V9 fabsd */
1391 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1392 3475187d bellard
                        gen_op_fabsd();
1393 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1394 3475187d bellard
                        break;
1395 af7bf89b bellard
                    case 0x81: /* V9 fstox */
1396 3475187d bellard
                        gen_op_load_fpr_FT1(rs2);
1397 3475187d bellard
                        gen_op_fstox();
1398 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1399 3475187d bellard
                        break;
1400 af7bf89b bellard
                    case 0x82: /* V9 fdtox */
1401 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1402 3475187d bellard
                        gen_op_fdtox();
1403 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1404 3475187d bellard
                        break;
1405 af7bf89b bellard
                    case 0x84: /* V9 fxtos */
1406 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1407 3475187d bellard
                        gen_op_fxtos();
1408 3475187d bellard
                        gen_op_store_FT0_fpr(rd);
1409 3475187d bellard
                        break;
1410 af7bf89b bellard
                    case 0x88: /* V9 fxtod */
1411 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1412 3475187d bellard
                        gen_op_fxtod();
1413 3475187d bellard
                        gen_op_store_DT0_fpr(DFPREG(rd));
1414 3475187d bellard
                        break;
1415 af7bf89b bellard
                    case 0x3: /* V9 fmovq */
1416 af7bf89b bellard
                    case 0x7: /* V9 fnegq */
1417 af7bf89b bellard
                    case 0xb: /* V9 fabsq */
1418 af7bf89b bellard
                    case 0x83: /* V9 fqtox */
1419 af7bf89b bellard
                    case 0x8c: /* V9 fxtoq */
1420 3475187d bellard
                        goto nfpu_insn;
1421 3475187d bellard
#endif
1422 3475187d bellard
                    default:
1423 e8af50a3 bellard
                        goto illegal_insn;
1424 e8af50a3 bellard
                }
1425 e80cfcfc bellard
            } else if (xop == 0x35) {        /* FPU Operations */
1426 3475187d bellard
#ifdef TARGET_SPARC64
1427 3475187d bellard
                int cond;
1428 3475187d bellard
#endif
1429 e80cfcfc bellard
#if !defined(CONFIG_USER_ONLY)
1430 55e4f664 bellard
                save_state(dc);
1431 e80cfcfc bellard
                gen_op_trap_ifnofpu();
1432 e80cfcfc bellard
#endif
1433 cf495bcf bellard
                rs1 = GET_FIELD(insn, 13, 17);
1434 e80cfcfc bellard
                rs2 = GET_FIELD(insn, 27, 31);
1435 e80cfcfc bellard
                xop = GET_FIELD(insn, 18, 26);
1436 3475187d bellard
#ifdef TARGET_SPARC64
1437 3475187d bellard
                if ((xop & 0x11f) == 0x005) { // V9 fmovsr
1438 3475187d bellard
                    cond = GET_FIELD_SP(insn, 14, 17);
1439 3475187d bellard
                    gen_op_load_fpr_FT0(rd);
1440 3475187d bellard
                    gen_op_load_fpr_FT1(rs2);
1441 3475187d bellard
                    rs1 = GET_FIELD(insn, 13, 17);
1442 3475187d bellard
                    gen_movl_reg_T0(rs1);
1443 3475187d bellard
                    flush_T2(dc);
1444 3475187d bellard
                    gen_cond_reg(cond);
1445 3475187d bellard
                    gen_op_fmovs_cc();
1446 3475187d bellard
                    gen_op_store_FT0_fpr(rd);
1447 3475187d bellard
                    break;
1448 3475187d bellard
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
1449 3475187d bellard
                    cond = GET_FIELD_SP(insn, 14, 17);
1450 3475187d bellard
                    gen_op_load_fpr_DT0(rd);
1451 3475187d bellard
                    gen_op_load_fpr_DT1(rs2);
1452 3475187d bellard
                    flush_T2(dc);
1453 3475187d bellard
                    rs1 = GET_FIELD(insn, 13, 17);
1454 3475187d bellard
                    gen_movl_reg_T0(rs1);
1455 3475187d bellard
                    gen_cond_reg(cond);
1456 3475187d bellard
                    gen_op_fmovs_cc();
1457 3475187d bellard
                    gen_op_store_DT0_fpr(rd);
1458 3475187d bellard
                    break;
1459 3475187d bellard
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
1460 3475187d bellard
                    goto nfpu_insn;
1461 3475187d bellard
                }
1462 3475187d bellard
#endif
1463 e80cfcfc bellard
                switch (xop) {
1464 3475187d bellard
#ifdef TARGET_SPARC64
1465 3475187d bellard
                    case 0x001: /* V9 fmovscc %fcc0 */
1466 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1467 3475187d bellard
                        gen_op_load_fpr_FT0(rd);
1468 3475187d bellard
                        gen_op_load_fpr_FT1(rs2);
1469 3475187d bellard
                        flush_T2(dc);
1470 3475187d bellard
                        gen_fcond[0][cond]();
1471 3475187d bellard
                        gen_op_fmovs_cc();
1472 3475187d bellard
                        gen_op_store_FT0_fpr(rd);
1473 3475187d bellard
                        break;
1474 3475187d bellard
                    case 0x002: /* V9 fmovdcc %fcc0 */
1475 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1476 3475187d bellard
                        gen_op_load_fpr_DT0(rd);
1477 3475187d bellard
                        gen_op_load_fpr_DT1(rs2);
1478 3475187d bellard
                        flush_T2(dc);
1479 3475187d bellard
                        gen_fcond[0][cond]();
1480 3475187d bellard
                        gen_op_fmovd_cc();
1481 3475187d bellard
                        gen_op_store_DT0_fpr(rd);
1482 3475187d bellard
                        break;
1483 3475187d bellard
                    case 0x003: /* V9 fmovqcc %fcc0 */
1484 3475187d bellard
                        goto nfpu_insn;
1485 3475187d bellard
                    case 0x041: /* V9 fmovscc %fcc1 */
1486 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1487 3475187d bellard
                        gen_op_load_fpr_FT0(rd);
1488 3475187d bellard
                        gen_op_load_fpr_FT1(rs2);
1489 3475187d bellard
                        flush_T2(dc);
1490 3475187d bellard
                        gen_fcond[1][cond]();
1491 3475187d bellard
                        gen_op_fmovs_cc();
1492 3475187d bellard
                        gen_op_store_FT0_fpr(rd);
1493 3475187d bellard
                        break;
1494 3475187d bellard
                    case 0x042: /* V9 fmovdcc %fcc1 */
1495 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1496 3475187d bellard
                        gen_op_load_fpr_DT0(rd);
1497 3475187d bellard
                        gen_op_load_fpr_DT1(rs2);
1498 3475187d bellard
                        flush_T2(dc);
1499 3475187d bellard
                        gen_fcond[1][cond]();
1500 3475187d bellard
                        gen_op_fmovd_cc();
1501 3475187d bellard
                        gen_op_store_DT0_fpr(rd);
1502 3475187d bellard
                        break;
1503 3475187d bellard
                    case 0x043: /* V9 fmovqcc %fcc1 */
1504 3475187d bellard
                        goto nfpu_insn;
1505 3475187d bellard
                    case 0x081: /* V9 fmovscc %fcc2 */
1506 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1507 3475187d bellard
                        gen_op_load_fpr_FT0(rd);
1508 3475187d bellard
                        gen_op_load_fpr_FT1(rs2);
1509 3475187d bellard
                        flush_T2(dc);
1510 3475187d bellard
                        gen_fcond[2][cond]();
1511 3475187d bellard
                        gen_op_fmovs_cc();
1512 3475187d bellard
                        gen_op_store_FT0_fpr(rd);
1513 3475187d bellard
                        break;
1514 3475187d bellard
                    case 0x082: /* V9 fmovdcc %fcc2 */
1515 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1516 3475187d bellard
                        gen_op_load_fpr_DT0(rd);
1517 3475187d bellard
                        gen_op_load_fpr_DT1(rs2);
1518 3475187d bellard
                        flush_T2(dc);
1519 3475187d bellard
                        gen_fcond[2][cond]();
1520 3475187d bellard
                        gen_op_fmovd_cc();
1521 3475187d bellard
                        gen_op_store_DT0_fpr(rd);
1522 3475187d bellard
                        break;
1523 3475187d bellard
                    case 0x083: /* V9 fmovqcc %fcc2 */
1524 3475187d bellard
                        goto nfpu_insn;
1525 3475187d bellard
                    case 0x0c1: /* V9 fmovscc %fcc3 */
1526 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1527 3475187d bellard
                        gen_op_load_fpr_FT0(rd);
1528 3475187d bellard
                        gen_op_load_fpr_FT1(rs2);
1529 3475187d bellard
                        flush_T2(dc);
1530 3475187d bellard
                        gen_fcond[3][cond]();
1531 3475187d bellard
                        gen_op_fmovs_cc();
1532 3475187d bellard
                        gen_op_store_FT0_fpr(rd);
1533 3475187d bellard
                        break;
1534 3475187d bellard
                    case 0x0c2: /* V9 fmovdcc %fcc3 */
1535 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1536 3475187d bellard
                        gen_op_load_fpr_DT0(rd);
1537 3475187d bellard
                        gen_op_load_fpr_DT1(rs2);
1538 3475187d bellard
                        flush_T2(dc);
1539 3475187d bellard
                        gen_fcond[3][cond]();
1540 3475187d bellard
                        gen_op_fmovd_cc();
1541 3475187d bellard
                        gen_op_store_DT0_fpr(rd);
1542 3475187d bellard
                        break;
1543 3475187d bellard
                    case 0x0c3: /* V9 fmovqcc %fcc3 */
1544 3475187d bellard
                        goto nfpu_insn;
1545 3475187d bellard
                    case 0x101: /* V9 fmovscc %icc */
1546 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1547 3475187d bellard
                        gen_op_load_fpr_FT0(rd);
1548 3475187d bellard
                        gen_op_load_fpr_FT1(rs2);
1549 3475187d bellard
                        flush_T2(dc);
1550 3475187d bellard
                        gen_cond[0][cond]();
1551 3475187d bellard
                        gen_op_fmovs_cc();
1552 3475187d bellard
                        gen_op_store_FT0_fpr(rd);
1553 3475187d bellard
                        break;
1554 3475187d bellard
                    case 0x102: /* V9 fmovdcc %icc */
1555 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1556 3475187d bellard
                        gen_op_load_fpr_DT0(rd);
1557 3475187d bellard
                        gen_op_load_fpr_DT1(rs2);
1558 3475187d bellard
                        flush_T2(dc);
1559 3475187d bellard
                        gen_cond[0][cond]();
1560 3475187d bellard
                        gen_op_fmovd_cc();
1561 3475187d bellard
                        gen_op_store_DT0_fpr(rd);
1562 3475187d bellard
                        break;
1563 3475187d bellard
                    case 0x103: /* V9 fmovqcc %icc */
1564 3475187d bellard
                        goto nfpu_insn;
1565 3475187d bellard
                    case 0x181: /* V9 fmovscc %xcc */
1566 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1567 3475187d bellard
                        gen_op_load_fpr_FT0(rd);
1568 3475187d bellard
                        gen_op_load_fpr_FT1(rs2);
1569 3475187d bellard
                        flush_T2(dc);
1570 3475187d bellard
                        gen_cond[1][cond]();
1571 3475187d bellard
                        gen_op_fmovs_cc();
1572 3475187d bellard
                        gen_op_store_FT0_fpr(rd);
1573 3475187d bellard
                        break;
1574 3475187d bellard
                    case 0x182: /* V9 fmovdcc %xcc */
1575 3475187d bellard
                        cond = GET_FIELD_SP(insn, 14, 17);
1576 3475187d bellard
                        gen_op_load_fpr_DT0(rd);
1577 3475187d bellard
                        gen_op_load_fpr_DT1(rs2);
1578 3475187d bellard
                        flush_T2(dc);
1579 3475187d bellard
                        gen_cond[1][cond]();
1580 3475187d bellard
                        gen_op_fmovd_cc();
1581 3475187d bellard
                        gen_op_store_DT0_fpr(rd);
1582 3475187d bellard
                        break;
1583 3475187d bellard
                    case 0x183: /* V9 fmovqcc %xcc */
1584 3475187d bellard
                        goto nfpu_insn;
1585 3475187d bellard
#endif
1586 3475187d bellard
                    case 0x51: /* V9 %fcc */
1587 e80cfcfc bellard
                        gen_op_load_fpr_FT0(rs1);
1588 e80cfcfc bellard
                        gen_op_load_fpr_FT1(rs2);
1589 3475187d bellard
#ifdef TARGET_SPARC64
1590 3475187d bellard
                        gen_fcmps[rd & 3]();
1591 3475187d bellard
#else
1592 e80cfcfc bellard
                        gen_op_fcmps();
1593 3475187d bellard
#endif
1594 e80cfcfc bellard
                        break;
1595 3475187d bellard
                    case 0x52: /* V9 %fcc */
1596 3475187d bellard
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1597 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1598 3475187d bellard
#ifdef TARGET_SPARC64
1599 3475187d bellard
                        gen_fcmpd[rd & 3]();
1600 3475187d bellard
#else
1601 e80cfcfc bellard
                        gen_op_fcmpd();
1602 3475187d bellard
#endif
1603 e80cfcfc bellard
                        break;
1604 e80cfcfc bellard
                    case 0x53: /* fcmpq */
1605 e80cfcfc bellard
                        goto nfpu_insn;
1606 3475187d bellard
                    case 0x55: /* fcmpes, V9 %fcc */
1607 e80cfcfc bellard
                        gen_op_load_fpr_FT0(rs1);
1608 e80cfcfc bellard
                        gen_op_load_fpr_FT1(rs2);
1609 3475187d bellard
#ifdef TARGET_SPARC64
1610 3475187d bellard
                        gen_fcmps[rd & 3]();
1611 3475187d bellard
#else
1612 e80cfcfc bellard
                        gen_op_fcmps(); /* XXX should trap if qNaN or sNaN  */
1613 3475187d bellard
#endif
1614 e80cfcfc bellard
                        break;
1615 3475187d bellard
                    case 0x56: /* fcmped, V9 %fcc */
1616 3475187d bellard
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1617 3475187d bellard
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1618 3475187d bellard
#ifdef TARGET_SPARC64
1619 3475187d bellard
                        gen_fcmpd[rd & 3]();
1620 3475187d bellard
#else
1621 e80cfcfc bellard
                        gen_op_fcmpd(); /* XXX should trap if qNaN or sNaN  */
1622 3475187d bellard
#endif
1623 e80cfcfc bellard
                        break;
1624 e80cfcfc bellard
                    case 0x57: /* fcmpeq */
1625 e80cfcfc bellard
                        goto nfpu_insn;
1626 e80cfcfc bellard
                    default:
1627 e80cfcfc bellard
                        goto illegal_insn;
1628 e80cfcfc bellard
                }
1629 e80cfcfc bellard
#if defined(OPTIM)
1630 e80cfcfc bellard
            } else if (xop == 0x2) {
1631 e80cfcfc bellard
                // clr/mov shortcut
1632 e80cfcfc bellard
1633 e80cfcfc bellard
                rs1 = GET_FIELD(insn, 13, 17);
1634 e80cfcfc bellard
                if (rs1 == 0) {
1635 e80cfcfc bellard
                    // or %g0, x, y -> mov T1, x; mov y, T1
1636 e80cfcfc bellard
                    if (IS_IMM) {        /* immediate */
1637 e80cfcfc bellard
                        rs2 = GET_FIELDs(insn, 19, 31);
1638 3475187d bellard
                        gen_movl_simm_T1(rs2);
1639 e80cfcfc bellard
                    } else {                /* register */
1640 e80cfcfc bellard
                        rs2 = GET_FIELD(insn, 27, 31);
1641 e80cfcfc bellard
                        gen_movl_reg_T1(rs2);
1642 e80cfcfc bellard
                    }
1643 e80cfcfc bellard
                    gen_movl_T1_reg(rd);
1644 e80cfcfc bellard
                } else {
1645 e80cfcfc bellard
                    gen_movl_reg_T0(rs1);
1646 e80cfcfc bellard
                    if (IS_IMM) {        /* immediate */
1647 e80cfcfc bellard
                        // or x, #0, y -> mov T1, x; mov y, T1
1648 e80cfcfc bellard
                        rs2 = GET_FIELDs(insn, 19, 31);
1649 e80cfcfc bellard
                        if (rs2 != 0) {
1650 3475187d bellard
                            gen_movl_simm_T1(rs2);
1651 e80cfcfc bellard
                            gen_op_or_T1_T0();
1652 e80cfcfc bellard
                        }
1653 e80cfcfc bellard
                    } else {                /* register */
1654 e80cfcfc bellard
                        // or x, %g0, y -> mov T1, x; mov y, T1
1655 e80cfcfc bellard
                        rs2 = GET_FIELD(insn, 27, 31);
1656 e80cfcfc bellard
                        if (rs2 != 0) {
1657 e80cfcfc bellard
                            gen_movl_reg_T1(rs2);
1658 e80cfcfc bellard
                            gen_op_or_T1_T0();
1659 e80cfcfc bellard
                        }
1660 e80cfcfc bellard
                    }
1661 e80cfcfc bellard
                    gen_movl_T0_reg(rd);
1662 e80cfcfc bellard
                }
1663 e80cfcfc bellard
#endif
1664 83469015 bellard
#ifdef TARGET_SPARC64
1665 83469015 bellard
            } else if (xop == 0x25) { /* sll, V9 sllx ( == sll) */
1666 83469015 bellard
                rs1 = GET_FIELD(insn, 13, 17);
1667 83469015 bellard
                gen_movl_reg_T0(rs1);
1668 83469015 bellard
                if (IS_IMM) {        /* immediate */
1669 83469015 bellard
                    rs2 = GET_FIELDs(insn, 20, 31);
1670 83469015 bellard
                    gen_movl_simm_T1(rs2);
1671 83469015 bellard
                } else {                /* register */
1672 83469015 bellard
                    rs2 = GET_FIELD(insn, 27, 31);
1673 83469015 bellard
                    gen_movl_reg_T1(rs2);
1674 83469015 bellard
                }
1675 83469015 bellard
                gen_op_sll();
1676 83469015 bellard
                gen_movl_T0_reg(rd);
1677 83469015 bellard
            } else if (xop == 0x26) { /* srl, V9 srlx */
1678 83469015 bellard
                rs1 = GET_FIELD(insn, 13, 17);
1679 83469015 bellard
                gen_movl_reg_T0(rs1);
1680 83469015 bellard
                if (IS_IMM) {        /* immediate */
1681 83469015 bellard
                    rs2 = GET_FIELDs(insn, 20, 31);
1682 83469015 bellard
                    gen_movl_simm_T1(rs2);
1683 83469015 bellard
                } else {                /* register */
1684 83469015 bellard
                    rs2 = GET_FIELD(insn, 27, 31);
1685 83469015 bellard
                    gen_movl_reg_T1(rs2);
1686 83469015 bellard
                }
1687 83469015 bellard
                if (insn & (1 << 12))
1688 83469015 bellard
                    gen_op_srlx();
1689 83469015 bellard
                else
1690 83469015 bellard
                    gen_op_srl();
1691 83469015 bellard
                gen_movl_T0_reg(rd);
1692 83469015 bellard
            } else if (xop == 0x27) { /* sra, V9 srax */
1693 83469015 bellard
                rs1 = GET_FIELD(insn, 13, 17);
1694 83469015 bellard
                gen_movl_reg_T0(rs1);
1695 83469015 bellard
                if (IS_IMM) {        /* immediate */
1696 83469015 bellard
                    rs2 = GET_FIELDs(insn, 20, 31);
1697 83469015 bellard
                    gen_movl_simm_T1(rs2);
1698 83469015 bellard
                } else {                /* register */
1699 83469015 bellard
                    rs2 = GET_FIELD(insn, 27, 31);
1700 83469015 bellard
                    gen_movl_reg_T1(rs2);
1701 83469015 bellard
                }
1702 83469015 bellard
                if (insn & (1 << 12))
1703 83469015 bellard
                    gen_op_srax();
1704 83469015 bellard
                else
1705 83469015 bellard
                    gen_op_sra();
1706 83469015 bellard
                gen_movl_T0_reg(rd);
1707 83469015 bellard
#endif
1708 e80cfcfc bellard
            } else if (xop < 0x38) {
1709 e80cfcfc bellard
                rs1 = GET_FIELD(insn, 13, 17);
1710 e80cfcfc bellard
                gen_movl_reg_T0(rs1);
1711 e80cfcfc bellard
                if (IS_IMM) {        /* immediate */
1712 cf495bcf bellard
                    rs2 = GET_FIELDs(insn, 19, 31);
1713 3475187d bellard
                    gen_movl_simm_T1(rs2);
1714 cf495bcf bellard
                } else {                /* register */
1715 cf495bcf bellard
                    rs2 = GET_FIELD(insn, 27, 31);
1716 cf495bcf bellard
                    gen_movl_reg_T1(rs2);
1717 cf495bcf bellard
                }
1718 cf495bcf bellard
                if (xop < 0x20) {
1719 cf495bcf bellard
                    switch (xop & ~0x10) {
1720 cf495bcf bellard
                    case 0x0:
1721 cf495bcf bellard
                        if (xop & 0x10)
1722 cf495bcf bellard
                            gen_op_add_T1_T0_cc();
1723 cf495bcf bellard
                        else
1724 cf495bcf bellard
                            gen_op_add_T1_T0();
1725 cf495bcf bellard
                        break;
1726 cf495bcf bellard
                    case 0x1:
1727 cf495bcf bellard
                        gen_op_and_T1_T0();
1728 cf495bcf bellard
                        if (xop & 0x10)
1729 cf495bcf bellard
                            gen_op_logic_T0_cc();
1730 cf495bcf bellard
                        break;
1731 cf495bcf bellard
                    case 0x2:
1732 e80cfcfc bellard
                        gen_op_or_T1_T0();
1733 e80cfcfc bellard
                        if (xop & 0x10)
1734 e80cfcfc bellard
                            gen_op_logic_T0_cc();
1735 e80cfcfc bellard
                        break;
1736 cf495bcf bellard
                    case 0x3:
1737 cf495bcf bellard
                        gen_op_xor_T1_T0();
1738 cf495bcf bellard
                        if (xop & 0x10)
1739 cf495bcf bellard
                            gen_op_logic_T0_cc();
1740 cf495bcf bellard
                        break;
1741 cf495bcf bellard
                    case 0x4:
1742 cf495bcf bellard
                        if (xop & 0x10)
1743 cf495bcf bellard
                            gen_op_sub_T1_T0_cc();
1744 cf495bcf bellard
                        else
1745 cf495bcf bellard
                            gen_op_sub_T1_T0();
1746 cf495bcf bellard
                        break;
1747 cf495bcf bellard
                    case 0x5:
1748 cf495bcf bellard
                        gen_op_andn_T1_T0();
1749 cf495bcf bellard
                        if (xop & 0x10)
1750 cf495bcf bellard
                            gen_op_logic_T0_cc();
1751 cf495bcf bellard
                        break;
1752 cf495bcf bellard
                    case 0x6:
1753 cf495bcf bellard
                        gen_op_orn_T1_T0();
1754 cf495bcf bellard
                        if (xop & 0x10)
1755 cf495bcf bellard
                            gen_op_logic_T0_cc();
1756 cf495bcf bellard
                        break;
1757 cf495bcf bellard
                    case 0x7:
1758 cf495bcf bellard
                        gen_op_xnor_T1_T0();
1759 cf495bcf bellard
                        if (xop & 0x10)
1760 cf495bcf bellard
                            gen_op_logic_T0_cc();
1761 cf495bcf bellard
                        break;
1762 cf495bcf bellard
                    case 0x8:
1763 cf495bcf bellard
                        if (xop & 0x10)
1764 af7bf89b bellard
                            gen_op_addx_T1_T0_cc();
1765 af7bf89b bellard
                        else
1766 af7bf89b bellard
                            gen_op_addx_T1_T0();
1767 cf495bcf bellard
                        break;
1768 cf495bcf bellard
                    case 0xa:
1769 cf495bcf bellard
                        gen_op_umul_T1_T0();
1770 cf495bcf bellard
                        if (xop & 0x10)
1771 cf495bcf bellard
                            gen_op_logic_T0_cc();
1772 cf495bcf bellard
                        break;
1773 cf495bcf bellard
                    case 0xb:
1774 cf495bcf bellard
                        gen_op_smul_T1_T0();
1775 cf495bcf bellard
                        if (xop & 0x10)
1776 cf495bcf bellard
                            gen_op_logic_T0_cc();
1777 cf495bcf bellard
                        break;
1778 cf495bcf bellard
                    case 0xc:
1779 cf495bcf bellard
                        if (xop & 0x10)
1780 af7bf89b bellard
                            gen_op_subx_T1_T0_cc();
1781 af7bf89b bellard
                        else
1782 af7bf89b bellard
                            gen_op_subx_T1_T0();
1783 cf495bcf bellard
                        break;
1784 cf495bcf bellard
                    case 0xe:
1785 cf495bcf bellard
                        gen_op_udiv_T1_T0();
1786 cf495bcf bellard
                        if (xop & 0x10)
1787 cf495bcf bellard
                            gen_op_div_cc();
1788 cf495bcf bellard
                        break;
1789 cf495bcf bellard
                    case 0xf:
1790 cf495bcf bellard
                        gen_op_sdiv_T1_T0();
1791 cf495bcf bellard
                        if (xop & 0x10)
1792 cf495bcf bellard
                            gen_op_div_cc();
1793 cf495bcf bellard
                        break;
1794 cf495bcf bellard
                    default:
1795 cf495bcf bellard
                        goto illegal_insn;
1796 cf495bcf bellard
                    }
1797 e80cfcfc bellard
                    gen_movl_T0_reg(rd);
1798 cf495bcf bellard
                } else {
1799 cf495bcf bellard
                    switch (xop) {
1800 3475187d bellard
#ifdef TARGET_SPARC64
1801 3475187d bellard
                    case 0x9: /* V9 mulx */
1802 3475187d bellard
                        gen_op_mulx_T1_T0();
1803 3475187d bellard
                        gen_movl_T0_reg(rd);
1804 3475187d bellard
                        break;
1805 3475187d bellard
                    case 0xd: /* V9 udivx */
1806 3475187d bellard
                        gen_op_udivx_T1_T0();
1807 3475187d bellard
                        gen_movl_T0_reg(rd);
1808 3475187d bellard
                        break;
1809 3475187d bellard
#endif
1810 e80cfcfc bellard
                    case 0x20: /* taddcc */
1811 e80cfcfc bellard
                    case 0x21: /* tsubcc */
1812 e80cfcfc bellard
                    case 0x22: /* taddcctv */
1813 e80cfcfc bellard
                    case 0x23: /* tsubcctv */
1814 e80cfcfc bellard
                        goto illegal_insn;
1815 cf495bcf bellard
                    case 0x24: /* mulscc */
1816 cf495bcf bellard
                        gen_op_mulscc_T1_T0();
1817 cf495bcf bellard
                        gen_movl_T0_reg(rd);
1818 cf495bcf bellard
                        break;
1819 83469015 bellard
#ifndef TARGET_SPARC64
1820 83469015 bellard
                    case 0x25:        /* sll */
1821 3475187d bellard
                        gen_op_sll();
1822 cf495bcf bellard
                        gen_movl_T0_reg(rd);
1823 cf495bcf bellard
                        break;
1824 83469015 bellard
                    case 0x26:  /* srl */
1825 3475187d bellard
                        gen_op_srl();
1826 cf495bcf bellard
                        gen_movl_T0_reg(rd);
1827 cf495bcf bellard
                        break;
1828 83469015 bellard
                    case 0x27:  /* sra */
1829 3475187d bellard
                        gen_op_sra();
1830 cf495bcf bellard
                        gen_movl_T0_reg(rd);
1831 cf495bcf bellard
                        break;
1832 83469015 bellard
#endif
1833 cf495bcf bellard
                    case 0x30:
1834 cf495bcf bellard
                        {
1835 cf495bcf bellard
                            switch(rd) {
1836 3475187d bellard
                            case 0: /* wry */
1837 3475187d bellard
                                gen_op_xor_T1_T0();
1838 3475187d bellard
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, y));
1839 cf495bcf bellard
                                break;
1840 3475187d bellard
#ifdef TARGET_SPARC64
1841 af7bf89b bellard
                            case 0x2: /* V9 wrccr */
1842 3475187d bellard
                                gen_op_wrccr();
1843 3475187d bellard
                                break;
1844 af7bf89b bellard
                            case 0x3: /* V9 wrasi */
1845 3475187d bellard
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, asi));
1846 3475187d bellard
                                break;
1847 af7bf89b bellard
                            case 0x6: /* V9 wrfprs */
1848 3475187d bellard
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, fprs));
1849 3475187d bellard
                                break;
1850 3475187d bellard
                            case 0xf: /* V9 sir, nop if user */
1851 3475187d bellard
#if !defined(CONFIG_USER_ONLY)
1852 3475187d bellard
                                if (supervisor(dc))
1853 3475187d bellard
                                    gen_op_sir();
1854 3475187d bellard
#endif
1855 3475187d bellard
                                break;
1856 83469015 bellard
                            case 0x17: /* Tick compare */
1857 83469015 bellard
#if !defined(CONFIG_USER_ONLY)
1858 83469015 bellard
                                if (!supervisor(dc))
1859 83469015 bellard
                                    goto illegal_insn;
1860 83469015 bellard
#endif
1861 83469015 bellard
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, tick_cmpr));
1862 83469015 bellard
                                break;
1863 83469015 bellard
                            case 0x18: /* System tick */
1864 83469015 bellard
#if !defined(CONFIG_USER_ONLY)
1865 83469015 bellard
                                if (!supervisor(dc))
1866 83469015 bellard
                                    goto illegal_insn;
1867 83469015 bellard
#endif
1868 83469015 bellard
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, stick_cmpr));
1869 83469015 bellard
                                break;
1870 83469015 bellard
                            case 0x19: /* System tick compare */
1871 83469015 bellard
#if !defined(CONFIG_USER_ONLY)
1872 83469015 bellard
                                if (!supervisor(dc))
1873 83469015 bellard
                                    goto illegal_insn;
1874 3475187d bellard
#endif
1875 83469015 bellard
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, stick_cmpr));
1876 83469015 bellard
                                break;
1877 83469015 bellard
1878 3475187d bellard
                            case 0x10: /* Performance Control */
1879 3475187d bellard
                            case 0x11: /* Performance Instrumentation Counter */
1880 3475187d bellard
                            case 0x12: /* Dispatch Control */
1881 3475187d bellard
                            case 0x13: /* Graphics Status */
1882 3475187d bellard
                            case 0x14: /* Softint set */
1883 3475187d bellard
                            case 0x15: /* Softint clear */
1884 3475187d bellard
                            case 0x16: /* Softint write */
1885 83469015 bellard
#endif
1886 3475187d bellard
                            default:
1887 cf495bcf bellard
                                goto illegal_insn;
1888 cf495bcf bellard
                            }
1889 cf495bcf bellard
                        }
1890 cf495bcf bellard
                        break;
1891 e8af50a3 bellard
#if !defined(CONFIG_USER_ONLY)
1892 af7bf89b bellard
                    case 0x31: /* wrpsr, V9 saved, restored */
1893 e8af50a3 bellard
                        {
1894 e8af50a3 bellard
                            if (!supervisor(dc))
1895 e8af50a3 bellard
                                goto priv_insn;
1896 3475187d bellard
#ifdef TARGET_SPARC64
1897 3475187d bellard
                            switch (rd) {
1898 3475187d bellard
                            case 0:
1899 3475187d bellard
                                gen_op_saved();
1900 3475187d bellard
                                break;
1901 3475187d bellard
                            case 1:
1902 3475187d bellard
                                gen_op_restored();
1903 3475187d bellard
                                break;
1904 3475187d bellard
                            default:
1905 3475187d bellard
                                goto illegal_insn;
1906 3475187d bellard
                            }
1907 3475187d bellard
#else
1908 e8af50a3 bellard
                            gen_op_xor_T1_T0();
1909 e8af50a3 bellard
                            gen_op_wrpsr();
1910 9e61bde5 bellard
                            save_state(dc);
1911 9e61bde5 bellard
                            gen_op_next_insn();
1912 9e61bde5 bellard
                            gen_op_movl_T0_0();
1913 9e61bde5 bellard
                            gen_op_exit_tb();
1914 9e61bde5 bellard
                            dc->is_br = 1;
1915 3475187d bellard
#endif
1916 e8af50a3 bellard
                        }
1917 e8af50a3 bellard
                        break;
1918 af7bf89b bellard
                    case 0x32: /* wrwim, V9 wrpr */
1919 e8af50a3 bellard
                        {
1920 e8af50a3 bellard
                            if (!supervisor(dc))
1921 e8af50a3 bellard
                                goto priv_insn;
1922 e8af50a3 bellard
                            gen_op_xor_T1_T0();
1923 3475187d bellard
#ifdef TARGET_SPARC64
1924 3475187d bellard
                            switch (rd) {
1925 3475187d bellard
                            case 0: // tpc
1926 3475187d bellard
                                gen_op_wrtpc();
1927 3475187d bellard
                                break;
1928 3475187d bellard
                            case 1: // tnpc
1929 3475187d bellard
                                gen_op_wrtnpc();
1930 3475187d bellard
                                break;
1931 3475187d bellard
                            case 2: // tstate
1932 3475187d bellard
                                gen_op_wrtstate();
1933 3475187d bellard
                                break;
1934 3475187d bellard
                            case 3: // tt
1935 3475187d bellard
                                gen_op_wrtt();
1936 3475187d bellard
                                break;
1937 3475187d bellard
                            case 4: // tick
1938 3475187d bellard
                                gen_op_wrtick();
1939 3475187d bellard
                                break;
1940 3475187d bellard
                            case 5: // tba
1941 83469015 bellard
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
1942 3475187d bellard
                                break;
1943 3475187d bellard
                            case 6: // pstate
1944 3475187d bellard
                                gen_op_wrpstate();
1945 3475187d bellard
                                break;
1946 3475187d bellard
                            case 7: // tl
1947 3475187d bellard
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, tl));
1948 3475187d bellard
                                break;
1949 3475187d bellard
                            case 8: // pil
1950 3475187d bellard
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, psrpil));
1951 3475187d bellard
                                break;
1952 3475187d bellard
                            case 9: // cwp
1953 3475187d bellard
                                gen_op_wrcwp();
1954 3475187d bellard
                                break;
1955 3475187d bellard
                            case 10: // cansave
1956 3475187d bellard
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, cansave));
1957 3475187d bellard
                                break;
1958 3475187d bellard
                            case 11: // canrestore
1959 3475187d bellard
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, canrestore));
1960 3475187d bellard
                                break;
1961 3475187d bellard
                            case 12: // cleanwin
1962 3475187d bellard
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, cleanwin));
1963 3475187d bellard
                                break;
1964 3475187d bellard
                            case 13: // otherwin
1965 3475187d bellard
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, otherwin));
1966 3475187d bellard
                                break;
1967 3475187d bellard
                            case 14: // wstate
1968 3475187d bellard
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, wstate));
1969 3475187d bellard
                                break;
1970 3475187d bellard
                            default:
1971 3475187d bellard
                                goto illegal_insn;
1972 3475187d bellard
                            }
1973 3475187d bellard
#else
1974 3475187d bellard
                            gen_op_movl_env_T0(offsetof(CPUSPARCState, wim));
1975 3475187d bellard
#endif
1976 e8af50a3 bellard
                        }
1977 e8af50a3 bellard
                        break;
1978 3475187d bellard
#ifndef TARGET_SPARC64
1979 3475187d bellard
                    case 0x33: /* wrtbr, V9 unimp */
1980 e8af50a3 bellard
                        {
1981 e8af50a3 bellard
                            if (!supervisor(dc))
1982 e8af50a3 bellard
                                goto priv_insn;
1983 e8af50a3 bellard
                            gen_op_xor_T1_T0();
1984 3475187d bellard
                            gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
1985 e8af50a3 bellard
                        }
1986 e8af50a3 bellard
                        break;
1987 e8af50a3 bellard
#endif
1988 3475187d bellard
#endif
1989 3475187d bellard
#ifdef TARGET_SPARC64
1990 af7bf89b bellard
                    case 0x2c: /* V9 movcc */
1991 3475187d bellard
                        {
1992 3475187d bellard
                            int cc = GET_FIELD_SP(insn, 11, 12);
1993 3475187d bellard
                            int cond = GET_FIELD_SP(insn, 14, 17);
1994 3475187d bellard
                            if (IS_IMM) {        /* immediate */
1995 3475187d bellard
                                rs2 = GET_FIELD_SPs(insn, 0, 10);
1996 3475187d bellard
                                gen_movl_simm_T1(rs2);
1997 3475187d bellard
                            }
1998 3475187d bellard
                            else {
1999 3475187d bellard
                                rs2 = GET_FIELD_SP(insn, 0, 4);
2000 3475187d bellard
                                gen_movl_reg_T1(rs2);
2001 3475187d bellard
                            }
2002 3475187d bellard
                            gen_movl_reg_T0(rd);
2003 3475187d bellard
                            flush_T2(dc);
2004 3475187d bellard
                            if (insn & (1 << 18)) {
2005 3475187d bellard
                                if (cc == 0)
2006 3475187d bellard
                                    gen_cond[0][cond]();
2007 3475187d bellard
                                else if (cc == 2)
2008 3475187d bellard
                                    gen_cond[1][cond]();
2009 3475187d bellard
                                else
2010 3475187d bellard
                                    goto illegal_insn;
2011 3475187d bellard
                            } else {
2012 3475187d bellard
                                gen_fcond[cc][cond]();
2013 3475187d bellard
                            }
2014 3475187d bellard
                            gen_op_mov_cc();
2015 3475187d bellard
                            gen_movl_T0_reg(rd);
2016 3475187d bellard
                            break;
2017 3475187d bellard
                        }
2018 af7bf89b bellard
                    case 0x2d: /* V9 sdivx */
2019 3475187d bellard
                        gen_op_sdivx_T1_T0();
2020 3475187d bellard
                        gen_movl_T0_reg(rd);
2021 3475187d bellard
                        break;
2022 af7bf89b bellard
                    case 0x2e: /* V9 popc */
2023 3475187d bellard
                        {
2024 3475187d bellard
                            if (IS_IMM) {        /* immediate */
2025 3475187d bellard
                                rs2 = GET_FIELD_SPs(insn, 0, 12);
2026 3475187d bellard
                                gen_movl_simm_T1(rs2);
2027 3475187d bellard
                                // XXX optimize: popc(constant)
2028 3475187d bellard
                            }
2029 3475187d bellard
                            else {
2030 3475187d bellard
                                rs2 = GET_FIELD_SP(insn, 0, 4);
2031 3475187d bellard
                                gen_movl_reg_T1(rs2);
2032 3475187d bellard
                            }
2033 3475187d bellard
                            gen_op_popc();
2034 3475187d bellard
                            gen_movl_T0_reg(rd);
2035 3475187d bellard
                        }
2036 af7bf89b bellard
                    case 0x2f: /* V9 movr */
2037 3475187d bellard
                        {
2038 3475187d bellard
                            int cond = GET_FIELD_SP(insn, 10, 12);
2039 3475187d bellard
                            rs1 = GET_FIELD(insn, 13, 17);
2040 3475187d bellard
                            flush_T2(dc);
2041 3475187d bellard
                            gen_movl_reg_T0(rs1);
2042 3475187d bellard
                            gen_cond_reg(cond);
2043 3475187d bellard
                            if (IS_IMM) {        /* immediate */
2044 3475187d bellard
                                rs2 = GET_FIELD_SPs(insn, 0, 10);
2045 3475187d bellard
                                gen_movl_simm_T1(rs2);
2046 3475187d bellard
                            }
2047 3475187d bellard
                            else {
2048 3475187d bellard
                                rs2 = GET_FIELD_SP(insn, 0, 4);
2049 3475187d bellard
                                gen_movl_reg_T1(rs2);
2050 3475187d bellard
                            }
2051 3475187d bellard
                            gen_movl_reg_T0(rd);
2052 3475187d bellard
                            gen_op_mov_cc();
2053 3475187d bellard
                            gen_movl_T0_reg(rd);
2054 3475187d bellard
                            break;
2055 3475187d bellard
                        }
2056 3475187d bellard
                    case 0x36: /* UltraSparc shutdown, VIS */
2057 3475187d bellard
                        {
2058 3475187d bellard
                            // XXX
2059 3475187d bellard
                        }
2060 3475187d bellard
#endif
2061 3475187d bellard
                    default:
2062 e80cfcfc bellard
                        goto illegal_insn;
2063 e80cfcfc bellard
                    }
2064 e80cfcfc bellard
                }
2065 3475187d bellard
#ifdef TARGET_SPARC64
2066 3475187d bellard
            } else if (xop == 0x39) { /* V9 return */
2067 3475187d bellard
                rs1 = GET_FIELD(insn, 13, 17);
2068 3475187d bellard
                gen_movl_reg_T0(rs1);
2069 3475187d bellard
                if (IS_IMM) {        /* immediate */
2070 3475187d bellard
                    rs2 = GET_FIELDs(insn, 19, 31);
2071 3475187d bellard
#if defined(OPTIM)
2072 3475187d bellard
                    if (rs2) {
2073 3475187d bellard
#endif
2074 3475187d bellard
                        gen_movl_simm_T1(rs2);
2075 3475187d bellard
                        gen_op_add_T1_T0();
2076 3475187d bellard
#if defined(OPTIM)
2077 3475187d bellard
                    }
2078 3475187d bellard
#endif
2079 3475187d bellard
                } else {                /* register */
2080 3475187d bellard
                    rs2 = GET_FIELD(insn, 27, 31);
2081 3475187d bellard
#if defined(OPTIM)
2082 3475187d bellard
                    if (rs2) {
2083 3475187d bellard
#endif
2084 3475187d bellard
                        gen_movl_reg_T1(rs2);
2085 3475187d bellard
                        gen_op_add_T1_T0();
2086 3475187d bellard
#if defined(OPTIM)
2087 3475187d bellard
                    }
2088 3475187d bellard
#endif
2089 3475187d bellard
                }
2090 83469015 bellard
                gen_op_restore();
2091 3475187d bellard
                gen_mov_pc_npc(dc);
2092 3475187d bellard
                gen_op_movl_npc_T0();
2093 3475187d bellard
                dc->npc = DYNAMIC_PC;
2094 3475187d bellard
                goto jmp_insn;
2095 3475187d bellard
#endif
2096 e80cfcfc bellard
            } else {
2097 e80cfcfc bellard
                rs1 = GET_FIELD(insn, 13, 17);
2098 e80cfcfc bellard
                gen_movl_reg_T0(rs1);
2099 e80cfcfc bellard
                if (IS_IMM) {        /* immediate */
2100 e80cfcfc bellard
                    rs2 = GET_FIELDs(insn, 19, 31);
2101 e80cfcfc bellard
#if defined(OPTIM)
2102 e80cfcfc bellard
                    if (rs2) {
2103 e8af50a3 bellard
#endif
2104 3475187d bellard
                        gen_movl_simm_T1(rs2);
2105 e80cfcfc bellard
                        gen_op_add_T1_T0();
2106 e80cfcfc bellard
#if defined(OPTIM)
2107 e80cfcfc bellard
                    }
2108 e8af50a3 bellard
#endif
2109 e80cfcfc bellard
                } else {                /* register */
2110 e80cfcfc bellard
                    rs2 = GET_FIELD(insn, 27, 31);
2111 e80cfcfc bellard
#if defined(OPTIM)
2112 e80cfcfc bellard
                    if (rs2) {
2113 e80cfcfc bellard
#endif
2114 e80cfcfc bellard
                        gen_movl_reg_T1(rs2);
2115 e80cfcfc bellard
                        gen_op_add_T1_T0();
2116 e80cfcfc bellard
#if defined(OPTIM)
2117 e80cfcfc bellard
                    }
2118 e8af50a3 bellard
#endif
2119 cf495bcf bellard
                }
2120 e80cfcfc bellard
                switch (xop) {
2121 e80cfcfc bellard
                case 0x38:        /* jmpl */
2122 e80cfcfc bellard
                    {
2123 e80cfcfc bellard
                        if (rd != 0) {
2124 0bee699e bellard
                            gen_op_movl_T1_im(dc->pc);
2125 0bee699e bellard
                            gen_movl_T1_reg(rd);
2126 e80cfcfc bellard
                        }
2127 0bee699e bellard
                        gen_mov_pc_npc(dc);
2128 0bee699e bellard
                        gen_op_movl_npc_T0();
2129 e80cfcfc bellard
                        dc->npc = DYNAMIC_PC;
2130 e80cfcfc bellard
                    }
2131 e80cfcfc bellard
                    goto jmp_insn;
2132 3475187d bellard
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
2133 af7bf89b bellard
                case 0x39:        /* rett, V9 return */
2134 e80cfcfc bellard
                    {
2135 e80cfcfc bellard
                        if (!supervisor(dc))
2136 e80cfcfc bellard
                            goto priv_insn;
2137 0bee699e bellard
                        gen_mov_pc_npc(dc);
2138 e80cfcfc bellard
                        gen_op_movl_npc_T0();
2139 0bee699e bellard
                        dc->npc = DYNAMIC_PC;
2140 e80cfcfc bellard
                        gen_op_rett();
2141 e80cfcfc bellard
                    }
2142 0bee699e bellard
                    goto jmp_insn;
2143 e80cfcfc bellard
#endif
2144 e80cfcfc bellard
                case 0x3b: /* flush */
2145 e80cfcfc bellard
                    gen_op_flush_T0();
2146 e80cfcfc bellard
                    break;
2147 e80cfcfc bellard
                case 0x3c:        /* save */
2148 e80cfcfc bellard
                    save_state(dc);
2149 e80cfcfc bellard
                    gen_op_save();
2150 e80cfcfc bellard
                    gen_movl_T0_reg(rd);
2151 e80cfcfc bellard
                    break;
2152 e80cfcfc bellard
                case 0x3d:        /* restore */
2153 e80cfcfc bellard
                    save_state(dc);
2154 e80cfcfc bellard
                    gen_op_restore();
2155 e80cfcfc bellard
                    gen_movl_T0_reg(rd);
2156 e80cfcfc bellard
                    break;
2157 3475187d bellard
#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
2158 af7bf89b bellard
                case 0x3e:      /* V9 done/retry */
2159 3475187d bellard
                    {
2160 3475187d bellard
                        switch (rd) {
2161 3475187d bellard
                        case 0:
2162 3475187d bellard
                            if (!supervisor(dc))
2163 3475187d bellard
                                goto priv_insn;
2164 83469015 bellard
                            dc->npc = DYNAMIC_PC;
2165 83469015 bellard
                            dc->pc = DYNAMIC_PC;
2166 3475187d bellard
                            gen_op_done();
2167 83469015 bellard
                            goto jmp_insn;
2168 3475187d bellard
                        case 1:
2169 3475187d bellard
                            if (!supervisor(dc))
2170 3475187d bellard
                                goto priv_insn;
2171 83469015 bellard
                            dc->npc = DYNAMIC_PC;
2172 83469015 bellard
                            dc->pc = DYNAMIC_PC;
2173 3475187d bellard
                            gen_op_retry();
2174 83469015 bellard
                            goto jmp_insn;
2175 3475187d bellard
                        default:
2176 3475187d bellard
                            goto illegal_insn;
2177 3475187d bellard
                        }
2178 3475187d bellard
                    }
2179 3475187d bellard
                    break;
2180 3475187d bellard
#endif
2181 3475187d bellard
                default:
2182 e80cfcfc bellard
                    goto illegal_insn;
2183 e80cfcfc bellard
                }
2184 cf495bcf bellard
            }
2185 cf495bcf bellard
            break;
2186 cf495bcf bellard
        }
2187 af7bf89b bellard
        break;
2188 cf495bcf bellard
    case 3:                        /* load/store instructions */
2189 cf495bcf bellard
        {
2190 cf495bcf bellard
            unsigned int xop = GET_FIELD(insn, 7, 12);
2191 cf495bcf bellard
            rs1 = GET_FIELD(insn, 13, 17);
2192 cf495bcf bellard
            gen_movl_reg_T0(rs1);
2193 cf495bcf bellard
            if (IS_IMM) {        /* immediate */
2194 cf495bcf bellard
                rs2 = GET_FIELDs(insn, 19, 31);
2195 e80cfcfc bellard
#if defined(OPTIM)
2196 e8af50a3 bellard
                if (rs2 != 0) {
2197 e80cfcfc bellard
#endif
2198 3475187d bellard
                    gen_movl_simm_T1(rs2);
2199 e8af50a3 bellard
                    gen_op_add_T1_T0();
2200 e80cfcfc bellard
#if defined(OPTIM)
2201 e8af50a3 bellard
                }
2202 e80cfcfc bellard
#endif
2203 cf495bcf bellard
            } else {                /* register */
2204 cf495bcf bellard
                rs2 = GET_FIELD(insn, 27, 31);
2205 e80cfcfc bellard
#if defined(OPTIM)
2206 e80cfcfc bellard
                if (rs2 != 0) {
2207 e80cfcfc bellard
#endif
2208 e80cfcfc bellard
                    gen_movl_reg_T1(rs2);
2209 e80cfcfc bellard
                    gen_op_add_T1_T0();
2210 e80cfcfc bellard
#if defined(OPTIM)
2211 e80cfcfc bellard
                }
2212 e80cfcfc bellard
#endif
2213 cf495bcf bellard
            }
2214 3475187d bellard
            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) || \
2215 3475187d bellard
                    (xop > 0x17 && xop < 0x1d ) || \
2216 3475187d bellard
                    (xop > 0x2c && xop < 0x33) || xop == 0x1f) {
2217 cf495bcf bellard
                switch (xop) {
2218 cf495bcf bellard
                case 0x0:        /* load word */
2219 e8af50a3 bellard
                    gen_op_ldst(ld);
2220 cf495bcf bellard
                    break;
2221 cf495bcf bellard
                case 0x1:        /* load unsigned byte */
2222 e8af50a3 bellard
                    gen_op_ldst(ldub);
2223 cf495bcf bellard
                    break;
2224 cf495bcf bellard
                case 0x2:        /* load unsigned halfword */
2225 e8af50a3 bellard
                    gen_op_ldst(lduh);
2226 cf495bcf bellard
                    break;
2227 cf495bcf bellard
                case 0x3:        /* load double word */
2228 e8af50a3 bellard
                    gen_op_ldst(ldd);
2229 cf495bcf bellard
                    gen_movl_T0_reg(rd + 1);
2230 cf495bcf bellard
                    break;
2231 cf495bcf bellard
                case 0x9:        /* load signed byte */
2232 e8af50a3 bellard
                    gen_op_ldst(ldsb);
2233 cf495bcf bellard
                    break;
2234 cf495bcf bellard
                case 0xa:        /* load signed halfword */
2235 e8af50a3 bellard
                    gen_op_ldst(ldsh);
2236 cf495bcf bellard
                    break;
2237 cf495bcf bellard
                case 0xd:        /* ldstub -- XXX: should be atomically */
2238 e8af50a3 bellard
                    gen_op_ldst(ldstub);
2239 cf495bcf bellard
                    break;
2240 cf495bcf bellard
                case 0x0f:        /* swap register with memory. Also atomically */
2241 e80cfcfc bellard
                    gen_movl_reg_T1(rd);
2242 e8af50a3 bellard
                    gen_op_ldst(swap);
2243 e8af50a3 bellard
                    break;
2244 3475187d bellard
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
2245 e8af50a3 bellard
                case 0x10:        /* load word alternate */
2246 3475187d bellard
#ifndef TARGET_SPARC64
2247 e8af50a3 bellard
                    if (!supervisor(dc))
2248 e8af50a3 bellard
                        goto priv_insn;
2249 3475187d bellard
#endif
2250 e8af50a3 bellard
                    gen_op_lda(insn, 1, 4, 0);
2251 e8af50a3 bellard
                    break;
2252 e8af50a3 bellard
                case 0x11:        /* load unsigned byte alternate */
2253 3475187d bellard
#ifndef TARGET_SPARC64
2254 e8af50a3 bellard
                    if (!supervisor(dc))
2255 e8af50a3 bellard
                        goto priv_insn;
2256 3475187d bellard
#endif
2257 e8af50a3 bellard
                    gen_op_lduba(insn, 1, 1, 0);
2258 e8af50a3 bellard
                    break;
2259 e8af50a3 bellard
                case 0x12:        /* load unsigned halfword alternate */
2260 3475187d bellard
#ifndef TARGET_SPARC64
2261 e8af50a3 bellard
                    if (!supervisor(dc))
2262 e8af50a3 bellard
                        goto priv_insn;
2263 3475187d bellard
#endif
2264 e8af50a3 bellard
                    gen_op_lduha(insn, 1, 2, 0);
2265 e8af50a3 bellard
                    break;
2266 e8af50a3 bellard
                case 0x13:        /* load double word alternate */
2267 3475187d bellard
#ifndef TARGET_SPARC64
2268 e8af50a3 bellard
                    if (!supervisor(dc))
2269 e8af50a3 bellard
                        goto priv_insn;
2270 3475187d bellard
#endif
2271 e8af50a3 bellard
                    gen_op_ldda(insn, 1, 8, 0);
2272 e8af50a3 bellard
                    gen_movl_T0_reg(rd + 1);
2273 e8af50a3 bellard
                    break;
2274 e8af50a3 bellard
                case 0x19:        /* load signed byte alternate */
2275 3475187d bellard
#ifndef TARGET_SPARC64
2276 e8af50a3 bellard
                    if (!supervisor(dc))
2277 e8af50a3 bellard
                        goto priv_insn;
2278 3475187d bellard
#endif
2279 e8af50a3 bellard
                    gen_op_ldsba(insn, 1, 1, 1);
2280 e8af50a3 bellard
                    break;
2281 e8af50a3 bellard
                case 0x1a:        /* load signed halfword alternate */
2282 3475187d bellard
#ifndef TARGET_SPARC64
2283 e8af50a3 bellard
                    if (!supervisor(dc))
2284 e8af50a3 bellard
                        goto priv_insn;
2285 3475187d bellard
#endif
2286 e8af50a3 bellard
                    gen_op_ldsha(insn, 1, 2 ,1);
2287 e8af50a3 bellard
                    break;
2288 e8af50a3 bellard
                case 0x1d:        /* ldstuba -- XXX: should be atomically */
2289 3475187d bellard
#ifndef TARGET_SPARC64
2290 e8af50a3 bellard
                    if (!supervisor(dc))
2291 e8af50a3 bellard
                        goto priv_insn;
2292 3475187d bellard
#endif
2293 e8af50a3 bellard
                    gen_op_ldstuba(insn, 1, 1, 0);
2294 e8af50a3 bellard
                    break;
2295 e8af50a3 bellard
                case 0x1f:        /* swap reg with alt. memory. Also atomically */
2296 3475187d bellard
#ifndef TARGET_SPARC64
2297 e8af50a3 bellard
                    if (!supervisor(dc))
2298 e8af50a3 bellard
                        goto priv_insn;
2299 3475187d bellard
#endif
2300 e80cfcfc bellard
                    gen_movl_reg_T1(rd);
2301 e8af50a3 bellard
                    gen_op_swapa(insn, 1, 4, 0);
2302 cf495bcf bellard
                    break;
2303 3475187d bellard
2304 3475187d bellard
#ifndef TARGET_SPARC64
2305 0fa85d43 bellard
                    /* avoid warnings */
2306 0fa85d43 bellard
                    (void) &gen_op_stfa;
2307 0fa85d43 bellard
                    (void) &gen_op_stdfa;
2308 0fa85d43 bellard
                    (void) &gen_op_ldfa;
2309 0fa85d43 bellard
                    (void) &gen_op_lddfa;
2310 3475187d bellard
#else
2311 3475187d bellard
#if !defined(CONFIG_USER_ONLY)
2312 3475187d bellard
                    (void) &gen_op_cas;
2313 3475187d bellard
                    (void) &gen_op_casx;
2314 e80cfcfc bellard
#endif
2315 3475187d bellard
#endif
2316 3475187d bellard
#endif
2317 3475187d bellard
#ifdef TARGET_SPARC64
2318 af7bf89b bellard
                case 0x08: /* V9 ldsw */
2319 3475187d bellard
                    gen_op_ldst(ldsw);
2320 3475187d bellard
                    break;
2321 af7bf89b bellard
                case 0x0b: /* V9 ldx */
2322 3475187d bellard
                    gen_op_ldst(ldx);
2323 3475187d bellard
                    break;
2324 af7bf89b bellard
                case 0x18: /* V9 ldswa */
2325 3475187d bellard
                    gen_op_ldswa(insn, 1, 4, 1);
2326 3475187d bellard
                    break;
2327 af7bf89b bellard
                case 0x1b: /* V9 ldxa */
2328 3475187d bellard
                    gen_op_ldxa(insn, 1, 8, 0);
2329 3475187d bellard
                    break;
2330 3475187d bellard
                case 0x2d: /* V9 prefetch, no effect */
2331 3475187d bellard
                    goto skip_move;
2332 af7bf89b bellard
                case 0x30: /* V9 ldfa */
2333 3475187d bellard
                    gen_op_ldfa(insn, 1, 8, 0); // XXX
2334 3475187d bellard
                    break;
2335 af7bf89b bellard
                case 0x33: /* V9 lddfa */
2336 3475187d bellard
                    gen_op_lddfa(insn, 1, 8, 0); // XXX
2337 af7bf89b bellard
2338 3475187d bellard
                    break;
2339 3475187d bellard
                case 0x3d: /* V9 prefetcha, no effect */
2340 3475187d bellard
                    goto skip_move;
2341 af7bf89b bellard
                case 0x32: /* V9 ldqfa */
2342 3475187d bellard
                    goto nfpu_insn;
2343 3475187d bellard
#endif
2344 3475187d bellard
                default:
2345 e80cfcfc bellard
                    goto illegal_insn;
2346 7a3f1944 bellard
                }
2347 cf495bcf bellard
                gen_movl_T1_reg(rd);
2348 3475187d bellard
#ifdef TARGET_SPARC64
2349 3475187d bellard
            skip_move: ;
2350 3475187d bellard
#endif
2351 e8af50a3 bellard
            } else if (xop >= 0x20 && xop < 0x24) {
2352 3475187d bellard
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
2353 55e4f664 bellard
                save_state(dc);
2354 e80cfcfc bellard
                gen_op_trap_ifnofpu();
2355 e80cfcfc bellard
#endif
2356 e8af50a3 bellard
                switch (xop) {
2357 e8af50a3 bellard
                case 0x20:        /* load fpreg */
2358 e8af50a3 bellard
                    gen_op_ldst(ldf);
2359 e8af50a3 bellard
                    gen_op_store_FT0_fpr(rd);
2360 e8af50a3 bellard
                    break;
2361 e8af50a3 bellard
                case 0x21:        /* load fsr */
2362 9e61bde5 bellard
                    gen_op_ldst(ldf);
2363 e8af50a3 bellard
                    gen_op_ldfsr();
2364 e8af50a3 bellard
                    break;
2365 af7bf89b bellard
                case 0x22:      /* load quad fpreg */
2366 af7bf89b bellard
                    goto nfpu_insn;
2367 e8af50a3 bellard
                case 0x23:        /* load double fpreg */
2368 e8af50a3 bellard
                    gen_op_ldst(lddf);
2369 3475187d bellard
                    gen_op_store_DT0_fpr(DFPREG(rd));
2370 e8af50a3 bellard
                    break;
2371 e80cfcfc bellard
                default:
2372 e80cfcfc bellard
                    goto illegal_insn;
2373 e8af50a3 bellard
                }
2374 3475187d bellard
            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) || \
2375 3475187d bellard
                       xop == 0xe || xop == 0x1e) {
2376 cf495bcf bellard
                gen_movl_reg_T1(rd);
2377 cf495bcf bellard
                switch (xop) {
2378 cf495bcf bellard
                case 0x4:
2379 e8af50a3 bellard
                    gen_op_ldst(st);
2380 cf495bcf bellard
                    break;
2381 cf495bcf bellard
                case 0x5:
2382 e8af50a3 bellard
                    gen_op_ldst(stb);
2383 cf495bcf bellard
                    break;
2384 cf495bcf bellard
                case 0x6:
2385 e8af50a3 bellard
                    gen_op_ldst(sth);
2386 cf495bcf bellard
                    break;
2387 cf495bcf bellard
                case 0x7:
2388 72cbca10 bellard
                    flush_T2(dc);
2389 cf495bcf bellard
                    gen_movl_reg_T2(rd + 1);
2390 e8af50a3 bellard
                    gen_op_ldst(std);
2391 e8af50a3 bellard
                    break;
2392 3475187d bellard
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
2393 e8af50a3 bellard
                case 0x14:
2394 3475187d bellard
#ifndef TARGET_SPARC64
2395 e8af50a3 bellard
                    if (!supervisor(dc))
2396 e8af50a3 bellard
                        goto priv_insn;
2397 3475187d bellard
#endif
2398 e8af50a3 bellard
                    gen_op_sta(insn, 0, 4, 0);
2399 d39c0b99 bellard
                    break;
2400 e8af50a3 bellard
                case 0x15:
2401 3475187d bellard
#ifndef TARGET_SPARC64
2402 e8af50a3 bellard
                    if (!supervisor(dc))
2403 e8af50a3 bellard
                        goto priv_insn;
2404 3475187d bellard
#endif
2405 e8af50a3 bellard
                    gen_op_stba(insn, 0, 1, 0);
2406 d39c0b99 bellard
                    break;
2407 e8af50a3 bellard
                case 0x16:
2408 3475187d bellard
#ifndef TARGET_SPARC64
2409 e8af50a3 bellard
                    if (!supervisor(dc))
2410 e8af50a3 bellard
                        goto priv_insn;
2411 3475187d bellard
#endif
2412 e8af50a3 bellard
                    gen_op_stha(insn, 0, 2, 0);
2413 d39c0b99 bellard
                    break;
2414 e8af50a3 bellard
                case 0x17:
2415 3475187d bellard
#ifndef TARGET_SPARC64
2416 e8af50a3 bellard
                    if (!supervisor(dc))
2417 e8af50a3 bellard
                        goto priv_insn;
2418 3475187d bellard
#endif
2419 e8af50a3 bellard
                    flush_T2(dc);
2420 e8af50a3 bellard
                    gen_movl_reg_T2(rd + 1);
2421 e8af50a3 bellard
                    gen_op_stda(insn, 0, 8, 0);
2422 d39c0b99 bellard
                    break;
2423 e80cfcfc bellard
#endif
2424 3475187d bellard
#ifdef TARGET_SPARC64
2425 af7bf89b bellard
                case 0x0e: /* V9 stx */
2426 3475187d bellard
                    gen_op_ldst(stx);
2427 3475187d bellard
                    break;
2428 af7bf89b bellard
                case 0x1e: /* V9 stxa */
2429 3475187d bellard
                    gen_op_stxa(insn, 0, 8, 0); // XXX
2430 3475187d bellard
                    break;
2431 3475187d bellard
#endif
2432 3475187d bellard
                default:
2433 e80cfcfc bellard
                    goto illegal_insn;
2434 7a3f1944 bellard
                }
2435 e8af50a3 bellard
            } else if (xop > 0x23 && xop < 0x28) {
2436 e80cfcfc bellard
#if !defined(CONFIG_USER_ONLY)
2437 e80cfcfc bellard
                gen_op_trap_ifnofpu();
2438 e80cfcfc bellard
#endif
2439 e8af50a3 bellard
                switch (xop) {
2440 e8af50a3 bellard
                case 0x24:
2441 e8af50a3 bellard
                    gen_op_load_fpr_FT0(rd);
2442 e8af50a3 bellard
                    gen_op_ldst(stf);
2443 e8af50a3 bellard
                    break;
2444 af7bf89b bellard
                case 0x25: /* stfsr, V9 stxfsr */
2445 e8af50a3 bellard
                    gen_op_stfsr();
2446 9e61bde5 bellard
                    gen_op_ldst(stf);
2447 e8af50a3 bellard
                    break;
2448 af7bf89b bellard
                case 0x26: /* stdfq */
2449 af7bf89b bellard
                    goto nfpu_insn;
2450 e8af50a3 bellard
                case 0x27:
2451 3475187d bellard
                    gen_op_load_fpr_DT0(DFPREG(rd));
2452 e8af50a3 bellard
                    gen_op_ldst(stdf);
2453 e8af50a3 bellard
                    break;
2454 e80cfcfc bellard
                default:
2455 3475187d bellard
                    goto illegal_insn;
2456 3475187d bellard
                }
2457 3475187d bellard
            } else if (xop > 0x33 && xop < 0x3f) {
2458 3475187d bellard
#ifdef TARGET_SPARC64
2459 3475187d bellard
                switch (xop) {
2460 af7bf89b bellard
                case 0x34: /* V9 stfa */
2461 3475187d bellard
                    gen_op_stfa(insn, 0, 0, 0); // XXX
2462 3475187d bellard
                    break;
2463 af7bf89b bellard
                case 0x37: /* V9 stdfa */
2464 3475187d bellard
                    gen_op_stdfa(insn, 0, 0, 0); // XXX
2465 3475187d bellard
                    break;
2466 af7bf89b bellard
                case 0x3c: /* V9 casa */
2467 3475187d bellard
                    gen_op_casa(insn, 0, 4, 0); // XXX
2468 3475187d bellard
                    break;
2469 af7bf89b bellard
                case 0x3e: /* V9 casxa */
2470 3475187d bellard
                    gen_op_casxa(insn, 0, 8, 0); // XXX
2471 3475187d bellard
                    break;
2472 af7bf89b bellard
                case 0x36: /* V9 stqfa */
2473 3475187d bellard
                    goto nfpu_insn;
2474 3475187d bellard
                default:
2475 e80cfcfc bellard
                    goto illegal_insn;
2476 e8af50a3 bellard
                }
2477 3475187d bellard
#else
2478 e80cfcfc bellard
                goto illegal_insn;
2479 3475187d bellard
#endif
2480 e8af50a3 bellard
            }
2481 e80cfcfc bellard
            else
2482 e80cfcfc bellard
                goto illegal_insn;
2483 7a3f1944 bellard
        }
2484 af7bf89b bellard
        break;
2485 cf495bcf bellard
    }
2486 cf495bcf bellard
    /* default case for non jump instructions */
2487 72cbca10 bellard
    if (dc->npc == DYNAMIC_PC) {
2488 72cbca10 bellard
        dc->pc = DYNAMIC_PC;
2489 72cbca10 bellard
        gen_op_next_insn();
2490 72cbca10 bellard
    } else if (dc->npc == JUMP_PC) {
2491 72cbca10 bellard
        /* we can do a static jump */
2492 83469015 bellard
        gen_branch2(dc, (long)dc->tb, dc->jump_pc[0], dc->jump_pc[1]);
2493 72cbca10 bellard
        dc->is_br = 1;
2494 72cbca10 bellard
    } else {
2495 cf495bcf bellard
        dc->pc = dc->npc;
2496 cf495bcf bellard
        dc->npc = dc->npc + 4;
2497 cf495bcf bellard
    }
2498 e80cfcfc bellard
 jmp_insn:
2499 cf495bcf bellard
    return;
2500 cf495bcf bellard
 illegal_insn:
2501 72cbca10 bellard
    save_state(dc);
2502 cf495bcf bellard
    gen_op_exception(TT_ILL_INSN);
2503 cf495bcf bellard
    dc->is_br = 1;
2504 e8af50a3 bellard
    return;
2505 e80cfcfc bellard
#if !defined(CONFIG_USER_ONLY)
2506 e8af50a3 bellard
 priv_insn:
2507 e8af50a3 bellard
    save_state(dc);
2508 e8af50a3 bellard
    gen_op_exception(TT_PRIV_INSN);
2509 e8af50a3 bellard
    dc->is_br = 1;
2510 e80cfcfc bellard
    return;
2511 e80cfcfc bellard
#endif
2512 e80cfcfc bellard
 nfpu_insn:
2513 e80cfcfc bellard
    save_state(dc);
2514 e80cfcfc bellard
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
2515 e80cfcfc bellard
    dc->is_br = 1;
2516 7a3f1944 bellard
}
2517 7a3f1944 bellard
2518 cf495bcf bellard
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
2519 e8af50a3 bellard
                                                 int spc, CPUSPARCState *env)
2520 7a3f1944 bellard
{
2521 72cbca10 bellard
    target_ulong pc_start, last_pc;
2522 cf495bcf bellard
    uint16_t *gen_opc_end;
2523 cf495bcf bellard
    DisasContext dc1, *dc = &dc1;
2524 e8af50a3 bellard
    int j, lj = -1;
2525 cf495bcf bellard
2526 cf495bcf bellard
    memset(dc, 0, sizeof(DisasContext));
2527 cf495bcf bellard
    dc->tb = tb;
2528 72cbca10 bellard
    pc_start = tb->pc;
2529 cf495bcf bellard
    dc->pc = pc_start;
2530 e80cfcfc bellard
    last_pc = dc->pc;
2531 72cbca10 bellard
    dc->npc = (target_ulong) tb->cs_base;
2532 e8af50a3 bellard
#if defined(CONFIG_USER_ONLY)
2533 e8af50a3 bellard
    dc->mem_idx = 0;
2534 e8af50a3 bellard
#else
2535 e8af50a3 bellard
    dc->mem_idx = ((env->psrs) != 0);
2536 e8af50a3 bellard
#endif
2537 cf495bcf bellard
    gen_opc_ptr = gen_opc_buf;
2538 cf495bcf bellard
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
2539 cf495bcf bellard
    gen_opparam_ptr = gen_opparam_buf;
2540 83469015 bellard
    nb_gen_labels = 0;
2541 cf495bcf bellard
2542 cf495bcf bellard
    do {
2543 e8af50a3 bellard
        if (env->nb_breakpoints > 0) {
2544 e8af50a3 bellard
            for(j = 0; j < env->nb_breakpoints; j++) {
2545 e8af50a3 bellard
                if (env->breakpoints[j] == dc->pc) {
2546 e80cfcfc bellard
                    if (dc->pc != pc_start)
2547 e80cfcfc bellard
                        save_state(dc);
2548 e80cfcfc bellard
                    gen_op_debug();
2549 e80cfcfc bellard
                    gen_op_movl_T0_0();
2550 e80cfcfc bellard
                    gen_op_exit_tb();
2551 e80cfcfc bellard
                    dc->is_br = 1;
2552 e80cfcfc bellard
                    goto exit_gen_loop;
2553 e8af50a3 bellard
                }
2554 e8af50a3 bellard
            }
2555 e8af50a3 bellard
        }
2556 e8af50a3 bellard
        if (spc) {
2557 e8af50a3 bellard
            if (loglevel > 0)
2558 e8af50a3 bellard
                fprintf(logfile, "Search PC...\n");
2559 e8af50a3 bellard
            j = gen_opc_ptr - gen_opc_buf;
2560 e8af50a3 bellard
            if (lj < j) {
2561 e8af50a3 bellard
                lj++;
2562 e8af50a3 bellard
                while (lj < j)
2563 e8af50a3 bellard
                    gen_opc_instr_start[lj++] = 0;
2564 e8af50a3 bellard
                gen_opc_pc[lj] = dc->pc;
2565 e8af50a3 bellard
                gen_opc_npc[lj] = dc->npc;
2566 e8af50a3 bellard
                gen_opc_instr_start[lj] = 1;
2567 e8af50a3 bellard
            }
2568 e8af50a3 bellard
        }
2569 cf495bcf bellard
        last_pc = dc->pc;
2570 cf495bcf bellard
        disas_sparc_insn(dc);
2571 3475187d bellard
2572 cf495bcf bellard
        if (dc->is_br)
2573 cf495bcf bellard
            break;
2574 cf495bcf bellard
        /* if the next PC is different, we abort now */
2575 cf495bcf bellard
        if (dc->pc != (last_pc + 4))
2576 cf495bcf bellard
            break;
2577 d39c0b99 bellard
        /* if we reach a page boundary, we stop generation so that the
2578 d39c0b99 bellard
           PC of a TT_TFAULT exception is always in the right page */
2579 d39c0b99 bellard
        if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
2580 d39c0b99 bellard
            break;
2581 e80cfcfc bellard
        /* if single step mode, we generate only one instruction and
2582 e80cfcfc bellard
           generate an exception */
2583 e80cfcfc bellard
        if (env->singlestep_enabled) {
2584 3475187d bellard
            gen_jmp_im(dc->pc);
2585 e80cfcfc bellard
            gen_op_movl_T0_0();
2586 e80cfcfc bellard
            gen_op_exit_tb();
2587 e80cfcfc bellard
            break;
2588 e80cfcfc bellard
        }
2589 cf495bcf bellard
    } while ((gen_opc_ptr < gen_opc_end) &&
2590 cf495bcf bellard
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
2591 e80cfcfc bellard
2592 e80cfcfc bellard
 exit_gen_loop:
2593 72cbca10 bellard
    if (!dc->is_br) {
2594 72cbca10 bellard
        if (dc->pc != DYNAMIC_PC && 
2595 72cbca10 bellard
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
2596 72cbca10 bellard
            /* static PC and NPC: we can use direct chaining */
2597 83469015 bellard
            gen_branch(dc, (long)tb, dc->pc, dc->npc);
2598 72cbca10 bellard
        } else {
2599 72cbca10 bellard
            if (dc->pc != DYNAMIC_PC)
2600 3475187d bellard
                gen_jmp_im(dc->pc);
2601 72cbca10 bellard
            save_npc(dc);
2602 72cbca10 bellard
            gen_op_movl_T0_0();
2603 72cbca10 bellard
            gen_op_exit_tb();
2604 72cbca10 bellard
        }
2605 72cbca10 bellard
    }
2606 cf495bcf bellard
    *gen_opc_ptr = INDEX_op_end;
2607 e8af50a3 bellard
    if (spc) {
2608 e8af50a3 bellard
        j = gen_opc_ptr - gen_opc_buf;
2609 e8af50a3 bellard
        lj++;
2610 e8af50a3 bellard
        while (lj <= j)
2611 e8af50a3 bellard
            gen_opc_instr_start[lj++] = 0;
2612 e8af50a3 bellard
        tb->size = 0;
2613 e8af50a3 bellard
#if 0
2614 e8af50a3 bellard
        if (loglevel > 0) {
2615 e8af50a3 bellard
            page_dump(logfile);
2616 e8af50a3 bellard
        }
2617 e8af50a3 bellard
#endif
2618 c3278b7b bellard
        gen_opc_jump_pc[0] = dc->jump_pc[0];
2619 c3278b7b bellard
        gen_opc_jump_pc[1] = dc->jump_pc[1];
2620 e8af50a3 bellard
    } else {
2621 e80cfcfc bellard
        tb->size = last_pc + 4 - pc_start;
2622 e8af50a3 bellard
    }
2623 7a3f1944 bellard
#ifdef DEBUG_DISAS
2624 e19e89a5 bellard
    if (loglevel & CPU_LOG_TB_IN_ASM) {
2625 cf495bcf bellard
        fprintf(logfile, "--------------\n");
2626 0fa85d43 bellard
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
2627 0fa85d43 bellard
        target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
2628 cf495bcf bellard
        fprintf(logfile, "\n");
2629 e19e89a5 bellard
        if (loglevel & CPU_LOG_TB_OP) {
2630 e19e89a5 bellard
            fprintf(logfile, "OP:\n");
2631 e19e89a5 bellard
            dump_ops(gen_opc_buf, gen_opparam_buf);
2632 e19e89a5 bellard
            fprintf(logfile, "\n");
2633 e19e89a5 bellard
        }
2634 cf495bcf bellard
    }
2635 7a3f1944 bellard
#endif
2636 cf495bcf bellard
    return 0;
2637 7a3f1944 bellard
}
2638 7a3f1944 bellard
2639 cf495bcf bellard
int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
2640 7a3f1944 bellard
{
2641 e8af50a3 bellard
    return gen_intermediate_code_internal(tb, 0, env);
2642 7a3f1944 bellard
}
2643 7a3f1944 bellard
2644 cf495bcf bellard
int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
2645 7a3f1944 bellard
{
2646 e8af50a3 bellard
    return gen_intermediate_code_internal(tb, 1, env);
2647 7a3f1944 bellard
}
2648 7a3f1944 bellard
2649 e80cfcfc bellard
extern int ram_size;
2650 cf495bcf bellard
2651 e80cfcfc bellard
void cpu_reset(CPUSPARCState *env)
2652 e80cfcfc bellard
{
2653 cf495bcf bellard
    memset(env, 0, sizeof(*env));
2654 bb05683b bellard
    tlb_flush(env, 1);
2655 cf495bcf bellard
    env->cwp = 0;
2656 cf495bcf bellard
    env->wim = 1;
2657 cf495bcf bellard
    env->regwptr = env->regbase + (env->cwp * 16);
2658 e8af50a3 bellard
#if defined(CONFIG_USER_ONLY)
2659 cf495bcf bellard
    env->user_mode_only = 1;
2660 e8af50a3 bellard
#else
2661 e8af50a3 bellard
    env->psrs = 1;
2662 0bee699e bellard
    env->psrps = 1;
2663 e80cfcfc bellard
    env->gregs[1] = ram_size;
2664 3475187d bellard
#ifdef TARGET_SPARC64
2665 83469015 bellard
    env->pstate = PS_PRIV;
2666 3475187d bellard
    env->version = GET_VER(env);
2667 83469015 bellard
    env->pc = 0x1fff0000000ULL;
2668 3475187d bellard
#else
2669 3475187d bellard
    env->mmuregs[0] = (0x04 << 24); /* Impl 0, ver 4, MMU disabled */
2670 83469015 bellard
    env->pc = 0xffd00000;
2671 3475187d bellard
#endif
2672 83469015 bellard
    env->npc = env->pc + 4;
2673 e8af50a3 bellard
#endif
2674 e80cfcfc bellard
}
2675 e80cfcfc bellard
2676 e80cfcfc bellard
CPUSPARCState *cpu_sparc_init(void)
2677 e80cfcfc bellard
{
2678 e80cfcfc bellard
    CPUSPARCState *env;
2679 e80cfcfc bellard
2680 c68ea704 bellard
    env = qemu_mallocz(sizeof(CPUSPARCState));
2681 c68ea704 bellard
    if (!env)
2682 c68ea704 bellard
        return NULL;
2683 c68ea704 bellard
    cpu_exec_init(env);
2684 e80cfcfc bellard
    cpu_reset(env);
2685 cf495bcf bellard
    return (env);
2686 7a3f1944 bellard
}
2687 7a3f1944 bellard
2688 7a3f1944 bellard
#define GET_FLAG(a,b) ((env->psr & a)?b:'-')
2689 7a3f1944 bellard
2690 7fe48483 bellard
void cpu_dump_state(CPUState *env, FILE *f, 
2691 7fe48483 bellard
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
2692 7fe48483 bellard
                    int flags)
2693 7a3f1944 bellard
{
2694 cf495bcf bellard
    int i, x;
2695 cf495bcf bellard
2696 af7bf89b bellard
    cpu_fprintf(f, "pc: " TARGET_FMT_lx "  npc: " TARGET_FMT_lx "\n", env->pc, env->npc);
2697 7fe48483 bellard
    cpu_fprintf(f, "General Registers:\n");
2698 cf495bcf bellard
    for (i = 0; i < 4; i++)
2699 af7bf89b bellard
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
2700 7fe48483 bellard
    cpu_fprintf(f, "\n");
2701 cf495bcf bellard
    for (; i < 8; i++)
2702 af7bf89b bellard
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
2703 7fe48483 bellard
    cpu_fprintf(f, "\nCurrent Register Window:\n");
2704 cf495bcf bellard
    for (x = 0; x < 3; x++) {
2705 cf495bcf bellard
        for (i = 0; i < 4; i++)
2706 af7bf89b bellard
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
2707 cf495bcf bellard
                    (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
2708 cf495bcf bellard
                    env->regwptr[i + x * 8]);
2709 7fe48483 bellard
        cpu_fprintf(f, "\n");
2710 cf495bcf bellard
        for (; i < 8; i++)
2711 af7bf89b bellard
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
2712 cf495bcf bellard
                    (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
2713 cf495bcf bellard
                    env->regwptr[i + x * 8]);
2714 7fe48483 bellard
        cpu_fprintf(f, "\n");
2715 cf495bcf bellard
    }
2716 7fe48483 bellard
    cpu_fprintf(f, "\nFloating Point Registers:\n");
2717 e8af50a3 bellard
    for (i = 0; i < 32; i++) {
2718 e8af50a3 bellard
        if ((i & 3) == 0)
2719 7fe48483 bellard
            cpu_fprintf(f, "%%f%02d:", i);
2720 7fe48483 bellard
        cpu_fprintf(f, " %016lf", env->fpr[i]);
2721 e8af50a3 bellard
        if ((i & 3) == 3)
2722 7fe48483 bellard
            cpu_fprintf(f, "\n");
2723 e8af50a3 bellard
    }
2724 7fe48483 bellard
    cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n", GET_PSR(env),
2725 cf495bcf bellard
            GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
2726 cf495bcf bellard
            GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
2727 e8af50a3 bellard
            env->psrs?'S':'-', env->psrps?'P':'-', 
2728 e8af50a3 bellard
            env->psret?'E':'-', env->wim);
2729 3475187d bellard
    cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env));
2730 7a3f1944 bellard
}
2731 edfcbd99 bellard
2732 e80cfcfc bellard
#if defined(CONFIG_USER_ONLY)
2733 d785e6be bellard
target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
2734 edfcbd99 bellard
{
2735 edfcbd99 bellard
    return addr;
2736 edfcbd99 bellard
}
2737 658138bc bellard
2738 e80cfcfc bellard
#else
2739 af7bf89b bellard
extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
2740 af7bf89b bellard
                                 int *access_index, target_ulong address, int rw,
2741 0fa85d43 bellard
                                 int is_user);
2742 0fa85d43 bellard
2743 d785e6be bellard
target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
2744 e80cfcfc bellard
{
2745 af7bf89b bellard
    target_phys_addr_t phys_addr;
2746 e80cfcfc bellard
    int prot, access_index;
2747 e80cfcfc bellard
2748 e80cfcfc bellard
    if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2, 0) != 0)
2749 e80cfcfc bellard
        return -1;
2750 e80cfcfc bellard
    return phys_addr;
2751 e80cfcfc bellard
}
2752 e80cfcfc bellard
#endif
2753 e80cfcfc bellard
2754 658138bc bellard
void helper_flush(target_ulong addr)
2755 658138bc bellard
{
2756 658138bc bellard
    addr &= ~7;
2757 658138bc bellard
    tb_invalidate_page_range(addr, addr + 8);
2758 658138bc bellard
}