Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ 157777ef

History | View | Annotate | Download (44.8 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 bd497938 bellard
   Copyright (C) 2003 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 bd497938 bellard
   NPC/PC static optimisations (use JUMP_TB when possible)
26 7a3f1944 bellard
   FPU-Instructions
27 7a3f1944 bellard
   Privileged instructions
28 bd497938 bellard
   Coprocessor-Instructions
29 7a3f1944 bellard
   Optimize synthetic instructions
30 7a3f1944 bellard
   Optional alignment and privileged instruction check
31 bd497938 bellard
*/
32 7a3f1944 bellard
33 7a3f1944 bellard
#include <stdarg.h>
34 7a3f1944 bellard
#include <stdlib.h>
35 7a3f1944 bellard
#include <stdio.h>
36 7a3f1944 bellard
#include <string.h>
37 7a3f1944 bellard
#include <inttypes.h>
38 7a3f1944 bellard
39 7a3f1944 bellard
#include "cpu.h"
40 7a3f1944 bellard
#include "exec-all.h"
41 7a3f1944 bellard
#include "disas.h"
42 7a3f1944 bellard
43 7a3f1944 bellard
#define DEBUG_DISAS
44 7a3f1944 bellard
45 72cbca10 bellard
#define DYNAMIC_PC  1 /* dynamic pc value */
46 72cbca10 bellard
#define JUMP_PC     2 /* dynamic pc value which takes only two values
47 72cbca10 bellard
                         according to jump_pc[T2] */
48 72cbca10 bellard
49 7a3f1944 bellard
typedef struct DisasContext {
50 72cbca10 bellard
    target_ulong pc;        /* current Program Counter: integer or DYNAMIC_PC */
51 72cbca10 bellard
    target_ulong npc;        /* next PC: integer or DYNAMIC_PC or JUMP_PC */
52 72cbca10 bellard
    target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
53 cf495bcf bellard
    int is_br;
54 e8af50a3 bellard
    int mem_idx;
55 cf495bcf bellard
    struct TranslationBlock *tb;
56 7a3f1944 bellard
} DisasContext;
57 7a3f1944 bellard
58 7a3f1944 bellard
static uint16_t *gen_opc_ptr;
59 7a3f1944 bellard
static uint32_t *gen_opparam_ptr;
60 7a3f1944 bellard
extern FILE *logfile;
61 7a3f1944 bellard
extern int loglevel;
62 7a3f1944 bellard
63 7a3f1944 bellard
enum {
64 7a3f1944 bellard
#define DEF(s,n,copy_size) INDEX_op_ ## s,
65 7a3f1944 bellard
#include "opc.h"
66 7a3f1944 bellard
#undef DEF
67 cf495bcf bellard
    NB_OPS
68 7a3f1944 bellard
};
69 7a3f1944 bellard
70 7a3f1944 bellard
#include "gen-op.h"
71 7a3f1944 bellard
72 7a3f1944 bellard
#define GET_FIELD(X, FROM, TO) \
73 7a3f1944 bellard
  ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
74 7a3f1944 bellard
75 7a3f1944 bellard
#define IS_IMM (insn & (1<<13))
76 7a3f1944 bellard
77 cf495bcf bellard
static void disas_sparc_insn(DisasContext * dc);
78 7a3f1944 bellard
79 7a3f1944 bellard
static GenOpFunc *gen_op_movl_TN_reg[2][32] = {
80 cf495bcf bellard
    {
81 cf495bcf bellard
     gen_op_movl_g0_T0,
82 cf495bcf bellard
     gen_op_movl_g1_T0,
83 cf495bcf bellard
     gen_op_movl_g2_T0,
84 cf495bcf bellard
     gen_op_movl_g3_T0,
85 cf495bcf bellard
     gen_op_movl_g4_T0,
86 cf495bcf bellard
     gen_op_movl_g5_T0,
87 cf495bcf bellard
     gen_op_movl_g6_T0,
88 cf495bcf bellard
     gen_op_movl_g7_T0,
89 cf495bcf bellard
     gen_op_movl_o0_T0,
90 cf495bcf bellard
     gen_op_movl_o1_T0,
91 cf495bcf bellard
     gen_op_movl_o2_T0,
92 cf495bcf bellard
     gen_op_movl_o3_T0,
93 cf495bcf bellard
     gen_op_movl_o4_T0,
94 cf495bcf bellard
     gen_op_movl_o5_T0,
95 cf495bcf bellard
     gen_op_movl_o6_T0,
96 cf495bcf bellard
     gen_op_movl_o7_T0,
97 cf495bcf bellard
     gen_op_movl_l0_T0,
98 cf495bcf bellard
     gen_op_movl_l1_T0,
99 cf495bcf bellard
     gen_op_movl_l2_T0,
100 cf495bcf bellard
     gen_op_movl_l3_T0,
101 cf495bcf bellard
     gen_op_movl_l4_T0,
102 cf495bcf bellard
     gen_op_movl_l5_T0,
103 cf495bcf bellard
     gen_op_movl_l6_T0,
104 cf495bcf bellard
     gen_op_movl_l7_T0,
105 cf495bcf bellard
     gen_op_movl_i0_T0,
106 cf495bcf bellard
     gen_op_movl_i1_T0,
107 cf495bcf bellard
     gen_op_movl_i2_T0,
108 cf495bcf bellard
     gen_op_movl_i3_T0,
109 cf495bcf bellard
     gen_op_movl_i4_T0,
110 cf495bcf bellard
     gen_op_movl_i5_T0,
111 cf495bcf bellard
     gen_op_movl_i6_T0,
112 cf495bcf bellard
     gen_op_movl_i7_T0,
113 cf495bcf bellard
     },
114 cf495bcf bellard
    {
115 cf495bcf bellard
     gen_op_movl_g0_T1,
116 cf495bcf bellard
     gen_op_movl_g1_T1,
117 cf495bcf bellard
     gen_op_movl_g2_T1,
118 cf495bcf bellard
     gen_op_movl_g3_T1,
119 cf495bcf bellard
     gen_op_movl_g4_T1,
120 cf495bcf bellard
     gen_op_movl_g5_T1,
121 cf495bcf bellard
     gen_op_movl_g6_T1,
122 cf495bcf bellard
     gen_op_movl_g7_T1,
123 cf495bcf bellard
     gen_op_movl_o0_T1,
124 cf495bcf bellard
     gen_op_movl_o1_T1,
125 cf495bcf bellard
     gen_op_movl_o2_T1,
126 cf495bcf bellard
     gen_op_movl_o3_T1,
127 cf495bcf bellard
     gen_op_movl_o4_T1,
128 cf495bcf bellard
     gen_op_movl_o5_T1,
129 cf495bcf bellard
     gen_op_movl_o6_T1,
130 cf495bcf bellard
     gen_op_movl_o7_T1,
131 cf495bcf bellard
     gen_op_movl_l0_T1,
132 cf495bcf bellard
     gen_op_movl_l1_T1,
133 cf495bcf bellard
     gen_op_movl_l2_T1,
134 cf495bcf bellard
     gen_op_movl_l3_T1,
135 cf495bcf bellard
     gen_op_movl_l4_T1,
136 cf495bcf bellard
     gen_op_movl_l5_T1,
137 cf495bcf bellard
     gen_op_movl_l6_T1,
138 cf495bcf bellard
     gen_op_movl_l7_T1,
139 cf495bcf bellard
     gen_op_movl_i0_T1,
140 cf495bcf bellard
     gen_op_movl_i1_T1,
141 cf495bcf bellard
     gen_op_movl_i2_T1,
142 cf495bcf bellard
     gen_op_movl_i3_T1,
143 cf495bcf bellard
     gen_op_movl_i4_T1,
144 cf495bcf bellard
     gen_op_movl_i5_T1,
145 cf495bcf bellard
     gen_op_movl_i6_T1,
146 cf495bcf bellard
     gen_op_movl_i7_T1,
147 cf495bcf bellard
     }
148 7a3f1944 bellard
};
149 7a3f1944 bellard
150 7a3f1944 bellard
static GenOpFunc *gen_op_movl_reg_TN[3][32] = {
151 cf495bcf bellard
    {
152 cf495bcf bellard
     gen_op_movl_T0_g0,
153 cf495bcf bellard
     gen_op_movl_T0_g1,
154 cf495bcf bellard
     gen_op_movl_T0_g2,
155 cf495bcf bellard
     gen_op_movl_T0_g3,
156 cf495bcf bellard
     gen_op_movl_T0_g4,
157 cf495bcf bellard
     gen_op_movl_T0_g5,
158 cf495bcf bellard
     gen_op_movl_T0_g6,
159 cf495bcf bellard
     gen_op_movl_T0_g7,
160 cf495bcf bellard
     gen_op_movl_T0_o0,
161 cf495bcf bellard
     gen_op_movl_T0_o1,
162 cf495bcf bellard
     gen_op_movl_T0_o2,
163 cf495bcf bellard
     gen_op_movl_T0_o3,
164 cf495bcf bellard
     gen_op_movl_T0_o4,
165 cf495bcf bellard
     gen_op_movl_T0_o5,
166 cf495bcf bellard
     gen_op_movl_T0_o6,
167 cf495bcf bellard
     gen_op_movl_T0_o7,
168 cf495bcf bellard
     gen_op_movl_T0_l0,
169 cf495bcf bellard
     gen_op_movl_T0_l1,
170 cf495bcf bellard
     gen_op_movl_T0_l2,
171 cf495bcf bellard
     gen_op_movl_T0_l3,
172 cf495bcf bellard
     gen_op_movl_T0_l4,
173 cf495bcf bellard
     gen_op_movl_T0_l5,
174 cf495bcf bellard
     gen_op_movl_T0_l6,
175 cf495bcf bellard
     gen_op_movl_T0_l7,
176 cf495bcf bellard
     gen_op_movl_T0_i0,
177 cf495bcf bellard
     gen_op_movl_T0_i1,
178 cf495bcf bellard
     gen_op_movl_T0_i2,
179 cf495bcf bellard
     gen_op_movl_T0_i3,
180 cf495bcf bellard
     gen_op_movl_T0_i4,
181 cf495bcf bellard
     gen_op_movl_T0_i5,
182 cf495bcf bellard
     gen_op_movl_T0_i6,
183 cf495bcf bellard
     gen_op_movl_T0_i7,
184 cf495bcf bellard
     },
185 cf495bcf bellard
    {
186 cf495bcf bellard
     gen_op_movl_T1_g0,
187 cf495bcf bellard
     gen_op_movl_T1_g1,
188 cf495bcf bellard
     gen_op_movl_T1_g2,
189 cf495bcf bellard
     gen_op_movl_T1_g3,
190 cf495bcf bellard
     gen_op_movl_T1_g4,
191 cf495bcf bellard
     gen_op_movl_T1_g5,
192 cf495bcf bellard
     gen_op_movl_T1_g6,
193 cf495bcf bellard
     gen_op_movl_T1_g7,
194 cf495bcf bellard
     gen_op_movl_T1_o0,
195 cf495bcf bellard
     gen_op_movl_T1_o1,
196 cf495bcf bellard
     gen_op_movl_T1_o2,
197 cf495bcf bellard
     gen_op_movl_T1_o3,
198 cf495bcf bellard
     gen_op_movl_T1_o4,
199 cf495bcf bellard
     gen_op_movl_T1_o5,
200 cf495bcf bellard
     gen_op_movl_T1_o6,
201 cf495bcf bellard
     gen_op_movl_T1_o7,
202 cf495bcf bellard
     gen_op_movl_T1_l0,
203 cf495bcf bellard
     gen_op_movl_T1_l1,
204 cf495bcf bellard
     gen_op_movl_T1_l2,
205 cf495bcf bellard
     gen_op_movl_T1_l3,
206 cf495bcf bellard
     gen_op_movl_T1_l4,
207 cf495bcf bellard
     gen_op_movl_T1_l5,
208 cf495bcf bellard
     gen_op_movl_T1_l6,
209 cf495bcf bellard
     gen_op_movl_T1_l7,
210 cf495bcf bellard
     gen_op_movl_T1_i0,
211 cf495bcf bellard
     gen_op_movl_T1_i1,
212 cf495bcf bellard
     gen_op_movl_T1_i2,
213 cf495bcf bellard
     gen_op_movl_T1_i3,
214 cf495bcf bellard
     gen_op_movl_T1_i4,
215 cf495bcf bellard
     gen_op_movl_T1_i5,
216 cf495bcf bellard
     gen_op_movl_T1_i6,
217 cf495bcf bellard
     gen_op_movl_T1_i7,
218 cf495bcf bellard
     },
219 cf495bcf bellard
    {
220 cf495bcf bellard
     gen_op_movl_T2_g0,
221 cf495bcf bellard
     gen_op_movl_T2_g1,
222 cf495bcf bellard
     gen_op_movl_T2_g2,
223 cf495bcf bellard
     gen_op_movl_T2_g3,
224 cf495bcf bellard
     gen_op_movl_T2_g4,
225 cf495bcf bellard
     gen_op_movl_T2_g5,
226 cf495bcf bellard
     gen_op_movl_T2_g6,
227 cf495bcf bellard
     gen_op_movl_T2_g7,
228 cf495bcf bellard
     gen_op_movl_T2_o0,
229 cf495bcf bellard
     gen_op_movl_T2_o1,
230 cf495bcf bellard
     gen_op_movl_T2_o2,
231 cf495bcf bellard
     gen_op_movl_T2_o3,
232 cf495bcf bellard
     gen_op_movl_T2_o4,
233 cf495bcf bellard
     gen_op_movl_T2_o5,
234 cf495bcf bellard
     gen_op_movl_T2_o6,
235 cf495bcf bellard
     gen_op_movl_T2_o7,
236 cf495bcf bellard
     gen_op_movl_T2_l0,
237 cf495bcf bellard
     gen_op_movl_T2_l1,
238 cf495bcf bellard
     gen_op_movl_T2_l2,
239 cf495bcf bellard
     gen_op_movl_T2_l3,
240 cf495bcf bellard
     gen_op_movl_T2_l4,
241 cf495bcf bellard
     gen_op_movl_T2_l5,
242 cf495bcf bellard
     gen_op_movl_T2_l6,
243 cf495bcf bellard
     gen_op_movl_T2_l7,
244 cf495bcf bellard
     gen_op_movl_T2_i0,
245 cf495bcf bellard
     gen_op_movl_T2_i1,
246 cf495bcf bellard
     gen_op_movl_T2_i2,
247 cf495bcf bellard
     gen_op_movl_T2_i3,
248 cf495bcf bellard
     gen_op_movl_T2_i4,
249 cf495bcf bellard
     gen_op_movl_T2_i5,
250 cf495bcf bellard
     gen_op_movl_T2_i6,
251 cf495bcf bellard
     gen_op_movl_T2_i7,
252 cf495bcf bellard
     }
253 7a3f1944 bellard
};
254 7a3f1944 bellard
255 7a3f1944 bellard
static GenOpFunc1 *gen_op_movl_TN_im[3] = {
256 cf495bcf bellard
    gen_op_movl_T0_im,
257 cf495bcf bellard
    gen_op_movl_T1_im,
258 cf495bcf bellard
    gen_op_movl_T2_im
259 7a3f1944 bellard
};
260 7a3f1944 bellard
261 e8af50a3 bellard
#define GEN32(func, NAME) \
262 e8af50a3 bellard
static GenOpFunc *NAME ## _table [32] = {                                     \
263 e8af50a3 bellard
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
264 e8af50a3 bellard
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
265 e8af50a3 bellard
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
266 e8af50a3 bellard
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
267 e8af50a3 bellard
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
268 e8af50a3 bellard
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
269 e8af50a3 bellard
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
270 e8af50a3 bellard
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
271 e8af50a3 bellard
};                                                                            \
272 e8af50a3 bellard
static inline void func(int n)                                                \
273 e8af50a3 bellard
{                                                                             \
274 e8af50a3 bellard
    NAME ## _table[n]();                                                      \
275 e8af50a3 bellard
}
276 e8af50a3 bellard
277 e8af50a3 bellard
/* floating point registers moves */
278 e8af50a3 bellard
GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fprf);
279 e8af50a3 bellard
GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fprf);
280 e8af50a3 bellard
GEN32(gen_op_load_fpr_FT2, gen_op_load_fpr_FT2_fprf);
281 e8af50a3 bellard
GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fprf);
282 e8af50a3 bellard
GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fprf);
283 e8af50a3 bellard
GEN32(gen_op_store_FT2_fpr, gen_op_store_FT2_fpr_fprf);
284 e8af50a3 bellard
285 e8af50a3 bellard
GEN32(gen_op_load_fpr_DT0, gen_op_load_fpr_DT0_fprf);
286 e8af50a3 bellard
GEN32(gen_op_load_fpr_DT1, gen_op_load_fpr_DT1_fprf);
287 e8af50a3 bellard
GEN32(gen_op_load_fpr_DT2, gen_op_load_fpr_DT2_fprf);
288 e8af50a3 bellard
GEN32(gen_op_store_DT0_fpr, gen_op_store_DT0_fpr_fprf);
289 e8af50a3 bellard
GEN32(gen_op_store_DT1_fpr, gen_op_store_DT1_fpr_fprf);
290 e8af50a3 bellard
GEN32(gen_op_store_DT2_fpr, gen_op_store_DT2_fpr_fprf);
291 e8af50a3 bellard
292 e8af50a3 bellard
#if defined(CONFIG_USER_ONLY)
293 e8af50a3 bellard
#define gen_op_ldst(name)        gen_op_##name##_raw()
294 0fa85d43 bellard
#define OP_LD_TABLE(width)
295 e8af50a3 bellard
#define supervisor(dc) 0
296 e8af50a3 bellard
#else
297 e8af50a3 bellard
#define gen_op_ldst(name)        (*gen_op_##name[dc->mem_idx])()
298 e8af50a3 bellard
#define OP_LD_TABLE(width)                                                      \
299 e8af50a3 bellard
static GenOpFunc *gen_op_##width[] = {                                        \
300 e8af50a3 bellard
    &gen_op_##width##_user,                                                   \
