Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ bb05683b

History | View | Annotate | Download (42.7 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 72cbca10 bellard
    gen_op_jmp_im((uint32_t)dc->pc);
427 72cbca10 bellard
    save_npc(dc);
428 72cbca10 bellard
}
429 72cbca10 bellard
430 cf495bcf bellard
static void gen_cond(int cond)
431 7a3f1944 bellard
{
432 7a3f1944 bellard
        switch (cond) {
433 cf495bcf bellard
        case 0x0:
434 cf495bcf bellard
            gen_op_movl_T2_0();
435 cf495bcf bellard
            break;
436 cf495bcf bellard
        case 0x1:
437 cf495bcf bellard
            gen_op_eval_be();
438 cf495bcf bellard
            break;
439 cf495bcf bellard
        case 0x2:
440 cf495bcf bellard
            gen_op_eval_ble();
441 cf495bcf bellard
            break;
442 cf495bcf bellard
        case 0x3:
443 cf495bcf bellard
            gen_op_eval_bl();
444 cf495bcf bellard
            break;
445 cf495bcf bellard
        case 0x4:
446 cf495bcf bellard
            gen_op_eval_bleu();
447 cf495bcf bellard
            break;
448 cf495bcf bellard
        case 0x5:
449 cf495bcf bellard
            gen_op_eval_bcs();
450 cf495bcf bellard
            break;
451 cf495bcf bellard
        case 0x6:
452 cf495bcf bellard
            gen_op_eval_bneg();
453 cf495bcf bellard
            break;
454 cf495bcf bellard
        case 0x7:
455 cf495bcf bellard
            gen_op_eval_bvs();
456 cf495bcf bellard
            break;
457 cf495bcf bellard
        case 0x8:
458 cf495bcf bellard
            gen_op_movl_T2_1();
459 cf495bcf bellard
            break;
460 cf495bcf bellard
        case 0x9:
461 cf495bcf bellard
            gen_op_eval_bne();
462 cf495bcf bellard
            break;
463 cf495bcf bellard
        case 0xa:
464 cf495bcf bellard
            gen_op_eval_bg();
465 cf495bcf bellard
            break;
466 cf495bcf bellard
        case 0xb:
467 cf495bcf bellard
            gen_op_eval_bge();
468 cf495bcf bellard
            break;
469 cf495bcf bellard
        case 0xc:
470 cf495bcf bellard
            gen_op_eval_bgu();
471 cf495bcf bellard
            break;
472 cf495bcf bellard
        case 0xd:
473 cf495bcf bellard
            gen_op_eval_bcc();
474 cf495bcf bellard
            break;
475 cf495bcf bellard
        case 0xe:
476 cf495bcf bellard
            gen_op_eval_bpos();
477 cf495bcf bellard
            break;
478 cf495bcf bellard
        default:
479 cf495bcf bellard
        case 0xf:
480 cf495bcf bellard
            gen_op_eval_bvc();
481 cf495bcf bellard
            break;
482 7a3f1944 bellard
        }
483 7a3f1944 bellard
}
484 7a3f1944 bellard
485 e8af50a3 bellard
static void gen_fcond(int cond)
486 e8af50a3 bellard
{
487 e8af50a3 bellard
        switch (cond) {
488 e8af50a3 bellard
        case 0x0:
489 e8af50a3 bellard
            gen_op_movl_T2_0();
490 e8af50a3 bellard
            break;
491 e8af50a3 bellard
        case 0x1:
492 e8af50a3 bellard
            gen_op_eval_fbne();
493 e8af50a3 bellard
            break;
494 e8af50a3 bellard
        case 0x2:
495 e8af50a3 bellard
            gen_op_eval_fblg();
496 e8af50a3 bellard
            break;
497 e8af50a3 bellard
        case 0x3:
498 e8af50a3 bellard
            gen_op_eval_fbul();
499 e8af50a3 bellard
            break;
500 e8af50a3 bellard
        case 0x4:
501 e8af50a3 bellard
            gen_op_eval_fbl();
502 e8af50a3 bellard
            break;
503 e8af50a3 bellard
        case 0x5:
504 e8af50a3 bellard
            gen_op_eval_fbug();
505 e8af50a3 bellard
            break;
506 e8af50a3 bellard
        case 0x6:
507 e8af50a3 bellard
            gen_op_eval_fbg();
508 e8af50a3 bellard
            break;
509 e8af50a3 bellard
        case 0x7:
510 e8af50a3 bellard
            gen_op_eval_fbu();
511 e8af50a3 bellard
            break;
512 e8af50a3 bellard
        case 0x8:
513 e8af50a3 bellard
            gen_op_movl_T2_1();
514 e8af50a3 bellard
            break;
515 e8af50a3 bellard
        case 0x9:
516 e8af50a3 bellard
            gen_op_eval_fbe();
517 e8af50a3 bellard
            break;
518 e8af50a3 bellard
        case 0xa:
519 e8af50a3 bellard
            gen_op_eval_fbue();
520 e8af50a3 bellard
            break;
521 e8af50a3 bellard
        case 0xb:
522 e8af50a3 bellard
            gen_op_eval_fbge();
523 e8af50a3 bellard
            break;
524 e8af50a3 bellard
        case 0xc:
525 e8af50a3 bellard
            gen_op_eval_fbuge();
526 e8af50a3 bellard
            break;
527 e8af50a3 bellard
        case 0xd:
528 e8af50a3 bellard
            gen_op_eval_fble();
529 e8af50a3 bellard
            break;
530 e8af50a3 bellard
        case 0xe:
531 e8af50a3 bellard
            gen_op_eval_fbule();
532 e8af50a3 bellard
            break;
533 e8af50a3 bellard
        default:
534 e8af50a3 bellard
        case 0xf:
535 e8af50a3 bellard
            gen_op_eval_fbo();
536 e8af50a3 bellard
            break;
537 e8af50a3 bellard
        }
538 e8af50a3 bellard
}
539 cf495bcf bellard
540 cf495bcf bellard
static void do_branch(DisasContext * dc, uint32_t target, uint32_t insn)
541 7a3f1944 bellard
{
542 cf495bcf bellard
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
543 cf495bcf bellard
    target += (uint32_t) dc->pc;
544 cf495bcf bellard
    if (cond == 0x0) {
545 cf495bcf bellard
        /* unconditional not taken */
546 cf495bcf bellard
        if (a) {
547 cf495bcf bellard
            dc->pc = dc->npc + 4;
548 cf495bcf bellard
            dc->npc = dc->pc + 4;
549 cf495bcf bellard
        } else {
550 cf495bcf bellard
            dc->pc = dc->npc;
551 cf495bcf bellard
            dc->npc = dc->pc + 4;
552 cf495bcf bellard
        }
553 cf495bcf bellard
    } else if (cond == 0x8) {
554 cf495bcf bellard
        /* unconditional taken */
555 cf495bcf bellard
        if (a) {
556 72cbca10 bellard
            dc->pc = target;
557 cf495bcf bellard
            dc->npc = dc->pc + 4;
558 cf495bcf bellard
        } else {
559 cf495bcf bellard
            dc->pc = dc->npc;
560 72cbca10 bellard
            dc->npc = target;
561 cf495bcf bellard
        }
562 cf495bcf bellard
    } else {
563 72cbca10 bellard
        flush_T2(dc);
564 cf495bcf bellard
        gen_cond(cond);
565 cf495bcf bellard
        if (a) {
566 72cbca10 bellard
            gen_op_branch_a((long)dc->tb, target, dc->npc);
567 cf495bcf bellard
            dc->is_br = 1;
568 cf495bcf bellard
        } else {
569 cf495bcf bellard
            dc->pc = dc->npc;
570 72cbca10 bellard
            dc->jump_pc[0] = target;
571 72cbca10 bellard
            dc->jump_pc[1] = dc->npc + 4;
572 72cbca10 bellard
            dc->npc = JUMP_PC;
573 cf495bcf bellard
        }
574 cf495bcf bellard
    }
575 7a3f1944 bellard
}
576 7a3f1944 bellard
577 e8af50a3 bellard
static void do_fbranch(DisasContext * dc, uint32_t target, uint32_t insn)
578 e8af50a3 bellard
{
579 e8af50a3 bellard
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
580 e8af50a3 bellard
    target += (uint32_t) dc->pc;
581 e8af50a3 bellard
    if (cond == 0x0) {
582 e8af50a3 bellard
        /* unconditional not taken */
583 e8af50a3 bellard
        if (a) {
584 e8af50a3 bellard
            dc->pc = dc->npc + 4;
585 e8af50a3 bellard
            dc->npc = dc->pc + 4;
586 e8af50a3 bellard
        } else {
587 e8af50a3 bellard
            dc->pc = dc->npc;
588 e8af50a3 bellard
            dc->npc = dc->pc + 4;
589 e8af50a3 bellard
        }
590 e8af50a3 bellard
    } else if (cond == 0x8) {
591 e8af50a3 bellard
        /* unconditional taken */
592 e8af50a3 bellard
        if (a) {
593 e8af50a3 bellard
            dc->pc = target;
594 e8af50a3 bellard
            dc->npc = dc->pc + 4;
595 e8af50a3 bellard
        } else {
596 e8af50a3 bellard
            dc->pc = dc->npc;
597 e8af50a3 bellard
            dc->npc = target;
598 e8af50a3 bellard
        }
599 e8af50a3 bellard
    } else {
600 e8af50a3 bellard
        flush_T2(dc);
601 e8af50a3 bellard
        gen_fcond(cond);
602 e8af50a3 bellard
        if (a) {
603 e8af50a3 bellard
            gen_op_branch_a((long)dc->tb, target, dc->npc);
604 e8af50a3 bellard
            dc->is_br = 1;
605 e8af50a3 bellard
        } else {
606 e8af50a3 bellard
            dc->pc = dc->npc;
607 e8af50a3 bellard
            dc->jump_pc[0] = target;
608 e8af50a3 bellard
            dc->jump_pc[1] = dc->npc + 4;
609 e8af50a3 bellard
            dc->npc = JUMP_PC;
610 e8af50a3 bellard
        }
611 e8af50a3 bellard
    }
612 e8af50a3 bellard
}
613 e8af50a3 bellard
614 0fa85d43 bellard
#if 0
615 e8af50a3 bellard
static void gen_debug(DisasContext *s, uint32_t pc)
616 e8af50a3 bellard
{
617 e8af50a3 bellard
    gen_op_jmp_im(pc);
618 e8af50a3 bellard
    gen_op_debug();
619 e8af50a3 bellard
    s->is_br = 1;
620 e8af50a3 bellard
}
621 0fa85d43 bellard
#endif
622 e8af50a3 bellard
623 cf495bcf bellard
#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
624 7a3f1944 bellard
625 cf495bcf bellard
static int sign_extend(int x, int len)
626 7a3f1944 bellard
{
627 cf495bcf bellard
    len = 32 - len;
628 cf495bcf bellard
    return (x << len) >> len;
629 7a3f1944 bellard
}
630 7a3f1944 bellard
631 cf495bcf bellard
static void disas_sparc_insn(DisasContext * dc)
632 cf495bcf bellard
{
633 cf495bcf bellard
    unsigned int insn, opc, rs1, rs2, rd;
634 7a3f1944 bellard
635 0fa85d43 bellard
    insn = ldl_code(dc->pc);
636 cf495bcf bellard
    opc = GET_FIELD(insn, 0, 1);
637 7a3f1944 bellard
638 cf495bcf bellard
    rd = GET_FIELD(insn, 2, 6);
639 cf495bcf bellard
    switch (opc) {
640 cf495bcf bellard
    case 0:                        /* branches/sethi */
641 cf495bcf bellard
        {
642 cf495bcf bellard
            unsigned int xop = GET_FIELD(insn, 7, 9);
643 cf495bcf bellard
            int target;
644 cf495bcf bellard
            target = GET_FIELD(insn, 10, 31);
645 cf495bcf bellard
            switch (xop) {
646 cf495bcf bellard
            case 0x0:
647 cf495bcf bellard
            case 0x1:                /* UNIMPL */
648 e80cfcfc bellard
            case 0x5:                /*CBN+x */
649 e8af50a3 bellard
            default:
650 cf495bcf bellard
                goto illegal_insn;
651 cf495bcf bellard
            case 0x2:                /* BN+x */
652 7a3f1944 bellard
                {
653 cf495bcf bellard
                    target <<= 2;
654 cf495bcf bellard
                    target = sign_extend(target, 22);
655 cf495bcf bellard
                    do_branch(dc, target, insn);
656 cf495bcf bellard
                    goto jmp_insn;
657 7a3f1944 bellard
                }
658 e8af50a3 bellard
            case 0x6:                /* FBN+x */
659 e8af50a3 bellard
                {
660 e80cfcfc bellard
#if !defined(CONFIG_USER_ONLY)
661 e80cfcfc bellard
                    gen_op_trap_ifnofpu();
662 e80cfcfc bellard
#endif
663 e8af50a3 bellard
                    target <<= 2;
664 e8af50a3 bellard
                    target = sign_extend(target, 22);
665 e8af50a3 bellard
                    do_fbranch(dc, target, insn);
666 e8af50a3 bellard
                    goto jmp_insn;
667 e8af50a3 bellard
                }
668 cf495bcf bellard
            case 0x4:                /* SETHI */
669 e80cfcfc bellard
#define OPTIM
670 e80cfcfc bellard
#if defined(OPTIM)
671 e80cfcfc bellard
                if (rd) { // nop
672 e80cfcfc bellard
#endif
673 e80cfcfc bellard
                    gen_movl_imm_T0(target << 10);
674 e80cfcfc bellard
                    gen_movl_T0_reg(rd);
675 e80cfcfc bellard
#if defined(OPTIM)
676 e80cfcfc bellard
                }
677 e80cfcfc bellard
#endif
678 cf495bcf bellard
                break;
679 cf495bcf bellard
            }
680 cf495bcf bellard
            break;
681 cf495bcf bellard
        }
682 cf495bcf bellard
    case 1:
683 cf495bcf bellard
        /*CALL*/ {
684 cf495bcf bellard
            unsigned int target = GET_FIELDs(insn, 2, 31) << 2;
685 cf495bcf bellard
686 cf495bcf bellard
            gen_op_movl_T0_im((long) (dc->pc));
687 cf495bcf bellard
            gen_movl_T0_reg(15);
688 72cbca10 bellard
            target = dc->pc + target;
689 cf495bcf bellard
            dc->pc = dc->npc;
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 cf495bcf bellard
                cond = GET_FIELD(insn, 3, 6);
723 cf495bcf bellard
                if (cond == 0x8) {
724 cf495bcf bellard
                    gen_op_trap_T0();
725 cf495bcf bellard
                    dc->is_br = 1;
726 cf495bcf bellard
                    goto jmp_insn;
727 cf495bcf bellard
                } else {
728 e80cfcfc bellard
                    gen_cond(cond);
729 cf495bcf bellard
                    gen_op_trapcc_T0();
730 cf495bcf bellard
                }
731 cf495bcf bellard
            } else if (xop == 0x28) {
732 cf495bcf bellard
                rs1 = GET_FIELD(insn, 13, 17);
733 cf495bcf bellard
                switch(rs1) {
734 cf495bcf bellard
                case 0: /* rdy */
735 cf495bcf bellard
                    gen_op_rdy();
736 cf495bcf bellard
                    gen_movl_T0_reg(rd);
737 cf495bcf bellard
                    break;
738 e8af50a3 bellard
                case 15: /* stbar */
739 e8af50a3 bellard
                    break; /* no effect? */
740 cf495bcf bellard
                default:
741 cf495bcf bellard
                    goto illegal_insn;
742 cf495bcf bellard
                }
743 e8af50a3 bellard
#if !defined(CONFIG_USER_ONLY)
744 e8af50a3 bellard
            } else if (xop == 0x29) {
745 e8af50a3 bellard
                if (!supervisor(dc))
746 e8af50a3 bellard
                    goto priv_insn;
747 e8af50a3 bellard
                gen_op_rdpsr();
748 e8af50a3 bellard
                gen_movl_T0_reg(rd);
749 e8af50a3 bellard
                break;
750 e8af50a3 bellard
            } else if (xop == 0x2a) {
751 e8af50a3 bellard
                if (!supervisor(dc))
752 e8af50a3 bellard
                    goto priv_insn;
753 e8af50a3 bellard
                gen_op_rdwim();
754 e8af50a3 bellard
                gen_movl_T0_reg(rd);
755 e8af50a3 bellard
                break;
756 e8af50a3 bellard
            } else if (xop == 0x2b) {
757 e8af50a3 bellard
                if (!supervisor(dc))
758 e8af50a3 bellard
                    goto priv_insn;
759 e8af50a3 bellard
                gen_op_rdtbr();
760 e8af50a3 bellard
                gen_movl_T0_reg(rd);
761 e8af50a3 bellard
                break;
762 e8af50a3 bellard
#endif
763 e80cfcfc bellard
            } else if (xop == 0x34) {        /* FPU Operations */
764 e80cfcfc bellard
#if !defined(CONFIG_USER_ONLY)
765 e80cfcfc bellard
                gen_op_trap_ifnofpu();
766 e80cfcfc bellard
#endif
767 e8af50a3 bellard
                rs1 = GET_FIELD(insn, 13, 17);
768 e8af50a3 bellard
                rs2 = GET_FIELD(insn, 27, 31);
769 e8af50a3 bellard
                xop = GET_FIELD(insn, 18, 26);
770 e8af50a3 bellard
                switch (xop) {
771 e8af50a3 bellard
                    case 0x1: /* fmovs */
772 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs2);
773 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
774 e8af50a3 bellard
                        break;
775 e8af50a3 bellard
                    case 0x5: /* fnegs */
776 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
777 e8af50a3 bellard
                        gen_op_fnegs();
778 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
779 e8af50a3 bellard
                        break;
780 e8af50a3 bellard
                    case 0x9: /* fabss */
781 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
782 e8af50a3 bellard
                        gen_op_fabss();
783 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
784 e8af50a3 bellard
                        break;
785 e8af50a3 bellard
                    case 0x29: /* fsqrts */
786 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
787 e8af50a3 bellard
                        gen_op_fsqrts();
788 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
789 e8af50a3 bellard
                        break;
790 e8af50a3 bellard
                    case 0x2a: /* fsqrtd */
791 e8af50a3 bellard
                        gen_op_load_fpr_DT1(rs2);
792 e8af50a3 bellard
                        gen_op_fsqrtd();
793 e8af50a3 bellard
                        gen_op_store_DT0_fpr(rd);
794 e8af50a3 bellard
                        break;
795 e80cfcfc bellard
                    case 0x2b: /* fsqrtq */
796 e80cfcfc bellard
                        goto nfpu_insn;
797 e8af50a3 bellard
                    case 0x41:
798 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs1);
799 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
800 e8af50a3 bellard
                        gen_op_fadds();
801 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
802 e8af50a3 bellard
                        break;
803 e8af50a3 bellard
                    case 0x42:
804 e8af50a3 bellard
                        gen_op_load_fpr_DT0(rs1);
805 e8af50a3 bellard
                        gen_op_load_fpr_DT1(rs2);
806 e8af50a3 bellard
                        gen_op_faddd();
807 e8af50a3 bellard
                        gen_op_store_DT0_fpr(rd);
808 e8af50a3 bellard
                        break;
809 e80cfcfc bellard
                    case 0x43: /* faddq */
810 e80cfcfc bellard
                        goto nfpu_insn;
811 e8af50a3 bellard
                    case 0x45:
812 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs1);
813 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
814 e8af50a3 bellard
                        gen_op_fsubs();
815 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
816 e8af50a3 bellard
                        break;
817 e8af50a3 bellard
                    case 0x46:
818 e8af50a3 bellard
                        gen_op_load_fpr_DT0(rs1);
819 e8af50a3 bellard
                        gen_op_load_fpr_DT1(rs2);
820 e8af50a3 bellard
                        gen_op_fsubd();
821 e8af50a3 bellard
                        gen_op_store_DT0_fpr(rd);
822 e8af50a3 bellard
                        break;
823 e80cfcfc bellard
                    case 0x47: /* fsubq */
824 e80cfcfc bellard
                        goto nfpu_insn;
825 e8af50a3 bellard
                    case 0x49:
826 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs1);
827 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
828 e8af50a3 bellard
                        gen_op_fmuls();
