Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ 24741ef3

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