301 e8af50a3 bellard
    &gen_op_##width##_kernel,                                                 \
302 e8af50a3 bellard
};                                                                            \
303 e8af50a3 bellard
                                                                              \
304 e8af50a3 bellard
static void gen_op_##width##a(int insn, int is_ld, int size, int sign)        \
305 e8af50a3 bellard
{                                                                             \
306 e8af50a3 bellard
    int asi;                                                                  \
307 e8af50a3 bellard
                                                                              \
308 e8af50a3 bellard
    asi = GET_FIELD(insn, 19, 26);                                            \
309 e8af50a3 bellard
    switch (asi) {                                                            \
310 e8af50a3 bellard
        case 10: /* User data access */                                       \
311 e8af50a3 bellard
            gen_op_##width##_user();                                          \
312 e8af50a3 bellard
            break;                                                            \
313 e8af50a3 bellard
        case 11: /* Supervisor data access */                                 \
314 e8af50a3 bellard
            gen_op_##width##_kernel();                                        \
315 e8af50a3 bellard
            break;                                                            \
316 e8af50a3 bellard
        case 0x20 ... 0x2f: /* MMU passthrough */                              \
317 e8af50a3 bellard
            if (is_ld)                                                        \
318 e8af50a3 bellard
                gen_op_ld_asi(asi, size, sign);                                      \
319 e8af50a3 bellard
            else                                                              \
320 e8af50a3 bellard
                gen_op_st_asi(asi, size, sign);                                      \
321 e8af50a3 bellard
            break;                                                            \
322 e8af50a3 bellard
        default:                                                              \
323 e8af50a3 bellard
            if (is_ld)                                                        \
324 e8af50a3 bellard
                gen_op_ld_asi(asi, size, sign);                                      \
325 e8af50a3 bellard
            else                                                              \
326 e8af50a3 bellard
                gen_op_st_asi(asi, size, sign);                                      \
327 e8af50a3 bellard
            break;                                                            \
328 e8af50a3 bellard
    }                                                                         \
329 e8af50a3 bellard
}
330 e8af50a3 bellard
331 e8af50a3 bellard
#define supervisor(dc) (dc->mem_idx == 1)
332 e8af50a3 bellard
#endif
333 e8af50a3 bellard
334 e8af50a3 bellard
OP_LD_TABLE(ld);
335 e8af50a3 bellard
OP_LD_TABLE(st);
336 e8af50a3 bellard
OP_LD_TABLE(ldub);
337 e8af50a3 bellard
OP_LD_TABLE(lduh);
338 e8af50a3 bellard
OP_LD_TABLE(ldsb);
339 e8af50a3 bellard
OP_LD_TABLE(ldsh);
340 e8af50a3 bellard
OP_LD_TABLE(stb);
341 e8af50a3 bellard
OP_LD_TABLE(sth);
342 e8af50a3 bellard
OP_LD_TABLE(std);
343 e8af50a3 bellard
OP_LD_TABLE(ldstub);
344 e8af50a3 bellard
OP_LD_TABLE(swap);
345 e8af50a3 bellard
OP_LD_TABLE(ldd);
346 e8af50a3 bellard
OP_LD_TABLE(stf);
347 e8af50a3 bellard
OP_LD_TABLE(stdf);
348 e8af50a3 bellard
OP_LD_TABLE(ldf);
349 e8af50a3 bellard
OP_LD_TABLE(lddf);
350 e8af50a3 bellard
351 cf495bcf bellard
static inline void gen_movl_imm_TN(int reg, int imm)
352 7a3f1944 bellard
{
353 cf495bcf bellard
    gen_op_movl_TN_im[reg] (imm);
354 7a3f1944 bellard
}
355 7a3f1944 bellard
356 cf495bcf bellard
static inline void gen_movl_imm_T1(int val)
357 7a3f1944 bellard
{
358 cf495bcf bellard
    gen_movl_imm_TN(1, val);
359 7a3f1944 bellard
}
360 7a3f1944 bellard
361 cf495bcf bellard
static inline void gen_movl_imm_T0(int val)
362 7a3f1944 bellard
{
363 cf495bcf bellard
    gen_movl_imm_TN(0, val);
364 7a3f1944 bellard
}
365 7a3f1944 bellard
366 cf495bcf bellard
static inline void gen_movl_reg_TN(int reg, int t)
367 7a3f1944 bellard
{
368 cf495bcf bellard
    if (reg)
369 cf495bcf bellard
        gen_op_movl_reg_TN[t][reg] ();
370 cf495bcf bellard
    else
371 cf495bcf bellard
        gen_movl_imm_TN(t, 0);
372 7a3f1944 bellard
}
373 7a3f1944 bellard
374 cf495bcf bellard
static inline void gen_movl_reg_T0(int reg)
375 7a3f1944 bellard
{
376 cf495bcf bellard
    gen_movl_reg_TN(reg, 0);
377 7a3f1944 bellard
}
378 7a3f1944 bellard
379 cf495bcf bellard
static inline void gen_movl_reg_T1(int reg)
380 7a3f1944 bellard
{
381 cf495bcf bellard
    gen_movl_reg_TN(reg, 1);
382 7a3f1944 bellard
}
383 7a3f1944 bellard
384 cf495bcf bellard
static inline void gen_movl_reg_T2(int reg)
385 7a3f1944 bellard
{
386 cf495bcf bellard
    gen_movl_reg_TN(reg, 2);
387 7a3f1944 bellard
}
388 7a3f1944 bellard
389 cf495bcf bellard
static inline void gen_movl_TN_reg(int reg, int t)
390 7a3f1944 bellard
{
391 cf495bcf bellard
    if (reg)
392 cf495bcf bellard
        gen_op_movl_TN_reg[t][reg] ();
393 7a3f1944 bellard
}
394 7a3f1944 bellard
395 cf495bcf bellard
static inline void gen_movl_T0_reg(int reg)
396 7a3f1944 bellard
{
397 cf495bcf bellard
    gen_movl_TN_reg(reg, 0);
398 7a3f1944 bellard
}
399 7a3f1944 bellard
400 cf495bcf bellard
static inline void gen_movl_T1_reg(int reg)
401 7a3f1944 bellard
{
402 cf495bcf bellard
    gen_movl_TN_reg(reg, 1);
403 7a3f1944 bellard
}
404 7a3f1944 bellard
405 72cbca10 bellard
/* call this function before using T2 as it may have been set for a jump */
406 72cbca10 bellard
static inline void flush_T2(DisasContext * dc)
407 72cbca10 bellard
{
408 72cbca10 bellard
    if (dc->npc == JUMP_PC) {
409 72cbca10 bellard
        gen_op_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
410 72cbca10 bellard
        dc->npc = DYNAMIC_PC;
411 72cbca10 bellard
    }
412 72cbca10 bellard
}
413 72cbca10 bellard
414 72cbca10 bellard
static inline void save_npc(DisasContext * dc)
415 72cbca10 bellard
{
416 72cbca10 bellard
    if (dc->npc == JUMP_PC) {
417 72cbca10 bellard
        gen_op_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
418 72cbca10 bellard
        dc->npc = DYNAMIC_PC;
419 72cbca10 bellard
    } else if (dc->npc != DYNAMIC_PC) {
420 72cbca10 bellard
        gen_op_movl_npc_im(dc->npc);
421 72cbca10 bellard
    }
422 72cbca10 bellard
}
423 72cbca10 bellard
424 72cbca10 bellard
static inline void save_state(DisasContext * dc)
425 72cbca10 bellard
{
426 af7bf89b bellard
    gen_op_jmp_im(dc->pc);
427 72cbca10 bellard
    save_npc(dc);
428 72cbca10 bellard
}
429 72cbca10 bellard
430 0bee699e bellard
static inline void gen_mov_pc_npc(DisasContext * dc)
431 0bee699e bellard
{
432 0bee699e bellard
    if (dc->npc == JUMP_PC) {
433 0bee699e bellard
        gen_op_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
434 0bee699e bellard
        gen_op_mov_pc_npc();
435 0bee699e bellard
        dc->pc = DYNAMIC_PC;
436 0bee699e bellard
    } else if (dc->npc == DYNAMIC_PC) {
437 0bee699e bellard
        gen_op_mov_pc_npc();
438 0bee699e bellard
        dc->pc = DYNAMIC_PC;
439 0bee699e bellard
    } else {
440 0bee699e bellard
        dc->pc = dc->npc;
441 0bee699e bellard
    }
442 0bee699e bellard
}
443 0bee699e bellard
444 cf495bcf bellard
static void gen_cond(int cond)
445 7a3f1944 bellard
{
446 7a3f1944 bellard
        switch (cond) {
447 cf495bcf bellard
        case 0x1:
448 cf495bcf bellard
            gen_op_eval_be();
449 cf495bcf bellard
            break;
450 cf495bcf bellard
        case 0x2:
451 cf495bcf bellard
            gen_op_eval_ble();
452 cf495bcf bellard
            break;
453 cf495bcf bellard
        case 0x3:
454 cf495bcf bellard
            gen_op_eval_bl();
455 cf495bcf bellard
            break;
456 cf495bcf bellard
        case 0x4:
457 cf495bcf bellard
            gen_op_eval_bleu();
458 cf495bcf bellard
            break;
459 cf495bcf bellard
        case 0x5:
460 cf495bcf bellard
            gen_op_eval_bcs();
461 cf495bcf bellard
            break;
462 cf495bcf bellard
        case 0x6:
463 cf495bcf bellard
            gen_op_eval_bneg();
464 cf495bcf bellard
            break;
465 cf495bcf bellard
        case 0x7:
466 cf495bcf bellard
            gen_op_eval_bvs();
467 cf495bcf bellard
            break;
468 cf495bcf bellard
        case 0x9:
469 cf495bcf bellard
            gen_op_eval_bne();
470 cf495bcf bellard
            break;
471 cf495bcf bellard
        case 0xa:
472 cf495bcf bellard
            gen_op_eval_bg();
473 cf495bcf bellard
            break;
474 cf495bcf bellard
        case 0xb:
475 cf495bcf bellard
            gen_op_eval_bge();
476 cf495bcf bellard
            break;
477 cf495bcf bellard
        case 0xc:
478 cf495bcf bellard
            gen_op_eval_bgu();
479 cf495bcf bellard
            break;
480 cf495bcf bellard
        case 0xd:
481 cf495bcf bellard
            gen_op_eval_bcc();
482 cf495bcf bellard
            break;
483 cf495bcf bellard
        case 0xe:
484 cf495bcf bellard
            gen_op_eval_bpos();
485 cf495bcf bellard
            break;
486 cf495bcf bellard
        default:
487 cf495bcf bellard
        case 0xf:
488 cf495bcf bellard
            gen_op_eval_bvc();
489 cf495bcf bellard
            break;
490 7a3f1944 bellard
        }
491 7a3f1944 bellard
}
492 7a3f1944 bellard
493 e8af50a3 bellard
static void gen_fcond(int cond)
494 e8af50a3 bellard
{
495 e8af50a3 bellard
        switch (cond) {
496 e8af50a3 bellard
        case 0x1:
497 e8af50a3 bellard
            gen_op_eval_fbne();
498 e8af50a3 bellard
            break;
499 e8af50a3 bellard
        case 0x2:
500 e8af50a3 bellard
            gen_op_eval_fblg();
501 e8af50a3 bellard
            break;
502 e8af50a3 bellard
        case 0x3:
503 e8af50a3 bellard
            gen_op_eval_fbul();
504 e8af50a3 bellard
            break;
505 e8af50a3 bellard
        case 0x4:
506 e8af50a3 bellard
            gen_op_eval_fbl();
507 e8af50a3 bellard
            break;
508 e8af50a3 bellard
        case 0x5:
509 e8af50a3 bellard
            gen_op_eval_fbug();
510 e8af50a3 bellard
            break;
511 e8af50a3 bellard
        case 0x6:
512 e8af50a3 bellard
            gen_op_eval_fbg();
513 e8af50a3 bellard
            break;
514 e8af50a3 bellard
        case 0x7:
515 e8af50a3 bellard
            gen_op_eval_fbu();
516 e8af50a3 bellard
            break;
517 e8af50a3 bellard
        case 0x9:
518 e8af50a3 bellard
            gen_op_eval_fbe();
519 e8af50a3 bellard
            break;
520 e8af50a3 bellard
        case 0xa:
521 e8af50a3 bellard
            gen_op_eval_fbue();
522 e8af50a3 bellard
            break;
523 e8af50a3 bellard
        case 0xb:
524 e8af50a3 bellard
            gen_op_eval_fbge();
525 e8af50a3 bellard
            break;
526 e8af50a3 bellard
        case 0xc:
527 e8af50a3 bellard
            gen_op_eval_fbuge();
528 e8af50a3 bellard
            break;
529 e8af50a3 bellard
        case 0xd:
530 e8af50a3 bellard
            gen_op_eval_fble();
531 e8af50a3 bellard
            break;
532 e8af50a3 bellard
        case 0xe:
533 e8af50a3 bellard
            gen_op_eval_fbule();
534 e8af50a3 bellard
            break;
535 e8af50a3 bellard
        default:
536 e8af50a3 bellard
        case 0xf:
537 e8af50a3 bellard
            gen_op_eval_fbo();
538 e8af50a3 bellard
            break;
539 e8af50a3 bellard
        }
540 e8af50a3 bellard
}
541 cf495bcf bellard
542 0bee699e bellard
/* XXX: potentially incorrect if dynamic npc */
543 af7bf89b bellard
static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn)
544 7a3f1944 bellard
{
545 cf495bcf bellard
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
546 af7bf89b bellard
    target_ulong target = dc->pc + offset;
547 af7bf89b bellard
548 cf495bcf bellard
    if (cond == 0x0) {
549 cf495bcf bellard
        /* unconditional not taken */
550 cf495bcf bellard
        if (a) {
551 0bee699e bellard
            dc->pc = dc->npc + 4; 
552 cf495bcf bellard
            dc->npc = dc->pc + 4;
553 cf495bcf bellard
        } else {
554 cf495bcf bellard
            dc->pc = dc->npc;
555 cf495bcf bellard
            dc->npc = dc->pc + 4;
556 cf495bcf bellard
        }
557 cf495bcf bellard
    } else if (cond == 0x8) {
558 cf495bcf bellard
        /* unconditional taken */
559 cf495bcf bellard
        if (a) {
560 72cbca10 bellard
            dc->pc = target;
561 cf495bcf bellard
            dc->npc = dc->pc + 4;
562 cf495bcf bellard
        } else {
563 cf495bcf bellard
            dc->pc = dc->npc;
564 72cbca10 bellard
            dc->npc = target;
565 cf495bcf bellard
        }
566 cf495bcf bellard
    } else {
567 72cbca10 bellard
        flush_T2(dc);
568 cf495bcf bellard
        gen_cond(cond);
569 cf495bcf bellard
        if (a) {
570 72cbca10 bellard
            gen_op_branch_a((long)dc->tb, target, dc->npc);
571 cf495bcf bellard
            dc->is_br = 1;
572 cf495bcf bellard
        } else {
573 cf495bcf bellard
            dc->pc = dc->npc;
574 72cbca10 bellard
            dc->jump_pc[0] = target;
575 72cbca10 bellard
            dc->jump_pc[1] = dc->npc + 4;
576 72cbca10 bellard
            dc->npc = JUMP_PC;
577 cf495bcf bellard
        }
578 cf495bcf bellard
    }
579 7a3f1944 bellard
}
580 7a3f1944 bellard
581 0bee699e bellard
/* XXX: potentially incorrect if dynamic npc */
582 af7bf89b bellard
static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn)
583 e8af50a3 bellard
{
584 e8af50a3 bellard
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
585 af7bf89b bellard
    target_ulong target = dc->pc + offset;
586 af7bf89b bellard
587 e8af50a3 bellard
    if (cond == 0x0) {
588 e8af50a3 bellard
        /* unconditional not taken */
589 e8af50a3 bellard
        if (a) {
590 e8af50a3 bellard
            dc->pc = dc->npc + 4;
591 e8af50a3 bellard
            dc->npc = dc->pc + 4;
592 e8af50a3 bellard
        } else {
593 e8af50a3 bellard
            dc->pc = dc->npc;
594 e8af50a3 bellard
            dc->npc = dc->pc + 4;
595 e8af50a3 bellard
        }
596 e8af50a3 bellard
    } else if (cond == 0x8) {
597 e8af50a3 bellard
        /* unconditional taken */
598 e8af50a3 bellard
        if (a) {
599 e8af50a3 bellard
            dc->pc = target;
600 e8af50a3 bellard
            dc->npc = dc->pc + 4;
601 e8af50a3 bellard
        } else {
602 e8af50a3 bellard
            dc->pc = dc->npc;
603 e8af50a3 bellard
            dc->npc = target;
604 e8af50a3 bellard
        }
605 e8af50a3 bellard
    } else {
606 e8af50a3 bellard
        flush_T2(dc);
607 e8af50a3 bellard
        gen_fcond(cond);
608 e8af50a3 bellard
        if (a) {
609 e8af50a3 bellard
            gen_op_branch_a((long)dc->tb, target, dc->npc);
610 e8af50a3 bellard
            dc->is_br = 1;
611 e8af50a3 bellard
        } else {
612 e8af50a3 bellard
            dc->pc = dc->npc;
613 e8af50a3 bellard
            dc->jump_pc[0] = target;
614 e8af50a3 bellard
            dc->jump_pc[1] = dc->npc + 4;
615 e8af50a3 bellard
            dc->npc = JUMP_PC;
616 e8af50a3 bellard
        }
617 e8af50a3 bellard
    }
618 e8af50a3 bellard
}
619 e8af50a3 bellard
620 cf495bcf bellard
#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
621 7a3f1944 bellard
622 cf495bcf bellard
static int sign_extend(int x, int len)
623 7a3f1944 bellard
{
624 cf495bcf bellard
    len = 32 - len;
625 cf495bcf bellard
    return (x << len) >> len;
626 7a3f1944 bellard
}
627 7a3f1944 bellard
628 0bee699e bellard
/* before an instruction, dc->pc must be static */
629 cf495bcf bellard
static void disas_sparc_insn(DisasContext * dc)
630 cf495bcf bellard
{
631 cf495bcf bellard
    unsigned int insn, opc, rs1, rs2, rd;
632 7a3f1944 bellard
633 0fa85d43 bellard
    insn = ldl_code(dc->pc);
634 cf495bcf bellard
    opc = GET_FIELD(insn, 0, 1);
635 7a3f1944 bellard
636 cf495bcf bellard
    rd = GET_FIELD(insn, 2, 6);
637 cf495bcf bellard
    switch (opc) {
638 cf495bcf bellard
    case 0:                        /* branches/sethi */
639 cf495bcf bellard
        {
640 cf495bcf bellard
            unsigned int xop = GET_FIELD(insn, 7, 9);
641 af7bf89b bellard
            int32_t target;
642 cf495bcf bellard
            target = GET_FIELD(insn, 10, 31);
643 cf495bcf bellard
            switch (xop) {
644 af7bf89b bellard
            case 0x0:                /* UNIMPL */
645 af7bf89b bellard
            case 0x1:                /* V9 BPcc */
646 af7bf89b bellard
            case 0x3:                /* V9 BPr */
647 af7bf89b bellard
            case 0x5:                /* V9 FBPcc */
648 e8af50a3 bellard
            default:
649 cf495bcf bellard
                goto illegal_insn;
650 cf495bcf bellard
            case 0x2:                /* BN+x */
651 7a3f1944 bellard
                {
652 cf495bcf bellard
                    target <<= 2;
653 cf495bcf bellard
                    target = sign_extend(target, 22);
654 cf495bcf bellard
                    do_branch(dc, target, insn);
655 cf495bcf bellard
                    goto jmp_insn;
656 7a3f1944 bellard
                }
657 e8af50a3 bellard
            case 0x6:                /* FBN+x */
658 e8af50a3 bellard
                {
659 e80cfcfc bellard
#if !defined(CONFIG_USER_ONLY)
660 e80cfcfc bellard
                    gen_op_trap_ifnofpu();
661 e80cfcfc bellard
#endif
662 e8af50a3 bellard
                    target <<= 2;
663 e8af50a3 bellard
                    target = sign_extend(target, 22);
664 e8af50a3 bellard
                    do_fbranch(dc, target, insn);
665 e8af50a3 bellard
                    goto jmp_insn;
666 e8af50a3 bellard
                }
667 cf495bcf bellard
            case 0x4:                /* SETHI */
668 e80cfcfc bellard
#define OPTIM
669 e80cfcfc bellard
#if defined(OPTIM)
670 e80cfcfc bellard
                if (rd) { // nop
671 e80cfcfc bellard
#endif
672 e80cfcfc bellard
                    gen_movl_imm_T0(target << 10);
673 e80cfcfc bellard
                    gen_movl_T0_reg(rd);
674 e80cfcfc bellard
#if defined(OPTIM)
675 e80cfcfc bellard
                }
676 e80cfcfc bellard
#endif
677 cf495bcf bellard
                break;
678 cf495bcf bellard
            }
679 cf495bcf bellard
            break;
680 cf495bcf bellard
        }
681 af7bf89b bellard
        break;
682 cf495bcf bellard
    case 1:
683 cf495bcf bellard
        /*CALL*/ {
684 af7bf89b bellard
            target_long target = GET_FIELDs(insn, 2, 31) << 2;
685 cf495bcf bellard
686 af7bf89b bellard
            gen_op_movl_T0_im(dc->pc);
687 cf495bcf bellard
            gen_movl_T0_reg(15);
688 af7bf89b bellard
            target += dc->pc;
689 0bee699e bellard
            gen_mov_pc_npc(dc);
690 72cbca10 bellard
            dc->npc = target;
691 cf495bcf bellard
        }
692 cf495bcf bellard
        goto jmp_insn;
693 cf495bcf bellard
    case 2:                        /* FPU & Logical Operations */
694 cf495bcf bellard
        {
695 cf495bcf bellard
            unsigned int xop = GET_FIELD(insn, 7, 12);
696 cf495bcf bellard
            if (xop == 0x3a) {        /* generate trap */
697 cf495bcf bellard
                int cond;
698 cf495bcf bellard
                rs1 = GET_FIELD(insn, 13, 17);
699 cf495bcf bellard
                gen_movl_reg_T0(rs1);
700 cf495bcf bellard
                if (IS_IMM) {
701 e8af50a3 bellard
                    rs2 = GET_FIELD(insn, 25, 31);
702 e80cfcfc bellard
#if defined(OPTIM)
703 e8af50a3 bellard
                    if (rs2 != 0) {
704 e80cfcfc bellard
#endif
705 e80cfcfc bellard
                        gen_movl_imm_T1(rs2);
706 e80cfcfc bellard
                        gen_op_add_T1_T0();
707 e80cfcfc bellard
#if defined(OPTIM)
708 e8af50a3 bellard
                    }
709 e80cfcfc bellard
#endif
710 cf495bcf bellard
                } else {
711 cf495bcf bellard
                    rs2 = GET_FIELD(insn, 27, 31);
712 e80cfcfc bellard
#if defined(OPTIM)
713 e80cfcfc bellard
                    if (rs2 != 0) {
714 e80cfcfc bellard
#endif
715 e80cfcfc bellard
                        gen_movl_reg_T1(rs2);
716 e80cfcfc bellard
                        gen_op_add_T1_T0();
717 e80cfcfc bellard
#if defined(OPTIM)
718 e80cfcfc bellard
                    }
719 e80cfcfc bellard
#endif
720 cf495bcf bellard
                }
721 cf495bcf bellard
                save_state(dc);
722 af7bf89b bellard
                /* V9 icc/xcc */
723 cf495bcf bellard
                cond = GET_FIELD(insn, 3, 6);
724 cf495bcf bellard
                if (cond == 0x8) {
725 cf495bcf bellard
                    gen_op_trap_T0();
726 cf495bcf bellard
                    dc->is_br = 1;
727 cf495bcf bellard
                    goto jmp_insn;
728 af7bf89b bellard
                } else if (cond != 0) {
729 e80cfcfc bellard
                    gen_cond(cond);
730 cf495bcf bellard
                    gen_op_trapcc_T0();
731 cf495bcf bellard
                }
732 cf495bcf bellard
            } else if (xop == 0x28) {
733 cf495bcf bellard
                rs1 = GET_FIELD(insn, 13, 17);
734 cf495bcf bellard
                switch(rs1) {
735 cf495bcf bellard
                case 0: /* rdy */
736 cf495bcf bellard
                    gen_op_rdy();
737 cf495bcf bellard
                    gen_movl_T0_reg(rd);
738 cf495bcf bellard
                    break;
739 af7bf89b bellard
                case 15: /* stbar / V9 membar */
740 e8af50a3 bellard
                    break; /* no effect? */
741 cf495bcf bellard
                default:
742 af7bf89b bellard
                case 0x2: /* V9 rdccr */
743 af7bf89b bellard
                case 0x3: /* V9 rdasi */
744 af7bf89b bellard
                case 0x4: /* V9 rdtick */
745 af7bf89b bellard
                case 0x5: /* V9 rdpc */
746 af7bf89b bellard
                case 0x6: /* V9 rdfprs */
747 cf495bcf bellard
                    goto illegal_insn;
748 cf495bcf bellard
                }
749 e8af50a3 bellard
#if !defined(CONFIG_USER_ONLY)
750 e8af50a3 bellard
            } else if (xop == 0x29) {
751 e8af50a3 bellard
                if (!supervisor(dc))
752 e8af50a3 bellard
                    goto priv_insn;
753 e8af50a3 bellard
                gen_op_rdpsr();
754 e8af50a3 bellard
                gen_movl_T0_reg(rd);
755 e8af50a3 bellard
                break;
756 e8af50a3 bellard
            } else if (xop == 0x2a) {
757 e8af50a3 bellard
                if (!supervisor(dc))
758 e8af50a3 bellard
                    goto priv_insn;
759 e8af50a3 bellard
                gen_op_rdwim();
760 e8af50a3 bellard
                gen_movl_T0_reg(rd);
761 e8af50a3 bellard
                break;
762 e8af50a3 bellard
            } else if (xop == 0x2b) {
763 e8af50a3 bellard
                if (!supervisor(dc))
764 e8af50a3 bellard
                    goto priv_insn;
765 e8af50a3 bellard
                gen_op_rdtbr();
766 e8af50a3 bellard
                gen_movl_T0_reg(rd);
767 e8af50a3 bellard
                break;
768 e8af50a3 bellard
#endif
769 e80cfcfc bellard
            } else if (xop == 0x34) {        /* FPU Operations */
770 e80cfcfc bellard
#if !defined(CONFIG_USER_ONLY)
771 e80cfcfc bellard
                gen_op_trap_ifnofpu();
772 e80cfcfc bellard
#endif
773 e8af50a3 bellard
                rs1 = GET_FIELD(insn, 13, 17);
774 e8af50a3 bellard
                rs2 = GET_FIELD(insn, 27, 31);
775 e8af50a3 bellard
                xop = GET_FIELD(insn, 18, 26);
776 e8af50a3 bellard
                switch (xop) {
777 e8af50a3 bellard
                    case 0x1: /* fmovs */
778 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs2);
779 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
780 e8af50a3 bellard
                        break;
781 e8af50a3 bellard
                    case 0x5: /* fnegs */
782 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
783 e8af50a3 bellard
                        gen_op_fnegs();
784 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
785 e8af50a3 bellard
                        break;
786 e8af50a3 bellard
                    case 0x9: /* fabss */
787 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
788 e8af50a3 bellard
                        gen_op_fabss();
789 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
790 e8af50a3 bellard
                        break;
791 e8af50a3 bellard
                    case 0x29: /* fsqrts */
792 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
793 e8af50a3 bellard
                        gen_op_fsqrts();
794 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
795 e8af50a3 bellard
                        break;
796 e8af50a3 bellard
                    case 0x2a: /* fsqrtd */
797 e8af50a3 bellard
                        gen_op_load_fpr_DT1(rs2);
798 e8af50a3 bellard
                        gen_op_fsqrtd();
799 e8af50a3 bellard
                        gen_op_store_DT0_fpr(rd);
800 e8af50a3 bellard
                        break;
801 e80cfcfc bellard
                    case 0x2b: /* fsqrtq */
802 e80cfcfc bellard
                        goto nfpu_insn;
803 e8af50a3 bellard
                    case 0x41:
804 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs1);
805 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
806 e8af50a3 bellard
                        gen_op_fadds();
807 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
808 e8af50a3 bellard
                        break;
809 e8af50a3 bellard
                    case 0x42:
810 e8af50a3 bellard
                        gen_op_load_fpr_DT0(rs1);
811 e8af50a3 bellard
                        gen_op_load_fpr_DT1(rs2);
812 e8af50a3 bellard
                        gen_op_faddd();
813 e8af50a3 bellard
                        gen_op_store_DT0_fpr(rd);
814 e8af50a3 bellard
                        break;
815 e80cfcfc bellard
                    case 0x43: /* faddq */
816 e80cfcfc bellard
                        goto nfpu_insn;
817 e8af50a3 bellard
                    case 0x45:
818 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs1);
819 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
820 e8af50a3 bellard
                        gen_op_fsubs();
821 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
822 e8af50a3 bellard
                        break;
823 e8af50a3 bellard
                    case 0x46:
824 e8af50a3 bellard
                        gen_op_load_fpr_DT0(rs1);
825 e8af50a3 bellard
                        gen_op_load_fpr_DT1(rs2);
826 e8af50a3 bellard
                        gen_op_fsubd();
827 e8af50a3 bellard
                        gen_op_store_DT0_fpr(rd);
828 e8af50a3 bellard
                        break;
829 e80cfcfc bellard
                    case 0x47: /* fsubq */
830 e80cfcfc bellard
                        goto nfpu_insn;
831 e8af50a3 bellard
                    case 0x49:
832 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs1);
833 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
834 e8af50a3 bellard
                        gen_op_fmuls();
835 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
836 e8af50a3 bellard
                        break;
837 e8af50a3 bellard
                    case 0x4a:
838 e8af50a3 bellard
                        gen_op_load_fpr_DT0(rs1);
839 e8af50a3 bellard
                        gen_op_load_fpr_DT1(rs2);
840 e8af50a3 bellard
                        gen_op_fmuld();
841 e8af50a3 bellard
                        gen_op_store_DT0_fpr(rd);
842 e8af50a3 bellard
                        break;
843 e80cfcfc bellard
                    case 0x4b: /* fmulq */
844 e80cfcfc bellard
                        goto nfpu_insn;
845 e8af50a3 bellard
                    case 0x4d:
846 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs1);
847 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
848 e8af50a3 bellard
                        gen_op_fdivs();