829 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
830 e8af50a3 bellard
                        break;
831 e8af50a3 bellard
                    case 0x4a:
832 e8af50a3 bellard
                        gen_op_load_fpr_DT0(rs1);
833 e8af50a3 bellard
                        gen_op_load_fpr_DT1(rs2);
834 e8af50a3 bellard
                        gen_op_fmuld();
835 e8af50a3 bellard
                        gen_op_store_DT0_fpr(rd);
836 e8af50a3 bellard
                        break;
837 e80cfcfc bellard
                    case 0x4b: /* fmulq */
838 e80cfcfc bellard
                        goto nfpu_insn;
839 e8af50a3 bellard
                    case 0x4d:
840 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs1);
841 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
842 e8af50a3 bellard
                        gen_op_fdivs();
843 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
844 e8af50a3 bellard
                        break;
845 e8af50a3 bellard
                    case 0x4e:
846 e8af50a3 bellard
                        gen_op_load_fpr_DT0(rs1);
847 e8af50a3 bellard
                        gen_op_load_fpr_DT1(rs2);
848 e8af50a3 bellard
                        gen_op_fdivd();
849 e8af50a3 bellard
                        gen_op_store_DT0_fpr(rd);
850 e8af50a3 bellard
                        break;
851 e80cfcfc bellard
                    case 0x4f: /* fdivq */
