Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ ed96ca35

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