849 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
850 e8af50a3 bellard
                        break;
851 e8af50a3 bellard
                    case 0x4e:
852 e8af50a3 bellard
                        gen_op_load_fpr_DT0(rs1);
853 e8af50a3 bellard
                        gen_op_load_fpr_DT1(rs2);
854 e8af50a3 bellard
                        gen_op_fdivd();
855 e8af50a3 bellard
                        gen_op_store_DT0_fpr(rd);
856 e8af50a3 bellard
                        break;
857 e80cfcfc bellard
                    case 0x4f: /* fdivq */
858 e80cfcfc bellard
                        goto nfpu_insn;
859 e8af50a3 bellard
                    case 0x69:
860 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs1);
861 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
862 e8af50a3 bellard
                        gen_op_fsmuld();
863 e8af50a3 bellard
                        gen_op_store_DT0_fpr(rd);
864 e8af50a3 bellard
                        break;
865 e80cfcfc bellard
                    case 0x6e: /* fdmulq */
866 e80cfcfc bellard
                        goto nfpu_insn;
867 e8af50a3 bellard
                    case 0xc4:
868 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
869 e8af50a3 bellard
                        gen_op_fitos();
870 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
871 e8af50a3 bellard
                        break;
872 e8af50a3 bellard
                    case 0xc6:
873 e8af50a3 bellard
                        gen_op_load_fpr_DT1(rs2);
874 e8af50a3 bellard
                        gen_op_fdtos();
875 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
876 e8af50a3 bellard
                        break;
877 e80cfcfc bellard
                    case 0xc7: /* fqtos */
878 e80cfcfc bellard
                        goto nfpu_insn;
879 e8af50a3 bellard
                    case 0xc8:
880 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
881 e8af50a3 bellard
                        gen_op_fitod();
882 e8af50a3 bellard
                        gen_op_store_DT0_fpr(rd);
883 e8af50a3 bellard
                        break;
884 e8af50a3 bellard
                    case 0xc9:
885 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
886 e8af50a3 bellard
                        gen_op_fstod();
887 e8af50a3 bellard
                        gen_op_store_DT0_fpr(rd);
888 e8af50a3 bellard
                        break;
889 e80cfcfc bellard
                    case 0xcb: /* fqtod */
890 e80cfcfc bellard
                        goto nfpu_insn;
891 e80cfcfc bellard
                    case 0xcc: /* fitoq */
892 e80cfcfc bellard
                        goto nfpu_insn;
893 e80cfcfc bellard
                    case 0xcd: /* fstoq */
894 e80cfcfc bellard
                        goto nfpu_insn;
895 e80cfcfc bellard
                    case 0xce: /* fdtoq */
896 e80cfcfc bellard
                        goto nfpu_insn;
897 e8af50a3 bellard
                    case 0xd1:
898 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
899 e8af50a3 bellard
                        gen_op_fstoi();
900 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
901 e8af50a3 bellard
                        break;
902 e8af50a3 bellard
                    case 0xd2:
903 e8af50a3 bellard
                        gen_op_load_fpr_DT1(rs2);
904 e8af50a3 bellard
                        gen_op_fdtoi();
905 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
906 e8af50a3 bellard
                        break;