852 e80cfcfc bellard
                        goto nfpu_insn;
853 e8af50a3 bellard
                    case 0x69:
854 e8af50a3 bellard
                        gen_op_load_fpr_FT0(rs1);
855 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
856 e8af50a3 bellard
                        gen_op_fsmuld();
857 e8af50a3 bellard
                        gen_op_store_DT0_fpr(rd);
858 e8af50a3 bellard
                        break;
859 e80cfcfc bellard
                    case 0x6e: /* fdmulq */
860 e80cfcfc bellard
                        goto nfpu_insn;
861 e8af50a3 bellard
                    case 0xc4:
862 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
863 e8af50a3 bellard
                        gen_op_fitos();
864 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
865 e8af50a3 bellard
                        break;
866 e8af50a3 bellard
                    case 0xc6:
867 e8af50a3 bellard
                        gen_op_load_fpr_DT1(rs2);
868 e8af50a3 bellard
                        gen_op_fdtos();
869 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
870 e8af50a3 bellard
                        break;
871 e80cfcfc bellard
                    case 0xc7: /* fqtos */
872 e80cfcfc bellard
                        goto nfpu_insn;
873 e8af50a3 bellard
                    case 0xc8:
874 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
875 e8af50a3 bellard
                        gen_op_fitod();
876 e8af50a3 bellard
                        gen_op_store_DT0_fpr(rd);
877 e8af50a3 bellard
                        break;
878 e8af50a3 bellard
                    case 0xc9:
879 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
880 e8af50a3 bellard
                        gen_op_fstod();
881 e8af50a3 bellard
                        gen_op_store_DT0_fpr(rd);
882 e8af50a3 bellard
                        break;
883 e80cfcfc bellard
                    case 0xcb: /* fqtod */
884 e80cfcfc bellard
                        goto nfpu_insn;
885 e80cfcfc bellard
                    case 0xcc: /* fitoq */
886 e80cfcfc bellard
                        goto nfpu_insn;
887 e80cfcfc bellard
                    case 0xcd: /* fstoq */
888 e80cfcfc bellard
                        goto nfpu_insn;
889 e80cfcfc bellard
                    case 0xce: /* fdtoq */
890 e80cfcfc bellard
                        goto nfpu_insn;
891 e8af50a3 bellard
                    case 0xd1:
892 e8af50a3 bellard
                        gen_op_load_fpr_FT1(rs2);
893 e8af50a3 bellard
                        gen_op_fstoi();
894 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
895 e8af50a3 bellard
                        break;
896 e8af50a3 bellard
                    case 0xd2:
897 e8af50a3 bellard
                        gen_op_load_fpr_DT1(rs2);
898 e8af50a3 bellard
                        gen_op_fdtoi();
899 e8af50a3 bellard
                        gen_op_store_FT0_fpr(rd);
900 e8af50a3 bellard
                        break;
901 e80cfcfc bellard
                    case 0xd3: /* fqtoi */
902 e80cfcfc bellard
                        goto nfpu_insn;
903 e8af50a3 bellard
                    default:
904 e8af50a3 bellard
                        goto illegal_insn;
905 e8af50a3 bellard
                }
