Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ 9143e598

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