907 e80cfcfc bellard
                    case 0xd3: /* fqtoi */
908 e80cfcfc bellard
                        goto nfpu_insn;
909 e8af50a3 bellard
                    default:
910 af7bf89b bellard
                    case 0x2: /* V9 fmovd */
911 af7bf89b bellard
                    case 0x6: /* V9 fnegd */
912 af7bf89b bellard
                    case 0xa: /* V9 fabsd */
913 af7bf89b bellard
                    case 0x81: /* V9 fstox */
914 af7bf89b bellard
                    case 0x82: /* V9 fdtox */
915 af7bf89b bellard
                    case 0x84: /* V9 fxtos */
916 af7bf89b bellard
                    case 0x88: /* V9 fxtod */
917 af7bf89b bellard
918 af7bf89b bellard
                    case 0x3: /* V9 fmovq */
919 af7bf89b bellard
                    case 0x7: /* V9 fnegq */
920 af7bf89b bellard
                    case 0xb: /* V9 fabsq */
921 af7bf89b bellard
                    case 0x83: /* V9 fqtox */
922 af7bf89b bellard
                    case 0x8c: /* V9 fxtoq */
923 e8af50a3 bellard
                        goto illegal_insn;
924 e8af50a3 bellard
                }
925 e80cfcfc bellard
            } else if (xop == 0x35) {        /* FPU Operations */
926 e80cfcfc bellard
#if !defined(CONFIG_USER_ONLY)
927 e80cfcfc bellard
                gen_op_trap_ifnofpu();
928 e80cfcfc bellard
#endif
929 cf495bcf bellard
                rs1 = GET_FIELD(insn, 13, 17);
930 e80cfcfc bellard
                rs2 = GET_FIELD(insn, 27, 31);
931 e80cfcfc bellard
                xop = GET_FIELD(insn, 18, 26);
932 af7bf89b bellard
                /* V9 fmovscc: x5, cond = x >> 1 */
933 af7bf89b bellard
                /* V9 fmovdcc: x6, cond = x >> 1 */
934 af7bf89b bellard
935 af7bf89b bellard
                /* V9 fmovqcc: x7, cond = x >> 1 */
936 e80cfcfc bellard
                switch (xop) {
937 e80cfcfc bellard
                    case 0x51:
938 e80cfcfc bellard
                        gen_op_load_fpr_FT0(rs1);
939 e80cfcfc bellard
                        gen_op_load_fpr_FT1(rs2);
940 e80cfcfc bellard
                        gen_op_fcmps();
941 e80cfcfc bellard
                        break;
942 e80cfcfc bellard
                    case 0x52:
943 e80cfcfc bellard
                        gen_op_load_fpr_DT0(rs1);
944 e80cfcfc bellard
                        gen_op_load_fpr_DT1(rs2);
945 e80cfcfc bellard
                        gen_op_fcmpd();
946 e80cfcfc bellard
                        break;
947 e80cfcfc bellard
                    case 0x53: /* fcmpq */
948 e80cfcfc bellard
                        goto nfpu_insn;
949 e80cfcfc bellard
                    case 0x55: /* fcmpes */
950 e80cfcfc bellard
                        gen_op_load_fpr_FT0(rs1);
951 e80cfcfc bellard
                        gen_op_load_fpr_FT1(rs2);
952 e80cfcfc bellard
                        gen_op_fcmps(); /* XXX should trap if qNaN or sNaN  */
953 e80cfcfc bellard
                        break;
954 e80cfcfc bellard
                    case 0x56: /* fcmped */
955 e80cfcfc bellard
                        gen_op_load_fpr_DT0(rs1);
956 e80cfcfc bellard
                        gen_op_load_fpr_DT1(rs2);
957 e80cfcfc bellard
                        gen_op_fcmpd(); /* XXX should trap if qNaN or sNaN  */
958 e80cfcfc bellard
                        break;
959 e80cfcfc bellard
                    case 0x57: /* fcmpeq */
960 e80cfcfc bellard
                        goto nfpu_insn;
961 e80cfcfc bellard
                    default:
962 e80cfcfc bellard
                        goto illegal_insn;
963 e80cfcfc bellard
                }
964 e80cfcfc bellard
#if defined(OPTIM)
965 e80cfcfc bellard
            } else if (xop == 0x2) {
966 e80cfcfc bellard
                // clr/mov shortcut
967 e80cfcfc bellard
968 e80cfcfc bellard
                rs1 = GET_FIELD(insn, 13, 17);
969 e80cfcfc bellard
                if (rs1 == 0) {
970 e80cfcfc bellard
                    // or %g0, x, y -> mov T1, x; mov y, T1
971 e80cfcfc bellard
                    if (IS_IMM) {        /* immediate */
972 e80cfcfc bellard
                        rs2 = GET_FIELDs(insn, 19, 31);
973 e80cfcfc bellard
                        gen_movl_imm_T1(rs2);
974 e80cfcfc bellard
                    } else {                /* register */
975 e80cfcfc bellard
                        rs2 = GET_FIELD(insn, 27, 31);
976 e80cfcfc bellard
                        gen_movl_reg_T1(rs2);
977 e80cfcfc bellard
                    }
978 e80cfcfc bellard
                    gen_movl_T1_reg(rd);
979 e80cfcfc bellard
                } else {
980 e80cfcfc bellard
                    gen_movl_reg_T0(rs1);
981 e80cfcfc bellard
                    if (IS_IMM) {        /* immediate */
982 e80cfcfc bellard
                        // or x, #0, y -> mov T1, x; mov y, T1
983 e80cfcfc bellard
                        rs2 = GET_FIELDs(insn, 19, 31);
984 e80cfcfc bellard
                        if (rs2 != 0) {
985 e80cfcfc bellard
                            gen_movl_imm_T1(rs2);
986 e80cfcfc bellard
                            gen_op_or_T1_T0();
987 e80cfcfc bellard
                        }
988 e80cfcfc bellard
                    } else {                /* register */
989 e80cfcfc bellard
                        // or x, %g0, y -> mov T1, x; mov y, T1
990 e80cfcfc bellard
                        rs2 = GET_FIELD(insn, 27, 31);
991 e80cfcfc bellard
                        if (rs2 != 0) {
992 e80cfcfc bellard
                            gen_movl_reg_T1(rs2);
993 e80cfcfc bellard
                            gen_op_or_T1_T0();
994 e80cfcfc bellard
                        }
995 e80cfcfc bellard
                    }
996 e80cfcfc bellard
                    gen_movl_T0_reg(rd);
997 e80cfcfc bellard
                }
998 e80cfcfc bellard
#endif
999 e80cfcfc bellard
            } else if (xop < 0x38) {
1000 e80cfcfc bellard
                rs1 = GET_FIELD(insn, 13, 17);
1001 e80cfcfc bellard
                gen_movl_reg_T0(rs1);
1002 e80cfcfc bellard
                if (IS_IMM) {        /* immediate */
1003 cf495bcf bellard
                    rs2 = GET_FIELDs(insn, 19, 31);
1004 cf495bcf bellard
                    gen_movl_imm_T1(rs2);
1005 cf495bcf bellard
                } else {                /* register */
1006 cf495bcf bellard
                    rs2 = GET_FIELD(insn, 27, 31);
1007 cf495bcf bellard
                    gen_movl_reg_T1(rs2);
1008 cf495bcf bellard
                }
1009 cf495bcf bellard
                if (xop < 0x20) {
1010 cf495bcf bellard
                    switch (xop & ~0x10) {
1011 cf495bcf bellard
                    case 0x0:
1012 cf495bcf bellard
                        if (xop & 0x10)
1013 cf495bcf bellard
                            gen_op_add_T1_T0_cc();
1014 cf495bcf bellard
                        else
1015 cf495bcf bellard
                            gen_op_add_T1_T0();
1016 cf495bcf bellard
                        break;
1017 cf495bcf bellard
                    case 0x1:
1018 cf495bcf bellard
                        gen_op_and_T1_T0();
1019 cf495bcf bellard
                        if (xop & 0x10)
1020 cf495bcf bellard
                            gen_op_logic_T0_cc();
1021 cf495bcf bellard
                        break;
1022 cf495bcf bellard
                    case 0x2:
1023 e80cfcfc bellard
                        gen_op_or_T1_T0();
1024 e80cfcfc bellard
                        if (xop & 0x10)
1025 e80cfcfc bellard
                            gen_op_logic_T0_cc();
1026 e80cfcfc bellard
                        break;
1027 cf495bcf bellard
                    case 0x3:
1028 cf495bcf bellard
                        gen_op_xor_T1_T0();
1029 cf495bcf bellard
                        if (xop & 0x10)
1030 cf495bcf bellard
                            gen_op_logic_T0_cc();
1031 cf495bcf bellard
                        break;
1032 cf495bcf bellard
                    case 0x4:
1033 cf495bcf bellard
                        if (xop & 0x10)
1034 cf495bcf bellard
                            gen_op_sub_T1_T0_cc();
1035 cf495bcf bellard
                        else
1036 cf495bcf bellard
                            gen_op_sub_T1_T0();
1037 cf495bcf bellard
                        break;
1038 cf495bcf bellard
                    case 0x5:
1039 cf495bcf bellard
                        gen_op_andn_T1_T0();
1040 cf495bcf bellard
                        if (xop & 0x10)
1041 cf495bcf bellard
                            gen_op_logic_T0_cc();
1042 cf495bcf bellard
                        break;
1043 cf495bcf bellard
                    case 0x6:
1044 cf495bcf bellard
                        gen_op_orn_T1_T0();
1045 cf495bcf bellard
                        if (xop & 0x10)
1046 cf495bcf bellard
                            gen_op_logic_T0_cc();
1047 cf495bcf bellard
                        break;
1048 cf495bcf bellard
                    case 0x7:
1049 cf495bcf bellard
                        gen_op_xnor_T1_T0();
1050 cf495bcf bellard
                        if (xop & 0x10)
1051 cf495bcf bellard
                            gen_op_logic_T0_cc();
1052 cf495bcf bellard
                        break;
1053 cf495bcf bellard
                    case 0x8:
1054 cf495bcf bellard
                        if (xop & 0x10)
1055 af7bf89b bellard
                            gen_op_addx_T1_T0_cc();
1056 af7bf89b bellard
                        else
1057 af7bf89b bellard
                            gen_op_addx_T1_T0();
1058 cf495bcf bellard
                        break;
1059 cf495bcf bellard
                    case 0xa:
1060 cf495bcf bellard
                        gen_op_umul_T1_T0();
1061 cf495bcf bellard
                        if (xop & 0x10)
1062 cf495bcf bellard
                            gen_op_logic_T0_cc();
1063 cf495bcf bellard
                        break;
1064 cf495bcf bellard
                    case 0xb:
1065 cf495bcf bellard
                        gen_op_smul_T1_T0();
1066 cf495bcf bellard
                        if (xop & 0x10)
1067 cf495bcf bellard
                            gen_op_logic_T0_cc();
1068 cf495bcf bellard
                        break;
1069 cf495bcf bellard
                    case 0xc:
1070 cf495bcf bellard
                        if (xop & 0x10)
1071 af7bf89b bellard
                            gen_op_subx_T1_T0_cc();
1072 af7bf89b bellard
                        else
1073 af7bf89b bellard
                            gen_op_subx_T1_T0();
1074 cf495bcf bellard
                        break;
1075 cf495bcf bellard
                    case 0xe:
1076 cf495bcf bellard
                        gen_op_udiv_T1_T0();
1077 cf495bcf bellard
                        if (xop & 0x10)
1078 cf495bcf bellard
                            gen_op_div_cc();
1079 cf495bcf bellard
                        break;
1080 cf495bcf bellard
                    case 0xf:
1081 cf495bcf bellard
                        gen_op_sdiv_T1_T0();
1082 cf495bcf bellard
                        if (xop & 0x10)
1083 cf495bcf bellard
                            gen_op_div_cc();
1084 cf495bcf bellard
                        break;
1085 cf495bcf bellard
                    default:
1086 af7bf89b bellard
                    case 0x9: /* V9 mulx */
1087 af7bf89b bellard
                    case 0xd: /* V9 udivx */
1088 cf495bcf bellard
                        goto illegal_insn;
1089 cf495bcf bellard
                    }
1090 e80cfcfc bellard
                    gen_movl_T0_reg(rd);
1091 cf495bcf bellard
                } else {
1092 cf495bcf bellard
                    switch (xop) {
1093 e80cfcfc bellard
                    case 0x20: /* taddcc */
1094 e80cfcfc bellard
                    case 0x21: /* tsubcc */
1095 e80cfcfc bellard
                    case 0x22: /* taddcctv */
1096 e80cfcfc bellard
                    case 0x23: /* tsubcctv */
1097 e80cfcfc bellard
                        goto illegal_insn;
1098 cf495bcf bellard
                    case 0x24: /* mulscc */
1099 cf495bcf bellard
                        gen_op_mulscc_T1_T0();
1100 cf495bcf bellard
                        gen_movl_T0_reg(rd);
1101 cf495bcf bellard
                        break;
1102 af7bf89b bellard
                    case 0x25:        /* sll, V9 sllx */
1103 cf495bcf bellard
                        gen_op_sll();
1104 cf495bcf bellard
                        gen_movl_T0_reg(rd);
1105 cf495bcf bellard
                        break;
1106 af7bf89b bellard
                    case 0x26:  /* srl, V9 srlx */
1107 cf495bcf bellard
                        gen_op_srl();
1108 cf495bcf bellard
                        gen_movl_T0_reg(rd);
1109 cf495bcf bellard
                        break;
1110 af7bf89b bellard
                    case 0x27:  /* sra, V9 srax */
1111 cf495bcf bellard
                        gen_op_sra();
1112 cf495bcf bellard
                        gen_movl_T0_reg(rd);
1113 cf495bcf bellard
                        break;
1114 cf495bcf bellard
                    case 0x30:
1115 cf495bcf bellard
                        {
1116 cf495bcf bellard
                            gen_op_xor_T1_T0();
1117 cf495bcf bellard
                            switch(rd) {
1118 cf495bcf bellard
                            case 0:
1119 cf495bcf bellard
                                gen_op_wry();
1120 cf495bcf bellard
                                break;
1121 cf495bcf bellard
                            default:
1122 af7bf89b bellard
                            case 0x2: /* V9 wrccr */
1123 af7bf89b bellard
                            case 0x3: /* V9 wrasi */
1124 af7bf89b bellard
                            case 0x6: /* V9 wrfprs */
1125 af7bf89b bellard
                            case 0xf: /* V9 sir */
1126 cf495bcf bellard
                                goto illegal_insn;
1127 cf495bcf bellard
                            }
1128 cf495bcf bellard
                        }
1129 cf495bcf bellard
                        break;
1130 e8af50a3 bellard
#if !defined(CONFIG_USER_ONLY)
1131 af7bf89b bellard
                    case 0x31: /* wrpsr, V9 saved, restored */
1132 e8af50a3 bellard
                        {
1133 e8af50a3 bellard
                            if (!supervisor(dc))
1134 e8af50a3 bellard
                                goto priv_insn;
1135 e8af50a3 bellard
                            gen_op_xor_T1_T0();
1136 e8af50a3 bellard
                            gen_op_wrpsr();
1137 e8af50a3 bellard
                        }
1138 e8af50a3 bellard
                        break;
1139 af7bf89b bellard
                    case 0x32: /* wrwim, V9 wrpr */
1140 e8af50a3 bellard
                        {
1141 e8af50a3 bellard
                            if (!supervisor(dc))
1142 e8af50a3 bellard
                                goto priv_insn;
1143 e8af50a3 bellard
                            gen_op_xor_T1_T0();
1144 e8af50a3 bellard
                            gen_op_wrwim();
1145 e8af50a3 bellard
                        }
1146 e8af50a3 bellard
                        break;
1147 e8af50a3 bellard
                    case 0x33:
1148 e8af50a3 bellard
                        {
1149 e8af50a3 bellard
                            if (!supervisor(dc))
1150 e8af50a3 bellard
                                goto priv_insn;
1151 e8af50a3 bellard
                            gen_op_xor_T1_T0();
1152 e8af50a3 bellard
                            gen_op_wrtbr();
1153 e8af50a3 bellard
                        }
1154 e8af50a3 bellard
                        break;
1155 e8af50a3 bellard
#endif
1156 e80cfcfc bellard
                    default:
1157 af7bf89b bellard
                    case 0x2a: /* V9 rdpr */
1158 af7bf89b bellard
                    case 0x2b: /* V9 flushw */
1159 af7bf89b bellard
                    case 0x2c: /* V9 movcc */
1160 af7bf89b bellard
                    case 0x2d: /* V9 sdivx */
1161 af7bf89b bellard
                    case 0x2e: /* V9 popc */
1162 af7bf89b bellard
                    case 0x2f: /* V9 movr */
1163 e80cfcfc bellard
                        goto illegal_insn;
1164 e80cfcfc bellard
                    }
1165 e80cfcfc bellard
                }
1166 e80cfcfc bellard
            } else {
1167 e80cfcfc bellard
                rs1 = GET_FIELD(insn, 13, 17);
1168 e80cfcfc bellard
                gen_movl_reg_T0(rs1);
1169 e80cfcfc bellard
                if (IS_IMM) {        /* immediate */
1170 e80cfcfc bellard
                    rs2 = GET_FIELDs(insn, 19, 31);
1171 e80cfcfc bellard
#if defined(OPTIM)
1172 e80cfcfc bellard
                    if (rs2) {
1173 e8af50a3 bellard
#endif
1174 e80cfcfc bellard
                        gen_movl_imm_T1(rs2);
1175 e80cfcfc bellard
                        gen_op_add_T1_T0();
1176 e80cfcfc bellard
#if defined(OPTIM)
1177 e80cfcfc bellard
                    }
1178 e8af50a3 bellard
#endif
1179 e80cfcfc bellard
                } else {                /* register */
1180 e80cfcfc bellard
                    rs2 = GET_FIELD(insn, 27, 31);
1181 e80cfcfc bellard
#if defined(OPTIM)
1182 e80cfcfc bellard
                    if (rs2) {
1183 e80cfcfc bellard
#endif
1184 e80cfcfc bellard
                        gen_movl_reg_T1(rs2);
1185 e80cfcfc bellard
                        gen_op_add_T1_T0();
1186 e80cfcfc bellard
#if defined(OPTIM)
1187 e80cfcfc bellard
                    }
1188 e8af50a3 bellard
#endif
1189 cf495bcf bellard
                }
1190 e80cfcfc bellard
                switch (xop) {
1191 e80cfcfc bellard
                case 0x38:        /* jmpl */
1192 e80cfcfc bellard
                    {
1193 e80cfcfc bellard
                        if (rd != 0) {
1194 0bee699e bellard
                            gen_op_movl_T1_im(dc->pc);
1195 0bee699e bellard
                            gen_movl_T1_reg(rd);
1196 e80cfcfc bellard
                        }
1197 0bee699e bellard
                        gen_mov_pc_npc(dc);
1198 0bee699e bellard
                        gen_op_movl_npc_T0();
1199 e80cfcfc bellard
                        dc->npc = DYNAMIC_PC;
1200 e80cfcfc bellard
                    }
1201 e80cfcfc bellard
                    goto jmp_insn;
1202 e80cfcfc bellard
#if !defined(CONFIG_USER_ONLY)
1203 af7bf89b bellard
                case 0x39:        /* rett, V9 return */
1204 e80cfcfc bellard
                    {
1205 e80cfcfc bellard
                        if (!supervisor(dc))
1206 e80cfcfc bellard
                            goto priv_insn;
1207 0bee699e bellard
                        gen_mov_pc_npc(dc);
1208 e80cfcfc bellard
                        gen_op_movl_npc_T0();
1209 0bee699e bellard
                        dc->npc = DYNAMIC_PC;
1210 e80cfcfc bellard
                        gen_op_rett();
1211 e80cfcfc bellard
                    }
1212 0bee699e bellard
                    goto jmp_insn;
1213 e80cfcfc bellard
#endif
1214 e80cfcfc bellard
                case 0x3b: /* flush */
1215 e80cfcfc bellard
                    gen_op_flush_T0();
1216 e80cfcfc bellard
                    break;
1217 e80cfcfc bellard
                case 0x3c:        /* save */
1218 e80cfcfc bellard
                    save_state(dc);
1219 e80cfcfc bellard
                    gen_op_save();
1220 e80cfcfc bellard
                    gen_movl_T0_reg(rd);
1221 e80cfcfc bellard
                    break;
1222 e80cfcfc bellard
                case 0x3d:        /* restore */
1223 e80cfcfc bellard
                    save_state(dc);
1224 e80cfcfc bellard
                    gen_op_restore();
1225 e80cfcfc bellard
                    gen_movl_T0_reg(rd);
1226 e80cfcfc bellard
                    break;
1227 e80cfcfc bellard
                default:
1228 af7bf89b bellard
                case 0x3e:      /* V9 done/retry */
1229 e80cfcfc bellard
                    goto illegal_insn;
1230 e80cfcfc bellard
                }
1231 cf495bcf bellard
            }