906 e80cfcfc bellard
            } else if (xop == 0x35) {        /* FPU Operations */
907 e80cfcfc bellard
#if !defined(CONFIG_USER_ONLY)
908 e80cfcfc bellard
                gen_op_trap_ifnofpu();
909 e80cfcfc bellard
#endif
910 cf495bcf bellard
                rs1 = GET_FIELD(insn, 13, 17);
911 e80cfcfc bellard
                rs2 = GET_FIELD(insn, 27, 31);
912 e80cfcfc bellard
                xop = GET_FIELD(insn, 18, 26);
913 e80cfcfc bellard
                switch (xop) {
914 e80cfcfc bellard
                    case 0x51:
915 e80cfcfc bellard
                        gen_op_load_fpr_FT0(rs1);
916 e80cfcfc bellard
                        gen_op_load_fpr_FT1(rs2);
917 e80cfcfc bellard
                        gen_op_fcmps();
918 e80cfcfc bellard
                        break;
919 e80cfcfc bellard
                    case 0x52:
920 e80cfcfc bellard
                        gen_op_load_fpr_DT0(rs1);
921 e80cfcfc bellard
                        gen_op_load_fpr_DT1(rs2);
922 e80cfcfc bellard
                        gen_op_fcmpd();
923 e80cfcfc bellard
                        break;
924 e80cfcfc bellard
                    case 0x53: /* fcmpq */
925 e80cfcfc bellard
                        goto nfpu_insn;
926 e80cfcfc bellard
                    case 0x55: /* fcmpes */
927 e80cfcfc bellard
                        gen_op_load_fpr_FT0(rs1);
928 e80cfcfc bellard
                        gen_op_load_fpr_FT1(rs2);
929 e80cfcfc bellard
                        gen_op_fcmps(); /* XXX should trap if qNaN or sNaN  */
930 e80cfcfc bellard
                        break;
931 e80cfcfc bellard
                    case 0x56: /* fcmped */
932 e80cfcfc bellard
                        gen_op_load_fpr_DT0(rs1);
933 e80cfcfc bellard
                        gen_op_load_fpr_DT1(rs2);
934 e80cfcfc bellard
                        gen_op_fcmpd(); /* XXX should trap if qNaN or sNaN  */
935 e80cfcfc bellard
                        break;
936 e80cfcfc bellard
                    case 0x57: /* fcmpeq */
937 e80cfcfc bellard
                        goto nfpu_insn;
938 e80cfcfc bellard
                    default:
939 e80cfcfc bellard
                        goto illegal_insn;
940 e80cfcfc bellard
                }
941 e80cfcfc bellard
#if defined(OPTIM)
942 e80cfcfc bellard
            } else if (xop == 0x2) {
943 e80cfcfc bellard
                // clr/mov shortcut
944 e80cfcfc bellard
945 e80cfcfc bellard
                rs1 = GET_FIELD(insn, 13, 17);
946 e80cfcfc bellard
                if (rs1 == 0) {
947 e80cfcfc bellard
                    // or %g0, x, y -> mov T1, x; mov y, T1
948 e80cfcfc bellard
                    if (IS_IMM) {        /* immediate */
949 e80cfcfc bellard
                        rs2 = GET_FIELDs(insn, 19, 31);
950 e80cfcfc bellard
                        gen_movl_imm_T1(rs2);
951 e80cfcfc bellard
                    } else {                /* register */
952 e80cfcfc bellard
                        rs2 = GET_FIELD(insn, 27, 31);
953 e80cfcfc bellard
                        gen_movl_reg_T1(rs2);
954 e80cfcfc bellard
                    }
955 e80cfcfc bellard
                    gen_movl_T1_reg(rd);
956 e80cfcfc bellard
                } else {
957 e80cfcfc bellard
                    gen_movl_reg_T0(rs1);
958 e80cfcfc bellard
                    if (IS_IMM) {        /* immediate */
959 e80cfcfc bellard
                        // or x, #0, y -> mov T1, x; mov y, T1
960 e80cfcfc bellard
                        rs2 = GET_FIELDs(insn, 19, 31);
961 e80cfcfc bellard
                        if (rs2 != 0) {
962 e80cfcfc bellard
                            gen_movl_imm_T1(rs2);
963 e80cfcfc bellard
                            gen_op_or_T1_T0();
964 e80cfcfc bellard
                        }
965 e80cfcfc bellard
                    } else {                /* register */
966 e80cfcfc bellard
                        // or x, %g0, y -> mov T1, x; mov y, T1
967 e80cfcfc bellard
                        rs2 = GET_FIELD(insn, 27, 31);
968 e80cfcfc bellard
                        if (rs2 != 0) {
969 e80cfcfc bellard
                            gen_movl_reg_T1(rs2);
970 e80cfcfc bellard
                            gen_op_or_T1_T0();
971 e80cfcfc bellard
                        }
972 e80cfcfc bellard
                    }
973 e80cfcfc bellard
                    gen_movl_T0_reg(rd);
974 e80cfcfc bellard
                }
975 e80cfcfc bellard
#endif
976 e80cfcfc bellard
            } else if (xop < 0x38) {
977 e80cfcfc bellard
                rs1 = GET_FIELD(insn, 13, 17);
978 e80cfcfc bellard
                gen_movl_reg_T0(rs1);
979 e80cfcfc bellard
                if (IS_IMM) {        /* immediate */
980 cf495bcf bellard
                    rs2 = GET_FIELDs(insn, 19, 31);
981 cf495bcf bellard
                    gen_movl_imm_T1(rs2);
982 cf495bcf bellard
                } else {                /* register */
983 cf495bcf bellard
                    rs2 = GET_FIELD(insn, 27, 31);
984 cf495bcf bellard
                    gen_movl_reg_T1(rs2);
985 cf495bcf bellard
                }
986 cf495bcf bellard
                if (xop < 0x20) {
987 cf495bcf bellard
                    switch (xop & ~0x10) {
988 cf495bcf bellard
                    case 0x0:
989 cf495bcf bellard
                        if (xop & 0x10)
990 cf495bcf bellard
                            gen_op_add_T1_T0_cc();
991 cf495bcf bellard
                        else
992 cf495bcf bellard
                            gen_op_add_T1_T0();
993 cf495bcf bellard
                        break;
994 cf495bcf bellard
                    case 0x1:
995 cf495bcf bellard
                        gen_op_and_T1_T0();
996 cf495bcf bellard
                        if (xop & 0x10)
997 cf495bcf bellard
                            gen_op_logic_T0_cc();
998 cf495bcf bellard
                        break;
999 cf495bcf bellard
                    case 0x2:
1000 e80cfcfc bellard
                        gen_op_or_T1_T0();
1001 e80cfcfc bellard
                        if (xop & 0x10)
1002 e80cfcfc bellard
                            gen_op_logic_T0_cc();
1003 e80cfcfc bellard
                        break;
1004 cf495bcf bellard
                    case 0x3:
1005 cf495bcf bellard
                        gen_op_xor_T1_T0();
1006 cf495bcf bellard
                        if (xop & 0x10)
1007 cf495bcf bellard
                            gen_op_logic_T0_cc();
1008 cf495bcf bellard
                        break;
1009 cf495bcf bellard
                    case 0x4:
1010 cf495bcf bellard
                        if (xop & 0x10)
1011 cf495bcf bellard
                            gen_op_sub_T1_T0_cc();
1012 cf495bcf bellard
                        else
1013 cf495bcf bellard
                            gen_op_sub_T1_T0();
1014 cf495bcf bellard
                        break;
1015 cf495bcf bellard
                    case 0x5:
1016 cf495bcf bellard
                        gen_op_andn_T1_T0();
1017 cf495bcf bellard
                        if (xop & 0x10)
1018 cf495bcf bellard
                            gen_op_logic_T0_cc();
1019 cf495bcf bellard
                        break;
1020 cf495bcf bellard
                    case 0x6:
1021 cf495bcf bellard
                        gen_op_orn_T1_T0();
1022 cf495bcf bellard
                        if (xop & 0x10)
1023 cf495bcf bellard
                            gen_op_logic_T0_cc();
1024 cf495bcf bellard
                        break;
1025 cf495bcf bellard
                    case 0x7:
1026 cf495bcf bellard
                        gen_op_xnor_T1_T0();
1027 cf495bcf bellard
                        if (xop & 0x10)
1028 cf495bcf bellard
                            gen_op_logic_T0_cc();
1029 cf495bcf bellard
                        break;
1030 cf495bcf bellard
                    case 0x8:
1031 cf495bcf bellard
                        gen_op_addx_T1_T0();
1032 cf495bcf bellard
                        if (xop & 0x10)
1033 cf495bcf bellard
                            gen_op_set_flags();
1034 cf495bcf bellard
                        break;
1035 cf495bcf bellard
                    case 0xa:
1036 cf495bcf bellard
                        gen_op_umul_T1_T0();
1037 cf495bcf bellard
                        if (xop & 0x10)
1038 cf495bcf bellard
                            gen_op_logic_T0_cc();
1039 cf495bcf bellard
                        break;
1040 cf495bcf bellard
                    case 0xb:
1041 cf495bcf bellard
                        gen_op_smul_T1_T0();
1042 cf495bcf bellard
                        if (xop & 0x10)
1043 cf495bcf bellard
                            gen_op_logic_T0_cc();
1044 cf495bcf bellard
                        break;
1045 cf495bcf bellard
                    case 0xc:
1046 cf495bcf bellard
                        gen_op_subx_T1_T0();
1047 cf495bcf bellard
                        if (xop & 0x10)
1048 cf495bcf bellard
                            gen_op_set_flags();
1049 cf495bcf bellard
                        break;
1050 cf495bcf bellard
                    case 0xe:
1051 cf495bcf bellard
                        gen_op_udiv_T1_T0();
1052 cf495bcf bellard
                        if (xop & 0x10)
1053 cf495bcf bellard
                            gen_op_div_cc();
1054 cf495bcf bellard
                        break;
1055 cf495bcf bellard
                    case 0xf:
1056 cf495bcf bellard
                        gen_op_sdiv_T1_T0();
1057 cf495bcf bellard
                        if (xop & 0x10)
1058 cf495bcf bellard
                            gen_op_div_cc();
1059 cf495bcf bellard
                        break;
1060 cf495bcf bellard
                    default:
1061 cf495bcf bellard
                        goto illegal_insn;
1062 cf495bcf bellard
                    }
1063 e80cfcfc bellard
                    gen_movl_T0_reg(rd);
1064 cf495bcf bellard
                } else {
1065 cf495bcf bellard
                    switch (xop) {
1066 e80cfcfc bellard
                    case 0x20: /* taddcc */
1067 e80cfcfc bellard
                    case 0x21: /* tsubcc */
1068 e80cfcfc bellard
                    case 0x22: /* taddcctv */
1069 e80cfcfc bellard
                    case 0x23: /* tsubcctv */
1070 e80cfcfc bellard
                        goto illegal_insn;
1071 cf495bcf bellard
                    case 0x24: /* mulscc */
1072 cf495bcf bellard
                        gen_op_mulscc_T1_T0();
1073 cf495bcf bellard
                        gen_movl_T0_reg(rd);
1074 cf495bcf bellard
                        break;
1075 cf495bcf bellard
                    case 0x25:        /* SLL */
1076 cf495bcf bellard
                        gen_op_sll();
1077 cf495bcf bellard
                        gen_movl_T0_reg(rd);
1078 cf495bcf bellard
                        break;
1079 cf495bcf bellard
                    case 0x26:
1080 cf495bcf bellard
                        gen_op_srl();
1081 cf495bcf bellard
                        gen_movl_T0_reg(rd);
1082 cf495bcf bellard
                        break;
1083 cf495bcf bellard
                    case 0x27:
1084 cf495bcf bellard
                        gen_op_sra();
1085 cf495bcf bellard
                        gen_movl_T0_reg(rd);
1086 cf495bcf bellard
                        break;
1087 cf495bcf bellard
                    case 0x30:
1088 cf495bcf bellard
                        {
1089 cf495bcf bellard
                            gen_op_xor_T1_T0();
1090 cf495bcf bellard
                            switch(rd) {
1091 cf495bcf bellard
                            case 0:
1092 cf495bcf bellard
                                gen_op_wry();
1093 cf495bcf bellard
                                break;
1094 cf495bcf bellard
                            default:
1095 cf495bcf bellard
                                goto illegal_insn;
1096 cf495bcf bellard
                            }
1097 cf495bcf bellard
                        }
1098 cf495bcf bellard
                        break;
1099 e8af50a3 bellard
#if !defined(CONFIG_USER_ONLY)
1100 e8af50a3 bellard
                    case 0x31:
1101 e8af50a3 bellard
                        {
1102 e8af50a3 bellard
                            if (!supervisor(dc))
1103 e8af50a3 bellard
                                goto priv_insn;
1104 e8af50a3 bellard
                            gen_op_xor_T1_T0();
1105 e8af50a3 bellard
                            gen_op_wrpsr();
1106 e8af50a3 bellard
                        }
1107 e8af50a3 bellard
                        break;
1108 e8af50a3 bellard
                    case 0x32:
1109 e8af50a3 bellard
                        {
1110 e8af50a3 bellard
                            if (!supervisor(dc))
1111 e8af50a3 bellard
                                goto priv_insn;
1112 e8af50a3 bellard
                            gen_op_xor_T1_T0();
1113 e8af50a3 bellard
                            gen_op_wrwim();
1114 e8af50a3 bellard
                        }
1115 e8af50a3 bellard
                        break;
1116 e8af50a3 bellard
                    case 0x33:
1117 e8af50a3 bellard
                        {
1118 e8af50a3 bellard
                            if (!supervisor(dc))
1119 e8af50a3 bellard
                                goto priv_insn;
1120 e8af50a3 bellard
                            gen_op_xor_T1_T0();
1121 e8af50a3 bellard
                            gen_op_wrtbr();
1122 e8af50a3 bellard
                        }
1123 e8af50a3 bellard
                        break;
1124 e8af50a3 bellard
#endif
1125 e80cfcfc bellard
                    default:
1126 e80cfcfc bellard
                        goto illegal_insn;
1127 e80cfcfc bellard
                    }
1128 e80cfcfc bellard
                }
1129 e80cfcfc bellard
            } else {
1130 e80cfcfc bellard
                rs1 = GET_FIELD(insn, 13, 17);
1131 e80cfcfc bellard
                gen_movl_reg_T0(rs1);
1132 e80cfcfc bellard
                if (IS_IMM) {        /* immediate */
1133 e80cfcfc bellard
                    rs2 = GET_FIELDs(insn, 19, 31);
1134 e80cfcfc bellard
#if defined(OPTIM)
1135 e80cfcfc bellard
                    if (rs2) {
1136 e8af50a3 bellard
#endif
1137 e80cfcfc bellard
                        gen_movl_imm_T1(rs2);
1138 e80cfcfc bellard
                        gen_op_add_T1_T0();
1139 e80cfcfc bellard
#if defined(OPTIM)
1140 e80cfcfc bellard
                    }
1141 e8af50a3 bellard
#endif
1142 e80cfcfc bellard
                } else {                /* register */
1143 e80cfcfc bellard
                    rs2 = GET_FIELD(insn, 27, 31);
1144 e80cfcfc bellard
#if defined(OPTIM)
1145 e80cfcfc bellard
                    if (rs2) {
1146 e80cfcfc bellard
#endif
1147 e80cfcfc bellard
                        gen_movl_reg_T1(rs2);
1148 e80cfcfc bellard
                        gen_op_add_T1_T0();
1149 e80cfcfc bellard
#if defined(OPTIM)
1150 e80cfcfc bellard
                    }
1151 e8af50a3 bellard
#endif
1152 cf495bcf bellard
                }
1153 e80cfcfc bellard
                switch (xop) {
1154 e80cfcfc bellard
                case 0x38:        /* jmpl */
1155 e80cfcfc bellard
                    {
1156 e80cfcfc bellard
                        gen_op_movl_npc_T0();
1157 e80cfcfc bellard
                        if (rd != 0) {
1158 e80cfcfc bellard
                            gen_op_movl_T0_im((long) (dc->pc));
1159 e80cfcfc bellard
                            gen_movl_T0_reg(rd);
1160 e80cfcfc bellard
                        }
1161 e80cfcfc bellard
                        dc->pc = dc->npc;
1162 e80cfcfc bellard
                        dc->npc = DYNAMIC_PC;
1163 e80cfcfc bellard
                    }
1164 e80cfcfc bellard
                    goto jmp_insn;
1165 e80cfcfc bellard
#if !defined(CONFIG_USER_ONLY)
1166 e80cfcfc bellard
                case 0x39:        /* rett */
1167 e80cfcfc bellard
                    {
1168 e80cfcfc bellard
                        if (!supervisor(dc))
1169 e80cfcfc bellard
                            goto priv_insn;
1170 e80cfcfc bellard
                        gen_op_movl_npc_T0();
1171 e80cfcfc bellard
                        gen_op_rett();
1172 e80cfcfc bellard
                    }
1173 e80cfcfc bellard
                    break;
1174 e80cfcfc bellard
#endif
1175 e80cfcfc bellard
                case 0x3b: /* flush */
1176 e80cfcfc bellard
                    gen_op_flush_T0();
1177 e80cfcfc bellard
                    break;
1178 e80cfcfc bellard
                case 0x3c:        /* save */
1179 e80cfcfc bellard
                    save_state(dc);
1180 e80cfcfc bellard
                    gen_op_save();
1181 e80cfcfc bellard
                    gen_movl_T0_reg(rd);
1182 e80cfcfc bellard
                    break;
1183 e80cfcfc bellard
                case 0x3d:        /* restore */
1184 e80cfcfc bellard
                    save_state(dc);
1185 e80cfcfc bellard
                    gen_op_restore();
1186 e80cfcfc bellard
                    gen_movl_T0_reg(rd);
1187 e80cfcfc bellard
                    break;
1188 e80cfcfc bellard
                default:
1189 e80cfcfc bellard
                    goto illegal_insn;
1190 e80cfcfc bellard
                }
1191 cf495bcf bellard
            }