1232 cf495bcf bellard
            break;
1233 cf495bcf bellard
        }
1234 af7bf89b bellard
        break;
1235 cf495bcf bellard
    case 3:                        /* load/store instructions */
1236 cf495bcf bellard
        {
1237 cf495bcf bellard
            unsigned int xop = GET_FIELD(insn, 7, 12);
1238 cf495bcf bellard
            rs1 = GET_FIELD(insn, 13, 17);
1239 cf495bcf bellard
            gen_movl_reg_T0(rs1);
1240 cf495bcf bellard
            if (IS_IMM) {        /* immediate */
1241 cf495bcf bellard
                rs2 = GET_FIELDs(insn, 19, 31);
1242 e80cfcfc bellard
#if defined(OPTIM)
1243 e8af50a3 bellard
                if (rs2 != 0) {
1244 e80cfcfc bellard
#endif
1245 e8af50a3 bellard
                    gen_movl_imm_T1(rs2);
1246 e8af50a3 bellard
                    gen_op_add_T1_T0();
1247 e80cfcfc bellard
#if defined(OPTIM)
1248 e8af50a3 bellard
                }
1249 e80cfcfc bellard
#endif
1250 cf495bcf bellard
            } else {                /* register */
1251 cf495bcf bellard
                rs2 = GET_FIELD(insn, 27, 31);
1252 e80cfcfc bellard
#if defined(OPTIM)
1253 e80cfcfc bellard
                if (rs2 != 0) {
1254 e80cfcfc bellard
#endif
1255 e80cfcfc bellard
                    gen_movl_reg_T1(rs2);
1256 e80cfcfc bellard
                    gen_op_add_T1_T0();
1257 e80cfcfc bellard
#if defined(OPTIM)
1258 e80cfcfc bellard
                }
1259 e80cfcfc bellard
#endif
1260 cf495bcf bellard
            }
1261 e8af50a3 bellard
            if (xop < 4 || (xop > 7 && xop < 0x14) || \
1262 e8af50a3 bellard
                    (xop > 0x17 && xop < 0x20)) {
1263 cf495bcf bellard
                switch (xop) {
1264 cf495bcf bellard
                case 0x0:        /* load word */
1265 e8af50a3 bellard
                    gen_op_ldst(ld);
1266 cf495bcf bellard
                    break;
1267 cf495bcf bellard
                case 0x1:        /* load unsigned byte */
1268 e8af50a3 bellard
                    gen_op_ldst(ldub);
1269 cf495bcf bellard
                    break;
1270 cf495bcf bellard
                case 0x2:        /* load unsigned halfword */
1271 e8af50a3 bellard
                    gen_op_ldst(lduh);
1272 cf495bcf bellard
                    break;
1273 cf495bcf bellard
                case 0x3:        /* load double word */
1274 e8af50a3 bellard
                    gen_op_ldst(ldd);
1275 cf495bcf bellard
                    gen_movl_T0_reg(rd + 1);
1276 cf495bcf bellard
                    break;
1277 cf495bcf bellard
                case 0x9:        /* load signed byte */
1278 e8af50a3 bellard
                    gen_op_ldst(ldsb);
1279 cf495bcf bellard
                    break;
1280 cf495bcf bellard
                case 0xa:        /* load signed halfword */
1281 e8af50a3 bellard
                    gen_op_ldst(ldsh);
1282 cf495bcf bellard
                    break;
1283 cf495bcf bellard
                case 0xd:        /* ldstub -- XXX: should be atomically */
1284 e8af50a3 bellard
                    gen_op_ldst(ldstub);
1285 cf495bcf bellard
                    break;
1286 cf495bcf bellard
                case 0x0f:        /* swap register with memory. Also atomically */
1287 e80cfcfc bellard
                    gen_movl_reg_T1(rd);
1288 e8af50a3 bellard
                    gen_op_ldst(swap);
1289 e8af50a3 bellard
                    break;
1290 e80cfcfc bellard
#if !defined(CONFIG_USER_ONLY)
1291 e8af50a3 bellard
                case 0x10:        /* load word alternate */
1292 e8af50a3 bellard
                    if (!supervisor(dc))
1293 e8af50a3 bellard
                        goto priv_insn;
1294 e8af50a3 bellard
                    gen_op_lda(insn, 1, 4, 0);
1295 e8af50a3 bellard
                    break;
1296 e8af50a3 bellard
                case 0x11:        /* load unsigned byte alternate */
1297 e8af50a3 bellard
                    if (!supervisor(dc))
1298 e8af50a3 bellard
                        goto priv_insn;
1299 e8af50a3 bellard
                    gen_op_lduba(insn, 1, 1, 0);
1300 e8af50a3 bellard
                    break;
1301 e8af50a3 bellard
                case 0x12:        /* load unsigned halfword alternate */
1302 e8af50a3 bellard
                    if (!supervisor(dc))
1303 e8af50a3 bellard
                        goto priv_insn;
1304 e8af50a3 bellard
                    gen_op_lduha(insn, 1, 2, 0);
1305 e8af50a3 bellard
                    break;
1306 e8af50a3 bellard
                case 0x13:        /* load double word alternate */
1307 e8af50a3 bellard
                    if (!supervisor(dc))
1308 e8af50a3 bellard
                        goto priv_insn;
1309 e8af50a3 bellard
                    gen_op_ldda(insn, 1, 8, 0);
1310 e8af50a3 bellard
                    gen_movl_T0_reg(rd + 1);
1311 e8af50a3 bellard
                    break;
1312 e8af50a3 bellard
                case 0x19:        /* load signed byte alternate */
1313 e8af50a3 bellard
                    if (!supervisor(dc))
1314 e8af50a3 bellard
                        goto priv_insn;
1315 e8af50a3 bellard
                    gen_op_ldsba(insn, 1, 1, 1);
1316 e8af50a3 bellard
                    break;
1317 e8af50a3 bellard
                case 0x1a:        /* load signed halfword alternate */
1318 e8af50a3 bellard
                    if (!supervisor(dc))
1319 e8af50a3 bellard
                        goto priv_insn;
1320 e8af50a3 bellard
                    gen_op_ldsha(insn, 1, 2 ,1);
1321 e8af50a3 bellard
                    break;
1322 e8af50a3 bellard
                case 0x1d:        /* ldstuba -- XXX: should be atomically */
1323 e8af50a3 bellard
                    if (!supervisor(dc))
1324 e8af50a3 bellard
                        goto priv_insn;
1325 e8af50a3 bellard
                    gen_op_ldstuba(insn, 1, 1, 0);
1326 e8af50a3 bellard
                    break;
1327 e8af50a3 bellard
                case 0x1f:        /* swap reg with alt. memory. Also atomically */
1328 e8af50a3 bellard
                    if (!supervisor(dc))
1329 e8af50a3 bellard
                        goto priv_insn;
1330 e80cfcfc bellard
                    gen_movl_reg_T1(rd);
1331 e8af50a3 bellard
                    gen_op_swapa(insn, 1, 4, 0);
1332 cf495bcf bellard
                    break;
1333 0fa85d43 bellard
                    
1334 0fa85d43 bellard
                    /* avoid warnings */
1335 0fa85d43 bellard
                    (void) &gen_op_stfa;
1336 0fa85d43 bellard
                    (void) &gen_op_stdfa;
1337 0fa85d43 bellard
                    (void) &gen_op_ldfa;
1338 0fa85d43 bellard
                    (void) &gen_op_lddfa;
1339 e80cfcfc bellard
#endif
1340 e80cfcfc bellard
                default:
1341 af7bf89b bellard
                case 0x08: /* V9 ldsw */
1342 af7bf89b bellard
                case 0x0b: /* V9 ldx */
1343 af7bf89b bellard
                case 0x18: /* V9 ldswa */
1344 af7bf89b bellard
                case 0x1b: /* V9 ldxa */
1345 af7bf89b bellard
                case 0x2d: /* V9 prefetch */
1346 af7bf89b bellard
                case 0x30: /* V9 ldfa */
1347 af7bf89b bellard
                case 0x33: /* V9 lddfa */
1348 af7bf89b bellard
                case 0x3d: /* V9 prefetcha */
1349 af7bf89b bellard
1350 af7bf89b bellard
                case 0x32: /* V9 ldqfa */
1351 e80cfcfc bellard
                    goto illegal_insn;
1352 7a3f1944 bellard
                }
1353 cf495bcf bellard
                gen_movl_T1_reg(rd);
1354 e8af50a3 bellard
            } else if (xop >= 0x20 && xop < 0x24) {
1355 e80cfcfc bellard
#if !defined(CONFIG_USER_ONLY)
1356 e80cfcfc bellard
                gen_op_trap_ifnofpu();
1357 e80cfcfc bellard
#endif
1358 e8af50a3 bellard
                switch (xop) {
1359 e8af50a3 bellard
                case 0x20:        /* load fpreg */
1360 e8af50a3 bellard
                    gen_op_ldst(ldf);
1361 e8af50a3 bellard
                    gen_op_store_FT0_fpr(rd);
1362 e8af50a3 bellard
                    break;
1363 e8af50a3 bellard
                case 0x21:        /* load fsr */
1364 e8af50a3 bellard
                    gen_op_ldfsr();
1365 e80cfcfc bellard
                    gen_op_store_FT0_fpr(rd);
1366 e8af50a3 bellard
                    break;
1367 af7bf89b bellard
                case 0x22:      /* load quad fpreg */
1368 af7bf89b bellard
                    goto nfpu_insn;
1369 e8af50a3 bellard
                case 0x23:        /* load double fpreg */
1370 e8af50a3 bellard
                    gen_op_ldst(lddf);
1371 e8af50a3 bellard
                    gen_op_store_DT0_fpr(rd);
1372 e8af50a3 bellard
                    break;
1373 e80cfcfc bellard
                default:
1374 e80cfcfc bellard
                    goto illegal_insn;
1375 e8af50a3 bellard
                }
1376 e8af50a3 bellard
            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18)) {
1377 cf495bcf bellard
                gen_movl_reg_T1(rd);
1378 cf495bcf bellard
                switch (xop) {
1379 cf495bcf bellard
                case 0x4:
1380 e8af50a3 bellard
                    gen_op_ldst(st);
1381 cf495bcf bellard
                    break;
1382 cf495bcf bellard
                case 0x5:
1383 e8af50a3 bellard
                    gen_op_ldst(stb);
1384 cf495bcf bellard
                    break;
1385 cf495bcf bellard
                case 0x6:
1386 e8af50a3 bellard
                    gen_op_ldst(sth);
1387 cf495bcf bellard
                    break;
1388 cf495bcf bellard
                case 0x7:
1389 72cbca10 bellard
                    flush_T2(dc);
1390 cf495bcf bellard
                    gen_movl_reg_T2(rd + 1);
1391 e8af50a3 bellard
                    gen_op_ldst(std);
1392 e8af50a3 bellard
                    break;
1393 e80cfcfc bellard
#if !defined(CONFIG_USER_ONLY)
1394 e8af50a3 bellard
                case 0x14:
1395 e8af50a3 bellard
                    if (!supervisor(dc))
1396 e8af50a3 bellard
                        goto priv_insn;
1397 e8af50a3 bellard
                    gen_op_sta(insn, 0, 4, 0);
1398 e8af50a3 bellard
                    break;
1399 e8af50a3 bellard
                case 0x15:
1400 e8af50a3 bellard
                    if (!supervisor(dc))
1401 e8af50a3 bellard
                        goto priv_insn;
1402 e8af50a3 bellard
                    gen_op_stba(insn, 0, 1, 0);
1403 e8af50a3 bellard
                    break;
1404 e8af50a3 bellard
                case 0x16:
1405 e8af50a3 bellard
                    if (!supervisor(dc))
1406 e8af50a3 bellard
                        goto priv_insn;
1407 e8af50a3 bellard
                    gen_op_stha(insn, 0, 2, 0);
1408 e8af50a3 bellard
                    break;
1409 e8af50a3 bellard
                case 0x17:
1410 e8af50a3 bellard
                    if (!supervisor(dc))
1411 e8af50a3 bellard
                        goto priv_insn;
1412 e8af50a3 bellard
                    flush_T2(dc);
1413 e8af50a3 bellard
                    gen_movl_reg_T2(rd + 1);
1414 e8af50a3 bellard
                    gen_op_stda(insn, 0, 8, 0);
1415 cf495bcf bellard
                    break;
1416 e80cfcfc bellard
#endif
1417 e80cfcfc bellard
                default:
1418 af7bf89b bellard
                case 0x0e: /* V9 stx */
1419 af7bf89b bellard
                case 0x1e: /* V9 stxa */
1420 e80cfcfc bellard
                    goto illegal_insn;
1421 7a3f1944 bellard
                }
1422 e8af50a3 bellard
            } else if (xop > 0x23 && xop < 0x28) {
1423 e80cfcfc bellard
#if !defined(CONFIG_USER_ONLY)
1424 e80cfcfc bellard
                gen_op_trap_ifnofpu();
1425 e80cfcfc bellard
#endif
1426 e8af50a3 bellard
                switch (xop) {
1427 e8af50a3 bellard
                case 0x24:
1428 e8af50a3 bellard
                    gen_op_load_fpr_FT0(rd);
1429 e8af50a3 bellard
                    gen_op_ldst(stf);
1430 e8af50a3 bellard
                    break;
1431 af7bf89b bellard
                case 0x25: /* stfsr, V9 stxfsr */
1432 e80cfcfc bellard
                    gen_op_load_fpr_FT0(rd);
1433 e8af50a3 bellard
                    gen_op_stfsr();
1434 e8af50a3 bellard
                    break;
1435 af7bf89b bellard
                case 0x26: /* stdfq */
1436 af7bf89b bellard
                    goto nfpu_insn;
1437 e8af50a3 bellard
                case 0x27:
1438 e8af50a3 bellard
                    gen_op_load_fpr_DT0(rd);
1439 e8af50a3 bellard
                    gen_op_ldst(stdf);
1440 e8af50a3 bellard
                    break;
1441 e80cfcfc bellard
                default:
1442 af7bf89b bellard
                case 0x34: /* V9 stfa */
1443 af7bf89b bellard
                case 0x37: /* V9 stdfa */
1444 af7bf89b bellard
                case 0x3c: /* V9 casa */
1445 af7bf89b bellard
                case 0x3e: /* V9 casxa */
1446 af7bf89b bellard
1447 af7bf89b bellard
                case 0x36: /* V9 stqfa */
1448 e80cfcfc bellard
                    goto illegal_insn;
1449 e8af50a3 bellard
                }
1450 e8af50a3 bellard
            } else if (xop > 0x33 && xop < 0x38) {
1451 e8af50a3 bellard
                /* Co-processor */
1452 e80cfcfc bellard
                goto illegal_insn;
1453 e8af50a3 bellard
            }