1192 cf495bcf bellard
            break;
1193 cf495bcf bellard
        }
1194 cf495bcf bellard
    case 3:                        /* load/store instructions */
1195 cf495bcf bellard
        {
1196 cf495bcf bellard
            unsigned int xop = GET_FIELD(insn, 7, 12);
1197 cf495bcf bellard
            rs1 = GET_FIELD(insn, 13, 17);
1198 cf495bcf bellard
            gen_movl_reg_T0(rs1);
1199 cf495bcf bellard
            if (IS_IMM) {        /* immediate */
1200 cf495bcf bellard
                rs2 = GET_FIELDs(insn, 19, 31);
1201 e80cfcfc bellard
#if defined(OPTIM)
1202 e8af50a3 bellard
                if (rs2 != 0) {
1203 e80cfcfc bellard
#endif
1204 e8af50a3 bellard
                    gen_movl_imm_T1(rs2);
1205 e8af50a3 bellard
                    gen_op_add_T1_T0();
1206 e80cfcfc bellard
#if defined(OPTIM)
1207 e8af50a3 bellard
                }
1208 e80cfcfc bellard
#endif
1209 cf495bcf bellard
            } else {                /* register */
1210 cf495bcf bellard
                rs2 = GET_FIELD(insn, 27, 31);
1211 e80cfcfc bellard
#if defined(OPTIM)
1212 e80cfcfc bellard
                if (rs2 != 0) {
1213 e80cfcfc bellard
#endif
1214 e80cfcfc bellard
                    gen_movl_reg_T1(rs2);
1215 e80cfcfc bellard
                    gen_op_add_T1_T0();
1216 e80cfcfc bellard
#if defined(OPTIM)
1217 e80cfcfc bellard
                }
1218 e80cfcfc bellard
#endif
1219 cf495bcf bellard
            }
1220 e8af50a3 bellard
            if (xop < 4 || (xop > 7 && xop < 0x14) || \
1221 e8af50a3 bellard
                    (xop > 0x17 && xop < 0x20)) {
1222 cf495bcf bellard
                switch (xop) {
1223 cf495bcf bellard
                case 0x0:        /* load word */
1224 e8af50a3 bellard
                    gen_op_ldst(ld);
1225 cf495bcf bellard
                    break;
1226 cf495bcf bellard
                case 0x1:        /* load unsigned byte */
1227 e8af50a3 bellard
                    gen_op_ldst(ldub);
1228 cf495bcf bellard
                    break;
1229 cf495bcf bellard
                case 0x2:        /* load unsigned halfword */
1230 e8af50a3 bellard
                    gen_op_ldst(lduh);
1231 cf495bcf bellard
                    break;
1232 cf495bcf bellard
                case 0x3:        /* load double word */
1233 e8af50a3 bellard
                    gen_op_ldst(ldd);
1234 cf495bcf bellard
                    gen_movl_T0_reg(rd + 1);
1235 cf495bcf bellard
                    break;
1236 cf495bcf bellard
                case 0x9:        /* load signed byte */
1237 e8af50a3 bellard
                    gen_op_ldst(ldsb);
1238 cf495bcf bellard
                    break;
1239 cf495bcf bellard
                case 0xa:        /* load signed halfword */
1240 e8af50a3 bellard
                    gen_op_ldst(ldsh);
1241 cf495bcf bellard
                    break;
1242 cf495bcf bellard
                case 0xd:        /* ldstub -- XXX: should be atomically */
1243 e8af50a3 bellard
                    gen_op_ldst(ldstub);
1244 cf495bcf bellard
                    break;
1245 cf495bcf bellard
                case 0x0f:        /* swap register with memory. Also atomically */
1246 e80cfcfc bellard
                    gen_movl_reg_T1(rd);
1247 e8af50a3 bellard
                    gen_op_ldst(swap);
1248 e8af50a3 bellard
                    break;
1249 e80cfcfc bellard
#if !defined(CONFIG_USER_ONLY)
1250 e8af50a3 bellard
                case 0x10:        /* load word alternate */
1251 e8af50a3 bellard
                    if (!supervisor(dc))
1252 e8af50a3 bellard
                        goto priv_insn;
1253 e8af50a3 bellard
                    gen_op_lda(insn, 1, 4, 0);
1254 e8af50a3 bellard
                    break;
1255 e8af50a3 bellard
                case 0x11:        /* load unsigned byte alternate */
1256 e8af50a3 bellard
                    if (!supervisor(dc))
1257 e8af50a3 bellard
                        goto priv_insn;
1258 e8af50a3 bellard
                    gen_op_lduba(insn, 1, 1, 0);
1259 e8af50a3 bellard
                    break;
1260 e8af50a3 bellard
                case 0x12:        /* load unsigned halfword alternate */
1261 e8af50a3 bellard
                    if (!supervisor(dc))
1262 e8af50a3 bellard
                        goto priv_insn;
1263 e8af50a3 bellard
                    gen_op_lduha(insn, 1, 2, 0);
1264 e8af50a3 bellard
                    break;
1265 e8af50a3 bellard
                case 0x13:        /* load double word alternate */
1266 e8af50a3 bellard
                    if (!supervisor(dc))
1267 e8af50a3 bellard
                        goto priv_insn;
1268 e8af50a3 bellard
                    gen_op_ldda(insn, 1, 8, 0);
1269 e8af50a3 bellard
                    gen_movl_T0_reg(rd + 1);
1270 e8af50a3 bellard
                    break;
1271 e8af50a3 bellard
                case 0x19:        /* load signed byte alternate */
1272 e8af50a3 bellard
                    if (!supervisor(dc))
1273 e8af50a3 bellard
                        goto priv_insn;
1274 e8af50a3 bellard
                    gen_op_ldsba(insn, 1, 1, 1);
1275 e8af50a3 bellard
                    break;
1276 e8af50a3 bellard
                case 0x1a:        /* load signed halfword alternate */
1277 e8af50a3 bellard
                    if (!supervisor(dc))
1278 e8af50a3 bellard
                        goto priv_insn;
1279 e8af50a3 bellard
                    gen_op_ldsha(insn, 1, 2 ,1);
1280 e8af50a3 bellard
                    break;
1281 e8af50a3 bellard
                case 0x1d:        /* ldstuba -- XXX: should be atomically */
1282 e8af50a3 bellard
                    if (!supervisor(dc))
1283 e8af50a3 bellard
                        goto priv_insn;
1284 e8af50a3 bellard
                    gen_op_ldstuba(insn, 1, 1, 0);
1285 e8af50a3 bellard
                    break;
1286 e8af50a3 bellard
                case 0x1f:        /* swap reg with alt. memory. Also atomically */
1287 e8af50a3 bellard
                    if (!supervisor(dc))
1288 e8af50a3 bellard
                        goto priv_insn;
1289 e80cfcfc bellard
                    gen_movl_reg_T1(rd);
1290 e8af50a3 bellard
                    gen_op_swapa(insn, 1, 4, 0);
1291 cf495bcf bellard
                    break;
1292 0fa85d43 bellard
                    
1293 0fa85d43 bellard
                    /* avoid warnings */
1294 0fa85d43 bellard
                    (void) &gen_op_stfa;
1295 0fa85d43 bellard
                    (void) &gen_op_stdfa;
1296 0fa85d43 bellard
                    (void) &gen_op_ldfa;
1297 0fa85d43 bellard
                    (void) &gen_op_lddfa;
1298 e80cfcfc bellard
#endif
1299 e80cfcfc bellard
                default:
1300 e80cfcfc bellard
                    goto illegal_insn;
1301 7a3f1944 bellard
                }
1302 cf495bcf bellard
                gen_movl_T1_reg(rd);
1303 e8af50a3 bellard
            } else if (xop >= 0x20 && xop < 0x24) {
1304 e80cfcfc bellard
#if !defined(CONFIG_USER_ONLY)
1305 e80cfcfc bellard
                gen_op_trap_ifnofpu();
1306 e80cfcfc bellard
#endif
1307 e8af50a3 bellard
                switch (xop) {
1308 e8af50a3 bellard
                case 0x20:        /* load fpreg */
1309 e8af50a3 bellard
                    gen_op_ldst(ldf);
1310 e8af50a3 bellard
                    gen_op_store_FT0_fpr(rd);
1311 e8af50a3 bellard
                    break;
1312 e8af50a3 bellard
                case 0x21:        /* load fsr */
1313 e8af50a3 bellard
                    gen_op_ldfsr();
1314 e80cfcfc bellard
                    gen_op_store_FT0_fpr(rd);
1315 e8af50a3 bellard
                    break;
1316 e8af50a3 bellard
                case 0x23:        /* load double fpreg */
1317 e8af50a3 bellard
                    gen_op_ldst(lddf);
1318 e8af50a3 bellard
                    gen_op_store_DT0_fpr(rd);
1319 e8af50a3 bellard
                    break;
1320 e80cfcfc bellard
                default:
1321 e80cfcfc bellard
                    goto illegal_insn;
1322 e8af50a3 bellard
                }
1323 e8af50a3 bellard
            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18)) {
1324 cf495bcf bellard
                gen_movl_reg_T1(rd);
1325 cf495bcf bellard
                switch (xop) {
1326 cf495bcf bellard
                case 0x4:
1327 e8af50a3 bellard
                    gen_op_ldst(st);
1328 cf495bcf bellard
                    break;
1329 cf495bcf bellard
                case 0x5:
1330 e8af50a3 bellard
                    gen_op_ldst(stb);
1331 cf495bcf bellard
                    break;
1332 cf495bcf bellard
                case 0x6:
1333 e8af50a3 bellard
                    gen_op_ldst(sth);
1334 cf495bcf bellard
                    break;
1335 cf495bcf bellard
                case 0x7:
1336 72cbca10 bellard
                    flush_T2(dc);
1337 cf495bcf bellard
                    gen_movl_reg_T2(rd + 1);
1338 e8af50a3 bellard
                    gen_op_ldst(std);
1339 e8af50a3 bellard
                    break;
1340 e80cfcfc bellard
#if !defined(CONFIG_USER_ONLY)
1341 e8af50a3 bellard
                case 0x14:
1342 e8af50a3 bellard
                    if (!supervisor(dc))
1343 e8af50a3 bellard
                        goto priv_insn;
1344 e8af50a3 bellard
                    gen_op_sta(insn, 0, 4, 0);
1345 e8af50a3 bellard
                    break;
1346 e8af50a3 bellard
                case 0x15:
1347 e8af50a3 bellard
                    if (!supervisor(dc))
1348 e8af50a3 bellard
                        goto priv_insn;
1349 e8af50a3 bellard
                    gen_op_stba(insn, 0, 1, 0);
1350 e8af50a3 bellard
                    break;
1351 e8af50a3 bellard
                case 0x16:
1352 e8af50a3 bellard
                    if (!supervisor(dc))
1353 e8af50a3 bellard
                        goto priv_insn;
1354 e8af50a3 bellard
                    gen_op_stha(insn, 0, 2, 0);
1355 e8af50a3 bellard
                    break;
1356 e8af50a3 bellard
                case 0x17:
1357 e8af50a3 bellard
                    if (!supervisor(dc))
1358 e8af50a3 bellard
                        goto priv_insn;
1359 e8af50a3 bellard
                    flush_T2(dc);
1360 e8af50a3 bellard
                    gen_movl_reg_T2(rd + 1);
1361 e8af50a3 bellard
                    gen_op_stda(insn, 0, 8, 0);
1362 cf495bcf bellard
                    break;
1363 e80cfcfc bellard
#endif
1364 e80cfcfc bellard
                default:
1365 e80cfcfc bellard
                    goto illegal_insn;
1366 7a3f1944 bellard
                }
1367 e8af50a3 bellard
            } else if (xop > 0x23 && xop < 0x28) {
1368 e80cfcfc bellard
#if !defined(CONFIG_USER_ONLY)
1369 e80cfcfc bellard
                gen_op_trap_ifnofpu();
1370 e80cfcfc bellard
#endif
1371 e8af50a3 bellard
                switch (xop) {
1372 e8af50a3 bellard
                case 0x24:
1373 e8af50a3 bellard
                    gen_op_load_fpr_FT0(rd);
1374 e8af50a3 bellard
                    gen_op_ldst(stf);
1375 e8af50a3 bellard
                    break;
1376 e8af50a3 bellard
                case 0x25:
1377 e80cfcfc bellard
                    gen_op_load_fpr_FT0(rd);
1378 e8af50a3 bellard
                    gen_op_stfsr();
1379 e8af50a3 bellard
                    break;
1380 e8af50a3 bellard
                case 0x27:
1381 e8af50a3 bellard
                    gen_op_load_fpr_DT0(rd);
1382 e8af50a3 bellard
                    gen_op_ldst(stdf);
1383 e8af50a3 bellard
                    break;
1384 e80cfcfc bellard
                case 0x26: /* stdfq */
1385 e80cfcfc bellard
                default:
1386 e80cfcfc bellard
                    goto illegal_insn;
1387 e8af50a3 bellard
                }
1388 e8af50a3 bellard
            } else if (xop > 0x33 && xop < 0x38) {
1389 e8af50a3 bellard
                /* Co-processor */
1390 e80cfcfc bellard
                goto illegal_insn;
1391 e8af50a3 bellard
            }