1454 e80cfcfc bellard
            else
1455 e80cfcfc bellard
                goto illegal_insn;
1456 7a3f1944 bellard
        }
1457 af7bf89b bellard
        break;
1458 cf495bcf bellard
    }
1459 cf495bcf bellard
    /* default case for non jump instructions */
1460 72cbca10 bellard
    if (dc->npc == DYNAMIC_PC) {
1461 72cbca10 bellard
        dc->pc = DYNAMIC_PC;
1462 72cbca10 bellard
        gen_op_next_insn();
1463 72cbca10 bellard
    } else if (dc->npc == JUMP_PC) {
1464 72cbca10 bellard
        /* we can do a static jump */
1465 72cbca10 bellard
        gen_op_branch2((long)dc->tb, dc->jump_pc[0], dc->jump_pc[1]);
1466 72cbca10 bellard
        dc->is_br = 1;
1467 72cbca10 bellard
    } else {
1468 cf495bcf bellard
        dc->pc = dc->npc;
1469 cf495bcf bellard
        dc->npc = dc->npc + 4;
1470 cf495bcf bellard
    }
1471 e80cfcfc bellard
 jmp_insn:
1472 cf495bcf bellard
    return;
1473 cf495bcf bellard
 illegal_insn:
1474 72cbca10 bellard
    save_state(dc);
1475 cf495bcf bellard
    gen_op_exception(TT_ILL_INSN);
1476 cf495bcf bellard
    dc->is_br = 1;
1477 e8af50a3 bellard
    return;
1478 e80cfcfc bellard
#if !defined(CONFIG_USER_ONLY)
1479 e8af50a3 bellard
 priv_insn:
1480 e8af50a3 bellard
    save_state(dc);
1481 e8af50a3 bellard
    gen_op_exception(TT_PRIV_INSN);
1482 e8af50a3 bellard
    dc->is_br = 1;
1483 e80cfcfc bellard
    return;
1484 e80cfcfc bellard
#endif
1485 e80cfcfc bellard
 nfpu_insn:
1486 e80cfcfc bellard
    save_state(dc);
1487 e80cfcfc bellard
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
1488 e80cfcfc bellard
    dc->is_br = 1;
1489 7a3f1944 bellard
}
1490 7a3f1944 bellard
1491 cf495bcf bellard
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
1492 e8af50a3 bellard
                                                 int spc, CPUSPARCState *env)
1493 7a3f1944 bellard
{
1494 72cbca10 bellard
    target_ulong pc_start, last_pc;
1495 cf495bcf bellard
    uint16_t *gen_opc_end;
1496 cf495bcf bellard
    DisasContext dc1, *dc = &dc1;
1497 e8af50a3 bellard
    int j, lj = -1;
1498 cf495bcf bellard
1499 cf495bcf bellard
    memset(dc, 0, sizeof(DisasContext));
1500 cf495bcf bellard
    dc->tb = tb;
1501 72cbca10 bellard
    pc_start = tb->pc;
1502 cf495bcf bellard
    dc->pc = pc_start;
1503 e80cfcfc bellard
    last_pc = dc->pc;
1504 72cbca10 bellard
    dc->npc = (target_ulong) tb->cs_base;
1505 e8af50a3 bellard
#if defined(CONFIG_USER_ONLY)
1506 e8af50a3 bellard
    dc->mem_idx = 0;
1507 e8af50a3 bellard
#else
1508 e8af50a3 bellard
    dc->mem_idx = ((env->psrs) != 0);
1509 e8af50a3 bellard
#endif
1510 cf495bcf bellard
    gen_opc_ptr = gen_opc_buf;
1511 cf495bcf bellard
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1512 cf495bcf bellard
    gen_opparam_ptr = gen_opparam_buf;
1513 cf495bcf bellard
1514 cf495bcf bellard
    do {
1515 e8af50a3 bellard
        if (env->nb_breakpoints > 0) {
1516 e8af50a3 bellard
            for(j = 0; j < env->nb_breakpoints; j++) {
1517 e8af50a3 bellard
                if (env->breakpoints[j] == dc->pc) {
1518 e80cfcfc bellard
                    if (dc->pc != pc_start)
1519 e80cfcfc bellard
                        save_state(dc);
1520 e80cfcfc bellard
                    gen_op_debug();
1521 e80cfcfc bellard
                    gen_op_movl_T0_0();
1522 e80cfcfc bellard
                    gen_op_exit_tb();
1523 e80cfcfc bellard
                    dc->is_br = 1;
1524 e80cfcfc bellard
                    goto exit_gen_loop;
1525 e8af50a3 bellard
                }
1526 e8af50a3 bellard
            }
1527 e8af50a3 bellard
        }
1528 e8af50a3 bellard
        if (spc) {
1529 e8af50a3 bellard
            if (loglevel > 0)
1530 e8af50a3 bellard
                fprintf(logfile, "Search PC...\n");
1531 e8af50a3 bellard
            j = gen_opc_ptr - gen_opc_buf;
1532 e8af50a3 bellard
            if (lj < j) {
1533 e8af50a3 bellard
                lj++;
1534 e8af50a3 bellard
                while (lj < j)
1535 e8af50a3 bellard
                    gen_opc_instr_start[lj++] = 0;
1536 e8af50a3 bellard
                gen_opc_pc[lj] = dc->pc;
1537 e8af50a3 bellard
                gen_opc_npc[lj] = dc->npc;
1538 e8af50a3 bellard
                gen_opc_instr_start[lj] = 1;
1539 e8af50a3 bellard
            }
1540 e8af50a3 bellard
        }
1541 cf495bcf bellard
        last_pc = dc->pc;
1542 cf495bcf bellard
        disas_sparc_insn(dc);
1543 cf495bcf bellard
        if (dc->is_br)
1544 cf495bcf bellard
            break;
1545 cf495bcf bellard
        /* if the next PC is different, we abort now */
1546 cf495bcf bellard
        if (dc->pc != (last_pc + 4))
1547 cf495bcf bellard
            break;
1548 e80cfcfc bellard
        /* if single step mode, we generate only one instruction and
1549 e80cfcfc bellard
           generate an exception */
1550 e80cfcfc bellard
        if (env->singlestep_enabled) {
1551 e80cfcfc bellard
            gen_op_jmp_im(dc->pc);
1552 e80cfcfc bellard
            gen_op_movl_T0_0();
1553 e80cfcfc bellard
            gen_op_exit_tb();
1554 e80cfcfc bellard
            break;
1555 e80cfcfc bellard
        }
1556 cf495bcf bellard
    } while ((gen_opc_ptr < gen_opc_end) &&
1557 cf495bcf bellard
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
1558 e80cfcfc bellard
1559 e80cfcfc bellard
 exit_gen_loop:
1560 72cbca10 bellard
    if (!dc->is_br) {
1561 72cbca10 bellard
        if (dc->pc != DYNAMIC_PC && 
1562 72cbca10 bellard
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
1563 72cbca10 bellard
            /* static PC and NPC: we can use direct chaining */
1564 72cbca10 bellard
            gen_op_branch((long)tb, dc->pc, dc->npc);
1565 72cbca10 bellard
        } else {
1566 72cbca10 bellard
            if (dc->pc != DYNAMIC_PC)
1567 72cbca10 bellard
                gen_op_jmp_im(dc->pc);
1568 72cbca10 bellard
            save_npc(dc);
1569 72cbca10 bellard
            gen_op_movl_T0_0();
1570 72cbca10 bellard
            gen_op_exit_tb();
1571 72cbca10 bellard
        }
1572 72cbca10 bellard
    }
1573 cf495bcf bellard
    *gen_opc_ptr = INDEX_op_end;
1574 e8af50a3 bellard
    if (spc) {
1575 e8af50a3 bellard
        j = gen_opc_ptr - gen_opc_buf;
1576 e8af50a3 bellard
        lj++;
1577 e8af50a3 bellard
        while (lj <= j)
1578 e8af50a3 bellard
            gen_opc_instr_start[lj++] = 0;
1579 e8af50a3 bellard
        tb->size = 0;
1580 e8af50a3 bellard
#if 0
1581 e8af50a3 bellard
        if (loglevel > 0) {
1582 e8af50a3 bellard
            page_dump(logfile);
1583 e8af50a3 bellard
        }
1584 e8af50a3 bellard
#endif
1585 e8af50a3 bellard
    } else {
1586 e80cfcfc bellard
        tb->size = last_pc + 4 - pc_start;
1587 e8af50a3 bellard
    }
1588 7a3f1944 bellard
#ifdef DEBUG_DISAS
1589 e19e89a5 bellard
    if (loglevel & CPU_LOG_TB_IN_ASM) {
1590 cf495bcf bellard
        fprintf(logfile, "--------------\n");
1591 0fa85d43 bellard
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
1592 0fa85d43 bellard
        target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
1593 cf495bcf bellard
        fprintf(logfile, "\n");
1594 e19e89a5 bellard
        if (loglevel & CPU_LOG_TB_OP) {
1595 e19e89a5 bellard
            fprintf(logfile, "OP:\n");
1596 e19e89a5 bellard
            dump_ops(gen_opc_buf, gen_opparam_buf);
1597 e19e89a5 bellard
            fprintf(logfile, "\n");
1598 e19e89a5 bellard
        }
1599 cf495bcf bellard
    }
1600 7a3f1944 bellard
#endif
1601 cf495bcf bellard
    return 0;
1602 7a3f1944 bellard
}
1603 7a3f1944 bellard
1604 cf495bcf bellard
int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
1605 7a3f1944 bellard
{
1606 e8af50a3 bellard
    return gen_intermediate_code_internal(tb, 0, env);
1607 7a3f1944 bellard
}
1608 7a3f1944 bellard
1609 cf495bcf bellard
int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
1610 7a3f1944 bellard
{
1611 e8af50a3 bellard
    return gen_intermediate_code_internal(tb, 1, env);
1612 7a3f1944 bellard
}
1613 7a3f1944 bellard
1614 e80cfcfc bellard
extern int ram_size;
1615 cf495bcf bellard
1616 e80cfcfc bellard
void cpu_reset(CPUSPARCState *env)
1617 e80cfcfc bellard
{
1618 cf495bcf bellard
    memset(env, 0, sizeof(*env));
1619 bb05683b bellard
    tlb_flush(env, 1);
1620 cf495bcf bellard
    env->cwp = 0;
1621 cf495bcf bellard
    env->wim = 1;
1622 cf495bcf bellard
    env->regwptr = env->regbase + (env->cwp * 16);
1623 e8af50a3 bellard
#if defined(CONFIG_USER_ONLY)
1624 cf495bcf bellard
    env->user_mode_only = 1;
1625 e8af50a3 bellard
#else
1626 e8af50a3 bellard
    env->psrs = 1;
1627 0bee699e bellard
    env->psrps = 1;
1628 e80cfcfc bellard
    env->pc = 0xffd00000;
1629 e80cfcfc bellard
    env->gregs[1] = ram_size;
1630 e80cfcfc bellard
    env->mmuregs[0] = (0x04 << 24); /* Impl 0, ver 4, MMU disabled */
1631 e8af50a3 bellard
    env->npc = env->pc + 4;
1632 e8af50a3 bellard
#endif
1633 e80cfcfc bellard
}
1634 e80cfcfc bellard
1635 e80cfcfc bellard
CPUSPARCState *cpu_sparc_init(void)
1636 e80cfcfc bellard
{
1637 e80cfcfc bellard
    CPUSPARCState *env;
1638 e80cfcfc bellard
1639 e80cfcfc bellard
    cpu_exec_init();
1640 e80cfcfc bellard
1641 e80cfcfc bellard
    if (!(env = malloc(sizeof(CPUSPARCState))))
1642 e80cfcfc bellard
        return (NULL);
1643 7496f526 bellard
    cpu_single_env = env;
1644 e80cfcfc bellard
    cpu_reset(env);
1645 cf495bcf bellard
    return (env);
1646 7a3f1944 bellard
}
1647 7a3f1944 bellard
1648 7a3f1944 bellard
#define GET_FLAG(a,b) ((env->psr & a)?b:'-')
1649 7a3f1944 bellard
1650 7fe48483 bellard
void cpu_dump_state(CPUState *env, FILE *f, 
1651 7fe48483 bellard
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
1652 7fe48483 bellard
                    int flags)
1653 7a3f1944 bellard
{
1654 cf495bcf bellard
    int i, x;
1655 cf495bcf bellard
1656 af7bf89b bellard
    cpu_fprintf(f, "pc: " TARGET_FMT_lx "  npc: " TARGET_FMT_lx "\n", env->pc, env->npc);
1657 7fe48483 bellard
    cpu_fprintf(f, "General Registers:\n");
1658 cf495bcf bellard
    for (i = 0; i < 4; i++)
1659 af7bf89b bellard
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
1660 7fe48483 bellard
    cpu_fprintf(f, "\n");
1661 cf495bcf bellard
    for (; i < 8; i++)
1662 af7bf89b bellard
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
1663 7fe48483 bellard
    cpu_fprintf(f, "\nCurrent Register Window:\n");
1664 cf495bcf bellard
    for (x = 0; x < 3; x++) {
1665 cf495bcf bellard
        for (i = 0; i < 4; i++)
1666 af7bf89b bellard
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
1667 cf495bcf bellard
                    (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
1668 cf495bcf bellard
                    env->regwptr[i + x * 8]);
1669 7fe48483 bellard
        cpu_fprintf(f, "\n");
1670 cf495bcf bellard
        for (; i < 8; i++)
1671 af7bf89b bellard
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
1672 cf495bcf bellard
                    (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
1673 cf495bcf bellard
                    env->regwptr[i + x * 8]);
1674 7fe48483 bellard
        cpu_fprintf(f, "\n");
1675 cf495bcf bellard
    }
1676 7fe48483 bellard
    cpu_fprintf(f, "\nFloating Point Registers:\n");
1677 e8af50a3 bellard
    for (i = 0; i < 32; i++) {
1678 e8af50a3 bellard
        if ((i & 3) == 0)
1679 7fe48483 bellard
            cpu_fprintf(f, "%%f%02d:", i);
1680 7fe48483 bellard
        cpu_fprintf(f, " %016lf", env->fpr[i]);
1681 e8af50a3 bellard
        if ((i & 3) == 3)
1682 7fe48483 bellard
            cpu_fprintf(f, "\n");
1683 e8af50a3 bellard
    }
1684 7fe48483 bellard
    cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n", GET_PSR(env),
1685 cf495bcf bellard
            GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
1686 cf495bcf bellard
            GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
1687 e8af50a3 bellard
            env->psrs?'S':'-', env->psrps?'P':'-', 
1688 e8af50a3 bellard
            env->psret?'E':'-', env->wim);
1689 7fe48483 bellard
    cpu_fprintf(f, "fsr: 0x%08x\n", env->fsr);
1690 7a3f1944 bellard
}
1691 edfcbd99 bellard
1692 e80cfcfc bellard
#if defined(CONFIG_USER_ONLY)
1693 af7bf89b bellard
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
1694 edfcbd99 bellard
{
1695 edfcbd99 bellard
    return addr;
1696 edfcbd99 bellard
}
1697 658138bc bellard
1698 e80cfcfc bellard
#else
1699 af7bf89b bellard
extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
1700 af7bf89b bellard
                                 int *access_index, target_ulong address, int rw,
1701 0fa85d43 bellard
                                 int is_user);
1702 0fa85d43 bellard
1703 af7bf89b bellard
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
1704 e80cfcfc bellard
{
1705 af7bf89b bellard
    target_phys_addr_t phys_addr;
1706 e80cfcfc bellard
    int prot, access_index;
1707 e80cfcfc bellard
1708 e80cfcfc bellard
    if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2, 0) != 0)
1709 e80cfcfc bellard
        return -1;
1710 e80cfcfc bellard
    return phys_addr;
1711 e80cfcfc bellard
}
1712 e80cfcfc bellard
#endif
1713 e80cfcfc bellard
1714 658138bc bellard
void helper_flush(target_ulong addr)
1715 658138bc bellard
{
1716 658138bc bellard
    addr &= ~7;
1717 658138bc bellard
    tb_invalidate_page_range(addr, addr + 8);
1718 658138bc bellard
}