1392 e80cfcfc bellard
            else
1393 e80cfcfc bellard
                goto illegal_insn;
1394 7a3f1944 bellard
        }
1395 cf495bcf bellard
    }
1396 cf495bcf bellard
    /* default case for non jump instructions */
1397 72cbca10 bellard
    if (dc->npc == DYNAMIC_PC) {
1398 72cbca10 bellard
        dc->pc = DYNAMIC_PC;
1399 72cbca10 bellard
        gen_op_next_insn();
1400 72cbca10 bellard
    } else if (dc->npc == JUMP_PC) {
1401 72cbca10 bellard
        /* we can do a static jump */
1402 72cbca10 bellard
        gen_op_branch2((long)dc->tb, dc->jump_pc[0], dc->jump_pc[1]);
1403 72cbca10 bellard
        dc->is_br = 1;
1404 72cbca10 bellard
    } else {
1405 cf495bcf bellard
        dc->pc = dc->npc;
1406 cf495bcf bellard
        dc->npc = dc->npc + 4;
1407 cf495bcf bellard
    }
1408 e80cfcfc bellard
 jmp_insn:
1409 cf495bcf bellard
    return;
1410 cf495bcf bellard
 illegal_insn:
1411 72cbca10 bellard
    save_state(dc);
1412 cf495bcf bellard
    gen_op_exception(TT_ILL_INSN);
1413 cf495bcf bellard
    dc->is_br = 1;
1414 e8af50a3 bellard
    return;
1415 e80cfcfc bellard
#if !defined(CONFIG_USER_ONLY)
1416 e8af50a3 bellard
 priv_insn:
1417 e8af50a3 bellard
    save_state(dc);
1418 e8af50a3 bellard
    gen_op_exception(TT_PRIV_INSN);
1419 e8af50a3 bellard
    dc->is_br = 1;
1420 e80cfcfc bellard
    return;
1421 e80cfcfc bellard
#endif
1422 e80cfcfc bellard
 nfpu_insn:
1423 e80cfcfc bellard
    save_state(dc);
1424 e80cfcfc bellard
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
1425 e80cfcfc bellard
    dc->is_br = 1;
1426 7a3f1944 bellard
}
1427 7a3f1944 bellard
1428 cf495bcf bellard
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
1429 e8af50a3 bellard
                                                 int spc, CPUSPARCState *env)
1430 7a3f1944 bellard
{
1431 72cbca10 bellard
    target_ulong pc_start, last_pc;
1432 cf495bcf bellard
    uint16_t *gen_opc_end;
1433 cf495bcf bellard
    DisasContext dc1, *dc = &dc1;
1434 e8af50a3 bellard
    int j, lj = -1;
1435 cf495bcf bellard
1436 cf495bcf bellard
    memset(dc, 0, sizeof(DisasContext));
1437 cf495bcf bellard
    dc->tb = tb;
1438 72cbca10 bellard
    pc_start = tb->pc;
1439 cf495bcf bellard
    dc->pc = pc_start;
1440 e80cfcfc bellard
    last_pc = dc->pc;
1441 72cbca10 bellard
    dc->npc = (target_ulong) tb->cs_base;
1442 e8af50a3 bellard
#if defined(CONFIG_USER_ONLY)
1443 e8af50a3 bellard
    dc->mem_idx = 0;
1444 e8af50a3 bellard
#else
1445 e8af50a3 bellard
    dc->mem_idx = ((env->psrs) != 0);
1446 e8af50a3 bellard
#endif
1447 cf495bcf bellard
    gen_opc_ptr = gen_opc_buf;
1448 cf495bcf bellard
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1449 cf495bcf bellard
    gen_opparam_ptr = gen_opparam_buf;
1450 cf495bcf bellard
1451 cf495bcf bellard
    do {
1452 e8af50a3 bellard
        if (env->nb_breakpoints > 0) {
1453 e8af50a3 bellard
            for(j = 0; j < env->nb_breakpoints; j++) {
1454 e8af50a3 bellard
                if (env->breakpoints[j] == dc->pc) {
1455 e80cfcfc bellard
                    if (dc->pc != pc_start)
1456 e80cfcfc bellard
                        save_state(dc);
1457 e80cfcfc bellard
                    gen_op_debug();
1458 e80cfcfc bellard
                    gen_op_movl_T0_0();
1459 e80cfcfc bellard
                    gen_op_exit_tb();
1460 e80cfcfc bellard
                    dc->is_br = 1;
1461 e80cfcfc bellard
                    goto exit_gen_loop;
1462 e8af50a3 bellard
                }
1463 e8af50a3 bellard
            }
1464 e8af50a3 bellard
        }
1465 e8af50a3 bellard
        if (spc) {
1466 e8af50a3 bellard
            if (loglevel > 0)
1467 e8af50a3 bellard
                fprintf(logfile, "Search PC...\n");
1468 e8af50a3 bellard
            j = gen_opc_ptr - gen_opc_buf;
1469 e8af50a3 bellard
            if (lj < j) {
1470 e8af50a3 bellard
                lj++;
1471 e8af50a3 bellard
                while (lj < j)
1472 e8af50a3 bellard
                    gen_opc_instr_start[lj++] = 0;
1473 e8af50a3 bellard
                gen_opc_pc[lj] = dc->pc;
1474 e8af50a3 bellard
                gen_opc_npc[lj] = dc->npc;
1475 e8af50a3 bellard
                gen_opc_instr_start[lj] = 1;
1476 e8af50a3 bellard
            }
1477 e8af50a3 bellard
        }
1478 cf495bcf bellard
        last_pc = dc->pc;
1479 cf495bcf bellard
        disas_sparc_insn(dc);
1480 cf495bcf bellard
        if (dc->is_br)
1481 cf495bcf bellard
            break;
1482 cf495bcf bellard
        /* if the next PC is different, we abort now */
1483 cf495bcf bellard
        if (dc->pc != (last_pc + 4))
1484 cf495bcf bellard
            break;
1485 e80cfcfc bellard
        /* if single step mode, we generate only one instruction and
1486 e80cfcfc bellard
           generate an exception */
1487 e80cfcfc bellard
        if (env->singlestep_enabled) {
1488 e80cfcfc bellard
            gen_op_jmp_im(dc->pc);
1489 e80cfcfc bellard
            gen_op_movl_T0_0();
1490 e80cfcfc bellard
            gen_op_exit_tb();
1491 e80cfcfc bellard
            break;
1492 e80cfcfc bellard
        }
1493 cf495bcf bellard
    } while ((gen_opc_ptr < gen_opc_end) &&
1494 cf495bcf bellard
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
1495 e80cfcfc bellard
1496 e80cfcfc bellard
 exit_gen_loop:
1497 72cbca10 bellard
    if (!dc->is_br) {
1498 72cbca10 bellard
        if (dc->pc != DYNAMIC_PC && 
1499 72cbca10 bellard
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
1500 72cbca10 bellard
            /* static PC and NPC: we can use direct chaining */
1501 72cbca10 bellard
            gen_op_branch((long)tb, dc->pc, dc->npc);
1502 72cbca10 bellard
        } else {
1503 72cbca10 bellard
            if (dc->pc != DYNAMIC_PC)
1504 72cbca10 bellard
                gen_op_jmp_im(dc->pc);
1505 72cbca10 bellard
            save_npc(dc);
1506 72cbca10 bellard
            gen_op_movl_T0_0();
1507 72cbca10 bellard
            gen_op_exit_tb();
1508 72cbca10 bellard
        }
1509 72cbca10 bellard
    }
1510 cf495bcf bellard
    *gen_opc_ptr = INDEX_op_end;
1511 e8af50a3 bellard
    if (spc) {
1512 e8af50a3 bellard
        j = gen_opc_ptr - gen_opc_buf;
1513 e8af50a3 bellard
        lj++;
1514 e8af50a3 bellard
        while (lj <= j)
1515 e8af50a3 bellard
            gen_opc_instr_start[lj++] = 0;
1516 e8af50a3 bellard
        tb->size = 0;
1517 e8af50a3 bellard
#if 0
1518 e8af50a3 bellard
        if (loglevel > 0) {
1519 e8af50a3 bellard
            page_dump(logfile);
1520 e8af50a3 bellard
        }
1521 e8af50a3 bellard
#endif
1522 e8af50a3 bellard
    } else {
1523 e80cfcfc bellard
        tb->size = last_pc + 4 - pc_start;
1524 e8af50a3 bellard
    }
1525 7a3f1944 bellard
#ifdef DEBUG_DISAS
1526 e19e89a5 bellard
    if (loglevel & CPU_LOG_TB_IN_ASM) {
1527 cf495bcf bellard
        fprintf(logfile, "--------------\n");
1528 0fa85d43 bellard
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
1529 0fa85d43 bellard
        target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
1530 cf495bcf bellard
        fprintf(logfile, "\n");
1531 e19e89a5 bellard
        if (loglevel & CPU_LOG_TB_OP) {
1532 e19e89a5 bellard
            fprintf(logfile, "OP:\n");
1533 e19e89a5 bellard
            dump_ops(gen_opc_buf, gen_opparam_buf);
1534 e19e89a5 bellard
            fprintf(logfile, "\n");
1535 e19e89a5 bellard
        }
1536 cf495bcf bellard
    }
1537 7a3f1944 bellard
#endif
1538 cf495bcf bellard
    return 0;
1539 7a3f1944 bellard
}
1540 7a3f1944 bellard
1541 cf495bcf bellard
int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
1542 7a3f1944 bellard
{
1543 e8af50a3 bellard
    return gen_intermediate_code_internal(tb, 0, env);
1544 7a3f1944 bellard
}
1545 7a3f1944 bellard
1546 cf495bcf bellard
int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
1547 7a3f1944 bellard
{
1548 e8af50a3 bellard
    return gen_intermediate_code_internal(tb, 1, env);
1549 7a3f1944 bellard
}
1550 7a3f1944 bellard
1551 e80cfcfc bellard
extern int ram_size;
1552 cf495bcf bellard
1553 e80cfcfc bellard
void cpu_reset(CPUSPARCState *env)
1554 e80cfcfc bellard
{
1555 cf495bcf bellard
    memset(env, 0, sizeof(*env));
1556 bb05683b bellard
    tlb_flush(env, 1);
1557 cf495bcf bellard
    env->cwp = 0;
1558 cf495bcf bellard
    env->wim = 1;
1559 cf495bcf bellard
    env->regwptr = env->regbase + (env->cwp * 16);
1560 e8af50a3 bellard
#if defined(CONFIG_USER_ONLY)
1561 cf495bcf bellard
    env->user_mode_only = 1;
1562 e8af50a3 bellard
#else
1563 e8af50a3 bellard
    env->psrs = 1;
1564 e80cfcfc bellard
    env->pc = 0xffd00000;
1565 e80cfcfc bellard
    env->gregs[1] = ram_size;
1566 e80cfcfc bellard
    env->mmuregs[0] = (0x04 << 24); /* Impl 0, ver 4, MMU disabled */
1567 e8af50a3 bellard
    env->npc = env->pc + 4;
1568 e8af50a3 bellard
#endif
1569 e80cfcfc bellard
}
1570 e80cfcfc bellard
1571 e80cfcfc bellard
CPUSPARCState *cpu_sparc_init(void)
1572 e80cfcfc bellard
{
1573 e80cfcfc bellard
    CPUSPARCState *env;
1574 e80cfcfc bellard
1575 e80cfcfc bellard
    cpu_exec_init();
1576 e80cfcfc bellard
1577 e80cfcfc bellard
    if (!(env = malloc(sizeof(CPUSPARCState))))
1578 e80cfcfc bellard
        return (NULL);
1579 7496f526 bellard
    cpu_single_env = env;
1580 e80cfcfc bellard
    cpu_reset(env);
1581 cf495bcf bellard
    return (env);
1582 7a3f1944 bellard
}
1583 7a3f1944 bellard
1584 7a3f1944 bellard
#define GET_FLAG(a,b) ((env->psr & a)?b:'-')
1585 7a3f1944 bellard
1586 7fe48483 bellard
void cpu_dump_state(CPUState *env, FILE *f, 
1587 7fe48483 bellard
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
1588 7fe48483 bellard
                    int flags)
1589 7a3f1944 bellard
{
1590 cf495bcf bellard
    int i, x;
1591 cf495bcf bellard
1592 7fe48483 bellard
    cpu_fprintf(f, "pc: 0x%08x  npc: 0x%08x\n", (int) env->pc, (int) env->npc);
1593 7fe48483 bellard
    cpu_fprintf(f, "General Registers:\n");
1594 cf495bcf bellard
    for (i = 0; i < 4; i++)
1595 7fe48483 bellard
        cpu_fprintf(f, "%%g%c: 0x%08x\t", i + '0', env->gregs[i]);
1596 7fe48483 bellard
    cpu_fprintf(f, "\n");
1597 cf495bcf bellard
    for (; i < 8; i++)
1598 7fe48483 bellard
        cpu_fprintf(f, "%%g%c: 0x%08x\t", i + '0', env->gregs[i]);
1599 7fe48483 bellard
    cpu_fprintf(f, "\nCurrent Register Window:\n");
1600 cf495bcf bellard
    for (x = 0; x < 3; x++) {
1601 cf495bcf bellard
        for (i = 0; i < 4; i++)
1602 7fe48483 bellard
            cpu_fprintf(f, "%%%c%d: 0x%08x\t",
1603 cf495bcf bellard
                    (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
1604 cf495bcf bellard
                    env->regwptr[i + x * 8]);
1605 7fe48483 bellard
        cpu_fprintf(f, "\n");
1606 cf495bcf bellard
        for (; i < 8; i++)
1607 7fe48483 bellard
            cpu_fprintf(f, "%%%c%d: 0x%08x\t",
1608 cf495bcf bellard
                    (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
1609 cf495bcf bellard
                    env->regwptr[i + x * 8]);
1610 7fe48483 bellard
        cpu_fprintf(f, "\n");
1611 cf495bcf bellard
    }
1612 7fe48483 bellard
    cpu_fprintf(f, "\nFloating Point Registers:\n");
1613 e8af50a3 bellard
    for (i = 0; i < 32; i++) {
1614 e8af50a3 bellard
        if ((i & 3) == 0)
1615 7fe48483 bellard
            cpu_fprintf(f, "%%f%02d:", i);
1616 7fe48483 bellard
        cpu_fprintf(f, " %016lf", env->fpr[i]);
1617 e8af50a3 bellard
        if ((i & 3) == 3)
1618 7fe48483 bellard
            cpu_fprintf(f, "\n");
1619 e8af50a3 bellard
    }
1620 7fe48483 bellard
    cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n", GET_PSR(env),
1621 cf495bcf bellard
            GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
1622 cf495bcf bellard
            GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
1623 e8af50a3 bellard
            env->psrs?'S':'-', env->psrps?'P':'-', 
1624 e8af50a3 bellard
            env->psret?'E':'-', env->wim);
1625 7fe48483 bellard
    cpu_fprintf(f, "fsr: 0x%08x\n", env->fsr);
1626 7a3f1944 bellard
}
1627 edfcbd99 bellard
1628 e80cfcfc bellard
#if defined(CONFIG_USER_ONLY)
1629 edfcbd99 bellard
target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
1630 edfcbd99 bellard
{
1631 edfcbd99 bellard
    return addr;
1632 edfcbd99 bellard
}
1633 658138bc bellard
1634 e80cfcfc bellard
#else
1635 0fa85d43 bellard
extern int get_physical_address (CPUState *env, uint32_t *physical, int *prot,
1636 0fa85d43 bellard
                                 int *access_index, uint32_t address, int rw,
1637 0fa85d43 bellard
                                 int is_user);
1638 0fa85d43 bellard
1639 e80cfcfc bellard
target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
1640 e80cfcfc bellard
{
1641 e80cfcfc bellard
    uint32_t phys_addr;
1642 e80cfcfc bellard
    int prot, access_index;
1643 e80cfcfc bellard
1644 e80cfcfc bellard
    if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2, 0) != 0)
1645 e80cfcfc bellard
        return -1;
1646 e80cfcfc bellard
    return phys_addr;
1647 e80cfcfc bellard
}
1648 e80cfcfc bellard
#endif
1649 e80cfcfc bellard
1650 658138bc bellard
void helper_flush(target_ulong addr)
1651 658138bc bellard
{
1652 658138bc bellard
    addr &= ~7;
1653 658138bc bellard
    tb_invalidate_page_range(addr, addr + 8);
1654 658138bc bellard
}