Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ 31741a27

History | View | Annotate | Download (189.6 kB)

1
/*
2
   SPARC translation
3

4
   Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
5
   Copyright (C) 2003-2005 Fabrice Bellard
6

7
   This library is free software; you can redistribute it and/or
8
   modify it under the terms of the GNU Lesser General Public
9
   License as published by the Free Software Foundation; either
10
   version 2 of the License, or (at your option) any later version.
11

12
   This library is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
   Lesser General Public License for more details.
16

17
   You should have received a copy of the GNU Lesser General Public
18
   License along with this library; if not, write to the Free Software
19
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 */
21

    
22
/*
23
   TODO-list:
24

25
   Rest of V9 instructions, VIS instructions
26
   NPC/PC static optimisations (use JUMP_TB when possible)
27
   Optimize synthetic instructions
28
*/
29

    
30
#include <stdarg.h>
31
#include <stdlib.h>
32
#include <stdio.h>
33
#include <string.h>
34
#include <inttypes.h>
35

    
36
#include "cpu.h"
37
#include "exec-all.h"
38
#include "disas.h"
39
#include "helper.h"
40
#include "tcg-op.h"
41

    
42
#define DEBUG_DISAS
43

    
44
#define DYNAMIC_PC  1 /* dynamic pc value */
45
#define JUMP_PC     2 /* dynamic pc value which takes only two values
46
                         according to jump_pc[T2] */
47

    
48
/* global register indexes */
49
static TCGv cpu_env, cpu_T[3], cpu_regwptr, cpu_cc_src, cpu_cc_src2, cpu_cc_dst;
50
static TCGv cpu_psr, cpu_fsr, cpu_pc, cpu_npc, cpu_gregs[8];
51
#ifdef TARGET_SPARC64
52
static TCGv cpu_xcc;
53
#endif
54
/* local register indexes (only used inside old micro ops) */
55
static TCGv cpu_tmp0, cpu_tmp32, cpu_tmp64;
56

    
57
typedef struct DisasContext {
58
    target_ulong pc;    /* current Program Counter: integer or DYNAMIC_PC */
59
    target_ulong npc;   /* next PC: integer or DYNAMIC_PC or JUMP_PC */
60
    target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
61
    int is_br;
62
    int mem_idx;
63
    int fpu_enabled;
64
    struct TranslationBlock *tb;
65
} DisasContext;
66

    
67
typedef struct sparc_def_t sparc_def_t;
68

    
69
struct sparc_def_t {
70
    const unsigned char *name;
71
    target_ulong iu_version;
72
    uint32_t fpu_version;
73
    uint32_t mmu_version;
74
    uint32_t mmu_bm;
75
    uint32_t mmu_ctpr_mask;
76
    uint32_t mmu_cxr_mask;
77
    uint32_t mmu_sfsr_mask;
78
    uint32_t mmu_trcr_mask;
79
};
80

    
81
static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name);
82

    
83
extern FILE *logfile;
84
extern int loglevel;
85

    
86
// This function uses non-native bit order
87
#define GET_FIELD(X, FROM, TO) \
88
  ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
89

    
90
// This function uses the order in the manuals, i.e. bit 0 is 2^0
91
#define GET_FIELD_SP(X, FROM, TO) \
92
    GET_FIELD(X, 31 - (TO), 31 - (FROM))
93

    
94
#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
95
#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
96

    
97
#ifdef TARGET_SPARC64
98
#define FFPREG(r) (r)
99
#define DFPREG(r) (((r & 1) << 5) | (r & 0x1e))
100
#define QFPREG(r) (((r & 1) << 5) | (r & 0x1c))
101
#else
102
#define FFPREG(r) (r)
103
#define DFPREG(r) (r & 0x1e)
104
#define QFPREG(r) (r & 0x1c)
105
#endif
106

    
107
static int sign_extend(int x, int len)
108
{
109
    len = 32 - len;
110
    return (x << len) >> len;
111
}
112

    
113
#define IS_IMM (insn & (1<<13))
114

    
115
/* floating point registers moves */
116
static void gen_op_load_fpr_FT0(unsigned int src)
117
{
118
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
119
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft0));
120
}
121

    
122
static void gen_op_load_fpr_FT1(unsigned int src)
123
{
124
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
125
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft1));
126
}
127

    
128
static void gen_op_store_FT0_fpr(unsigned int dst)
129
{
130
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft0));
131
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst]));
132
}
133

    
134
static void gen_op_load_fpr_DT0(unsigned int src)
135
{
136
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
137
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) + offsetof(CPU_DoubleU, l.upper));
138
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
139
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) + offsetof(CPU_DoubleU, l.lower));
140
}
141

    
142
static void gen_op_load_fpr_DT1(unsigned int src)
143
{
144
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
145
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt1) + offsetof(CPU_DoubleU, l.upper));
146
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
147
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt1) + offsetof(CPU_DoubleU, l.lower));
148
}
149

    
150
static void gen_op_store_DT0_fpr(unsigned int dst)
151
{
152
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) + offsetof(CPU_DoubleU, l.upper));
153
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst]));
154
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) + offsetof(CPU_DoubleU, l.lower));
155
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 1]));
156
}
157

    
158
#ifdef CONFIG_USER_ONLY
159
static void gen_op_load_fpr_QT0(unsigned int src)
160
{
161
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
162
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upmost));
163
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
164
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upper));
165
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 2]));
166
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lower));
167
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 3]));
168
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lowest));
169
}
170

    
171
static void gen_op_load_fpr_QT1(unsigned int src)
172
{
173
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
174
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.upmost));
175
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
176
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.upper));
177
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 2]));
178
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.lower));
179
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 3]));
180
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.lowest));
181
}
182

    
183
static void gen_op_store_QT0_fpr(unsigned int dst)
184
{
185
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upmost));
186
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst]));
187
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upper));
188
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 1]));
189
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lower));
190
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 2]));
191
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lowest));
192
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 3]));
193
}
194
#endif
195

    
196
/* moves */
197
#ifdef CONFIG_USER_ONLY
198
#define supervisor(dc) 0
199
#ifdef TARGET_SPARC64
200
#define hypervisor(dc) 0
201
#endif
202
#define gen_op_ldst(name)        gen_op_##name##_raw()
203
#else
204
#define supervisor(dc) (dc->mem_idx >= 1)
205
#ifdef TARGET_SPARC64
206
#define hypervisor(dc) (dc->mem_idx == 2)
207
#define OP_LD_TABLE(width)                                              \
208
    static GenOpFunc * const gen_op_##width[] = {                       \
209
        &gen_op_##width##_user,                                         \
210
        &gen_op_##width##_kernel,                                       \
211
        &gen_op_##width##_hypv,                                         \
212
    };
213
#else
214
#define OP_LD_TABLE(width)                                              \
215
    static GenOpFunc * const gen_op_##width[] = {                       \
216
        &gen_op_##width##_user,                                         \
217
        &gen_op_##width##_kernel,                                       \
218
    };
219
#endif
220
#define gen_op_ldst(name)        (*gen_op_##name[dc->mem_idx])()
221
#endif
222

    
223
#ifndef CONFIG_USER_ONLY
224
#ifdef __i386__
225
OP_LD_TABLE(std);
226
#endif /* __i386__ */
227
OP_LD_TABLE(stdf);
228
OP_LD_TABLE(lddf);
229
#endif
230

    
231
#ifdef TARGET_ABI32
232
#define ABI32_MASK(addr) tcg_gen_andi_tl(addr, addr, 0xffffffffULL);
233
#else
234
#define ABI32_MASK(addr)
235
#endif
236

    
237
static inline void gen_movl_reg_TN(int reg, TCGv tn)
238
{
239
    if (reg == 0)
240
        tcg_gen_movi_tl(tn, 0);
241
    else if (reg < 8)
242
        tcg_gen_mov_tl(tn, cpu_gregs[reg]);
243
    else {
244
        tcg_gen_ld_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
245
    }
246
}
247

    
248
static inline void gen_movl_TN_reg(int reg, TCGv tn)
249
{
250
    if (reg == 0)
251
        return;
252
    else if (reg < 8)
253
        tcg_gen_mov_tl(cpu_gregs[reg], tn);
254
    else {
255
        tcg_gen_st_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
256
    }
257
}
258

    
259
static inline void gen_goto_tb(DisasContext *s, int tb_num,
260
                               target_ulong pc, target_ulong npc)
261
{
262
    TranslationBlock *tb;
263

    
264
    tb = s->tb;
265
    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
266
        (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK))  {
267
        /* jump to same page: we can use a direct jump */
268
        tcg_gen_goto_tb(tb_num);
269
        tcg_gen_movi_tl(cpu_pc, pc);
270
        tcg_gen_movi_tl(cpu_npc, npc);
271
        tcg_gen_exit_tb((long)tb + tb_num);
272
    } else {
273
        /* jump to another page: currently not optimized */
274
        tcg_gen_movi_tl(cpu_pc, pc);
275
        tcg_gen_movi_tl(cpu_npc, npc);
276
        tcg_gen_exit_tb(0);
277
    }
278
}
279

    
280
// XXX suboptimal
281
static inline void gen_mov_reg_N(TCGv reg, TCGv src)
282
{
283
    tcg_gen_extu_i32_tl(reg, src);
284
    tcg_gen_shri_tl(reg, reg, 23);
285
    tcg_gen_andi_tl(reg, reg, 0x1);
286
}
287

    
288
static inline void gen_mov_reg_Z(TCGv reg, TCGv src)
289
{
290
    tcg_gen_extu_i32_tl(reg, src);
291
    tcg_gen_shri_tl(reg, reg, 22);
292
    tcg_gen_andi_tl(reg, reg, 0x1);
293
}
294

    
295
static inline void gen_mov_reg_V(TCGv reg, TCGv src)
296
{
297
    tcg_gen_extu_i32_tl(reg, src);
298
    tcg_gen_shri_tl(reg, reg, 21);
299
    tcg_gen_andi_tl(reg, reg, 0x1);
300
}
301

    
302
static inline void gen_mov_reg_C(TCGv reg, TCGv src)
303
{
304
    tcg_gen_extu_i32_tl(reg, src);
305
    tcg_gen_shri_tl(reg, reg, 20);
306
    tcg_gen_andi_tl(reg, reg, 0x1);
307
}
308

    
309
static inline void gen_cc_clear_icc(void)
310
{
311
    tcg_gen_movi_i32(cpu_psr, 0);
312
}
313

    
314
#ifdef TARGET_SPARC64
315
static inline void gen_cc_clear_xcc(void)
316
{
317
    tcg_gen_movi_i32(cpu_xcc, 0);
318
}
319
#endif
320

    
321
/* old op:
322
    if (!T0)
323
        env->psr |= PSR_ZERO;
324
    if ((int32_t) T0 < 0)
325
        env->psr |= PSR_NEG;
326
*/
327
static inline void gen_cc_NZ_icc(TCGv dst)
328
{
329
    TCGv r_temp;
330
    int l1, l2;
331

    
332
    l1 = gen_new_label();
333
    l2 = gen_new_label();
334
    r_temp = tcg_temp_new(TCG_TYPE_TL);
335
    tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
336
    tcg_gen_brcond_tl(TCG_COND_NE, r_temp, tcg_const_tl(0), l1);
337
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_ZERO);
338
    gen_set_label(l1);
339
    tcg_gen_ext_i32_tl(r_temp, dst);
340
    tcg_gen_brcond_tl(TCG_COND_GE, r_temp, tcg_const_tl(0), l2);
341
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_NEG);
342
    gen_set_label(l2);
343
}
344

    
345
#ifdef TARGET_SPARC64
346
static inline void gen_cc_NZ_xcc(TCGv dst)
347
{
348
    int l1, l2;
349

    
350
    l1 = gen_new_label();
351
    l2 = gen_new_label();
352
    tcg_gen_brcond_tl(TCG_COND_NE, dst, tcg_const_tl(0), l1);
353
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_ZERO);
354
    gen_set_label(l1);
355
    tcg_gen_brcond_tl(TCG_COND_GE, dst, tcg_const_tl(0), l2);
356
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_NEG);
357
    gen_set_label(l2);
358
}
359
#endif
360

    
361
/* old op:
362
    if (T0 < src1)
363
        env->psr |= PSR_CARRY;
364
*/
365
static inline void gen_cc_C_add_icc(TCGv dst, TCGv src1)
366
{
367
    TCGv r_temp;
368
    int l1;
369

    
370
    l1 = gen_new_label();
371
    r_temp = tcg_temp_new(TCG_TYPE_TL);
372
    tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
373
    tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l1);
374
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
375
    gen_set_label(l1);
376
}
377

    
378
#ifdef TARGET_SPARC64
379
static inline void gen_cc_C_add_xcc(TCGv dst, TCGv src1)
380
{
381
    int l1;
382

    
383
    l1 = gen_new_label();
384
    tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l1);
385
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
386
    gen_set_label(l1);
387
}
388
#endif
389

    
390
/* old op:
391
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
392
        env->psr |= PSR_OVF;
393
*/
394
static inline void gen_cc_V_add_icc(TCGv dst, TCGv src1, TCGv src2)
395
{
396
    TCGv r_temp;
397
    int l1;
398

    
399
    l1 = gen_new_label();
400

    
401
    r_temp = tcg_temp_new(TCG_TYPE_TL);
402
    tcg_gen_xor_tl(r_temp, src1, src2);
403
    tcg_gen_xori_tl(r_temp, r_temp, -1);
404
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
405
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
406
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
407
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
408
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
409
    gen_set_label(l1);
410
}
411

    
412
#ifdef TARGET_SPARC64
413
static inline void gen_cc_V_add_xcc(TCGv dst, TCGv src1, TCGv src2)
414
{
415
    TCGv r_temp;
416
    int l1;
417

    
418
    l1 = gen_new_label();
419

    
420
    r_temp = tcg_temp_new(TCG_TYPE_TL);
421
    tcg_gen_xor_tl(r_temp, src1, src2);
422
    tcg_gen_xori_tl(r_temp, r_temp, -1);
423
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
424
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
425
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
426
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
427
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_OVF);
428
    gen_set_label(l1);
429
}
430
#endif
431

    
432
static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
433
{
434
    TCGv r_temp;
435
    int l1;
436

    
437
    l1 = gen_new_label();
438

    
439
    r_temp = tcg_temp_new(TCG_TYPE_TL);
440
    tcg_gen_xor_tl(r_temp, src1, src2);
441
    tcg_gen_xori_tl(r_temp, r_temp, -1);
442
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
443
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
444
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
445
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
446
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
447
    gen_set_label(l1);
448
}
449

    
450
static inline void gen_cc_V_tag(TCGv src1, TCGv src2)
451
{
452
    int l1;
453

    
454
    l1 = gen_new_label();
455
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
456
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
457
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
458
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
459
    gen_set_label(l1);
460
}
461

    
462
static inline void gen_tag_tv(TCGv src1, TCGv src2)
463
{
464
    int l1;
465

    
466
    l1 = gen_new_label();
467
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
468
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
469
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
470
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
471
    gen_set_label(l1);
472
}
473

    
474
static inline void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2)
475
{
476
    tcg_gen_mov_tl(cpu_cc_src, src1);
477
    tcg_gen_add_tl(dst, src1, src2);
478
    gen_cc_clear_icc();
479
    gen_cc_NZ_icc(dst);
480
    gen_cc_C_add_icc(dst, cpu_cc_src);
481
    gen_cc_V_add_icc(dst, cpu_cc_src, src2);
482
#ifdef TARGET_SPARC64
483
    gen_cc_clear_xcc();
484
    gen_cc_NZ_xcc(dst);
485
    gen_cc_C_add_xcc(dst, cpu_cc_src);
486
    gen_cc_V_add_xcc(dst, cpu_cc_src, src2);
487
#endif
488
}
489

    
490
static inline void gen_op_addx_cc(TCGv dst, TCGv src1, TCGv src2)
491
{
492
    tcg_gen_mov_tl(cpu_cc_src, src1);
493
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
494
    tcg_gen_add_tl(dst, src1, cpu_tmp0);
495
    gen_cc_clear_icc();
496
    gen_cc_C_add_icc(dst, cpu_cc_src);
497
#ifdef TARGET_SPARC64
498
    gen_cc_clear_xcc();
499
    gen_cc_C_add_xcc(dst, cpu_cc_src);
500
#endif
501
    tcg_gen_add_tl(dst, dst, src2);
502
    gen_cc_NZ_icc(dst);
503
    gen_cc_C_add_icc(dst, cpu_cc_src);
504
    gen_cc_V_add_icc(dst, cpu_cc_src, src2);
505
#ifdef TARGET_SPARC64
506
    gen_cc_NZ_xcc(dst);
507
    gen_cc_C_add_xcc(dst, cpu_cc_src);
508
    gen_cc_V_add_xcc(dst, cpu_cc_src, src2);
509
#endif
510
}
511

    
512
static inline void gen_op_tadd_cc(TCGv dst, TCGv src1, TCGv src2)
513
{
514
    tcg_gen_mov_tl(cpu_cc_src, src1);
515
    tcg_gen_add_tl(dst, src1, src2);
516
    gen_cc_clear_icc();
517
    gen_cc_NZ_icc(dst);
518
    gen_cc_C_add_icc(dst, cpu_cc_src);
519
    gen_cc_V_add_icc(dst, cpu_cc_src, src2);
520
    gen_cc_V_tag(cpu_cc_src, src2);
521
#ifdef TARGET_SPARC64
522
    gen_cc_clear_xcc();
523
    gen_cc_NZ_xcc(dst);
524
    gen_cc_C_add_xcc(dst, cpu_cc_src);
525
    gen_cc_V_add_xcc(dst, cpu_cc_src, src2);
526
#endif
527
}
528

    
529
static inline void gen_op_tadd_ccTV(TCGv dst, TCGv src1, TCGv src2)
530
{
531
    gen_tag_tv(src1, src2);
532
    tcg_gen_mov_tl(cpu_cc_src, src1);
533
    tcg_gen_add_tl(dst, src1, src2);
534
    gen_add_tv(dst, cpu_cc_src, src2);
535
    gen_cc_clear_icc();
536
    gen_cc_NZ_icc(dst);
537
    gen_cc_C_add_icc(dst, cpu_cc_src);
538
#ifdef TARGET_SPARC64
539
    gen_cc_clear_xcc();
540
    gen_cc_NZ_xcc(dst);
541
    gen_cc_C_add_xcc(dst, cpu_cc_src);
542
    gen_cc_V_add_xcc(dst, cpu_cc_src, src2);
543
#endif
544
}
545

    
546
/* old op:
547
    if (src1 < T1)
548
        env->psr |= PSR_CARRY;
549
*/
550
static inline void gen_cc_C_sub_icc(TCGv src1, TCGv src2)
551
{
552
    TCGv r_temp1, r_temp2;
553
    int l1;
554

    
555
    l1 = gen_new_label();
556
    r_temp1 = tcg_temp_new(TCG_TYPE_TL);
557
    r_temp2 = tcg_temp_new(TCG_TYPE_TL);
558
    tcg_gen_andi_tl(r_temp1, src1, 0xffffffffULL);
559
    tcg_gen_andi_tl(r_temp2, src2, 0xffffffffULL);
560
    tcg_gen_brcond_tl(TCG_COND_GEU, r_temp1, r_temp2, l1);
561
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
562
    gen_set_label(l1);
563
}
564

    
565
#ifdef TARGET_SPARC64
566
static inline void gen_cc_C_sub_xcc(TCGv src1, TCGv src2)
567
{
568
    int l1;
569

    
570
    l1 = gen_new_label();
571
    tcg_gen_brcond_tl(TCG_COND_GEU, src1, src2, l1);
572
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
573
    gen_set_label(l1);
574
}
575
#endif
576

    
577
/* old op:
578
    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
579
        env->psr |= PSR_OVF;
580
*/
581
static inline void gen_cc_V_sub_icc(TCGv dst, TCGv src1, TCGv src2)
582
{
583
    TCGv r_temp;
584
    int l1;
585

    
586
    l1 = gen_new_label();
587

    
588
    r_temp = tcg_temp_new(TCG_TYPE_TL);
589
    tcg_gen_xor_tl(r_temp, src1, src2);
590
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
591
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
592
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
593
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
594
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
595
    gen_set_label(l1);
596
}
597

    
598
#ifdef TARGET_SPARC64
599
static inline void gen_cc_V_sub_xcc(TCGv dst, TCGv src1, TCGv src2)
600
{
601
    TCGv r_temp;
602
    int l1;
603

    
604
    l1 = gen_new_label();
605

    
606
    r_temp = tcg_temp_new(TCG_TYPE_TL);
607
    tcg_gen_xor_tl(r_temp, src1, src2);
608
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
609
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
610
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
611
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
612
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_OVF);
613
    gen_set_label(l1);
614
}
615
#endif
616

    
617
static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
618
{
619
    TCGv r_temp;
620
    int l1;
621

    
622
    l1 = gen_new_label();
623

    
624
    r_temp = tcg_temp_new(TCG_TYPE_TL);
625
    tcg_gen_xor_tl(r_temp, src1, src2);
626
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
627
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
628
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
629
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
630
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
631
    gen_set_label(l1);
632
    tcg_gen_discard_tl(r_temp);
633
}
634

    
635
static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2)
636
{
637
    tcg_gen_mov_tl(cpu_cc_src, src1);
638
    tcg_gen_sub_tl(dst, src1, src2);
639
    gen_cc_clear_icc();
640
    gen_cc_NZ_icc(dst);
641
    gen_cc_C_sub_icc(cpu_cc_src, src2);
642
    gen_cc_V_sub_icc(dst, cpu_cc_src, src2);
643
#ifdef TARGET_SPARC64
644
    gen_cc_clear_xcc();
645
    gen_cc_NZ_xcc(dst);
646
    gen_cc_C_sub_xcc(cpu_cc_src, src2);
647
    gen_cc_V_sub_xcc(dst, cpu_cc_src, src2);
648
#endif
649
}
650

    
651
static inline void gen_op_subx_cc(TCGv dst, TCGv src1, TCGv src2)
652
{
653
    tcg_gen_mov_tl(cpu_cc_src, src1);
654
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
655
    tcg_gen_sub_tl(dst, src1, cpu_tmp0);
656
    gen_cc_clear_icc();
657
    gen_cc_C_sub_icc(dst, cpu_cc_src);
658
#ifdef TARGET_SPARC64
659
    gen_cc_clear_xcc();
660
    gen_cc_C_sub_xcc(dst, cpu_cc_src);
661
#endif
662
    tcg_gen_sub_tl(dst, dst, src2);
663
    gen_cc_NZ_icc(dst);
664
    gen_cc_C_sub_icc(dst, cpu_cc_src);
665
    gen_cc_V_sub_icc(dst, cpu_cc_src, src2);
666
#ifdef TARGET_SPARC64
667
    gen_cc_NZ_xcc(dst);
668
    gen_cc_C_sub_xcc(dst, cpu_cc_src);
669
    gen_cc_V_sub_xcc(dst, cpu_cc_src, src2);
670
#endif
671
}
672

    
673
static inline void gen_op_tsub_cc(TCGv dst, TCGv src1, TCGv src2)
674
{
675
    tcg_gen_mov_tl(cpu_cc_src, src1);
676
    tcg_gen_sub_tl(dst, src1, src2);
677
    gen_cc_clear_icc();
678
    gen_cc_NZ_icc(dst);
679
    gen_cc_C_sub_icc(cpu_cc_src, src2);
680
    gen_cc_V_sub_icc(dst, cpu_cc_src, src2);
681
    gen_cc_V_tag(cpu_cc_src, src2);
682
#ifdef TARGET_SPARC64
683
    gen_cc_clear_xcc();
684
    gen_cc_NZ_xcc(dst);
685
    gen_cc_C_sub_xcc(cpu_cc_src, src2);
686
    gen_cc_V_sub_xcc(dst, cpu_cc_src, src2);
687
#endif
688
}
689

    
690
static inline void gen_op_tsub_ccTV(TCGv dst, TCGv src1, TCGv src2)
691
{
692
    gen_tag_tv(src1, src2);
693
    tcg_gen_mov_tl(cpu_cc_src, src1);
694
    tcg_gen_sub_tl(dst, src1, src2);
695
    gen_sub_tv(dst, cpu_cc_src, src2);
696
    gen_cc_clear_icc();
697
    gen_cc_NZ_icc(dst);
698
    gen_cc_C_sub_icc(cpu_cc_src, src2);
699
#ifdef TARGET_SPARC64
700
    gen_cc_clear_xcc();
701
    gen_cc_NZ_xcc(dst);
702
    gen_cc_C_sub_xcc(cpu_cc_src, src2);
703
    gen_cc_V_sub_xcc(dst, cpu_cc_src, src2);
704
#endif
705
}
706

    
707
static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
708
{
709
    TCGv r_temp, r_temp2;
710
    int l1, l2;
711

    
712
    l1 = gen_new_label();
713
    l2 = gen_new_label();
714
    r_temp = tcg_temp_new(TCG_TYPE_TL);
715
    r_temp2 = tcg_temp_new(TCG_TYPE_I32);
716

    
717
    /* old op:
718
    if (!(env->y & 1))
719
        T1 = 0;
720
    */
721
    tcg_gen_ld32u_tl(r_temp, cpu_env, offsetof(CPUSPARCState, y));
722
    tcg_gen_trunc_tl_i32(r_temp2, r_temp);
723
    tcg_gen_andi_i32(r_temp2, r_temp2, 0x1);
724
    tcg_gen_brcond_i32(TCG_COND_EQ, r_temp2, tcg_const_i32(0), l1);
725
    tcg_gen_mov_tl(cpu_cc_src2, src2);
726
    tcg_gen_br(l2);
727
    gen_set_label(l1);
728
    tcg_gen_movi_tl(cpu_cc_src2, 0);
729
    gen_set_label(l2);
730

    
731
    // b2 = T0 & 1;
732
    // env->y = (b2 << 31) | (env->y >> 1);
733
    tcg_gen_trunc_tl_i32(r_temp2, src1);
734
    tcg_gen_andi_i32(r_temp2, r_temp2, 0x1);
735
    tcg_gen_shli_i32(r_temp2, r_temp2, 31);
736
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, y));
737
    tcg_gen_shri_i32(cpu_tmp32, cpu_tmp32, 1);
738
    tcg_gen_or_i32(cpu_tmp32, cpu_tmp32, r_temp2);
739
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, y));
740

    
741
    // b1 = N ^ V;
742
    gen_mov_reg_N(cpu_tmp0, cpu_psr);
743
    gen_mov_reg_V(r_temp, cpu_psr);
744
    tcg_gen_xor_tl(cpu_tmp0, cpu_tmp0, r_temp);
745

    
746
    // T0 = (b1 << 31) | (T0 >> 1);
747
    // src1 = T0;
748
    tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
749
    tcg_gen_shri_tl(cpu_cc_src, src1, 1);
750
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
751

    
752
    /* do addition and update flags */
753
    tcg_gen_add_tl(dst, cpu_cc_src, cpu_cc_src2);
754
    tcg_gen_discard_tl(r_temp);
755

    
756
    gen_cc_clear_icc();
757
    gen_cc_NZ_icc(dst);
758
    gen_cc_V_add_icc(dst, cpu_cc_src, cpu_cc_src2);
759
    gen_cc_C_add_icc(dst, cpu_cc_src);
760
}
761

    
762
static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
763
{
764
    TCGv r_temp, r_temp2;
765

    
766
    r_temp = tcg_temp_new(TCG_TYPE_I64);
767
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);
768

    
769
    tcg_gen_extu_tl_i64(r_temp, src2);
770
    tcg_gen_extu_tl_i64(r_temp2, src1);
771
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
772

    
773
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
774
    tcg_gen_trunc_i64_i32(r_temp, r_temp);
775
    tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
776
#ifdef TARGET_SPARC64
777
    tcg_gen_mov_i64(dst, r_temp2);
778
#else
779
    tcg_gen_trunc_i64_tl(dst, r_temp2);
780
#endif
781

    
782
    tcg_gen_discard_i64(r_temp);
783
    tcg_gen_discard_i64(r_temp2);
784
}
785

    
786
static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
787
{
788
    TCGv r_temp, r_temp2;
789

    
790
    r_temp = tcg_temp_new(TCG_TYPE_I64);
791
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);
792

    
793
    tcg_gen_ext_tl_i64(r_temp, src2);
794
    tcg_gen_ext_tl_i64(r_temp2, src1);
795
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
796

    
797
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
798
    tcg_gen_trunc_i64_i32(r_temp, r_temp);
799
    tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
800
#ifdef TARGET_SPARC64
801
    tcg_gen_mov_i64(dst, r_temp2);
802
#else
803
    tcg_gen_trunc_i64_tl(dst, r_temp2);
804
#endif
805

    
806
    tcg_gen_discard_i64(r_temp);
807
    tcg_gen_discard_i64(r_temp2);
808
}
809

    
810
#ifdef TARGET_SPARC64
811
static inline void gen_trap_ifdivzero_tl(TCGv divisor)
812
{
813
    int l1;
814

    
815
    l1 = gen_new_label();
816
    tcg_gen_brcond_tl(TCG_COND_NE, divisor, tcg_const_tl(0), l1);
817
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_DIV_ZERO));
818
    gen_set_label(l1);
819
}
820

    
821
static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
822
{
823
    int l1, l2;
824

    
825
    l1 = gen_new_label();
826
    l2 = gen_new_label();
827
    gen_trap_ifdivzero_tl(src2);
828
    tcg_gen_brcond_tl(TCG_COND_NE, src1, tcg_const_tl(INT64_MIN), l1);
829
    tcg_gen_brcond_tl(TCG_COND_NE, src2, tcg_const_tl(-1), l1);
830
    tcg_gen_movi_i64(dst, INT64_MIN);
831
    tcg_gen_br(l2);
832
    gen_set_label(l1);
833
    tcg_gen_div_i64(dst, src1, src2);
834
    gen_set_label(l2);
835
}
836
#endif
837

    
838
static inline void gen_op_div_cc(TCGv dst)
839
{
840
    int l1;
841

    
842
    gen_cc_clear_icc();
843
    gen_cc_NZ_icc(dst);
844
    l1 = gen_new_label();
845
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, cc_src2));
846
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
847
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
848
    gen_set_label(l1);
849
}
850

    
851
static inline void gen_op_logic_cc(TCGv dst)
852
{
853
    gen_cc_clear_icc();
854
    gen_cc_NZ_icc(dst);
855
#ifdef TARGET_SPARC64
856
    gen_cc_clear_xcc();
857
    gen_cc_NZ_xcc(dst);
858
#endif
859
}
860

    
861
// 1
862
static inline void gen_op_eval_ba(TCGv dst)
863
{
864
    tcg_gen_movi_tl(dst, 1);
865
}
866

    
867
// Z
868
static inline void gen_op_eval_be(TCGv dst, TCGv src)
869
{
870
    gen_mov_reg_Z(dst, src);
871
}
872

    
873
// Z | (N ^ V)
874
static inline void gen_op_eval_ble(TCGv dst, TCGv src)
875
{
876
    gen_mov_reg_N(cpu_tmp0, src);
877
    gen_mov_reg_V(dst, src);
878
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
879
    gen_mov_reg_Z(cpu_tmp0, src);
880
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
881
}
882

    
883
// N ^ V
884
static inline void gen_op_eval_bl(TCGv dst, TCGv src)
885
{
886
    gen_mov_reg_V(cpu_tmp0, src);
887
    gen_mov_reg_N(dst, src);
888
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
889
}
890

    
891
// C | Z
892
static inline void gen_op_eval_bleu(TCGv dst, TCGv src)
893
{
894
    gen_mov_reg_Z(cpu_tmp0, src);
895
    gen_mov_reg_C(dst, src);
896
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
897
}
898

    
899
// C
900
static inline void gen_op_eval_bcs(TCGv dst, TCGv src)
901
{
902
    gen_mov_reg_C(dst, src);
903
}
904

    
905
// V
906
static inline void gen_op_eval_bvs(TCGv dst, TCGv src)
907
{
908
    gen_mov_reg_V(dst, src);
909
}
910

    
911
// 0
912
static inline void gen_op_eval_bn(TCGv dst)
913
{
914
    tcg_gen_movi_tl(dst, 0);
915
}
916

    
917
// N
918
static inline void gen_op_eval_bneg(TCGv dst, TCGv src)
919
{
920
    gen_mov_reg_N(dst, src);
921
}
922

    
923
// !Z
924
static inline void gen_op_eval_bne(TCGv dst, TCGv src)
925
{
926
    gen_mov_reg_Z(dst, src);
927
    tcg_gen_xori_tl(dst, dst, 0x1);
928
}
929

    
930
// !(Z | (N ^ V))
931
static inline void gen_op_eval_bg(TCGv dst, TCGv src)
932
{
933
    gen_mov_reg_N(cpu_tmp0, src);
934
    gen_mov_reg_V(dst, src);
935
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
936
    gen_mov_reg_Z(cpu_tmp0, src);
937
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
938
    tcg_gen_xori_tl(dst, dst, 0x1);
939
}
940

    
941
// !(N ^ V)
942
static inline void gen_op_eval_bge(TCGv dst, TCGv src)
943
{
944
    gen_mov_reg_V(cpu_tmp0, src);
945
    gen_mov_reg_N(dst, src);
946
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
947
    tcg_gen_xori_tl(dst, dst, 0x1);
948
}
949

    
950
// !(C | Z)
951
static inline void gen_op_eval_bgu(TCGv dst, TCGv src)
952
{
953
    gen_mov_reg_Z(cpu_tmp0, src);
954
    gen_mov_reg_C(dst, src);
955
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
956
    tcg_gen_xori_tl(dst, dst, 0x1);
957
}
958

    
959
// !C
960
static inline void gen_op_eval_bcc(TCGv dst, TCGv src)
961
{
962
    gen_mov_reg_C(dst, src);
963
    tcg_gen_xori_tl(dst, dst, 0x1);
964
}
965

    
966
// !N
967
static inline void gen_op_eval_bpos(TCGv dst, TCGv src)
968
{
969
    gen_mov_reg_N(dst, src);
970
    tcg_gen_xori_tl(dst, dst, 0x1);
971
}
972

    
973
// !V
974
static inline void gen_op_eval_bvc(TCGv dst, TCGv src)
975
{
976
    gen_mov_reg_V(dst, src);
977
    tcg_gen_xori_tl(dst, dst, 0x1);
978
}
979

    
980
/*
981
  FPSR bit field FCC1 | FCC0:
982
   0 =
983
   1 <
984
   2 >
985
   3 unordered
986
*/
987
static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src,
988
                                    unsigned int fcc_offset)
989
{
990
    tcg_gen_extu_i32_tl(reg, src);
991
    tcg_gen_shri_tl(reg, reg, 10 + fcc_offset);
992
    tcg_gen_andi_tl(reg, reg, 0x1);
993
}
994

    
995
static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
996
                                    unsigned int fcc_offset)
997
{
998
    tcg_gen_extu_i32_tl(reg, src);
999
    tcg_gen_shri_tl(reg, reg, 11 + fcc_offset);
1000
    tcg_gen_andi_tl(reg, reg, 0x1);
1001
}
1002

    
1003
// !0: FCC0 | FCC1
1004
static inline void gen_op_eval_fbne(TCGv dst, TCGv src,
1005
                                    unsigned int fcc_offset)
1006
{
1007
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1008
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1009
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
1010
}
1011

    
1012
// 1 or 2: FCC0 ^ FCC1
1013
static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
1014
                                    unsigned int fcc_offset)
1015
{
1016
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1017
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1018
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1019
}
1020

    
1021
// 1 or 3: FCC0
1022
static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
1023
                                    unsigned int fcc_offset)
1024
{
1025
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1026
}
1027

    
1028
// 1: FCC0 & !FCC1
1029
static inline void gen_op_eval_fbl(TCGv dst, TCGv src,
1030
                                    unsigned int fcc_offset)
1031
{
1032
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1033
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1034
    tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
1035
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1036
}
1037

    
1038
// 2 or 3: FCC1
1039
static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
1040
                                    unsigned int fcc_offset)
1041
{
1042
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1043
}
1044

    
1045
// 2: !FCC0 & FCC1
1046
static inline void gen_op_eval_fbg(TCGv dst, TCGv src,
1047
                                    unsigned int fcc_offset)
1048
{
1049
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1050
    tcg_gen_xori_tl(dst, dst, 0x1);
1051
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1052
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1053
}
1054

    
1055
// 3: FCC0 & FCC1
1056
static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
1057
                                    unsigned int fcc_offset)
1058
{
1059
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1060
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1061
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1062
}
1063

    
1064
// 0: !(FCC0 | FCC1)
1065
static inline void gen_op_eval_fbe(TCGv dst, TCGv src,
1066
                                    unsigned int fcc_offset)
1067
{
1068
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1069
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1070
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
1071
    tcg_gen_xori_tl(dst, dst, 0x1);
1072
}
1073

    
1074
// 0 or 3: !(FCC0 ^ FCC1)
1075
static inline void gen_op_eval_fbue(TCGv dst, TCGv src,
1076
                                    unsigned int fcc_offset)
1077
{
1078
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1079
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1080
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1081
    tcg_gen_xori_tl(dst, dst, 0x1);
1082
}
1083

    
1084
// 0 or 2: !FCC0
1085
static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
1086
                                    unsigned int fcc_offset)
1087
{
1088
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1089
    tcg_gen_xori_tl(dst, dst, 0x1);
1090
}
1091

    
1092
// !1: !(FCC0 & !FCC1)
1093
static inline void gen_op_eval_fbuge(TCGv dst, TCGv src,
1094
                                    unsigned int fcc_offset)
1095
{
1096
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1097
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1098
    tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
1099
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1100
    tcg_gen_xori_tl(dst, dst, 0x1);
1101
}
1102

    
1103
// 0 or 1: !FCC1
1104
static inline void gen_op_eval_fble(TCGv dst, TCGv src,
1105
                                    unsigned int fcc_offset)
1106
{
1107
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1108
    tcg_gen_xori_tl(dst, dst, 0x1);
1109
}
1110

    
1111
// !2: !(!FCC0 & FCC1)
1112
static inline void gen_op_eval_fbule(TCGv dst, TCGv src,
1113
                                    unsigned int fcc_offset)
1114
{
1115
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1116
    tcg_gen_xori_tl(dst, dst, 0x1);
1117
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1118
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1119
    tcg_gen_xori_tl(dst, dst, 0x1);
1120
}
1121

    
1122
// !3: !(FCC0 & FCC1)
1123
static inline void gen_op_eval_fbo(TCGv dst, TCGv src,
1124
                                    unsigned int fcc_offset)
1125
{
1126
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1127
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1128
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1129
    tcg_gen_xori_tl(dst, dst, 0x1);
1130
}
1131

    
1132
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
1133
                               target_ulong pc2, TCGv r_cond)
1134
{
1135
    int l1;
1136

    
1137
    l1 = gen_new_label();
1138

    
1139
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1140

    
1141
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
1142

    
1143
    gen_set_label(l1);
1144
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
1145
}
1146

    
1147
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
1148
                                target_ulong pc2, TCGv r_cond)
1149
{
1150
    int l1;
1151

    
1152
    l1 = gen_new_label();
1153

    
1154
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1155

    
1156
    gen_goto_tb(dc, 0, pc2, pc1);
1157

    
1158
    gen_set_label(l1);
1159
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
1160
}
1161

    
1162
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
1163
                                      TCGv r_cond)
1164
{
1165
    int l1, l2;
1166

    
1167
    l1 = gen_new_label();
1168
    l2 = gen_new_label();
1169

    
1170
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1171

    
1172
    tcg_gen_movi_tl(cpu_npc, npc1);
1173
    tcg_gen_br(l2);
1174

    
1175
    gen_set_label(l1);
1176
    tcg_gen_movi_tl(cpu_npc, npc2);
1177
    gen_set_label(l2);
1178
}
1179

    
1180
/* call this function before using the condition register as it may
1181
   have been set for a jump */
1182
static inline void flush_cond(DisasContext *dc, TCGv cond)
1183
{
1184
    if (dc->npc == JUMP_PC) {
1185
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1186
        dc->npc = DYNAMIC_PC;
1187
    }
1188
}
1189

    
1190
static inline void save_npc(DisasContext *dc, TCGv cond)
1191
{
1192
    if (dc->npc == JUMP_PC) {
1193
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1194
        dc->npc = DYNAMIC_PC;
1195
    } else if (dc->npc != DYNAMIC_PC) {
1196
        tcg_gen_movi_tl(cpu_npc, dc->npc);
1197
    }
1198
}
1199

    
1200
static inline void save_state(DisasContext *dc, TCGv cond)
1201
{
1202
    tcg_gen_movi_tl(cpu_pc, dc->pc);
1203
    save_npc(dc, cond);
1204
}
1205

    
1206
static inline void gen_mov_pc_npc(DisasContext *dc, TCGv cond)
1207
{
1208
    if (dc->npc == JUMP_PC) {
1209
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1210
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1211
        dc->pc = DYNAMIC_PC;
1212
    } else if (dc->npc == DYNAMIC_PC) {
1213
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1214
        dc->pc = DYNAMIC_PC;
1215
    } else {
1216
        dc->pc = dc->npc;
1217
    }
1218
}
1219

    
1220
static inline void gen_op_next_insn(void)
1221
{
1222
    tcg_gen_mov_tl(cpu_pc, cpu_npc);
1223
    tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
1224
}
1225

    
1226
static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond)
1227
{
1228
    TCGv r_src;
1229

    
1230
#ifdef TARGET_SPARC64
1231
    if (cc)
1232
        r_src = cpu_xcc;
1233
    else
1234
        r_src = cpu_psr;
1235
#else
1236
    r_src = cpu_psr;
1237
#endif
1238
    switch (cond) {
1239
    case 0x0:
1240
        gen_op_eval_bn(r_dst);
1241
        break;
1242
    case 0x1:
1243
        gen_op_eval_be(r_dst, r_src);
1244
        break;
1245
    case 0x2:
1246
        gen_op_eval_ble(r_dst, r_src);
1247
        break;
1248
    case 0x3:
1249
        gen_op_eval_bl(r_dst, r_src);
1250
        break;
1251
    case 0x4:
1252
        gen_op_eval_bleu(r_dst, r_src);
1253
        break;
1254
    case 0x5:
1255
        gen_op_eval_bcs(r_dst, r_src);
1256
        break;
1257
    case 0x6:
1258
        gen_op_eval_bneg(r_dst, r_src);
1259
        break;
1260
    case 0x7:
1261
        gen_op_eval_bvs(r_dst, r_src);
1262
        break;
1263
    case 0x8:
1264
        gen_op_eval_ba(r_dst);
1265
        break;
1266
    case 0x9:
1267
        gen_op_eval_bne(r_dst, r_src);
1268
        break;
1269
    case 0xa:
1270
        gen_op_eval_bg(r_dst, r_src);
1271
        break;
1272
    case 0xb:
1273
        gen_op_eval_bge(r_dst, r_src);
1274
        break;
1275
    case 0xc:
1276
        gen_op_eval_bgu(r_dst, r_src);
1277
        break;
1278
    case 0xd:
1279
        gen_op_eval_bcc(r_dst, r_src);
1280
        break;
1281
    case 0xe:
1282
        gen_op_eval_bpos(r_dst, r_src);
1283
        break;
1284
    case 0xf:
1285
        gen_op_eval_bvc(r_dst, r_src);
1286
        break;
1287
    }
1288
}
1289

    
1290
static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
1291
{
1292
    unsigned int offset;
1293

    
1294
    switch (cc) {
1295
    default:
1296
    case 0x0:
1297
        offset = 0;
1298
        break;
1299
    case 0x1:
1300
        offset = 32 - 10;
1301
        break;
1302
    case 0x2:
1303
        offset = 34 - 10;
1304
        break;
1305
    case 0x3:
1306
        offset = 36 - 10;
1307
        break;
1308
    }
1309

    
1310
    switch (cond) {
1311
    case 0x0:
1312
        gen_op_eval_bn(r_dst);
1313
        break;
1314
    case 0x1:
1315
        gen_op_eval_fbne(r_dst, cpu_fsr, offset);
1316
        break;
1317
    case 0x2:
1318
        gen_op_eval_fblg(r_dst, cpu_fsr, offset);
1319
        break;
1320
    case 0x3:
1321
        gen_op_eval_fbul(r_dst, cpu_fsr, offset);
1322
        break;
1323
    case 0x4:
1324
        gen_op_eval_fbl(r_dst, cpu_fsr, offset);
1325
        break;
1326
    case 0x5:
1327
        gen_op_eval_fbug(r_dst, cpu_fsr, offset);
1328
        break;
1329
    case 0x6:
1330
        gen_op_eval_fbg(r_dst, cpu_fsr, offset);
1331
        break;
1332
    case 0x7:
1333
        gen_op_eval_fbu(r_dst, cpu_fsr, offset);
1334
        break;
1335
    case 0x8:
1336
        gen_op_eval_ba(r_dst);
1337
        break;
1338
    case 0x9:
1339
        gen_op_eval_fbe(r_dst, cpu_fsr, offset);
1340
        break;
1341
    case 0xa:
1342
        gen_op_eval_fbue(r_dst, cpu_fsr, offset);
1343
        break;
1344
    case 0xb:
1345
        gen_op_eval_fbge(r_dst, cpu_fsr, offset);
1346
        break;
1347
    case 0xc:
1348
        gen_op_eval_fbuge(r_dst, cpu_fsr, offset);
1349
        break;
1350
    case 0xd:
1351
        gen_op_eval_fble(r_dst, cpu_fsr, offset);
1352
        break;
1353
    case 0xe:
1354
        gen_op_eval_fbule(r_dst, cpu_fsr, offset);
1355
        break;
1356
    case 0xf:
1357
        gen_op_eval_fbo(r_dst, cpu_fsr, offset);
1358
        break;
1359
    }
1360
}
1361

    
1362
#ifdef TARGET_SPARC64
1363
// Inverted logic
1364
static const int gen_tcg_cond_reg[8] = {
1365
    -1,
1366
    TCG_COND_NE,
1367
    TCG_COND_GT,
1368
    TCG_COND_GE,
1369
    -1,
1370
    TCG_COND_EQ,
1371
    TCG_COND_LE,
1372
    TCG_COND_LT,
1373
};
1374

    
1375
static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
1376
{
1377
    int l1;
1378

    
1379
    l1 = gen_new_label();
1380
    tcg_gen_movi_tl(r_dst, 0);
1381
    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], r_src, tcg_const_tl(0), l1);
1382
    tcg_gen_movi_tl(r_dst, 1);
1383
    gen_set_label(l1);
1384
}
1385
#endif
1386

    
1387
/* XXX: potentially incorrect if dynamic npc */
1388
static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1389
                      TCGv r_cond)
1390
{
1391
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1392
    target_ulong target = dc->pc + offset;
1393

    
1394
    if (cond == 0x0) {
1395
        /* unconditional not taken */
1396
        if (a) {
1397
            dc->pc = dc->npc + 4;
1398
            dc->npc = dc->pc + 4;
1399
        } else {
1400
            dc->pc = dc->npc;
1401
            dc->npc = dc->pc + 4;
1402
        }
1403
    } else if (cond == 0x8) {
1404
        /* unconditional taken */
1405
        if (a) {
1406
            dc->pc = target;
1407
            dc->npc = dc->pc + 4;
1408
        } else {
1409
            dc->pc = dc->npc;
1410
            dc->npc = target;
1411
        }
1412
    } else {
1413
        flush_cond(dc, r_cond);
1414
        gen_cond(r_cond, cc, cond);
1415
        if (a) {
1416
            gen_branch_a(dc, target, dc->npc, r_cond);
1417
            dc->is_br = 1;
1418
        } else {
1419
            dc->pc = dc->npc;
1420
            dc->jump_pc[0] = target;
1421
            dc->jump_pc[1] = dc->npc + 4;
1422
            dc->npc = JUMP_PC;
1423
        }
1424
    }
1425
}
1426

    
1427
/* XXX: potentially incorrect if dynamic npc */
1428
static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1429
                      TCGv r_cond)
1430
{
1431
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1432
    target_ulong target = dc->pc + offset;
1433

    
1434
    if (cond == 0x0) {
1435
        /* unconditional not taken */
1436
        if (a) {
1437
            dc->pc = dc->npc + 4;
1438
            dc->npc = dc->pc + 4;
1439
        } else {
1440
            dc->pc = dc->npc;
1441
            dc->npc = dc->pc + 4;
1442
        }
1443
    } else if (cond == 0x8) {
1444
        /* unconditional taken */
1445
        if (a) {
1446
            dc->pc = target;
1447
            dc->npc = dc->pc + 4;
1448
        } else {
1449
            dc->pc = dc->npc;
1450
            dc->npc = target;
1451
        }
1452
    } else {
1453
        flush_cond(dc, r_cond);
1454
        gen_fcond(r_cond, cc, cond);
1455
        if (a) {
1456
            gen_branch_a(dc, target, dc->npc, r_cond);
1457
            dc->is_br = 1;
1458
        } else {
1459
            dc->pc = dc->npc;
1460
            dc->jump_pc[0] = target;
1461
            dc->jump_pc[1] = dc->npc + 4;
1462
            dc->npc = JUMP_PC;
1463
        }
1464
    }
1465
}
1466

    
1467
#ifdef TARGET_SPARC64
1468
/* XXX: potentially incorrect if dynamic npc */
1469
static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
1470
                          TCGv r_cond, TCGv r_reg)
1471
{
1472
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1473
    target_ulong target = dc->pc + offset;
1474

    
1475
    flush_cond(dc, r_cond);
1476
    gen_cond_reg(r_cond, cond, r_reg);
1477
    if (a) {
1478
        gen_branch_a(dc, target, dc->npc, r_cond);
1479
        dc->is_br = 1;
1480
    } else {
1481
        dc->pc = dc->npc;
1482
        dc->jump_pc[0] = target;
1483
        dc->jump_pc[1] = dc->npc + 4;
1484
        dc->npc = JUMP_PC;
1485
    }
1486
}
1487

    
1488
static GenOpFunc * const gen_fcmps[4] = {
1489
    helper_fcmps,
1490
    helper_fcmps_fcc1,
1491
    helper_fcmps_fcc2,
1492
    helper_fcmps_fcc3,
1493
};
1494

    
1495
static GenOpFunc * const gen_fcmpd[4] = {
1496
    helper_fcmpd,
1497
    helper_fcmpd_fcc1,
1498
    helper_fcmpd_fcc2,
1499
    helper_fcmpd_fcc3,
1500
};
1501

    
1502
#if defined(CONFIG_USER_ONLY)
1503
static GenOpFunc * const gen_fcmpq[4] = {
1504
    helper_fcmpq,
1505
    helper_fcmpq_fcc1,
1506
    helper_fcmpq_fcc2,
1507
    helper_fcmpq_fcc3,
1508
};
1509
#endif
1510

    
1511
static GenOpFunc * const gen_fcmpes[4] = {
1512
    helper_fcmpes,
1513
    helper_fcmpes_fcc1,
1514
    helper_fcmpes_fcc2,
1515
    helper_fcmpes_fcc3,
1516
};
1517

    
1518
static GenOpFunc * const gen_fcmped[4] = {
1519
    helper_fcmped,
1520
    helper_fcmped_fcc1,
1521
    helper_fcmped_fcc2,
1522
    helper_fcmped_fcc3,
1523
};
1524

    
1525
#if defined(CONFIG_USER_ONLY)
1526
static GenOpFunc * const gen_fcmpeq[4] = {
1527
    helper_fcmpeq,
1528
    helper_fcmpeq_fcc1,
1529
    helper_fcmpeq_fcc2,
1530
    helper_fcmpeq_fcc3,
1531
};
1532
#endif
1533

    
1534
static inline void gen_op_fcmps(int fccno)
1535
{
1536
    tcg_gen_helper_0_0(gen_fcmps[fccno]);
1537
}
1538

    
1539
static inline void gen_op_fcmpd(int fccno)
1540
{
1541
    tcg_gen_helper_0_0(gen_fcmpd[fccno]);
1542
}
1543

    
1544
#if defined(CONFIG_USER_ONLY)
1545
static inline void gen_op_fcmpq(int fccno)
1546
{
1547
    tcg_gen_helper_0_0(gen_fcmpq[fccno]);
1548
}
1549
#endif
1550

    
1551
static inline void gen_op_fcmpes(int fccno)
1552
{
1553
    tcg_gen_helper_0_0(gen_fcmpes[fccno]);
1554
}
1555

    
1556
static inline void gen_op_fcmped(int fccno)
1557
{
1558
    tcg_gen_helper_0_0(gen_fcmped[fccno]);
1559
}
1560

    
1561
#if defined(CONFIG_USER_ONLY)
1562
static inline void gen_op_fcmpeq(int fccno)
1563
{
1564
    tcg_gen_helper_0_0(gen_fcmpeq[fccno]);
1565
}
1566
#endif
1567

    
1568
#else
1569

    
1570
static inline void gen_op_fcmps(int fccno)
1571
{
1572
    tcg_gen_helper_0_0(helper_fcmps);
1573
}
1574

    
1575
static inline void gen_op_fcmpd(int fccno)
1576
{
1577
    tcg_gen_helper_0_0(helper_fcmpd);
1578
}
1579

    
1580
#if defined(CONFIG_USER_ONLY)
1581
static inline void gen_op_fcmpq(int fccno)
1582
{
1583
    tcg_gen_helper_0_0(helper_fcmpq);
1584
}
1585
#endif
1586

    
1587
static inline void gen_op_fcmpes(int fccno)
1588
{
1589
    tcg_gen_helper_0_0(helper_fcmpes);
1590
}
1591

    
1592
static inline void gen_op_fcmped(int fccno)
1593
{
1594
    tcg_gen_helper_0_0(helper_fcmped);
1595
}
1596

    
1597
#if defined(CONFIG_USER_ONLY)
1598
static inline void gen_op_fcmpeq(int fccno)
1599
{
1600
    tcg_gen_helper_0_0(helper_fcmpeq);
1601
}
1602
#endif
1603

    
1604
#endif
1605

    
1606
static inline void gen_op_fpexception_im(int fsr_flags)
1607
{
1608
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~FSR_FTT_MASK);
1609
    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
1610
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_FP_EXCP));
1611
}
1612

    
1613
static int gen_trap_ifnofpu(DisasContext *dc, TCGv r_cond)
1614
{
1615
#if !defined(CONFIG_USER_ONLY)
1616
    if (!dc->fpu_enabled) {
1617
        save_state(dc, r_cond);
1618
        tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_NFPU_INSN));
1619
        dc->is_br = 1;
1620
        return 1;
1621
    }
1622
#endif
1623
    return 0;
1624
}
1625

    
1626
static inline void gen_op_clear_ieee_excp_and_FTT(void)
1627
{
1628
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~(FSR_FTT_MASK | FSR_CEXC_MASK));
1629
}
1630

    
1631
static inline void gen_clear_float_exceptions(void)
1632
{
1633
    tcg_gen_helper_0_0(helper_clear_float_exceptions);
1634
}
1635

    
1636
/* asi moves */
1637
#ifdef TARGET_SPARC64
1638
static inline TCGv gen_get_asi(int insn, TCGv r_addr)
1639
{
1640
    int asi, offset;
1641
    TCGv r_asi;
1642

    
1643
    if (IS_IMM) {
1644
        r_asi = tcg_temp_new(TCG_TYPE_I32);
1645
        offset = GET_FIELD(insn, 25, 31);
1646
        tcg_gen_addi_tl(r_addr, r_addr, offset);
1647
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
1648
    } else {
1649
        asi = GET_FIELD(insn, 19, 26);
1650
        r_asi = tcg_const_i32(asi);
1651
    }
1652
    return r_asi;
1653
}
1654

    
1655
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size, int sign)
1656
{
1657
    TCGv r_asi;
1658

    
1659
    r_asi = gen_get_asi(insn, addr);
1660
    tcg_gen_helper_1_4(helper_ld_asi, dst, addr, r_asi,
1661
                       tcg_const_i32(size), tcg_const_i32(sign));
1662
    tcg_gen_discard_i32(r_asi);
1663
}
1664

    
1665
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1666
{
1667
    TCGv r_asi;
1668

    
1669
    r_asi = gen_get_asi(insn, addr);
1670
    tcg_gen_helper_0_4(helper_st_asi, addr, src, r_asi, tcg_const_i32(size));
1671
    tcg_gen_discard_i32(r_asi);
1672
}
1673

    
1674
static inline void gen_ldf_asi(TCGv addr, int insn, int size, int rd)
1675
{
1676
    TCGv r_asi;
1677

    
1678
    r_asi = gen_get_asi(insn, addr);
1679
    tcg_gen_helper_0_4(helper_ldf_asi, addr, r_asi, tcg_const_i32(size),
1680
                       tcg_const_i32(rd));
1681
    tcg_gen_discard_i32(r_asi);
1682
}
1683

    
1684
static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
1685
{
1686
    TCGv r_asi;
1687

    
1688
    r_asi = gen_get_asi(insn, addr);
1689
    tcg_gen_helper_0_4(helper_stf_asi, addr, r_asi, tcg_const_i32(size),
1690
                       tcg_const_i32(rd));
1691
    tcg_gen_discard_i32(r_asi);
1692
}
1693

    
1694
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1695
{
1696
    TCGv r_temp, r_asi;
1697

    
1698
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1699
    r_asi = gen_get_asi(insn, addr);
1700
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, addr, r_asi,
1701
                       tcg_const_i32(4), tcg_const_i32(0));
1702
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, r_asi,
1703
                       tcg_const_i32(4));
1704
    tcg_gen_extu_i32_tl(dst, r_temp);
1705
    tcg_gen_discard_i32(r_asi);
1706
    tcg_gen_discard_i32(r_temp);
1707
}
1708

    
1709
static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn)
1710
{
1711
    TCGv r_asi;
1712

    
1713
    r_asi = gen_get_asi(insn, addr);
1714
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi,
1715
                       tcg_const_i32(8), tcg_const_i32(0));
1716
    tcg_gen_andi_i64(lo, cpu_tmp64, 0xffffffffULL);
1717
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1718
    tcg_gen_andi_i64(hi, cpu_tmp64, 0xffffffffULL);
1719
    tcg_gen_discard_i32(r_asi);
1720
}
1721

    
1722
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1723
{
1724
    TCGv r_temp, r_asi;
1725

    
1726
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1727
    gen_movl_reg_TN(rd + 1, r_temp);
1728
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi,
1729
                       r_temp);
1730
    r_asi = gen_get_asi(insn, addr);
1731
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi,
1732
                       tcg_const_i32(8));
1733
    tcg_gen_discard_i32(r_asi);
1734
    tcg_gen_discard_i32(r_temp);
1735
}
1736

    
1737
static inline void gen_cas_asi(TCGv dst, TCGv addr, TCGv val2, int insn, int rd)
1738
{
1739
    TCGv r_val1, r_asi;
1740

    
1741
    r_val1 = tcg_temp_new(TCG_TYPE_I32);
1742
    gen_movl_reg_TN(rd, r_val1);
1743
    r_asi = gen_get_asi(insn, addr);
1744
    tcg_gen_helper_1_4(helper_cas_asi, dst, addr, r_val1, val2, r_asi);
1745
    tcg_gen_discard_i32(r_asi);
1746
    tcg_gen_discard_i32(r_val1);
1747
}
1748

    
1749
static inline void gen_casx_asi(TCGv dst, TCGv addr, TCGv val2, int insn, int rd)
1750
{
1751
    TCGv r_asi;
1752

    
1753
    gen_movl_reg_TN(rd, cpu_tmp64);
1754
    r_asi = gen_get_asi(insn, addr);
1755
    tcg_gen_helper_1_4(helper_casx_asi, dst, addr, cpu_tmp64, val2, r_asi);
1756
    tcg_gen_discard_i32(r_asi);
1757
}
1758

    
1759
#elif !defined(CONFIG_USER_ONLY)
1760

    
1761
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size, int sign)
1762
{
1763
    int asi;
1764

    
1765
    asi = GET_FIELD(insn, 19, 26);
1766
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, tcg_const_i32(asi),
1767
                       tcg_const_i32(size), tcg_const_i32(sign));
1768
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1769
}
1770

    
1771
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1772
{
1773
    int asi;
1774

    
1775
    tcg_gen_extu_tl_i64(cpu_tmp64, src);
1776
    asi = GET_FIELD(insn, 19, 26);
1777
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, tcg_const_i32(asi),
1778
                       tcg_const_i32(size));
1779
}
1780

    
1781
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1782
{
1783
    int asi;
1784
    TCGv r_temp;
1785

    
1786
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1787
    asi = GET_FIELD(insn, 19, 26);
1788
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, addr, tcg_const_i32(asi),
1789
                       tcg_const_i32(4), tcg_const_i32(0));
1790
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, tcg_const_i32(asi),
1791
                       tcg_const_i32(4));
1792
    tcg_gen_extu_i32_tl(dst, r_temp);
1793
    tcg_gen_discard_i32(r_temp);
1794
}
1795

    
1796
static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn)
1797
{
1798
    int asi;
1799

    
1800
    asi = GET_FIELD(insn, 19, 26);
1801
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, tcg_const_i32(asi),
1802
                       tcg_const_i32(8), tcg_const_i32(0));
1803
    tcg_gen_trunc_i64_tl(lo, cpu_tmp64);
1804
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1805
    tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
1806
}
1807

    
1808
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1809
{
1810
    int asi;
1811
    TCGv r_temp;
1812

    
1813
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1814
    gen_movl_reg_TN(rd + 1, r_temp);
1815
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi, r_temp);
1816
    asi = GET_FIELD(insn, 19, 26);
1817
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, tcg_const_i32(asi),
1818
                       tcg_const_i32(8));
1819
}
1820
#endif
1821

    
1822
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1823
static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
1824
{
1825
    int asi;
1826

    
1827
    gen_ld_asi(dst, addr, insn, 1, 0);
1828

    
1829
    asi = GET_FIELD(insn, 19, 26);
1830
    tcg_gen_helper_0_4(helper_st_asi, addr, tcg_const_i64(0xffULL),
1831
                       tcg_const_i32(asi), tcg_const_i32(1));
1832
}
1833
#endif
1834

    
1835
/* before an instruction, dc->pc must be static */
1836
static void disas_sparc_insn(DisasContext * dc)
1837
{
1838
    unsigned int insn, opc, rs1, rs2, rd;
1839

    
1840
    insn = ldl_code(dc->pc);
1841
    opc = GET_FIELD(insn, 0, 1);
1842

    
1843
    rd = GET_FIELD(insn, 2, 6);
1844
    switch (opc) {
1845
    case 0:                     /* branches/sethi */
1846
        {
1847
            unsigned int xop = GET_FIELD(insn, 7, 9);
1848
            int32_t target;
1849
            switch (xop) {
1850
#ifdef TARGET_SPARC64
1851
            case 0x1:           /* V9 BPcc */
1852
                {
1853
                    int cc;
1854

    
1855
                    target = GET_FIELD_SP(insn, 0, 18);
1856
                    target = sign_extend(target, 18);
1857
                    target <<= 2;
1858
                    cc = GET_FIELD_SP(insn, 20, 21);
1859
                    if (cc == 0)
1860
                        do_branch(dc, target, insn, 0, cpu_T[2]);
1861
                    else if (cc == 2)
1862
                        do_branch(dc, target, insn, 1, cpu_T[2]);
1863
                    else
1864
                        goto illegal_insn;
1865
                    goto jmp_insn;
1866
                }
1867
            case 0x3:           /* V9 BPr */
1868
                {
1869
                    target = GET_FIELD_SP(insn, 0, 13) |
1870
                        (GET_FIELD_SP(insn, 20, 21) << 14);
1871
                    target = sign_extend(target, 16);
1872
                    target <<= 2;
1873
                    rs1 = GET_FIELD(insn, 13, 17);
1874
                    gen_movl_reg_TN(rs1, cpu_T[0]);
1875
                    do_branch_reg(dc, target, insn, cpu_T[2], cpu_T[0]);
1876
                    goto jmp_insn;
1877
                }
1878
            case 0x5:           /* V9 FBPcc */
1879
                {
1880
                    int cc = GET_FIELD_SP(insn, 20, 21);
1881
                    if (gen_trap_ifnofpu(dc, cpu_T[2]))
1882
                        goto jmp_insn;
1883
                    target = GET_FIELD_SP(insn, 0, 18);
1884
                    target = sign_extend(target, 19);
1885
                    target <<= 2;
1886
                    do_fbranch(dc, target, insn, cc, cpu_T[2]);
1887
                    goto jmp_insn;
1888
                }
1889
#else
1890
            case 0x7:           /* CBN+x */
1891
                {
1892
                    goto ncp_insn;
1893
                }
1894
#endif
1895
            case 0x2:           /* BN+x */
1896
                {
1897
                    target = GET_FIELD(insn, 10, 31);
1898
                    target = sign_extend(target, 22);
1899
                    target <<= 2;
1900
                    do_branch(dc, target, insn, 0, cpu_T[2]);
1901
                    goto jmp_insn;
1902
                }
1903
            case 0x6:           /* FBN+x */
1904
                {
1905
                    if (gen_trap_ifnofpu(dc, cpu_T[2]))
1906
                        goto jmp_insn;
1907
                    target = GET_FIELD(insn, 10, 31);
1908
                    target = sign_extend(target, 22);
1909
                    target <<= 2;
1910
                    do_fbranch(dc, target, insn, 0, cpu_T[2]);
1911
                    goto jmp_insn;
1912
                }
1913
            case 0x4:           /* SETHI */
1914
#define OPTIM
1915
#if defined(OPTIM)
1916
                if (rd) { // nop
1917
#endif
1918
                    uint32_t value = GET_FIELD(insn, 10, 31);
1919
                    tcg_gen_movi_tl(cpu_T[0], value << 10);
1920
                    gen_movl_TN_reg(rd, cpu_T[0]);
1921
#if defined(OPTIM)
1922
                }
1923
#endif
1924
                break;
1925
            case 0x0:           /* UNIMPL */
1926
            default:
1927
                goto illegal_insn;
1928
            }
1929
            break;
1930
        }
1931
        break;
1932
    case 1:
1933
        /*CALL*/ {
1934
            target_long target = GET_FIELDs(insn, 2, 31) << 2;
1935

    
1936
            gen_movl_TN_reg(15, tcg_const_tl(dc->pc));
1937
            target += dc->pc;
1938
            gen_mov_pc_npc(dc, cpu_T[2]);
1939
            dc->npc = target;
1940
        }
1941
        goto jmp_insn;
1942
    case 2:                     /* FPU & Logical Operations */
1943
        {
1944
            unsigned int xop = GET_FIELD(insn, 7, 12);
1945
            if (xop == 0x3a) {  /* generate trap */
1946
                int cond;
1947

    
1948
                rs1 = GET_FIELD(insn, 13, 17);
1949
                gen_movl_reg_TN(rs1, cpu_T[0]);
1950
                if (IS_IMM) {
1951
                    rs2 = GET_FIELD(insn, 25, 31);
1952
                    tcg_gen_addi_tl(cpu_T[0], cpu_T[0], rs2);
1953
                } else {
1954
                    rs2 = GET_FIELD(insn, 27, 31);
1955
#if defined(OPTIM)
1956
                    if (rs2 != 0) {
1957
#endif
1958
                        gen_movl_reg_TN(rs2, cpu_T[1]);
1959
                        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1960
#if defined(OPTIM)
1961
                    }
1962
#endif
1963
                }
1964
                cond = GET_FIELD(insn, 3, 6);
1965
                if (cond == 0x8) {
1966
                    save_state(dc, cpu_T[2]);
1967
                    tcg_gen_helper_0_1(helper_trap, cpu_T[0]);
1968
                } else if (cond != 0) {
1969
                    TCGv r_cond = tcg_temp_new(TCG_TYPE_TL);
1970
#ifdef TARGET_SPARC64
1971
                    /* V9 icc/xcc */
1972
                    int cc = GET_FIELD_SP(insn, 11, 12);
1973

    
1974
                    save_state(dc, cpu_T[2]);
1975
                    if (cc == 0)
1976
                        gen_cond(r_cond, 0, cond);
1977
                    else if (cc == 2)
1978
                        gen_cond(r_cond, 1, cond);
1979
                    else
1980
                        goto illegal_insn;
1981
#else
1982
                    save_state(dc, cpu_T[2]);
1983
                    gen_cond(r_cond, 0, cond);
1984
#endif
1985
                    tcg_gen_helper_0_2(helper_trapcc, cpu_T[0], r_cond);
1986
                    tcg_gen_discard_tl(r_cond);
1987
                }
1988
                gen_op_next_insn();
1989
                tcg_gen_exit_tb(0);
1990
                dc->is_br = 1;
1991
                goto jmp_insn;
1992
            } else if (xop == 0x28) {
1993
                rs1 = GET_FIELD(insn, 13, 17);
1994
                switch(rs1) {
1995
                case 0: /* rdy */
1996
#ifndef TARGET_SPARC64
1997
                case 0x01 ... 0x0e: /* undefined in the SPARCv8
1998
                                       manual, rdy on the microSPARC
1999
                                       II */
2000
                case 0x0f:          /* stbar in the SPARCv8 manual,
2001
                                       rdy on the microSPARC II */
2002
                case 0x10 ... 0x1f: /* implementation-dependent in the
2003
                                       SPARCv8 manual, rdy on the
2004
                                       microSPARC II */
2005
#endif
2006
                    tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, y));
2007
                    gen_movl_TN_reg(rd, cpu_T[0]);
2008
                    break;
2009
#ifdef TARGET_SPARC64
2010
                case 0x2: /* V9 rdccr */
2011
                    tcg_gen_helper_1_0(helper_rdccr, cpu_T[0]);
2012
                    gen_movl_TN_reg(rd, cpu_T[0]);
2013
                    break;
2014
                case 0x3: /* V9 rdasi */
2015
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, asi));
2016
                    tcg_gen_ext_i32_tl(cpu_T[0], cpu_tmp32);
2017
                    gen_movl_TN_reg(rd, cpu_T[0]);
2018
                    break;
2019
                case 0x4: /* V9 rdtick */
2020
                    {
2021
                        TCGv r_tickptr;
2022

    
2023
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2024
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2025
                                       offsetof(CPUState, tick));
2026
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_T[0],
2027
                                           r_tickptr);
2028
                        gen_movl_TN_reg(rd, cpu_T[0]);
2029
                        tcg_gen_discard_ptr(r_tickptr);
2030
                    }
2031
                    break;
2032
                case 0x5: /* V9 rdpc */
2033
                    tcg_gen_movi_tl(cpu_T[0], dc->pc);
2034
                    gen_movl_TN_reg(rd, cpu_T[0]);
2035
                    break;
2036
                case 0x6: /* V9 rdfprs */
2037
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fprs));
2038
                    tcg_gen_ext_i32_tl(cpu_T[0], cpu_tmp32);
2039
                    gen_movl_TN_reg(rd, cpu_T[0]);
2040
                    break;
2041
                case 0xf: /* V9 membar */
2042
                    break; /* no effect */
2043
                case 0x13: /* Graphics Status */
2044
                    if (gen_trap_ifnofpu(dc, cpu_T[2]))
2045
                        goto jmp_insn;
2046
                    tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, gsr));
2047
                    gen_movl_TN_reg(rd, cpu_T[0]);
2048
                    break;
2049
                case 0x17: /* Tick compare */
2050
                    tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, tick_cmpr));
2051
                    gen_movl_TN_reg(rd, cpu_T[0]);
2052
                    break;
2053
                case 0x18: /* System tick */
2054
                    {
2055
                        TCGv r_tickptr;
2056

    
2057
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2058
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2059
                                       offsetof(CPUState, stick));
2060
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_T[0],
2061
                                           r_tickptr);
2062
                        gen_movl_TN_reg(rd, cpu_T[0]);
2063
                        tcg_gen_discard_ptr(r_tickptr);
2064
                    }
2065
                    break;
2066
                case 0x19: /* System tick compare */
2067
                    tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, stick_cmpr));
2068
                    gen_movl_TN_reg(rd, cpu_T[0]);
2069
                    break;
2070
                case 0x10: /* Performance Control */
2071
                case 0x11: /* Performance Instrumentation Counter */
2072
                case 0x12: /* Dispatch Control */
2073
                case 0x14: /* Softint set, WO */
2074
                case 0x15: /* Softint clear, WO */
2075
                case 0x16: /* Softint write */
2076
#endif
2077
                default:
2078
                    goto illegal_insn;
2079
                }
2080
#if !defined(CONFIG_USER_ONLY)
2081
            } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
2082
#ifndef TARGET_SPARC64
2083
                if (!supervisor(dc))
2084
                    goto priv_insn;
2085
                tcg_gen_helper_1_0(helper_rdpsr, cpu_T[0]);
2086
#else
2087
                if (!hypervisor(dc))
2088
                    goto priv_insn;
2089
                rs1 = GET_FIELD(insn, 13, 17);
2090
                switch (rs1) {
2091
                case 0: // hpstate
2092
                    // gen_op_rdhpstate();
2093
                    break;
2094
                case 1: // htstate
2095
                    // gen_op_rdhtstate();
2096
                    break;
2097
                case 3: // hintp
2098
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, hintp));
2099
                    tcg_gen_ext_i32_tl(cpu_T[0], cpu_tmp32);
2100
                    break;
2101
                case 5: // htba
2102
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, htba));
2103
                    tcg_gen_ext_i32_tl(cpu_T[0], cpu_tmp32);
2104
                    break;
2105
                case 6: // hver
2106
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, hver));
2107
                    tcg_gen_ext_i32_tl(cpu_T[0], cpu_tmp32);
2108
                    break;
2109
                case 31: // hstick_cmpr
2110
                    tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
2111
                    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, hstick_cmpr));
2112
                    break;
2113
                default:
2114
                    goto illegal_insn;
2115
                }
2116
#endif
2117
                gen_movl_TN_reg(rd, cpu_T[0]);
2118
                break;
2119
            } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
2120
                if (!supervisor(dc))
2121
                    goto priv_insn;
2122
#ifdef TARGET_SPARC64
2123
                rs1 = GET_FIELD(insn, 13, 17);
2124
                switch (rs1) {
2125
                case 0: // tpc
2126
                    {
2127
                        TCGv r_tsptr;
2128

    
2129
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2130
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2131
                                       offsetof(CPUState, tsptr));
2132
                        tcg_gen_ld_tl(cpu_T[0], r_tsptr,
2133
                                      offsetof(trap_state, tpc));
2134
                        tcg_gen_discard_ptr(r_tsptr);
2135
                    }
2136
                    break;
2137
                case 1: // tnpc
2138
                    {
2139
                        TCGv r_tsptr;
2140

    
2141
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2142
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2143
                                       offsetof(CPUState, tsptr));
2144
                        tcg_gen_ld_tl(cpu_T[0], r_tsptr,
2145
                                      offsetof(trap_state, tnpc));
2146
                        tcg_gen_discard_ptr(r_tsptr);
2147
                    }
2148
                    break;
2149
                case 2: // tstate
2150
                    {
2151
                        TCGv r_tsptr;
2152

    
2153
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2154
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2155
                                       offsetof(CPUState, tsptr));
2156
                        tcg_gen_ld_tl(cpu_T[0], r_tsptr,
2157
                                      offsetof(trap_state, tstate));
2158
                        tcg_gen_discard_ptr(r_tsptr);
2159
                    }
2160
                    break;
2161
                case 3: // tt
2162
                    {
2163
                        TCGv r_tsptr;
2164

    
2165
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2166
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2167
                                       offsetof(CPUState, tsptr));
2168
                        tcg_gen_ld_i32(cpu_T[0], r_tsptr,
2169
                                       offsetof(trap_state, tt));
2170
                        tcg_gen_discard_ptr(r_tsptr);
2171
                    }
2172
                    break;
2173
                case 4: // tick
2174
                    {
2175
                        TCGv r_tickptr;
2176

    
2177
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2178
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2179
                                       offsetof(CPUState, tick));
2180
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_T[0],
2181
                                           r_tickptr);
2182
                        gen_movl_TN_reg(rd, cpu_T[0]);
2183
                        tcg_gen_discard_ptr(r_tickptr);
2184
                    }
2185
                    break;
2186
                case 5: // tba
2187
                    tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, tbr));
2188
                    break;
2189
                case 6: // pstate
2190
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, pstate));
2191
                    tcg_gen_ext_i32_tl(cpu_T[0], cpu_tmp32);
2192
                    break;
2193
                case 7: // tl
2194
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, tl));
2195
                    tcg_gen_ext_i32_tl(cpu_T[0], cpu_tmp32);
2196
                    break;
2197
                case 8: // pil
2198
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, psrpil));
2199
                    tcg_gen_ext_i32_tl(cpu_T[0], cpu_tmp32);
2200
                    break;
2201
                case 9: // cwp
2202
                    tcg_gen_helper_1_0(helper_rdcwp, cpu_T[0]);
2203
                    break;
2204
                case 10: // cansave
2205
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, cansave));
2206
                    tcg_gen_ext_i32_tl(cpu_T[0], cpu_tmp32);
2207
                    break;
2208
                case 11: // canrestore
2209
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, canrestore));
2210
                    tcg_gen_ext_i32_tl(cpu_T[0], cpu_tmp32);
2211
                    break;
2212
                case 12: // cleanwin
2213
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, cleanwin));
2214
                    tcg_gen_ext_i32_tl(cpu_T[0], cpu_tmp32);
2215
                    break;
2216
                case 13: // otherwin
2217
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, otherwin));
2218
                    tcg_gen_ext_i32_tl(cpu_T[0], cpu_tmp32);
2219
                    break;
2220
                case 14: // wstate
2221
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, wstate));
2222
                    tcg_gen_ext_i32_tl(cpu_T[0], cpu_tmp32);
2223
                    break;
2224
                case 16: // UA2005 gl
2225
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, gl));
2226
                    tcg_gen_ext_i32_tl(cpu_T[0], cpu_tmp32);
2227
                    break;
2228
                case 26: // UA2005 strand status
2229
                    if (!hypervisor(dc))
2230
                        goto priv_insn;
2231
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ssr));
2232
                    tcg_gen_ext_i32_tl(cpu_T[0], cpu_tmp32);
2233
                    break;
2234
                case 31: // ver
2235
                    tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, version));
2236
                    break;
2237
                case 15: // fq
2238
                default:
2239
                    goto illegal_insn;
2240
                }
2241
#else
2242
                tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, wim));
2243
                tcg_gen_ext_i32_tl(cpu_T[0], cpu_tmp32);
2244
#endif
2245
                gen_movl_TN_reg(rd, cpu_T[0]);
2246
                break;
2247
            } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
2248
#ifdef TARGET_SPARC64
2249
                tcg_gen_helper_0_0(helper_flushw);
2250
#else
2251
                if (!supervisor(dc))
2252
                    goto priv_insn;
2253
                tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, tbr));
2254
                gen_movl_TN_reg(rd, cpu_T[0]);
2255
#endif
2256
                break;
2257
#endif
2258
            } else if (xop == 0x34) {   /* FPU Operations */
2259
                if (gen_trap_ifnofpu(dc, cpu_T[2]))
2260
                    goto jmp_insn;
2261
                gen_op_clear_ieee_excp_and_FTT();
2262
                rs1 = GET_FIELD(insn, 13, 17);
2263
                rs2 = GET_FIELD(insn, 27, 31);
2264
                xop = GET_FIELD(insn, 18, 26);
2265
                switch (xop) {
2266
                    case 0x1: /* fmovs */
2267
                        gen_op_load_fpr_FT0(rs2);
2268
                        gen_op_store_FT0_fpr(rd);
2269
                        break;
2270
                    case 0x5: /* fnegs */
2271
                        gen_op_load_fpr_FT1(rs2);
2272
                        tcg_gen_helper_0_0(helper_fnegs);
2273
                        gen_op_store_FT0_fpr(rd);
2274
                        break;
2275
                    case 0x9: /* fabss */
2276
                        gen_op_load_fpr_FT1(rs2);
2277
                        tcg_gen_helper_0_0(helper_fabss);
2278
                        gen_op_store_FT0_fpr(rd);
2279
                        break;
2280
                    case 0x29: /* fsqrts */
2281
                        gen_op_load_fpr_FT1(rs2);
2282
                        gen_clear_float_exceptions();
2283
                        tcg_gen_helper_0_0(helper_fsqrts);
2284
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2285
                        gen_op_store_FT0_fpr(rd);
2286
                        break;
2287
                    case 0x2a: /* fsqrtd */
2288
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2289
                        gen_clear_float_exceptions();
2290
                        tcg_gen_helper_0_0(helper_fsqrtd);
2291
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2292
                        gen_op_store_DT0_fpr(DFPREG(rd));
2293
                        break;
2294
                    case 0x2b: /* fsqrtq */
2295
#if defined(CONFIG_USER_ONLY)
2296
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2297
                        gen_clear_float_exceptions();
2298
                        tcg_gen_helper_0_0(helper_fsqrtq);
2299
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2300
                        gen_op_store_QT0_fpr(QFPREG(rd));
2301
                        break;
2302
#else
2303
                        goto nfpu_insn;
2304
#endif
2305
                    case 0x41:
2306
                        gen_op_load_fpr_FT0(rs1);
2307
                        gen_op_load_fpr_FT1(rs2);
2308
                        gen_clear_float_exceptions();
2309
                        tcg_gen_helper_0_0(helper_fadds);
2310
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2311
                        gen_op_store_FT0_fpr(rd);
2312
                        break;
2313
                    case 0x42:
2314
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2315
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2316
                        gen_clear_float_exceptions();
2317
                        tcg_gen_helper_0_0(helper_faddd);
2318
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2319
                        gen_op_store_DT0_fpr(DFPREG(rd));
2320
                        break;
2321
                    case 0x43: /* faddq */
2322
#if defined(CONFIG_USER_ONLY)
2323
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2324
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2325
                        gen_clear_float_exceptions();
2326
                        tcg_gen_helper_0_0(helper_faddq);
2327
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2328
                        gen_op_store_QT0_fpr(QFPREG(rd));
2329
                        break;
2330
#else
2331
                        goto nfpu_insn;
2332
#endif
2333
                    case 0x45:
2334
                        gen_op_load_fpr_FT0(rs1);
2335
                        gen_op_load_fpr_FT1(rs2);
2336
                        gen_clear_float_exceptions();
2337
                        tcg_gen_helper_0_0(helper_fsubs);
2338
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2339
                        gen_op_store_FT0_fpr(rd);
2340
                        break;
2341
                    case 0x46:
2342
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2343
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2344
                        gen_clear_float_exceptions();
2345
                        tcg_gen_helper_0_0(helper_fsubd);
2346
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2347
                        gen_op_store_DT0_fpr(DFPREG(rd));
2348
                        break;
2349
                    case 0x47: /* fsubq */
2350
#if defined(CONFIG_USER_ONLY)
2351
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2352
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2353
                        gen_clear_float_exceptions();
2354
                        tcg_gen_helper_0_0(helper_fsubq);
2355
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2356
                        gen_op_store_QT0_fpr(QFPREG(rd));
2357
                        break;
2358
#else
2359
                        goto nfpu_insn;
2360
#endif
2361
                    case 0x49:
2362
                        gen_op_load_fpr_FT0(rs1);
2363
                        gen_op_load_fpr_FT1(rs2);
2364
                        gen_clear_float_exceptions();
2365
                        tcg_gen_helper_0_0(helper_fmuls);
2366
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2367
                        gen_op_store_FT0_fpr(rd);
2368
                        break;
2369
                    case 0x4a:
2370
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2371
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2372
                        gen_clear_float_exceptions();
2373
                        tcg_gen_helper_0_0(helper_fmuld);
2374
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2375
                        gen_op_store_DT0_fpr(DFPREG(rd));
2376
                        break;
2377
                    case 0x4b: /* fmulq */
2378
#if defined(CONFIG_USER_ONLY)
2379
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2380
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2381
                        gen_clear_float_exceptions();
2382
                        tcg_gen_helper_0_0(helper_fmulq);
2383
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2384
                        gen_op_store_QT0_fpr(QFPREG(rd));
2385
                        break;
2386
#else
2387
                        goto nfpu_insn;
2388
#endif
2389
                    case 0x4d:
2390
                        gen_op_load_fpr_FT0(rs1);
2391
                        gen_op_load_fpr_FT1(rs2);
2392
                        gen_clear_float_exceptions();
2393
                        tcg_gen_helper_0_0(helper_fdivs);
2394
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2395
                        gen_op_store_FT0_fpr(rd);
2396
                        break;
2397
                    case 0x4e:
2398
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2399
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2400
                        gen_clear_float_exceptions();
2401
                        tcg_gen_helper_0_0(helper_fdivd);
2402
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2403
                        gen_op_store_DT0_fpr(DFPREG(rd));
2404
                        break;
2405
                    case 0x4f: /* fdivq */
2406
#if defined(CONFIG_USER_ONLY)
2407
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2408
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2409
                        gen_clear_float_exceptions();
2410
                        tcg_gen_helper_0_0(helper_fdivq);
2411
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2412
                        gen_op_store_QT0_fpr(QFPREG(rd));
2413
                        break;
2414
#else
2415
                        goto nfpu_insn;
2416
#endif
2417
                    case 0x69:
2418
                        gen_op_load_fpr_FT0(rs1);
2419
                        gen_op_load_fpr_FT1(rs2);
2420
                        gen_clear_float_exceptions();
2421
                        tcg_gen_helper_0_0(helper_fsmuld);
2422
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2423
                        gen_op_store_DT0_fpr(DFPREG(rd));
2424
                        break;
2425
                    case 0x6e: /* fdmulq */
2426
#if defined(CONFIG_USER_ONLY)
2427
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2428
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2429
                        gen_clear_float_exceptions();
2430
                        tcg_gen_helper_0_0(helper_fdmulq);
2431
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2432
                        gen_op_store_QT0_fpr(QFPREG(rd));
2433
                        break;
2434
#else
2435
                        goto nfpu_insn;
2436
#endif
2437
                    case 0xc4:
2438
                        gen_op_load_fpr_FT1(rs2);
2439
                        gen_clear_float_exceptions();
2440
                        tcg_gen_helper_0_0(helper_fitos);
2441
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2442
                        gen_op_store_FT0_fpr(rd);
2443
                        break;
2444
                    case 0xc6:
2445
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2446
                        gen_clear_float_exceptions();
2447
                        tcg_gen_helper_0_0(helper_fdtos);
2448
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2449
                        gen_op_store_FT0_fpr(rd);
2450
                        break;
2451
                    case 0xc7: /* fqtos */
2452
#if defined(CONFIG_USER_ONLY)
2453
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2454
                        gen_clear_float_exceptions();
2455
                        tcg_gen_helper_0_0(helper_fqtos);
2456
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2457
                        gen_op_store_FT0_fpr(rd);
2458
                        break;
2459
#else
2460
                        goto nfpu_insn;
2461
#endif
2462
                    case 0xc8:
2463
                        gen_op_load_fpr_FT1(rs2);
2464
                        tcg_gen_helper_0_0(helper_fitod);
2465
                        gen_op_store_DT0_fpr(DFPREG(rd));
2466
                        break;
2467
                    case 0xc9:
2468
                        gen_op_load_fpr_FT1(rs2);
2469
                        tcg_gen_helper_0_0(helper_fstod);
2470
                        gen_op_store_DT0_fpr(DFPREG(rd));
2471
                        break;
2472
                    case 0xcb: /* fqtod */
2473
#if defined(CONFIG_USER_ONLY)
2474
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2475
                        gen_clear_float_exceptions();
2476
                        tcg_gen_helper_0_0(helper_fqtod);
2477
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2478
                        gen_op_store_DT0_fpr(DFPREG(rd));
2479
                        break;
2480
#else
2481
                        goto nfpu_insn;
2482
#endif
2483
                    case 0xcc: /* fitoq */
2484
#if defined(CONFIG_USER_ONLY)
2485
                        gen_op_load_fpr_FT1(rs2);
2486
                        tcg_gen_helper_0_0(helper_fitoq);
2487
                        gen_op_store_QT0_fpr(QFPREG(rd));
2488
                        break;
2489
#else
2490
                        goto nfpu_insn;
2491
#endif
2492
                    case 0xcd: /* fstoq */
2493
#if defined(CONFIG_USER_ONLY)
2494
                        gen_op_load_fpr_FT1(rs2);
2495
                        tcg_gen_helper_0_0(helper_fstoq);
2496
                        gen_op_store_QT0_fpr(QFPREG(rd));
2497
                        break;
2498
#else
2499
                        goto nfpu_insn;
2500
#endif
2501
                    case 0xce: /* fdtoq */
2502
#if defined(CONFIG_USER_ONLY)
2503
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2504
                        tcg_gen_helper_0_0(helper_fdtoq);
2505
                        gen_op_store_QT0_fpr(QFPREG(rd));
2506
                        break;
2507
#else
2508
                        goto nfpu_insn;
2509
#endif
2510
                    case 0xd1:
2511
                        gen_op_load_fpr_FT1(rs2);
2512
                        gen_clear_float_exceptions();
2513
                        tcg_gen_helper_0_0(helper_fstoi);
2514
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2515
                        gen_op_store_FT0_fpr(rd);
2516
                        break;
2517
                    case 0xd2:
2518
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2519
                        gen_clear_float_exceptions();
2520
                        tcg_gen_helper_0_0(helper_fdtoi);
2521
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2522
                        gen_op_store_FT0_fpr(rd);
2523
                        break;
2524
                    case 0xd3: /* fqtoi */
2525
#if defined(CONFIG_USER_ONLY)
2526
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2527
                        gen_clear_float_exceptions();
2528
                        tcg_gen_helper_0_0(helper_fqtoi);
2529
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2530
                        gen_op_store_FT0_fpr(rd);
2531
                        break;
2532
#else
2533
                        goto nfpu_insn;
2534
#endif
2535
#ifdef TARGET_SPARC64
2536
                    case 0x2: /* V9 fmovd */
2537
                        gen_op_load_fpr_DT0(DFPREG(rs2));
2538
                        gen_op_store_DT0_fpr(DFPREG(rd));
2539
                        break;
2540
                    case 0x3: /* V9 fmovq */
2541
#if defined(CONFIG_USER_ONLY)
2542
                        gen_op_load_fpr_QT0(QFPREG(rs2));
2543
                        gen_op_store_QT0_fpr(QFPREG(rd));
2544
                        break;
2545
#else
2546
                        goto nfpu_insn;
2547
#endif
2548
                    case 0x6: /* V9 fnegd */
2549
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2550
                        tcg_gen_helper_0_0(helper_fnegd);
2551
                        gen_op_store_DT0_fpr(DFPREG(rd));
2552
                        break;
2553
                    case 0x7: /* V9 fnegq */
2554
#if defined(CONFIG_USER_ONLY)
2555
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2556
                        tcg_gen_helper_0_0(helper_fnegq);
2557
                        gen_op_store_QT0_fpr(QFPREG(rd));
2558
                        break;
2559
#else
2560
                        goto nfpu_insn;
2561
#endif
2562
                    case 0xa: /* V9 fabsd */
2563
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2564
                        tcg_gen_helper_0_0(helper_fabsd);
2565
                        gen_op_store_DT0_fpr(DFPREG(rd));
2566
                        break;
2567
                    case 0xb: /* V9 fabsq */
2568
#if defined(CONFIG_USER_ONLY)
2569
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2570
                        tcg_gen_helper_0_0(helper_fabsq);
2571
                        gen_op_store_QT0_fpr(QFPREG(rd));
2572
                        break;
2573
#else
2574
                        goto nfpu_insn;
2575
#endif
2576
                    case 0x81: /* V9 fstox */
2577
                        gen_op_load_fpr_FT1(rs2);
2578
                        gen_clear_float_exceptions();
2579
                        tcg_gen_helper_0_0(helper_fstox);
2580
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2581
                        gen_op_store_DT0_fpr(DFPREG(rd));
2582
                        break;
2583
                    case 0x82: /* V9 fdtox */
2584
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2585
                        gen_clear_float_exceptions();
2586
                        tcg_gen_helper_0_0(helper_fdtox);
2587
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2588
                        gen_op_store_DT0_fpr(DFPREG(rd));
2589
                        break;
2590
                    case 0x83: /* V9 fqtox */
2591
#if defined(CONFIG_USER_ONLY)
2592
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2593
                        gen_clear_float_exceptions();
2594
                        tcg_gen_helper_0_0(helper_fqtox);
2595
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2596
                        gen_op_store_DT0_fpr(DFPREG(rd));
2597
                        break;
2598
#else
2599
                        goto nfpu_insn;
2600
#endif
2601
                    case 0x84: /* V9 fxtos */
2602
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2603
                        gen_clear_float_exceptions();
2604
                        tcg_gen_helper_0_0(helper_fxtos);
2605
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2606
                        gen_op_store_FT0_fpr(rd);
2607
                        break;
2608
                    case 0x88: /* V9 fxtod */
2609
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2610
                        gen_clear_float_exceptions();
2611
                        tcg_gen_helper_0_0(helper_fxtod);
2612
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2613
                        gen_op_store_DT0_fpr(DFPREG(rd));
2614
                        break;
2615
                    case 0x8c: /* V9 fxtoq */
2616
#if defined(CONFIG_USER_ONLY)
2617
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2618
                        gen_clear_float_exceptions();
2619
                        tcg_gen_helper_0_0(helper_fxtoq);
2620
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2621
                        gen_op_store_QT0_fpr(QFPREG(rd));
2622
                        break;
2623
#else
2624
                        goto nfpu_insn;
2625
#endif
2626
#endif
2627
                    default:
2628
                        goto illegal_insn;
2629
                }
2630
            } else if (xop == 0x35) {   /* FPU Operations */
2631
#ifdef TARGET_SPARC64
2632
                int cond;
2633
#endif
2634
                if (gen_trap_ifnofpu(dc, cpu_T[2]))
2635
                    goto jmp_insn;
2636
                gen_op_clear_ieee_excp_and_FTT();
2637
                rs1 = GET_FIELD(insn, 13, 17);
2638
                rs2 = GET_FIELD(insn, 27, 31);
2639
                xop = GET_FIELD(insn, 18, 26);
2640
#ifdef TARGET_SPARC64
2641
                if ((xop & 0x11f) == 0x005) { // V9 fmovsr
2642
                    int l1;
2643

    
2644
                    l1 = gen_new_label();
2645
                    cond = GET_FIELD_SP(insn, 14, 17);
2646
                    rs1 = GET_FIELD(insn, 13, 17);
2647
                    gen_movl_reg_TN(rs1, cpu_T[0]);
2648
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0],
2649
                                      tcg_const_tl(0), l1);
2650
                    gen_op_load_fpr_FT0(rs2);
2651
                    gen_op_store_FT0_fpr(rd);
2652
                    gen_set_label(l1);
2653
                    break;
2654
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
2655
                    int l1;
2656

    
2657
                    l1 = gen_new_label();
2658
                    cond = GET_FIELD_SP(insn, 14, 17);
2659
                    rs1 = GET_FIELD(insn, 13, 17);
2660
                    gen_movl_reg_TN(rs1, cpu_T[0]);
2661
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0],
2662
                                      tcg_const_tl(0), l1);
2663
                    gen_op_load_fpr_DT0(DFPREG(rs2));
2664
                    gen_op_store_DT0_fpr(DFPREG(rd));
2665
                    gen_set_label(l1);
2666
                    break;
2667
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
2668
#if defined(CONFIG_USER_ONLY)
2669
                    int l1;
2670

    
2671
                    l1 = gen_new_label();
2672
                    cond = GET_FIELD_SP(insn, 14, 17);
2673
                    rs1 = GET_FIELD(insn, 13, 17);
2674
                    gen_movl_reg_TN(rs1, cpu_T[0]);
2675
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0],
2676
                                      tcg_const_tl(0), l1);
2677
                    gen_op_load_fpr_QT0(QFPREG(rs2));
2678
                    gen_op_store_QT0_fpr(QFPREG(rd));
2679
                    gen_set_label(l1);
2680
                    break;
2681
#else
2682
                    goto nfpu_insn;
2683
#endif
2684
                }
2685
#endif
2686
                switch (xop) {
2687
#ifdef TARGET_SPARC64
2688
#define FMOVCC(size_FDQ, fcc)                                           \
2689
                    {                                                   \
2690
                        TCGv r_cond;                                    \
2691
                        int l1;                                         \
2692
                                                                        \
2693
                        l1 = gen_new_label();                           \
2694
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2695
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2696
                        gen_fcond(r_cond, fcc, cond);                   \
2697
                        tcg_gen_brcond_tl(TCG_COND_EQ, r_cond,          \
2698
                                          tcg_const_tl(0), l1);         \
2699
                        glue(glue(gen_op_load_fpr_, size_FDQ), T0)(glue(size_FDQ, FPREG(rs2))); \
2700
                        glue(glue(gen_op_store_, size_FDQ), T0_fpr)(glue(size_FDQ, FPREG(rd))); \
2701
                        gen_set_label(l1);                              \
2702
                        tcg_gen_discard_tl(r_cond);                     \
2703
                    }
2704
                    case 0x001: /* V9 fmovscc %fcc0 */
2705
                        FMOVCC(F, 0);
2706
                        break;
2707
                    case 0x002: /* V9 fmovdcc %fcc0 */
2708
                        FMOVCC(D, 0);
2709
                        break;
2710
                    case 0x003: /* V9 fmovqcc %fcc0 */
2711
#if defined(CONFIG_USER_ONLY)
2712
                        FMOVCC(Q, 0);
2713
                        break;
2714
#else
2715
                        goto nfpu_insn;
2716
#endif
2717
                    case 0x041: /* V9 fmovscc %fcc1 */
2718
                        FMOVCC(F, 1);
2719
                        break;
2720
                    case 0x042: /* V9 fmovdcc %fcc1 */
2721
                        FMOVCC(D, 1);
2722
                        break;
2723
                    case 0x043: /* V9 fmovqcc %fcc1 */
2724
#if defined(CONFIG_USER_ONLY)
2725
                        FMOVCC(Q, 1);
2726
                        break;
2727
#else
2728
                        goto nfpu_insn;
2729
#endif
2730
                    case 0x081: /* V9 fmovscc %fcc2 */
2731
                        FMOVCC(F, 2);
2732
                        break;
2733
                    case 0x082: /* V9 fmovdcc %fcc2 */
2734
                        FMOVCC(D, 2);
2735
                        break;
2736
                    case 0x083: /* V9 fmovqcc %fcc2 */
2737
#if defined(CONFIG_USER_ONLY)
2738
                        FMOVCC(Q, 2);
2739
                        break;
2740
#else
2741
                        goto nfpu_insn;
2742
#endif
2743
                    case 0x0c1: /* V9 fmovscc %fcc3 */
2744
                        FMOVCC(F, 3);
2745
                        break;
2746
                    case 0x0c2: /* V9 fmovdcc %fcc3 */
2747
                        FMOVCC(D, 3);
2748
                        break;
2749
                    case 0x0c3: /* V9 fmovqcc %fcc3 */
2750
#if defined(CONFIG_USER_ONLY)
2751
                        FMOVCC(Q, 3);
2752
                        break;
2753
#else
2754
                        goto nfpu_insn;
2755
#endif
2756
#undef FMOVCC
2757
#define FMOVCC(size_FDQ, icc)                                           \
2758
                    {                                                   \
2759
                        TCGv r_cond;                                    \
2760
                        int l1;                                         \
2761
                                                                        \
2762
                        l1 = gen_new_label();                           \
2763
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2764
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2765
                        gen_cond(r_cond, icc, cond);                    \
2766
                        tcg_gen_brcond_tl(TCG_COND_EQ, r_cond,          \
2767
                                          tcg_const_tl(0), l1);         \
2768
                        glue(glue(gen_op_load_fpr_, size_FDQ), T0)(glue(size_FDQ, FPREG(rs2))); \
2769
                        glue(glue(gen_op_store_, size_FDQ), T0_fpr)(glue(size_FDQ, FPREG(rd))); \
2770
                        gen_set_label(l1);                              \
2771
                        tcg_gen_discard_tl(r_cond);                     \
2772
                    }
2773

    
2774
                    case 0x101: /* V9 fmovscc %icc */
2775
                        FMOVCC(F, 0);
2776
                        break;
2777
                    case 0x102: /* V9 fmovdcc %icc */
2778
                        FMOVCC(D, 0);
2779
                    case 0x103: /* V9 fmovqcc %icc */
2780
#if defined(CONFIG_USER_ONLY)
2781
                        FMOVCC(D, 0);
2782
                        break;
2783
#else
2784
                        goto nfpu_insn;
2785
#endif
2786
                    case 0x181: /* V9 fmovscc %xcc */
2787
                        FMOVCC(F, 1);
2788
                        break;
2789
                    case 0x182: /* V9 fmovdcc %xcc */
2790
                        FMOVCC(D, 1);
2791
                        break;
2792
                    case 0x183: /* V9 fmovqcc %xcc */
2793
#if defined(CONFIG_USER_ONLY)
2794
                        FMOVCC(Q, 1);
2795
                        break;
2796
#else
2797
                        goto nfpu_insn;
2798
#endif
2799
#undef FMOVCC
2800
#endif
2801
                    case 0x51: /* fcmps, V9 %fcc */
2802
                        gen_op_load_fpr_FT0(rs1);
2803
                        gen_op_load_fpr_FT1(rs2);
2804
                        gen_op_fcmps(rd & 3);
2805
                        break;
2806
                    case 0x52: /* fcmpd, V9 %fcc */
2807
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2808
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2809
                        gen_op_fcmpd(rd & 3);
2810
                        break;
2811
                    case 0x53: /* fcmpq, V9 %fcc */
2812
#if defined(CONFIG_USER_ONLY)
2813
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2814
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2815
                        gen_op_fcmpq(rd & 3);
2816
                        break;
2817
#else /* !defined(CONFIG_USER_ONLY) */
2818
                        goto nfpu_insn;
2819
#endif
2820
                    case 0x55: /* fcmpes, V9 %fcc */
2821
                        gen_op_load_fpr_FT0(rs1);
2822
                        gen_op_load_fpr_FT1(rs2);
2823
                        gen_op_fcmpes(rd & 3);
2824
                        break;
2825
                    case 0x56: /* fcmped, V9 %fcc */
2826
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2827
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2828
                        gen_op_fcmped(rd & 3);
2829
                        break;
2830
                    case 0x57: /* fcmpeq, V9 %fcc */
2831
#if defined(CONFIG_USER_ONLY)
2832
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2833
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2834
                        gen_op_fcmpeq(rd & 3);
2835
                        break;
2836
#else/* !defined(CONFIG_USER_ONLY) */
2837
                        goto nfpu_insn;
2838
#endif
2839
                    default:
2840
                        goto illegal_insn;
2841
                }
2842
#if defined(OPTIM)
2843
            } else if (xop == 0x2) {
2844
                // clr/mov shortcut
2845

    
2846
                rs1 = GET_FIELD(insn, 13, 17);
2847
                if (rs1 == 0) {
2848
                    // or %g0, x, y -> mov T0, x; mov y, T0
2849
                    if (IS_IMM) {       /* immediate */
2850
                        rs2 = GET_FIELDs(insn, 19, 31);
2851
                        tcg_gen_movi_tl(cpu_T[0], (int)rs2);
2852
                    } else {            /* register */
2853
                        rs2 = GET_FIELD(insn, 27, 31);
2854
                        gen_movl_reg_TN(rs2, cpu_T[0]);
2855
                    }
2856
                } else {
2857
                    gen_movl_reg_TN(rs1, cpu_T[0]);
2858
                    if (IS_IMM) {       /* immediate */
2859
                        rs2 = GET_FIELDs(insn, 19, 31);
2860
                        tcg_gen_ori_tl(cpu_T[0], cpu_T[0], (int)rs2);
2861
                    } else {            /* register */
2862
                        // or x, %g0, y -> mov T1, x; mov y, T1
2863
                        rs2 = GET_FIELD(insn, 27, 31);
2864
                        if (rs2 != 0) {
2865
                            gen_movl_reg_TN(rs2, cpu_T[1]);
2866
                            tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2867
                        }
2868
                    }
2869
                }
2870
                gen_movl_TN_reg(rd, cpu_T[0]);
2871
#endif
2872
#ifdef TARGET_SPARC64
2873
            } else if (xop == 0x25) { /* sll, V9 sllx */
2874
                rs1 = GET_FIELD(insn, 13, 17);
2875
                gen_movl_reg_TN(rs1, cpu_T[0]);
2876
                if (IS_IMM) {   /* immediate */
2877
                    rs2 = GET_FIELDs(insn, 20, 31);
2878
                    if (insn & (1 << 12)) {
2879
                        tcg_gen_shli_i64(cpu_T[0], cpu_T[0], rs2 & 0x3f);
2880
                    } else {
2881
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
2882
                        tcg_gen_shli_i64(cpu_T[0], cpu_T[0], rs2 & 0x1f);
2883
                    }
2884
                } else {                /* register */
2885
                    rs2 = GET_FIELD(insn, 27, 31);
2886
                    gen_movl_reg_TN(rs2, cpu_T[1]);
2887
                    if (insn & (1 << 12)) {
2888
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x3f);
2889
                        tcg_gen_shl_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2890
                    } else {
2891
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x1f);
2892
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
2893
                        tcg_gen_shl_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2894
                    }
2895
                }
2896
                gen_movl_TN_reg(rd, cpu_T[0]);
2897
            } else if (xop == 0x26) { /* srl, V9 srlx */
2898
                rs1 = GET_FIELD(insn, 13, 17);
2899
                gen_movl_reg_TN(rs1, cpu_T[0]);
2900
                if (IS_IMM) {   /* immediate */
2901
                    rs2 = GET_FIELDs(insn, 20, 31);
2902
                    if (insn & (1 << 12)) {
2903
                        tcg_gen_shri_i64(cpu_T[0], cpu_T[0], rs2 & 0x3f);
2904
                    } else {
2905
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
2906
                        tcg_gen_shri_i64(cpu_T[0], cpu_T[0], rs2 & 0x1f);
2907
                    }
2908
                } else {                /* register */
2909
                    rs2 = GET_FIELD(insn, 27, 31);
2910
                    gen_movl_reg_TN(rs2, cpu_T[1]);
2911
                    if (insn & (1 << 12)) {
2912
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x3f);
2913
                        tcg_gen_shr_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2914
                    } else {
2915
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x1f);
2916
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
2917
                        tcg_gen_shr_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2918
                    }
2919
                }
2920
                gen_movl_TN_reg(rd, cpu_T[0]);
2921
            } else if (xop == 0x27) { /* sra, V9 srax */
2922
                rs1 = GET_FIELD(insn, 13, 17);
2923
                gen_movl_reg_TN(rs1, cpu_T[0]);
2924
                if (IS_IMM) {   /* immediate */
2925
                    rs2 = GET_FIELDs(insn, 20, 31);
2926
                    if (insn & (1 << 12)) {
2927
                        tcg_gen_sari_i64(cpu_T[0], cpu_T[0], rs2 & 0x3f);
2928
                    } else {
2929
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
2930
                        tcg_gen_ext_i32_i64(cpu_T[0], cpu_T[0]);
2931
                        tcg_gen_sari_i64(cpu_T[0], cpu_T[0], rs2 & 0x1f);
2932
                    }
2933
                } else {                /* register */
2934
                    rs2 = GET_FIELD(insn, 27, 31);
2935
                    gen_movl_reg_TN(rs2, cpu_T[1]);
2936
                    if (insn & (1 << 12)) {
2937
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x3f);
2938
                        tcg_gen_sar_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2939
                    } else {
2940
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x1f);
2941
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
2942
                        tcg_gen_sar_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2943
                    }
2944
                }
2945
                gen_movl_TN_reg(rd, cpu_T[0]);
2946
#endif
2947
            } else if (xop < 0x36) {
2948
                rs1 = GET_FIELD(insn, 13, 17);
2949
                gen_movl_reg_TN(rs1, cpu_T[0]);
2950
                if (IS_IMM) {   /* immediate */
2951
                    rs2 = GET_FIELDs(insn, 19, 31);
2952
                    tcg_gen_movi_tl(cpu_T[1], (int)rs2);
2953
                } else {                /* register */
2954
                    rs2 = GET_FIELD(insn, 27, 31);
2955
                    gen_movl_reg_TN(rs2, cpu_T[1]);
2956
                }
2957
                if (xop < 0x20) {
2958
                    switch (xop & ~0x10) {
2959
                    case 0x0:
2960
                        if (xop & 0x10)
2961
                            gen_op_add_cc(cpu_T[0], cpu_T[0], cpu_T[1]);
2962
                        else
2963
                            tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2964
                        break;
2965
                    case 0x1:
2966
                        tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2967
                        if (xop & 0x10)
2968
                            gen_op_logic_cc(cpu_T[0]);
2969
                        break;
2970
                    case 0x2:
2971
                        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2972
                        if (xop & 0x10)
2973
                            gen_op_logic_cc(cpu_T[0]);
2974
                        break;
2975
                    case 0x3:
2976
                        tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2977
                        if (xop & 0x10)
2978
                            gen_op_logic_cc(cpu_T[0]);
2979
                        break;
2980
                    case 0x4:
2981
                        if (xop & 0x10)
2982
                            gen_op_sub_cc(cpu_T[0], cpu_T[0], cpu_T[1]);
2983
                        else
2984
                            tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2985
                        break;
2986
                    case 0x5:
2987
                        tcg_gen_xori_tl(cpu_T[1], cpu_T[1], -1);
2988
                        tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2989
                        if (xop & 0x10)
2990
                            gen_op_logic_cc(cpu_T[0]);
2991
                        break;
2992
                    case 0x6:
2993
                        tcg_gen_xori_tl(cpu_T[1], cpu_T[1], -1);
2994
                        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2995
                        if (xop & 0x10)
2996
                            gen_op_logic_cc(cpu_T[0]);
2997
                        break;
2998
                    case 0x7:
2999
                        tcg_gen_xori_tl(cpu_T[1], cpu_T[1], -1);
3000
                        tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3001
                        if (xop & 0x10)
3002
                            gen_op_logic_cc(cpu_T[0]);
3003
                        break;
3004
                    case 0x8:
3005
                        if (xop & 0x10)
3006
                            gen_op_addx_cc(cpu_T[0], cpu_T[0], cpu_T[1]);
3007
                        else {
3008
                            gen_mov_reg_C(cpu_tmp0, cpu_psr);
3009
                            tcg_gen_add_tl(cpu_T[1], cpu_T[1], cpu_tmp0);
3010
                            tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3011
                        }
3012
                        break;
3013
#ifdef TARGET_SPARC64
3014
                    case 0x9: /* V9 mulx */
3015
                        tcg_gen_mul_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
3016
                        break;
3017
#endif
3018
                    case 0xa:
3019
                        gen_op_umul(cpu_T[0], cpu_T[0], cpu_T[1]);
3020
                        if (xop & 0x10)
3021
                            gen_op_logic_cc(cpu_T[0]);
3022
                        break;
3023
                    case 0xb:
3024
                        gen_op_smul(cpu_T[0], cpu_T[0], cpu_T[1]);
3025
                        if (xop & 0x10)
3026
                            gen_op_logic_cc(cpu_T[0]);
3027
                        break;
3028
                    case 0xc:
3029
                        if (xop & 0x10)
3030
                            gen_op_subx_cc(cpu_T[0], cpu_T[0], cpu_T[1]);
3031
                        else {
3032
                            gen_mov_reg_C(cpu_tmp0, cpu_psr);
3033
                            tcg_gen_add_tl(cpu_T[1], cpu_T[1], cpu_tmp0);
3034
                            tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3035
                        }
3036
                        break;
3037
#ifdef TARGET_SPARC64
3038
                    case 0xd: /* V9 udivx */
3039
                        gen_trap_ifdivzero_tl(cpu_T[1]);
3040
                        tcg_gen_divu_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
3041
                        break;
3042
#endif
3043
                    case 0xe:
3044
                        tcg_gen_helper_1_2(helper_udiv, cpu_T[0], cpu_T[0], cpu_T[1]);
3045
                        if (xop & 0x10)
3046
                            gen_op_div_cc(cpu_T[0]);
3047
                        break;
3048
                    case 0xf:
3049
                        tcg_gen_helper_1_2(helper_sdiv, cpu_T[0], cpu_T[0], cpu_T[1]);
3050
                        if (xop & 0x10)
3051
                            gen_op_div_cc(cpu_T[0]);
3052
                        break;
3053
                    default:
3054
                        goto illegal_insn;
3055
                    }
3056
                    gen_movl_TN_reg(rd, cpu_T[0]);
3057
                } else {
3058
                    switch (xop) {
3059
                    case 0x20: /* taddcc */
3060
                        gen_op_tadd_cc(cpu_T[0], cpu_T[0], cpu_T[1]);
3061
                        gen_movl_TN_reg(rd, cpu_T[0]);
3062
                        break;
3063
                    case 0x21: /* tsubcc */
3064
                        gen_op_tsub_cc(cpu_T[0], cpu_T[0], cpu_T[1]);
3065
                        gen_movl_TN_reg(rd, cpu_T[0]);
3066
                        break;
3067
                    case 0x22: /* taddcctv */
3068
                        save_state(dc, cpu_T[2]);
3069
                        gen_op_tadd_ccTV(cpu_T[0], cpu_T[0], cpu_T[1]);
3070
                        gen_movl_TN_reg(rd, cpu_T[0]);
3071
                        break;
3072
                    case 0x23: /* tsubcctv */
3073
                        save_state(dc, cpu_T[2]);
3074
                        gen_op_tsub_ccTV(cpu_T[0], cpu_T[0], cpu_T[1]);
3075
                        gen_movl_TN_reg(rd, cpu_T[0]);
3076
                        break;
3077
                    case 0x24: /* mulscc */
3078
                        gen_op_mulscc(cpu_T[0], cpu_T[0], cpu_T[1]);
3079
                        gen_movl_TN_reg(rd, cpu_T[0]);
3080
                        break;
3081
#ifndef TARGET_SPARC64
3082
                    case 0x25:  /* sll */
3083
                        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 0x1f);
3084
                        tcg_gen_shl_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3085
                        gen_movl_TN_reg(rd, cpu_T[0]);
3086
                        break;
3087
                    case 0x26:  /* srl */
3088
                        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 0x1f);
3089
                        tcg_gen_shr_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3090
                        gen_movl_TN_reg(rd, cpu_T[0]);
3091
                        break;
3092
                    case 0x27:  /* sra */
3093
                        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 0x1f);
3094
                        tcg_gen_sar_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3095
                        gen_movl_TN_reg(rd, cpu_T[0]);
3096
                        break;
3097
#endif
3098
                    case 0x30:
3099
                        {
3100
                            switch(rd) {
3101
                            case 0: /* wry */
3102
                                tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3103
                                tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, y));
3104
                                break;
3105
#ifndef TARGET_SPARC64
3106
                            case 0x01 ... 0x0f: /* undefined in the
3107
                                                   SPARCv8 manual, nop
3108
                                                   on the microSPARC
3109
                                                   II */
3110
                            case 0x10 ... 0x1f: /* implementation-dependent
3111
                                                   in the SPARCv8
3112
                                                   manual, nop on the
3113
                                                   microSPARC II */
3114
                                break;
3115
#else
3116
                            case 0x2: /* V9 wrccr */
3117
                                tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3118
                                tcg_gen_helper_0_1(helper_wrccr, cpu_T[0]);
3119
                                break;
3120
                            case 0x3: /* V9 wrasi */
3121
                                tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3122
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3123
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, asi));
3124
                                break;
3125
                            case 0x6: /* V9 wrfprs */
3126
                                tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3127
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3128
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fprs));
3129
                                save_state(dc, cpu_T[2]);
3130
                                gen_op_next_insn();
3131
                                tcg_gen_exit_tb(0);
3132
                                dc->is_br = 1;
3133
                                break;
3134
                            case 0xf: /* V9 sir, nop if user */
3135
#if !defined(CONFIG_USER_ONLY)
3136
                                if (supervisor(dc))
3137
                                    ; // XXX
3138
#endif
3139
                                break;
3140
                            case 0x13: /* Graphics Status */
3141
                                if (gen_trap_ifnofpu(dc, cpu_T[2]))
3142
                                    goto jmp_insn;
3143
                                tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3144
                                tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, gsr));
3145
                                break;
3146
                            case 0x17: /* Tick compare */
3147
#if !defined(CONFIG_USER_ONLY)
3148
                                if (!supervisor(dc))
3149
                                    goto illegal_insn;
3150
#endif
3151
                                {
3152
                                    TCGv r_tickptr;
3153

    
3154
                                    tcg_gen_xor_tl(cpu_T[0], cpu_T[0],
3155
                                                   cpu_T[1]);
3156
                                    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState,
3157
                                                                 tick_cmpr));
3158
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3159
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3160
                                                   offsetof(CPUState, tick));
3161
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3162
                                                       r_tickptr, cpu_T[0]);
3163
                                    tcg_gen_discard_ptr(r_tickptr);
3164
                                }
3165
                                break;
3166
                            case 0x18: /* System tick */
3167
#if !defined(CONFIG_USER_ONLY)
3168
                                if (!supervisor(dc))
3169
                                    goto illegal_insn;
3170
#endif
3171
                                {
3172
                                    TCGv r_tickptr;
3173

    
3174
                                    tcg_gen_xor_tl(cpu_T[0], cpu_T[0],
3175
                                                   cpu_T[1]);
3176
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3177
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3178
                                                   offsetof(CPUState, stick));
3179
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3180
                                                       r_tickptr, cpu_T[0]);
3181
                                    tcg_gen_discard_ptr(r_tickptr);
3182
                                }
3183
                                break;
3184
                            case 0x19: /* System tick compare */
3185
#if !defined(CONFIG_USER_ONLY)
3186
                                if (!supervisor(dc))
3187
                                    goto illegal_insn;
3188
#endif
3189
                                {
3190
                                    TCGv r_tickptr;
3191

    
3192
                                    tcg_gen_xor_tl(cpu_T[0], cpu_T[0],
3193
                                                   cpu_T[1]);
3194
                                    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState,
3195
                                                                 stick_cmpr));
3196
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3197
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3198
                                                   offsetof(CPUState, stick));
3199
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3200
                                                       r_tickptr, cpu_T[0]);
3201
                                    tcg_gen_discard_ptr(r_tickptr);
3202
                                }
3203
                                break;
3204

    
3205
                            case 0x10: /* Performance Control */
3206
                            case 0x11: /* Performance Instrumentation Counter */
3207
                            case 0x12: /* Dispatch Control */
3208
                            case 0x14: /* Softint set */
3209
                            case 0x15: /* Softint clear */
3210
                            case 0x16: /* Softint write */
3211
#endif
3212
                            default:
3213
                                goto illegal_insn;
3214
                            }
3215
                        }
3216
                        break;
3217
#if !defined(CONFIG_USER_ONLY)
3218
                    case 0x31: /* wrpsr, V9 saved, restored */
3219
                        {
3220
                            if (!supervisor(dc))
3221
                                goto priv_insn;
3222
#ifdef TARGET_SPARC64
3223
                            switch (rd) {
3224
                            case 0:
3225
                                tcg_gen_helper_0_0(helper_saved);
3226
                                break;
3227
                            case 1:
3228
                                tcg_gen_helper_0_0(helper_restored);
3229
                                break;
3230
                            case 2: /* UA2005 allclean */
3231
                            case 3: /* UA2005 otherw */
3232
                            case 4: /* UA2005 normalw */
3233
                            case 5: /* UA2005 invalw */
3234
                                // XXX
3235
                            default:
3236
                                goto illegal_insn;
3237
                            }
3238
#else
3239
                            tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3240
                            tcg_gen_helper_0_1(helper_wrpsr, cpu_T[0]);
3241
                            save_state(dc, cpu_T[2]);
3242
                            gen_op_next_insn();
3243
                            tcg_gen_exit_tb(0);
3244
                            dc->is_br = 1;
3245
#endif
3246
                        }
3247
                        break;
3248
                    case 0x32: /* wrwim, V9 wrpr */
3249
                        {
3250
                            if (!supervisor(dc))
3251
                                goto priv_insn;
3252
                            tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3253
#ifdef TARGET_SPARC64
3254
                            switch (rd) {
3255
                            case 0: // tpc
3256
                                {
3257
                                    TCGv r_tsptr;
3258

    
3259
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3260
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3261
                                                   offsetof(CPUState, tsptr));
3262
                                    tcg_gen_st_tl(cpu_T[0], r_tsptr,
3263
                                                  offsetof(trap_state, tpc));
3264
                                    tcg_gen_discard_ptr(r_tsptr);
3265
                                }
3266
                                break;
3267
                            case 1: // tnpc
3268
                                {
3269
                                    TCGv r_tsptr;
3270

    
3271
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3272
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3273
                                                   offsetof(CPUState, tsptr));
3274
                                    tcg_gen_st_tl(cpu_T[0], r_tsptr,
3275
                                                  offsetof(trap_state, tnpc));
3276
                                    tcg_gen_discard_ptr(r_tsptr);
3277
                                }
3278
                                break;
3279
                            case 2: // tstate
3280
                                {
3281
                                    TCGv r_tsptr;
3282

    
3283
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3284
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3285
                                                   offsetof(CPUState, tsptr));
3286
                                    tcg_gen_st_tl(cpu_T[0], r_tsptr,
3287
                                                  offsetof(trap_state, tstate));
3288
                                    tcg_gen_discard_ptr(r_tsptr);
3289
                                }
3290
                                break;
3291
                            case 3: // tt
3292
                                {
3293
                                    TCGv r_tsptr;
3294

    
3295
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3296
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3297
                                                   offsetof(CPUState, tsptr));
3298
                                    tcg_gen_st_i32(cpu_T[0], r_tsptr,
3299
                                                   offsetof(trap_state, tt));
3300
                                    tcg_gen_discard_ptr(r_tsptr);
3301
                                }
3302
                                break;
3303
                            case 4: // tick
3304
                                {
3305
                                    TCGv r_tickptr;
3306

    
3307
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3308
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3309
                                                   offsetof(CPUState, tick));
3310
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3311
                                                       r_tickptr, cpu_T[0]);
3312
                                    tcg_gen_discard_ptr(r_tickptr);
3313
                                }
3314
                                break;
3315
                            case 5: // tba
3316
                                tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, tbr));
3317
                                break;
3318
                            case 6: // pstate
3319
                                save_state(dc, cpu_T[2]);
3320
                                tcg_gen_helper_0_1(helper_wrpstate, cpu_T[0]);
3321
                                gen_op_next_insn();
3322
                                tcg_gen_exit_tb(0);
3323
                                dc->is_br = 1;
3324
                                break;
3325
                            case 7: // tl
3326
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3327
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, tl));
3328
                                break;
3329
                            case 8: // pil
3330
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3331
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, psrpil));
3332
                                break;
3333
                            case 9: // cwp
3334
                                tcg_gen_helper_0_1(helper_wrcwp, cpu_T[0]);
3335
                                break;
3336
                            case 10: // cansave
3337
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3338
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, cansave));
3339
                                break;
3340
                            case 11: // canrestore
3341
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3342
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, canrestore));
3343
                                break;
3344
                            case 12: // cleanwin
3345
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3346
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, cleanwin));
3347
                                break;
3348
                            case 13: // otherwin
3349
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3350
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, otherwin));
3351
                                break;
3352
                            case 14: // wstate
3353
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3354
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, wstate));
3355
                                break;
3356
                            case 16: // UA2005 gl
3357
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3358
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, gl));
3359
                                break;
3360
                            case 26: // UA2005 strand status
3361
                                if (!hypervisor(dc))
3362
                                    goto priv_insn;
3363
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3364
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ssr));
3365
                                break;
3366
                            default:
3367
                                goto illegal_insn;
3368
                            }
3369
#else
3370
                            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], ((1 << NWINDOWS) - 1));
3371
                            tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3372
                            tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, wim));
3373
#endif
3374
                        }
3375
                        break;
3376
                    case 0x33: /* wrtbr, UA2005 wrhpr */
3377
                        {
3378
#ifndef TARGET_SPARC64
3379
                            if (!supervisor(dc))
3380
                                goto priv_insn;
3381
                            tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3382
                            tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, tbr));
3383
#else
3384
                            if (!hypervisor(dc))
3385
                                goto priv_insn;
3386
                            tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3387
                            switch (rd) {
3388
                            case 0: // hpstate
3389
                                // XXX gen_op_wrhpstate();
3390
                                save_state(dc, cpu_T[2]);
3391
                                gen_op_next_insn();
3392
                                tcg_gen_exit_tb(0);
3393
                                dc->is_br = 1;
3394
                                break;
3395
                            case 1: // htstate
3396
                                // XXX gen_op_wrhtstate();
3397
                                break;
3398
                            case 3: // hintp
3399
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3400
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, hintp));
3401
                                break;
3402
                            case 5: // htba
3403
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3404
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, htba));
3405
                                break;
3406
                            case 31: // hstick_cmpr
3407
                                {
3408
                                    TCGv r_tickptr;
3409

    
3410
                                    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState,
3411
                                                                 hstick_cmpr));
3412
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3413
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3414
                                                   offsetof(CPUState, hstick));
3415
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3416
                                                       r_tickptr, cpu_T[0]);
3417
                                    tcg_gen_discard_ptr(r_tickptr);
3418
                                }
3419
                                break;
3420
                            case 6: // hver readonly
3421
                            default:
3422
                                goto illegal_insn;
3423
                            }
3424
#endif
3425
                        }
3426
                        break;
3427
#endif
3428
#ifdef TARGET_SPARC64
3429
                    case 0x2c: /* V9 movcc */
3430
                        {
3431
                            int cc = GET_FIELD_SP(insn, 11, 12);
3432
                            int cond = GET_FIELD_SP(insn, 14, 17);
3433
                            TCGv r_cond;
3434
                            int l1;
3435

    
3436
                            r_cond = tcg_temp_new(TCG_TYPE_TL);
3437
                            if (insn & (1 << 18)) {
3438
                                if (cc == 0)
3439
                                    gen_cond(r_cond, 0, cond);
3440
                                else if (cc == 2)
3441
                                    gen_cond(r_cond, 1, cond);
3442
                                else
3443
                                    goto illegal_insn;
3444
                            } else {
3445
                                gen_fcond(r_cond, cc, cond);
3446
                            }
3447

    
3448
                            l1 = gen_new_label();
3449

    
3450
                            tcg_gen_brcond_tl(TCG_COND_EQ, r_cond,
3451
                                              tcg_const_tl(0), l1);
3452
                            if (IS_IMM) {       /* immediate */
3453
                                rs2 = GET_FIELD_SPs(insn, 0, 10);
3454
                                tcg_gen_movi_tl(cpu_T[1], (int)rs2);
3455
                            } else {
3456
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3457
                                gen_movl_reg_TN(rs2, cpu_T[1]);
3458
                            }
3459
                            gen_movl_TN_reg(rd, cpu_T[1]);
3460
                            gen_set_label(l1);
3461
                            tcg_gen_discard_tl(r_cond);
3462
                            break;
3463
                        }
3464
                    case 0x2d: /* V9 sdivx */
3465
                        gen_op_sdivx(cpu_T[0], cpu_T[0], cpu_T[1]);
3466
                        gen_movl_TN_reg(rd, cpu_T[0]);
3467
                        break;
3468
                    case 0x2e: /* V9 popc */
3469
                        {
3470
                            if (IS_IMM) {       /* immediate */
3471
                                rs2 = GET_FIELD_SPs(insn, 0, 12);
3472
                                tcg_gen_movi_tl(cpu_T[1], (int)rs2);
3473
                                // XXX optimize: popc(constant)
3474
                            }
3475
                            else {
3476
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3477
                                gen_movl_reg_TN(rs2, cpu_T[1]);
3478
                            }
3479
                            tcg_gen_helper_1_1(helper_popc, cpu_T[0],
3480
                                               cpu_T[1]);
3481
                            gen_movl_TN_reg(rd, cpu_T[0]);
3482
                        }
3483
                    case 0x2f: /* V9 movr */
3484
                        {
3485
                            int cond = GET_FIELD_SP(insn, 10, 12);
3486
                            int l1;
3487

    
3488
                            rs1 = GET_FIELD(insn, 13, 17);
3489
                            gen_movl_reg_TN(rs1, cpu_T[0]);
3490

    
3491
                            l1 = gen_new_label();
3492

    
3493
                            tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0],
3494
                                              tcg_const_tl(0), l1);
3495
                            if (IS_IMM) {       /* immediate */
3496
                                rs2 = GET_FIELD_SPs(insn, 0, 9);
3497
                                tcg_gen_movi_tl(cpu_T[1], (int)rs2);
3498
                            } else {
3499
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3500
                                gen_movl_reg_TN(rs2, cpu_T[1]);
3501
                            }
3502
                            gen_movl_TN_reg(rd, cpu_T[1]);
3503
                            gen_set_label(l1);
3504
                            break;
3505
                        }
3506
#endif
3507
                    default:
3508
                        goto illegal_insn;
3509
                    }
3510
                }
3511
            } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
3512
#ifdef TARGET_SPARC64
3513
                int opf = GET_FIELD_SP(insn, 5, 13);
3514
                rs1 = GET_FIELD(insn, 13, 17);
3515
                rs2 = GET_FIELD(insn, 27, 31);
3516
                if (gen_trap_ifnofpu(dc, cpu_T[2]))
3517
                    goto jmp_insn;
3518

    
3519
                switch (opf) {
3520
                case 0x000: /* VIS I edge8cc */
3521
                case 0x001: /* VIS II edge8n */
3522
                case 0x002: /* VIS I edge8lcc */
3523
                case 0x003: /* VIS II edge8ln */
3524
                case 0x004: /* VIS I edge16cc */
3525
                case 0x005: /* VIS II edge16n */
3526
                case 0x006: /* VIS I edge16lcc */
3527
                case 0x007: /* VIS II edge16ln */
3528
                case 0x008: /* VIS I edge32cc */
3529
                case 0x009: /* VIS II edge32n */
3530
                case 0x00a: /* VIS I edge32lcc */
3531
                case 0x00b: /* VIS II edge32ln */
3532
                    // XXX
3533
                    goto illegal_insn;
3534
                case 0x010: /* VIS I array8 */
3535
                    gen_movl_reg_TN(rs1, cpu_T[0]);
3536
                    gen_movl_reg_TN(rs2, cpu_T[1]);
3537
                    tcg_gen_helper_1_2(helper_array8, cpu_T[0], cpu_T[0],
3538
                                       cpu_T[1]);
3539
                    gen_movl_TN_reg(rd, cpu_T[0]);
3540
                    break;
3541
                case 0x012: /* VIS I array16 */
3542
                    gen_movl_reg_TN(rs1, cpu_T[0]);
3543
                    gen_movl_reg_TN(rs2, cpu_T[1]);
3544
                    tcg_gen_helper_1_2(helper_array8, cpu_T[0], cpu_T[0],
3545
                                       cpu_T[1]);
3546
                    tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 1);
3547
                    gen_movl_TN_reg(rd, cpu_T[0]);
3548
                    break;
3549
                case 0x014: /* VIS I array32 */
3550
                    gen_movl_reg_TN(rs1, cpu_T[0]);
3551
                    gen_movl_reg_TN(rs2, cpu_T[1]);
3552
                    tcg_gen_helper_1_2(helper_array8, cpu_T[0], cpu_T[0],
3553
                                       cpu_T[1]);
3554
                    tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 2);
3555
                    gen_movl_TN_reg(rd, cpu_T[0]);
3556
                    break;
3557
                case 0x018: /* VIS I alignaddr */
3558
                    gen_movl_reg_TN(rs1, cpu_T[0]);
3559
                    gen_movl_reg_TN(rs2, cpu_T[1]);
3560
                    tcg_gen_helper_1_2(helper_alignaddr, cpu_T[0], cpu_T[0],
3561
                                       cpu_T[1]);
3562
                    gen_movl_TN_reg(rd, cpu_T[0]);
3563
                    break;
3564
                case 0x019: /* VIS II bmask */
3565
                case 0x01a: /* VIS I alignaddrl */
3566
                    // XXX
3567
                    goto illegal_insn;
3568
                case 0x020: /* VIS I fcmple16 */
3569
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3570
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3571
                    tcg_gen_helper_0_0(helper_fcmple16);
3572
                    gen_op_store_DT0_fpr(DFPREG(rd));
3573
                    break;
3574
                case 0x022: /* VIS I fcmpne16 */
3575
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3576
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3577
                    tcg_gen_helper_0_0(helper_fcmpne16);
3578
                    gen_op_store_DT0_fpr(DFPREG(rd));
3579
                    break;
3580
                case 0x024: /* VIS I fcmple32 */
3581
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3582
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3583
                    tcg_gen_helper_0_0(helper_fcmple32);
3584
                    gen_op_store_DT0_fpr(DFPREG(rd));
3585
                    break;
3586
                case 0x026: /* VIS I fcmpne32 */
3587
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3588
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3589
                    tcg_gen_helper_0_0(helper_fcmpne32);
3590
                    gen_op_store_DT0_fpr(DFPREG(rd));
3591
                    break;
3592
                case 0x028: /* VIS I fcmpgt16 */
3593
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3594
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3595
                    tcg_gen_helper_0_0(helper_fcmpgt16);
3596
                    gen_op_store_DT0_fpr(DFPREG(rd));
3597
                    break;
3598
                case 0x02a: /* VIS I fcmpeq16 */
3599
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3600
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3601
                    tcg_gen_helper_0_0(helper_fcmpeq16);
3602
                    gen_op_store_DT0_fpr(DFPREG(rd));
3603
                    break;
3604
                case 0x02c: /* VIS I fcmpgt32 */
3605
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3606
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3607
                    tcg_gen_helper_0_0(helper_fcmpgt32);
3608
                    gen_op_store_DT0_fpr(DFPREG(rd));
3609
                    break;
3610
                case 0x02e: /* VIS I fcmpeq32 */
3611
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3612
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3613
                    tcg_gen_helper_0_0(helper_fcmpeq32);
3614
                    gen_op_store_DT0_fpr(DFPREG(rd));
3615
                    break;
3616
                case 0x031: /* VIS I fmul8x16 */
3617
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3618
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3619
                    tcg_gen_helper_0_0(helper_fmul8x16);
3620
                    gen_op_store_DT0_fpr(DFPREG(rd));
3621
                    break;
3622
                case 0x033: /* VIS I fmul8x16au */
3623
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3624
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3625
                    tcg_gen_helper_0_0(helper_fmul8x16au);
3626
                    gen_op_store_DT0_fpr(DFPREG(rd));
3627
                    break;
3628
                case 0x035: /* VIS I fmul8x16al */
3629
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3630
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3631
                    tcg_gen_helper_0_0(helper_fmul8x16al);
3632
                    gen_op_store_DT0_fpr(DFPREG(rd));
3633
                    break;
3634
                case 0x036: /* VIS I fmul8sux16 */
3635
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3636
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3637
                    tcg_gen_helper_0_0(helper_fmul8sux16);
3638
                    gen_op_store_DT0_fpr(DFPREG(rd));
3639
                    break;
3640
                case 0x037: /* VIS I fmul8ulx16 */
3641
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3642
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3643
                    tcg_gen_helper_0_0(helper_fmul8ulx16);
3644
                    gen_op_store_DT0_fpr(DFPREG(rd));
3645
                    break;
3646
                case 0x038: /* VIS I fmuld8sux16 */
3647
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3648
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3649
                    tcg_gen_helper_0_0(helper_fmuld8sux16);
3650
                    gen_op_store_DT0_fpr(DFPREG(rd));
3651
                    break;
3652
                case 0x039: /* VIS I fmuld8ulx16 */
3653
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3654
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3655
                    tcg_gen_helper_0_0(helper_fmuld8ulx16);
3656
                    gen_op_store_DT0_fpr(DFPREG(rd));
3657
                    break;
3658
                case 0x03a: /* VIS I fpack32 */
3659
                case 0x03b: /* VIS I fpack16 */
3660
                case 0x03d: /* VIS I fpackfix */
3661
                case 0x03e: /* VIS I pdist */
3662
                    // XXX
3663
                    goto illegal_insn;
3664
                case 0x048: /* VIS I faligndata */
3665
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3666
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3667
                    tcg_gen_helper_0_0(helper_faligndata);
3668
                    gen_op_store_DT0_fpr(DFPREG(rd));
3669
                    break;
3670
                case 0x04b: /* VIS I fpmerge */
3671
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3672
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3673
                    tcg_gen_helper_0_0(helper_fpmerge);
3674
                    gen_op_store_DT0_fpr(DFPREG(rd));
3675
                    break;
3676
                case 0x04c: /* VIS II bshuffle */
3677
                    // XXX
3678
                    goto illegal_insn;
3679
                case 0x04d: /* VIS I fexpand */
3680
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3681
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3682
                    tcg_gen_helper_0_0(helper_fexpand);
3683
                    gen_op_store_DT0_fpr(DFPREG(rd));
3684
                    break;
3685
                case 0x050: /* VIS I fpadd16 */
3686
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3687
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3688
                    tcg_gen_helper_0_0(helper_fpadd16);
3689
                    gen_op_store_DT0_fpr(DFPREG(rd));
3690
                    break;
3691
                case 0x051: /* VIS I fpadd16s */
3692
                    gen_op_load_fpr_FT0(rs1);
3693
                    gen_op_load_fpr_FT1(rs2);
3694
                    tcg_gen_helper_0_0(helper_fpadd16s);
3695
                    gen_op_store_FT0_fpr(rd);
3696
                    break;
3697
                case 0x052: /* VIS I fpadd32 */
3698
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3699
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3700
                    tcg_gen_helper_0_0(helper_fpadd32);
3701
                    gen_op_store_DT0_fpr(DFPREG(rd));
3702
                    break;
3703
                case 0x053: /* VIS I fpadd32s */
3704
                    gen_op_load_fpr_FT0(rs1);
3705
                    gen_op_load_fpr_FT1(rs2);
3706
                    tcg_gen_helper_0_0(helper_fpadd32s);
3707
                    gen_op_store_FT0_fpr(rd);
3708
                    break;
3709
                case 0x054: /* VIS I fpsub16 */
3710
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3711
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3712
                    tcg_gen_helper_0_0(helper_fpsub16);
3713
                    gen_op_store_DT0_fpr(DFPREG(rd));
3714
                    break;
3715
                case 0x055: /* VIS I fpsub16s */
3716
                    gen_op_load_fpr_FT0(rs1);
3717
                    gen_op_load_fpr_FT1(rs2);
3718
                    tcg_gen_helper_0_0(helper_fpsub16s);
3719
                    gen_op_store_FT0_fpr(rd);
3720
                    break;
3721
                case 0x056: /* VIS I fpsub32 */
3722
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3723
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3724
                    tcg_gen_helper_0_0(helper_fpadd32);
3725
                    gen_op_store_DT0_fpr(DFPREG(rd));
3726
                    break;
3727
                case 0x057: /* VIS I fpsub32s */
3728
                    gen_op_load_fpr_FT0(rs1);
3729
                    gen_op_load_fpr_FT1(rs2);
3730
                    tcg_gen_helper_0_0(helper_fpsub32s);
3731
                    gen_op_store_FT0_fpr(rd);
3732
                    break;
3733
                case 0x060: /* VIS I fzero */
3734
                    tcg_gen_helper_0_0(helper_movl_DT0_0);
3735
                    gen_op_store_DT0_fpr(DFPREG(rd));
3736
                    break;
3737
                case 0x061: /* VIS I fzeros */
3738
                    tcg_gen_helper_0_0(helper_movl_FT0_0);
3739
                    gen_op_store_FT0_fpr(rd);
3740
                    break;
3741
                case 0x062: /* VIS I fnor */
3742
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3743
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3744
                    tcg_gen_helper_0_0(helper_fnor);
3745
                    gen_op_store_DT0_fpr(DFPREG(rd));
3746
                    break;
3747
                case 0x063: /* VIS I fnors */
3748
                    gen_op_load_fpr_FT0(rs1);
3749
                    gen_op_load_fpr_FT1(rs2);
3750
                    tcg_gen_helper_0_0(helper_fnors);
3751
                    gen_op_store_FT0_fpr(rd);
3752
                    break;
3753
                case 0x064: /* VIS I fandnot2 */
3754
                    gen_op_load_fpr_DT1(DFPREG(rs1));
3755
                    gen_op_load_fpr_DT0(DFPREG(rs2));
3756
                    tcg_gen_helper_0_0(helper_fandnot);
3757
                    gen_op_store_DT0_fpr(DFPREG(rd));
3758
                    break;
3759
                case 0x065: /* VIS I fandnot2s */
3760
                    gen_op_load_fpr_FT1(rs1);
3761
                    gen_op_load_fpr_FT0(rs2);
3762
                    tcg_gen_helper_0_0(helper_fandnots);
3763
                    gen_op_store_FT0_fpr(rd);
3764
                    break;
3765
                case 0x066: /* VIS I fnot2 */
3766
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3767
                    tcg_gen_helper_0_0(helper_fnot);
3768
                    gen_op_store_DT0_fpr(DFPREG(rd));
3769
                    break;
3770
                case 0x067: /* VIS I fnot2s */
3771
                    gen_op_load_fpr_FT1(rs2);
3772
                    tcg_gen_helper_0_0(helper_fnot);
3773
                    gen_op_store_FT0_fpr(rd);
3774
                    break;
3775
                case 0x068: /* VIS I fandnot1 */
3776
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3777
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3778
                    tcg_gen_helper_0_0(helper_fandnot);
3779
                    gen_op_store_DT0_fpr(DFPREG(rd));
3780
                    break;
3781
                case 0x069: /* VIS I fandnot1s */
3782
                    gen_op_load_fpr_FT0(rs1);
3783
                    gen_op_load_fpr_FT1(rs2);
3784
                    tcg_gen_helper_0_0(helper_fandnots);
3785
                    gen_op_store_FT0_fpr(rd);
3786
                    break;
3787
                case 0x06a: /* VIS I fnot1 */
3788
                    gen_op_load_fpr_DT1(DFPREG(rs1));
3789
                    tcg_gen_helper_0_0(helper_fnot);
3790
                    gen_op_store_DT0_fpr(DFPREG(rd));
3791
                    break;
3792
                case 0x06b: /* VIS I fnot1s */
3793
                    gen_op_load_fpr_FT1(rs1);
3794
                    tcg_gen_helper_0_0(helper_fnot);
3795
                    gen_op_store_FT0_fpr(rd);
3796
                    break;
3797
                case 0x06c: /* VIS I fxor */
3798
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3799
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3800
                    tcg_gen_helper_0_0(helper_fxor);
3801
                    gen_op_store_DT0_fpr(DFPREG(rd));
3802
                    break;
3803
                case 0x06d: /* VIS I fxors */
3804
                    gen_op_load_fpr_FT0(rs1);
3805
                    gen_op_load_fpr_FT1(rs2);
3806
                    tcg_gen_helper_0_0(helper_fxors);
3807
                    gen_op_store_FT0_fpr(rd);
3808
                    break;
3809
                case 0x06e: /* VIS I fnand */
3810
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3811
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3812
                    tcg_gen_helper_0_0(helper_fnand);
3813
                    gen_op_store_DT0_fpr(DFPREG(rd));
3814
                    break;
3815
                case 0x06f: /* VIS I fnands */
3816
                    gen_op_load_fpr_FT0(rs1);
3817
                    gen_op_load_fpr_FT1(rs2);
3818
                    tcg_gen_helper_0_0(helper_fnands);
3819
                    gen_op_store_FT0_fpr(rd);
3820
                    break;
3821
                case 0x070: /* VIS I fand */
3822
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3823
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3824
                    tcg_gen_helper_0_0(helper_fand);
3825
                    gen_op_store_DT0_fpr(DFPREG(rd));
3826
                    break;
3827
                case 0x071: /* VIS I fands */
3828
                    gen_op_load_fpr_FT0(rs1);
3829
                    gen_op_load_fpr_FT1(rs2);
3830
                    tcg_gen_helper_0_0(helper_fands);
3831
                    gen_op_store_FT0_fpr(rd);
3832
                    break;
3833
                case 0x072: /* VIS I fxnor */
3834
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3835
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3836
                    tcg_gen_helper_0_0(helper_fxnor);
3837
                    gen_op_store_DT0_fpr(DFPREG(rd));
3838
                    break;
3839
                case 0x073: /* VIS I fxnors */
3840
                    gen_op_load_fpr_FT0(rs1);
3841
                    gen_op_load_fpr_FT1(rs2);
3842
                    tcg_gen_helper_0_0(helper_fxnors);
3843
                    gen_op_store_FT0_fpr(rd);
3844
                    break;
3845
                case 0x074: /* VIS I fsrc1 */
3846
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3847
                    gen_op_store_DT0_fpr(DFPREG(rd));
3848
                    break;
3849
                case 0x075: /* VIS I fsrc1s */
3850
                    gen_op_load_fpr_FT0(rs1);
3851
                    gen_op_store_FT0_fpr(rd);
3852
                    break;
3853
                case 0x076: /* VIS I fornot2 */
3854
                    gen_op_load_fpr_DT1(DFPREG(rs1));
3855
                    gen_op_load_fpr_DT0(DFPREG(rs2));
3856
                    tcg_gen_helper_0_0(helper_fornot);
3857
                    gen_op_store_DT0_fpr(DFPREG(rd));
3858
                    break;
3859
                case 0x077: /* VIS I fornot2s */
3860
                    gen_op_load_fpr_FT1(rs1);
3861
                    gen_op_load_fpr_FT0(rs2);
3862
                    tcg_gen_helper_0_0(helper_fornots);
3863
                    gen_op_store_FT0_fpr(rd);
3864
                    break;
3865
                case 0x078: /* VIS I fsrc2 */
3866
                    gen_op_load_fpr_DT0(DFPREG(rs2));
3867
                    gen_op_store_DT0_fpr(DFPREG(rd));
3868
                    break;
3869
                case 0x079: /* VIS I fsrc2s */
3870
                    gen_op_load_fpr_FT0(rs2);
3871
                    gen_op_store_FT0_fpr(rd);
3872
                    break;
3873
                case 0x07a: /* VIS I fornot1 */
3874
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3875
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3876
                    tcg_gen_helper_0_0(helper_fornot);
3877
                    gen_op_store_DT0_fpr(DFPREG(rd));
3878
                    break;
3879
                case 0x07b: /* VIS I fornot1s */
3880
                    gen_op_load_fpr_FT0(rs1);
3881
                    gen_op_load_fpr_FT1(rs2);
3882
                    tcg_gen_helper_0_0(helper_fornots);
3883
                    gen_op_store_FT0_fpr(rd);
3884
                    break;
3885
                case 0x07c: /* VIS I for */
3886
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3887
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3888
                    tcg_gen_helper_0_0(helper_for);
3889
                    gen_op_store_DT0_fpr(DFPREG(rd));
3890
                    break;
3891
                case 0x07d: /* VIS I fors */
3892
                    gen_op_load_fpr_FT0(rs1);
3893
                    gen_op_load_fpr_FT1(rs2);
3894
                    tcg_gen_helper_0_0(helper_fors);
3895
                    gen_op_store_FT0_fpr(rd);
3896
                    break;
3897
                case 0x07e: /* VIS I fone */
3898
                    tcg_gen_helper_0_0(helper_movl_DT0_1);
3899
                    gen_op_store_DT0_fpr(DFPREG(rd));
3900
                    break;
3901
                case 0x07f: /* VIS I fones */
3902
                    tcg_gen_helper_0_0(helper_movl_FT0_1);
3903
                    gen_op_store_FT0_fpr(rd);
3904
                    break;
3905
                case 0x080: /* VIS I shutdown */
3906
                case 0x081: /* VIS II siam */
3907
                    // XXX
3908
                    goto illegal_insn;
3909
                default:
3910
                    goto illegal_insn;
3911
                }
3912
#else
3913
                goto ncp_insn;
3914
#endif
3915
            } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
3916
#ifdef TARGET_SPARC64
3917
                goto illegal_insn;
3918
#else
3919
                goto ncp_insn;
3920
#endif
3921
#ifdef TARGET_SPARC64
3922
            } else if (xop == 0x39) { /* V9 return */
3923
                rs1 = GET_FIELD(insn, 13, 17);
3924
                save_state(dc, cpu_T[2]);
3925
                gen_movl_reg_TN(rs1, cpu_T[0]);
3926
                if (IS_IMM) {   /* immediate */
3927
                    rs2 = GET_FIELDs(insn, 19, 31);
3928
                    tcg_gen_addi_tl(cpu_T[0], cpu_T[0], (int)rs2);
3929
                } else {                /* register */
3930
                    rs2 = GET_FIELD(insn, 27, 31);
3931
#if defined(OPTIM)
3932
                    if (rs2) {
3933
#endif
3934
                        gen_movl_reg_TN(rs2, cpu_T[1]);
3935
                        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3936
#if defined(OPTIM)
3937
                    }
3938
#endif
3939
                }
3940
                tcg_gen_helper_0_0(helper_restore);
3941
                gen_mov_pc_npc(dc, cpu_T[2]);
3942
                tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(3));
3943
                tcg_gen_mov_tl(cpu_npc, cpu_T[0]);
3944
                dc->npc = DYNAMIC_PC;
3945
                goto jmp_insn;
3946
#endif
3947
            } else {
3948
                rs1 = GET_FIELD(insn, 13, 17);
3949
                gen_movl_reg_TN(rs1, cpu_T[0]);
3950
                if (IS_IMM) {   /* immediate */
3951
                    rs2 = GET_FIELDs(insn, 19, 31);
3952
                    tcg_gen_addi_tl(cpu_T[0], cpu_T[0], (int)rs2);
3953
                } else {                /* register */
3954
                    rs2 = GET_FIELD(insn, 27, 31);
3955
#if defined(OPTIM)
3956
                    if (rs2) {
3957
#endif
3958
                        gen_movl_reg_TN(rs2, cpu_T[1]);
3959
                        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3960
#if defined(OPTIM)
3961
                    }
3962
#endif
3963
                }
3964
                switch (xop) {
3965
                case 0x38:      /* jmpl */
3966
                    {
3967
                        if (rd != 0) {
3968
                            tcg_gen_movi_tl(cpu_T[1], dc->pc);
3969
                            gen_movl_TN_reg(rd, cpu_T[1]);
3970
                        }
3971
                        gen_mov_pc_npc(dc, cpu_T[2]);
3972
                        tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(3));
3973
                        tcg_gen_mov_tl(cpu_npc, cpu_T[0]);
3974
                        dc->npc = DYNAMIC_PC;
3975
                    }
3976
                    goto jmp_insn;
3977
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
3978
                case 0x39:      /* rett, V9 return */
3979
                    {
3980
                        if (!supervisor(dc))
3981
                            goto priv_insn;
3982
                        gen_mov_pc_npc(dc, cpu_T[2]);
3983
                        tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(3));
3984
                        tcg_gen_mov_tl(cpu_npc, cpu_T[0]);
3985
                        dc->npc = DYNAMIC_PC;
3986
                        tcg_gen_helper_0_0(helper_rett);
3987
                    }
3988
                    goto jmp_insn;
3989
#endif
3990
                case 0x3b: /* flush */
3991
                    tcg_gen_helper_0_1(helper_flush, cpu_T[0]);
3992
                    break;
3993
                case 0x3c:      /* save */
3994
                    save_state(dc, cpu_T[2]);
3995
                    tcg_gen_helper_0_0(helper_save);
3996
                    gen_movl_TN_reg(rd, cpu_T[0]);
3997
                    break;
3998
                case 0x3d:      /* restore */
3999
                    save_state(dc, cpu_T[2]);
4000
                    tcg_gen_helper_0_0(helper_restore);
4001
                    gen_movl_TN_reg(rd, cpu_T[0]);
4002
                    break;
4003
#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
4004
                case 0x3e:      /* V9 done/retry */
4005
                    {
4006
                        switch (rd) {
4007
                        case 0:
4008
                            if (!supervisor(dc))
4009
                                goto priv_insn;
4010
                            dc->npc = DYNAMIC_PC;
4011
                            dc->pc = DYNAMIC_PC;
4012
                            tcg_gen_helper_0_0(helper_done);
4013
                            goto jmp_insn;
4014
                        case 1:
4015
                            if (!supervisor(dc))
4016
                                goto priv_insn;
4017
                            dc->npc = DYNAMIC_PC;
4018
                            dc->pc = DYNAMIC_PC;
4019
                            tcg_gen_helper_0_0(helper_retry);
4020
                            goto jmp_insn;
4021
                        default:
4022
                            goto illegal_insn;
4023
                        }
4024
                    }
4025
                    break;
4026
#endif
4027
                default:
4028
                    goto illegal_insn;
4029
                }
4030
            }
4031
            break;
4032
        }
4033
        break;
4034
    case 3:                     /* load/store instructions */
4035
        {
4036
            unsigned int xop = GET_FIELD(insn, 7, 12);
4037
            rs1 = GET_FIELD(insn, 13, 17);
4038
            save_state(dc, cpu_T[2]);
4039
            gen_movl_reg_TN(rs1, cpu_T[0]);
4040
            if (xop == 0x3c || xop == 0x3e)
4041
            {
4042
                rs2 = GET_FIELD(insn, 27, 31);
4043
                gen_movl_reg_TN(rs2, cpu_T[1]);
4044
            }
4045
            else if (IS_IMM) {       /* immediate */
4046
                rs2 = GET_FIELDs(insn, 19, 31);
4047
                tcg_gen_addi_tl(cpu_T[0], cpu_T[0], (int)rs2);
4048
            } else {            /* register */
4049
                rs2 = GET_FIELD(insn, 27, 31);
4050
#if defined(OPTIM)
4051
                if (rs2 != 0) {
4052
#endif
4053
                    gen_movl_reg_TN(rs2, cpu_T[1]);
4054
                    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
4055
#if defined(OPTIM)
4056
                }
4057
#endif
4058
            }
4059
            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
4060
                (xop > 0x17 && xop <= 0x1d ) ||
4061
                (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
4062
                switch (xop) {
4063
                case 0x0:       /* load unsigned word */
4064
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(3));
4065
                    ABI32_MASK(cpu_T[0]);
4066
                    tcg_gen_qemu_ld32u(cpu_T[1], cpu_T[0], dc->mem_idx);
4067
                    break;
4068
                case 0x1:       /* load unsigned byte */
4069
                    ABI32_MASK(cpu_T[0]);
4070
                    tcg_gen_qemu_ld8u(cpu_T[1], cpu_T[0], dc->mem_idx);
4071
                    break;
4072
                case 0x2:       /* load unsigned halfword */
4073
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(1));
4074
                    ABI32_MASK(cpu_T[0]);
4075
                    tcg_gen_qemu_ld16u(cpu_T[1], cpu_T[0], dc->mem_idx);
4076
                    break;
4077
                case 0x3:       /* load double word */
4078
                    if (rd & 1)
4079
                        goto illegal_insn;
4080
                    else {
4081
                        tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(7));
4082
                        ABI32_MASK(cpu_T[0]);
4083
                        tcg_gen_qemu_ld64(cpu_tmp64, cpu_T[0], dc->mem_idx);
4084
                        tcg_gen_trunc_i64_tl(cpu_T[0], cpu_tmp64);
4085
                        tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0xffffffffULL);
4086
                        gen_movl_TN_reg(rd + 1, cpu_T[0]);
4087
                        tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
4088
                        tcg_gen_trunc_i64_tl(cpu_T[1], cpu_tmp64);
4089
                        tcg_gen_andi_tl(cpu_T[1], cpu_T[1], 0xffffffffULL);
4090
                    }
4091
                    break;
4092
                case 0x9:       /* load signed byte */
4093
                    ABI32_MASK(cpu_T[0]);
4094
                    tcg_gen_qemu_ld8s(cpu_T[1], cpu_T[0], dc->mem_idx);
4095
                    break;
4096
                case 0xa:       /* load signed halfword */
4097
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(1));
4098
                    ABI32_MASK(cpu_T[0]);
4099
                    tcg_gen_qemu_ld16s(cpu_T[1], cpu_T[0], dc->mem_idx);
4100
                    break;
4101
                case 0xd:       /* ldstub -- XXX: should be atomically */
4102
                    ABI32_MASK(cpu_T[0]);
4103
                    tcg_gen_qemu_ld8s(cpu_T[1], cpu_T[0], dc->mem_idx);
4104
                    tcg_gen_qemu_st8(tcg_const_tl(0xff), cpu_T[0], dc->mem_idx);
4105
                    break;
4106
                case 0x0f:      /* swap register with memory. Also atomically */
4107
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(3));
4108
                    gen_movl_reg_TN(rd, cpu_T[1]);
4109
                    ABI32_MASK(cpu_T[0]);
4110
                    tcg_gen_qemu_ld32u(cpu_tmp32, cpu_T[0], dc->mem_idx);
4111
                    tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], dc->mem_idx);
4112
                    tcg_gen_extu_i32_tl(cpu_T[1], cpu_tmp32);
4113
                    break;
4114
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4115
                case 0x10:      /* load word alternate */
4116
#ifndef TARGET_SPARC64
4117
                    if (IS_IMM)
4118
                        goto illegal_insn;
4119
                    if (!supervisor(dc))
4120
                        goto priv_insn;
4121
#endif
4122
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(3));
4123
                    gen_ld_asi(cpu_T[1], cpu_T[0], insn, 4, 0);
4124
                    break;
4125
                case 0x11:      /* load unsigned byte alternate */
4126
#ifndef TARGET_SPARC64
4127
                    if (IS_IMM)
4128
                        goto illegal_insn;
4129
                    if (!supervisor(dc))
4130
                        goto priv_insn;
4131
#endif
4132
                    gen_ld_asi(cpu_T[1], cpu_T[0], insn, 1, 0);
4133
                    break;
4134
                case 0x12:      /* load unsigned halfword alternate */
4135
#ifndef TARGET_SPARC64
4136
                    if (IS_IMM)
4137
                        goto illegal_insn;
4138
                    if (!supervisor(dc))
4139
                        goto priv_insn;
4140
#endif
4141
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(1));
4142
                    gen_ld_asi(cpu_T[1], cpu_T[0], insn, 2, 0);
4143
                    break;
4144
                case 0x13:      /* load double word alternate */
4145
#ifndef TARGET_SPARC64
4146
                    if (IS_IMM)
4147
                        goto illegal_insn;
4148
                    if (!supervisor(dc))
4149
                        goto priv_insn;
4150
#endif
4151
                    if (rd & 1)
4152
                        goto illegal_insn;
4153
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(7));
4154
                    gen_ldda_asi(cpu_T[0], cpu_T[1], cpu_T[0], insn);
4155
                    gen_movl_TN_reg(rd + 1, cpu_T[0]);
4156
                    break;
4157
                case 0x19:      /* load signed byte alternate */
4158
#ifndef TARGET_SPARC64
4159
                    if (IS_IMM)
4160
                        goto illegal_insn;
4161
                    if (!supervisor(dc))
4162
                        goto priv_insn;
4163
#endif
4164
                    gen_ld_asi(cpu_T[1], cpu_T[0], insn, 1, 1);
4165
                    break;
4166
                case 0x1a:      /* load signed halfword alternate */
4167
#ifndef TARGET_SPARC64
4168
                    if (IS_IMM)
4169
                        goto illegal_insn;
4170
                    if (!supervisor(dc))
4171
                        goto priv_insn;
4172
#endif
4173
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(1));
4174
                    gen_ld_asi(cpu_T[1], cpu_T[0], insn, 2, 1);
4175
                    break;
4176
                case 0x1d:      /* ldstuba -- XXX: should be atomically */
4177
#ifndef TARGET_SPARC64
4178
                    if (IS_IMM)
4179
                        goto illegal_insn;
4180
                    if (!supervisor(dc))
4181
                        goto priv_insn;
4182
#endif
4183
                    gen_ldstub_asi(cpu_T[1], cpu_T[0], insn);
4184
                    break;
4185
                case 0x1f:      /* swap reg with alt. memory. Also atomically */
4186
#ifndef TARGET_SPARC64
4187
                    if (IS_IMM)
4188
                        goto illegal_insn;
4189
                    if (!supervisor(dc))
4190
                        goto priv_insn;
4191
#endif
4192
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(3));
4193
                    gen_movl_reg_TN(rd, cpu_T[1]);
4194
                    gen_swap_asi(cpu_T[1], cpu_T[0], insn);
4195
                    break;
4196

    
4197
#ifndef TARGET_SPARC64
4198
                case 0x30: /* ldc */
4199
                case 0x31: /* ldcsr */
4200
                case 0x33: /* lddc */
4201
                    goto ncp_insn;
4202
#endif
4203
#endif
4204
#ifdef TARGET_SPARC64
4205
                case 0x08: /* V9 ldsw */
4206
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(3));
4207
                    ABI32_MASK(cpu_T[0]);
4208
                    tcg_gen_qemu_ld32s(cpu_T[1], cpu_T[0], dc->mem_idx);
4209
                    break;
4210
                case 0x0b: /* V9 ldx */
4211
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(7));
4212
                    ABI32_MASK(cpu_T[0]);
4213
                    tcg_gen_qemu_ld64(cpu_T[1], cpu_T[0], dc->mem_idx);
4214
                    break;
4215
                case 0x18: /* V9 ldswa */
4216
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(3));
4217
                    gen_ld_asi(cpu_T[1], cpu_T[0], insn, 4, 1);
4218
                    break;
4219
                case 0x1b: /* V9 ldxa */
4220
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(7));
4221
                    gen_ld_asi(cpu_T[1], cpu_T[0], insn, 8, 0);
4222
                    break;
4223
                case 0x2d: /* V9 prefetch, no effect */
4224
                    goto skip_move;
4225
                case 0x30: /* V9 ldfa */
4226
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(3));
4227
                    gen_ldf_asi(cpu_T[0], insn, 4, rd);
4228
                    goto skip_move;
4229
                case 0x33: /* V9 lddfa */
4230
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(3));
4231
                    gen_ldf_asi(cpu_T[0], insn, 8, DFPREG(rd));
4232
                    goto skip_move;
4233
                case 0x3d: /* V9 prefetcha, no effect */
4234
                    goto skip_move;
4235
                case 0x32: /* V9 ldqfa */
4236
#if defined(CONFIG_USER_ONLY)
4237
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(3));
4238
                    gen_ldf_asi(cpu_T[0], insn, 16, QFPREG(rd));
4239
                    goto skip_move;
4240
#else
4241
                    goto nfpu_insn;
4242
#endif
4243
#endif
4244
                default:
4245
                    goto illegal_insn;
4246
                }
4247
                gen_movl_TN_reg(rd, cpu_T[1]);
4248
#ifdef TARGET_SPARC64
4249
            skip_move: ;
4250
#endif
4251
            } else if (xop >= 0x20 && xop < 0x24) {
4252
                if (gen_trap_ifnofpu(dc, cpu_T[2]))
4253
                    goto jmp_insn;
4254
                switch (xop) {
4255
                case 0x20:      /* load fpreg */
4256
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(3));
4257
                    tcg_gen_qemu_ld32u(cpu_tmp32, cpu_T[0], dc->mem_idx);
4258
                    tcg_gen_st_i32(cpu_tmp32, cpu_env,
4259
                                   offsetof(CPUState, fpr[rd]));
4260
                    break;
4261
                case 0x21:      /* load fsr */
4262
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(3));
4263
                    tcg_gen_qemu_ld32u(cpu_tmp32, cpu_T[0], dc->mem_idx);
4264
                    tcg_gen_st_i32(cpu_tmp32, cpu_env,
4265
                                   offsetof(CPUState, ft0));
4266
                    tcg_gen_helper_0_0(helper_ldfsr);
4267
                    break;
4268
                case 0x22:      /* load quad fpreg */
4269
#if defined(CONFIG_USER_ONLY)
4270
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(7));
4271
                    gen_op_ldst(ldqf);
4272
                    gen_op_store_QT0_fpr(QFPREG(rd));
4273
                    break;
4274
#else
4275
                    goto nfpu_insn;
4276
#endif
4277
                case 0x23:      /* load double fpreg */
4278
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(7));
4279
                    gen_op_ldst(lddf);
4280
                    gen_op_store_DT0_fpr(DFPREG(rd));
4281
                    break;
4282
                default:
4283
                    goto illegal_insn;
4284
                }
4285
            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) || \
4286
                       xop == 0xe || xop == 0x1e) {
4287
                gen_movl_reg_TN(rd, cpu_T[1]);
4288
                switch (xop) {
4289
                case 0x4: /* store word */
4290
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(3));
4291
                    ABI32_MASK(cpu_T[0]);
4292
                    tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], dc->mem_idx);
4293
                    break;
4294
                case 0x5: /* store byte */
4295
                    ABI32_MASK(cpu_T[0]);
4296
                    tcg_gen_qemu_st8(cpu_T[1], cpu_T[0], dc->mem_idx);
4297
                    break;
4298
                case 0x6: /* store halfword */
4299
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(1));
4300
                    ABI32_MASK(cpu_T[0]);
4301
                    tcg_gen_qemu_st16(cpu_T[1], cpu_T[0], dc->mem_idx);
4302
                    break;
4303
                case 0x7: /* store double word */
4304
                    if (rd & 1)
4305
                        goto illegal_insn;
4306
#ifndef __i386__
4307
                    else {
4308
                        TCGv r_low;
4309

    
4310
                        tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(7));
4311
                        r_low = tcg_temp_new(TCG_TYPE_I32);
4312
                        gen_movl_reg_TN(rd + 1, r_low);
4313
                        tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, cpu_T[1],
4314
                                           r_low);
4315
                        tcg_gen_qemu_st64(cpu_tmp64, cpu_T[0], dc->mem_idx);
4316
                    }
4317
#else /* __i386__ */
4318
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(7));
4319
                    flush_cond(dc, cpu_T[2]);
4320
                    gen_movl_reg_TN(rd + 1, cpu_T[2]);
4321
                    gen_op_ldst(std);
4322
#endif /* __i386__ */
4323
                    break;
4324
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4325
                case 0x14: /* store word alternate */
4326
#ifndef TARGET_SPARC64
4327
                    if (IS_IMM)
4328
                        goto illegal_insn;
4329
                    if (!supervisor(dc))
4330
                        goto priv_insn;
4331
#endif
4332
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(3));
4333
                    gen_st_asi(cpu_T[1], cpu_T[0], insn, 4);
4334
                    break;
4335
                case 0x15: /* store byte alternate */
4336
#ifndef TARGET_SPARC64
4337
                    if (IS_IMM)
4338
                        goto illegal_insn;
4339
                    if (!supervisor(dc))
4340
                        goto priv_insn;
4341
#endif
4342
                    gen_st_asi(cpu_T[1], cpu_T[0], insn, 1);
4343
                    break;
4344
                case 0x16: /* store halfword alternate */
4345
#ifndef TARGET_SPARC64
4346
                    if (IS_IMM)
4347
                        goto illegal_insn;
4348
                    if (!supervisor(dc))
4349
                        goto priv_insn;
4350
#endif
4351
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(1));
4352
                    gen_st_asi(cpu_T[1], cpu_T[0], insn, 2);
4353
                    break;
4354
                case 0x17: /* store double word alternate */
4355
#ifndef TARGET_SPARC64
4356
                    if (IS_IMM)
4357
                        goto illegal_insn;
4358
                    if (!supervisor(dc))
4359
                        goto priv_insn;
4360
#endif
4361
                    if (rd & 1)
4362
                        goto illegal_insn;
4363
                    else {
4364
                        tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(7));
4365
                        gen_stda_asi(cpu_T[1], cpu_T[0], insn, rd);
4366
                    }
4367
                    break;
4368
#endif
4369
#ifdef TARGET_SPARC64
4370
                case 0x0e: /* V9 stx */
4371
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(7));
4372
                    ABI32_MASK(cpu_T[0]);
4373
                    tcg_gen_qemu_st64(cpu_T[1], cpu_T[0], dc->mem_idx);
4374
                    break;
4375
                case 0x1e: /* V9 stxa */
4376
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(7));
4377
                    gen_st_asi(cpu_T[1], cpu_T[0], insn, 8);
4378
                    break;
4379
#endif
4380
                default:
4381
                    goto illegal_insn;
4382
                }
4383
            } else if (xop > 0x23 && xop < 0x28) {
4384
                if (gen_trap_ifnofpu(dc, cpu_T[2]))
4385
                    goto jmp_insn;
4386
                switch (xop) {
4387
                case 0x24: /* store fpreg */
4388
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(3));
4389
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
4390
                                   offsetof(CPUState, fpr[rd]));
4391
                    tcg_gen_qemu_st32(cpu_tmp32, cpu_T[0], dc->mem_idx);
4392
                    break;
4393
                case 0x25: /* stfsr, V9 stxfsr */
4394
#ifdef CONFIG_USER_ONLY
4395
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(3));
4396
#endif
4397
                    tcg_gen_helper_0_0(helper_stfsr);
4398
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
4399
                                   offsetof(CPUState, ft0));
4400
                    tcg_gen_qemu_st32(cpu_tmp32, cpu_T[0], dc->mem_idx);
4401
                    break;
4402
                case 0x26:
4403
#ifdef TARGET_SPARC64
4404
#if defined(CONFIG_USER_ONLY)
4405
                    /* V9 stqf, store quad fpreg */
4406
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(7));
4407
                    gen_op_load_fpr_QT0(QFPREG(rd));
4408
                    gen_op_ldst(stqf);
4409
                    break;
4410
#else
4411
                    goto nfpu_insn;
4412
#endif
4413
#else /* !TARGET_SPARC64 */
4414
                    /* stdfq, store floating point queue */
4415
#if defined(CONFIG_USER_ONLY)
4416
                    goto illegal_insn;
4417
#else
4418
                    if (!supervisor(dc))
4419
                        goto priv_insn;
4420
                    if (gen_trap_ifnofpu(dc, cpu_T[2]))
4421
                        goto jmp_insn;
4422
                    goto nfq_insn;
4423
#endif
4424
#endif
4425
                case 0x27:
4426
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(7));
4427
                    gen_op_load_fpr_DT0(DFPREG(rd));
4428
                    gen_op_ldst(stdf);
4429
                    break;
4430
                default:
4431
                    goto illegal_insn;
4432
                }
4433
            } else if (xop > 0x33 && xop < 0x3f) {
4434
                switch (xop) {
4435
#ifdef TARGET_SPARC64
4436
                case 0x34: /* V9 stfa */
4437
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(3));
4438
                    gen_op_load_fpr_FT0(rd);
4439
                    gen_stf_asi(cpu_T[0], insn, 4, rd);
4440
                    break;
4441
                case 0x36: /* V9 stqfa */
4442
#if defined(CONFIG_USER_ONLY)
4443
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(7));
4444
                    gen_op_load_fpr_QT0(QFPREG(rd));
4445
                    gen_stf_asi(cpu_T[0], insn, 16, QFPREG(rd));
4446
                    break;
4447
#else
4448
                    goto nfpu_insn;
4449
#endif
4450
                case 0x37: /* V9 stdfa */
4451
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(3));
4452
                    gen_op_load_fpr_DT0(DFPREG(rd));
4453
                    gen_stf_asi(cpu_T[0], insn, 8, DFPREG(rd));
4454
                    break;
4455
                case 0x3c: /* V9 casa */
4456
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(3));
4457
                    gen_cas_asi(cpu_T[1], cpu_T[0], cpu_T[1], insn, rd);
4458
                    gen_movl_TN_reg(rd, cpu_T[1]);
4459
                    break;
4460
                case 0x3e: /* V9 casxa */
4461
                    tcg_gen_helper_0_2(helper_check_align, cpu_T[0], tcg_const_i32(7));
4462
                    gen_casx_asi(cpu_T[1], cpu_T[0], cpu_T[1], insn, rd);
4463
                    gen_movl_TN_reg(rd, cpu_T[1]);
4464
                    break;
4465
#else
4466
                case 0x34: /* stc */
4467
                case 0x35: /* stcsr */
4468
                case 0x36: /* stdcq */
4469
                case 0x37: /* stdc */
4470
                    goto ncp_insn;
4471
#endif
4472
                default:
4473
                    goto illegal_insn;
4474
                }
4475
            }
4476
            else
4477
                goto illegal_insn;
4478
        }
4479
        break;
4480
    }
4481
    /* default case for non jump instructions */
4482
    if (dc->npc == DYNAMIC_PC) {
4483
        dc->pc = DYNAMIC_PC;
4484
        gen_op_next_insn();
4485
    } else if (dc->npc == JUMP_PC) {
4486
        /* we can do a static jump */
4487
        gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
4488
        dc->is_br = 1;
4489
    } else {
4490
        dc->pc = dc->npc;
4491
        dc->npc = dc->npc + 4;
4492
    }
4493
 jmp_insn:
4494
    return;
4495
 illegal_insn:
4496
    save_state(dc, cpu_T[2]);
4497
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_ILL_INSN));
4498
    dc->is_br = 1;
4499
    return;
4500
#if !defined(CONFIG_USER_ONLY)
4501
 priv_insn:
4502
    save_state(dc, cpu_T[2]);
4503
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_PRIV_INSN));
4504
    dc->is_br = 1;
4505
    return;
4506
 nfpu_insn:
4507
    save_state(dc, cpu_T[2]);
4508
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
4509
    dc->is_br = 1;
4510
    return;
4511
#ifndef TARGET_SPARC64
4512
 nfq_insn:
4513
    save_state(dc, cpu_T[2]);
4514
    gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
4515
    dc->is_br = 1;
4516
    return;
4517
#endif
4518
#endif
4519
#ifndef TARGET_SPARC64
4520
 ncp_insn:
4521
    save_state(dc, cpu_T[2]);
4522
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_NCP_INSN));
4523
    dc->is_br = 1;
4524
    return;
4525
#endif
4526
}
4527

    
4528
static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
4529
{
4530
}
4531

    
4532
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
4533
                                                 int spc, CPUSPARCState *env)
4534
{
4535
    target_ulong pc_start, last_pc;
4536
    uint16_t *gen_opc_end;
4537
    DisasContext dc1, *dc = &dc1;
4538
    int j, lj = -1;
4539

    
4540
    memset(dc, 0, sizeof(DisasContext));
4541
    dc->tb = tb;
4542
    pc_start = tb->pc;
4543
    dc->pc = pc_start;
4544
    last_pc = dc->pc;
4545
    dc->npc = (target_ulong) tb->cs_base;
4546
    dc->mem_idx = cpu_mmu_index(env);
4547
    dc->fpu_enabled = cpu_fpu_enabled(env);
4548
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4549

    
4550
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
4551
    cpu_tmp32 = tcg_temp_new(TCG_TYPE_I32);
4552
    cpu_tmp64 = tcg_temp_new(TCG_TYPE_I64);
4553

    
4554
    do {
4555
        if (env->nb_breakpoints > 0) {
4556
            for(j = 0; j < env->nb_breakpoints; j++) {
4557
                if (env->breakpoints[j] == dc->pc) {
4558
                    if (dc->pc != pc_start)
4559
                        save_state(dc, cpu_T[2]);
4560
                    tcg_gen_helper_0_0(helper_debug);
4561
                    tcg_gen_exit_tb(0);
4562
                    dc->is_br = 1;
4563
                    goto exit_gen_loop;
4564
                }
4565
            }
4566
        }
4567
        if (spc) {
4568
            if (loglevel > 0)
4569
                fprintf(logfile, "Search PC...\n");
4570
            j = gen_opc_ptr - gen_opc_buf;
4571
            if (lj < j) {
4572
                lj++;
4573
                while (lj < j)
4574
                    gen_opc_instr_start[lj++] = 0;
4575
                gen_opc_pc[lj] = dc->pc;
4576
                gen_opc_npc[lj] = dc->npc;
4577
                gen_opc_instr_start[lj] = 1;
4578
            }
4579
        }
4580
        last_pc = dc->pc;
4581
        disas_sparc_insn(dc);
4582

    
4583
        if (dc->is_br)
4584
            break;
4585
        /* if the next PC is different, we abort now */
4586
        if (dc->pc != (last_pc + 4))
4587
            break;
4588
        /* if we reach a page boundary, we stop generation so that the
4589
           PC of a TT_TFAULT exception is always in the right page */
4590
        if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
4591
            break;
4592
        /* if single step mode, we generate only one instruction and
4593
           generate an exception */
4594
        if (env->singlestep_enabled) {
4595
            tcg_gen_movi_tl(cpu_pc, dc->pc);
4596
            tcg_gen_exit_tb(0);
4597
            break;
4598
        }
4599
    } while ((gen_opc_ptr < gen_opc_end) &&
4600
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
4601

    
4602
 exit_gen_loop:
4603
    if (!dc->is_br) {
4604
        if (dc->pc != DYNAMIC_PC &&
4605
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
4606
            /* static PC and NPC: we can use direct chaining */
4607
            gen_goto_tb(dc, 0, dc->pc, dc->npc);
4608
        } else {
4609
            if (dc->pc != DYNAMIC_PC)
4610
                tcg_gen_movi_tl(cpu_pc, dc->pc);
4611
            save_npc(dc, cpu_T[2]);
4612
            tcg_gen_exit_tb(0);
4613
        }
4614
    }
4615
    *gen_opc_ptr = INDEX_op_end;
4616
    if (spc) {
4617
        j = gen_opc_ptr - gen_opc_buf;
4618
        lj++;
4619
        while (lj <= j)
4620
            gen_opc_instr_start[lj++] = 0;
4621
#if 0
4622
        if (loglevel > 0) {
4623
            page_dump(logfile);
4624
        }
4625
#endif
4626
        gen_opc_jump_pc[0] = dc->jump_pc[0];
4627
        gen_opc_jump_pc[1] = dc->jump_pc[1];
4628
    } else {
4629
        tb->size = last_pc + 4 - pc_start;
4630
    }
4631
#ifdef DEBUG_DISAS
4632
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4633
        fprintf(logfile, "--------------\n");
4634
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
4635
        target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
4636
        fprintf(logfile, "\n");
4637
    }
4638
#endif
4639
    return 0;
4640
}
4641

    
4642
int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
4643
{
4644
    return gen_intermediate_code_internal(tb, 0, env);
4645
}
4646

    
4647
int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
4648
{
4649
    return gen_intermediate_code_internal(tb, 1, env);
4650
}
4651

    
4652
void cpu_reset(CPUSPARCState *env)
4653
{
4654
    tlb_flush(env, 1);
4655
    env->cwp = 0;
4656
    env->wim = 1;
4657
    env->regwptr = env->regbase + (env->cwp * 16);
4658
#if defined(CONFIG_USER_ONLY)
4659
    env->user_mode_only = 1;
4660
#ifdef TARGET_SPARC64
4661
    env->cleanwin = NWINDOWS - 2;
4662
    env->cansave = NWINDOWS - 2;
4663
    env->pstate = PS_RMO | PS_PEF | PS_IE;
4664
    env->asi = 0x82; // Primary no-fault
4665
#endif
4666
#else
4667
    env->psret = 0;
4668
    env->psrs = 1;
4669
    env->psrps = 1;
4670
#ifdef TARGET_SPARC64
4671
    env->pstate = PS_PRIV;
4672
    env->hpstate = HS_PRIV;
4673
    env->pc = 0x1fff0000000ULL;
4674
    env->tsptr = &env->ts[env->tl];
4675
#else
4676
    env->pc = 0;
4677
    env->mmuregs[0] &= ~(MMU_E | MMU_NF);
4678
    env->mmuregs[0] |= env->mmu_bm;
4679
#endif
4680
    env->npc = env->pc + 4;
4681
#endif
4682
}
4683

    
4684
CPUSPARCState *cpu_sparc_init(const char *cpu_model)
4685
{
4686
    CPUSPARCState *env;
4687
    const sparc_def_t *def;
4688
    static int inited;
4689
    unsigned int i;
4690
    static const char * const gregnames[8] = {
4691
        NULL, // g0 not used
4692
        "g1",
4693
        "g2",
4694
        "g3",
4695
        "g4",
4696
        "g5",
4697
        "g6",
4698
        "g7",
4699
    };
4700

    
4701
    def = cpu_sparc_find_by_name(cpu_model);
4702
    if (!def)
4703
        return NULL;
4704

    
4705
    env = qemu_mallocz(sizeof(CPUSPARCState));
4706
    if (!env)
4707
        return NULL;
4708
    cpu_exec_init(env);
4709
    env->cpu_model_str = cpu_model;
4710
    env->version = def->iu_version;
4711
    env->fsr = def->fpu_version;
4712
#if !defined(TARGET_SPARC64)
4713
    env->mmu_bm = def->mmu_bm;
4714
    env->mmu_ctpr_mask = def->mmu_ctpr_mask;
4715
    env->mmu_cxr_mask = def->mmu_cxr_mask;
4716
    env->mmu_sfsr_mask = def->mmu_sfsr_mask;
4717
    env->mmu_trcr_mask = def->mmu_trcr_mask;
4718
    env->mmuregs[0] |= def->mmu_version;
4719
    cpu_sparc_set_id(env, 0);
4720
#endif
4721

    
4722
    /* init various static tables */
4723
    if (!inited) {
4724
        inited = 1;
4725

    
4726
        tcg_set_macro_func(&tcg_ctx, tcg_macro_func);
4727
        cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
4728
        cpu_regwptr = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
4729
                                         offsetof(CPUState, regwptr),
4730
                                         "regwptr");
4731
        //#if TARGET_LONG_BITS > HOST_LONG_BITS
4732
#ifdef TARGET_SPARC64
4733
        cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
4734
                                      TCG_AREG0, offsetof(CPUState, t0), "T0");
4735
        cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
4736
                                      TCG_AREG0, offsetof(CPUState, t1), "T1");
4737
        cpu_T[2] = tcg_global_mem_new(TCG_TYPE_TL,
4738
                                      TCG_AREG0, offsetof(CPUState, t2), "T2");
4739
        cpu_xcc = tcg_global_mem_new(TCG_TYPE_I32,
4740
                                     TCG_AREG0, offsetof(CPUState, xcc),
4741
                                     "xcc");
4742
#else
4743
        cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
4744
        cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
4745
        cpu_T[2] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T2");
4746
#endif
4747
        cpu_cc_src = tcg_global_mem_new(TCG_TYPE_TL,
4748
                                        TCG_AREG0, offsetof(CPUState, cc_src),
4749
                                        "cc_src");
4750
        cpu_cc_src2 = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4751
                                         offsetof(CPUState, cc_src2),
4752
                                         "cc_src2");
4753
        cpu_cc_dst = tcg_global_mem_new(TCG_TYPE_TL,
4754
                                        TCG_AREG0, offsetof(CPUState, cc_dst),
4755
                                        "cc_dst");
4756
        cpu_psr = tcg_global_mem_new(TCG_TYPE_I32,
4757
                                     TCG_AREG0, offsetof(CPUState, psr),
4758
                                     "psr");
4759
        cpu_fsr = tcg_global_mem_new(TCG_TYPE_TL,
4760
                                     TCG_AREG0, offsetof(CPUState, fsr),
4761
                                     "fsr");
4762
        cpu_pc = tcg_global_mem_new(TCG_TYPE_TL,
4763
                                    TCG_AREG0, offsetof(CPUState, pc),
4764
                                    "pc");
4765
        cpu_npc = tcg_global_mem_new(TCG_TYPE_TL,
4766
                                    TCG_AREG0, offsetof(CPUState, npc),
4767
                                    "npc");
4768
        for (i = 1; i < 8; i++)
4769
            cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4770
                                              offsetof(CPUState, gregs[i]),
4771
                                              gregnames[i]);
4772
    }
4773

    
4774
    cpu_reset(env);
4775
    
4776
    return env;
4777
}
4778

    
4779
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
4780
{
4781
#if !defined(TARGET_SPARC64)
4782
    env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
4783
#endif
4784
}
4785

    
4786
static const sparc_def_t sparc_defs[] = {
4787
#ifdef TARGET_SPARC64
4788
    {
4789
        .name = "Fujitsu Sparc64",
4790
        .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)
4791
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4792
        .fpu_version = 0x00000000,
4793
        .mmu_version = 0,
4794
    },
4795
    {
4796
        .name = "Fujitsu Sparc64 III",
4797
        .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)
4798
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4799
        .fpu_version = 0x00000000,
4800
        .mmu_version = 0,
4801
    },
4802
    {
4803
        .name = "Fujitsu Sparc64 IV",
4804
        .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)
4805
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4806
        .fpu_version = 0x00000000,
4807
        .mmu_version = 0,
4808
    },
4809
    {
4810
        .name = "Fujitsu Sparc64 V",
4811
        .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)
4812
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4813
        .fpu_version = 0x00000000,
4814
        .mmu_version = 0,
4815
    },
4816
    {
4817
        .name = "TI UltraSparc I",
4818
        .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)
4819
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4820
        .fpu_version = 0x00000000,
4821
        .mmu_version = 0,
4822
    },
4823
    {
4824
        .name = "TI UltraSparc II",
4825
        .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)
4826
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4827
        .fpu_version = 0x00000000,
4828
        .mmu_version = 0,
4829
    },
4830
    {
4831
        .name = "TI UltraSparc IIi",
4832
        .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)
4833
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4834
        .fpu_version = 0x00000000,
4835
        .mmu_version = 0,
4836
    },
4837
    {
4838
        .name = "TI UltraSparc IIe",
4839
        .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)
4840
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4841
        .fpu_version = 0x00000000,
4842
        .mmu_version = 0,
4843
    },
4844
    {
4845
        .name = "Sun UltraSparc III",
4846
        .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)
4847
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4848
        .fpu_version = 0x00000000,
4849
        .mmu_version = 0,
4850
    },
4851
    {
4852
        .name = "Sun UltraSparc III Cu",
4853
        .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)
4854
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4855
        .fpu_version = 0x00000000,
4856
        .mmu_version = 0,
4857
    },
4858
    {
4859
        .name = "Sun UltraSparc IIIi",
4860
        .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)
4861
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4862
        .fpu_version = 0x00000000,
4863
        .mmu_version = 0,
4864
    },
4865
    {
4866
        .name = "Sun UltraSparc IV",
4867
        .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)
4868
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4869
        .fpu_version = 0x00000000,
4870
        .mmu_version = 0,
4871
    },
4872
    {
4873
        .name = "Sun UltraSparc IV+",
4874
        .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)
4875
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4876
        .fpu_version = 0x00000000,
4877
        .mmu_version = 0,
4878
    },
4879
    {
4880
        .name = "Sun UltraSparc IIIi+",
4881
        .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)
4882
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4883
        .fpu_version = 0x00000000,
4884
        .mmu_version = 0,
4885
    },
4886
    {
4887
        .name = "NEC UltraSparc I",
4888
        .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)
4889
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4890
        .fpu_version = 0x00000000,
4891
        .mmu_version = 0,
4892
    },
4893
#else
4894
    {
4895
        .name = "Fujitsu MB86900",
4896
        .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
4897
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
4898
        .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
4899
        .mmu_bm = 0x00004000,
4900
        .mmu_ctpr_mask = 0x007ffff0,
4901
        .mmu_cxr_mask = 0x0000003f,
4902
        .mmu_sfsr_mask = 0xffffffff,
4903
        .mmu_trcr_mask = 0xffffffff,
4904
    },
4905
    {
4906
        .name = "Fujitsu MB86904",
4907
        .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
4908
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
4909
        .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
4910
        .mmu_bm = 0x00004000,
4911
        .mmu_ctpr_mask = 0x00ffffc0,
4912
        .mmu_cxr_mask = 0x000000ff,
4913
        .mmu_sfsr_mask = 0x00016fff,
4914
        .mmu_trcr_mask = 0x00ffffff,
4915
    },
4916
    {
4917
        .name = "Fujitsu MB86907",
4918
        .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
4919
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
4920
        .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
4921
        .mmu_bm = 0x00004000,
4922
        .mmu_ctpr_mask = 0xffffffc0,
4923
        .mmu_cxr_mask = 0x000000ff,
4924
        .mmu_sfsr_mask = 0x00016fff,
4925
        .mmu_trcr_mask = 0xffffffff,
4926
    },
4927
    {
4928
        .name = "LSI L64811",
4929
        .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
4930
        .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
4931
        .mmu_version = 0x10 << 24,
4932
        .mmu_bm = 0x00004000,
4933
        .mmu_ctpr_mask = 0x007ffff0,
4934
        .mmu_cxr_mask = 0x0000003f,
4935
        .mmu_sfsr_mask = 0xffffffff,
4936
        .mmu_trcr_mask = 0xffffffff,
4937
    },
4938
    {
4939
        .name = "Cypress CY7C601",
4940
        .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
4941
        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
4942
        .mmu_version = 0x10 << 24,
4943
        .mmu_bm = 0x00004000,
4944
        .mmu_ctpr_mask = 0x007ffff0,
4945
        .mmu_cxr_mask = 0x0000003f,
4946
        .mmu_sfsr_mask = 0xffffffff,
4947
        .mmu_trcr_mask = 0xffffffff,
4948
    },
4949
    {
4950
        .name = "Cypress CY7C611",
4951
        .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
4952
        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
4953
        .mmu_version = 0x10 << 24,
4954
        .mmu_bm = 0x00004000,
4955
        .mmu_ctpr_mask = 0x007ffff0,
4956
        .mmu_cxr_mask = 0x0000003f,
4957
        .mmu_sfsr_mask = 0xffffffff,
4958
        .mmu_trcr_mask = 0xffffffff,
4959
    },
4960
    {
4961
        .name = "TI SuperSparc II",
4962
        .iu_version = 0x40000000,
4963
        .fpu_version = 0 << 17,
4964
        .mmu_version = 0x04000000,
4965
        .mmu_bm = 0x00002000,
4966
        .mmu_ctpr_mask = 0xffffffc0,
4967
        .mmu_cxr_mask = 0x0000ffff,
4968
        .mmu_sfsr_mask = 0xffffffff,
4969
        .mmu_trcr_mask = 0xffffffff,
4970
    },
4971
    {
4972
        .name = "TI MicroSparc I",
4973
        .iu_version = 0x41000000,
4974
        .fpu_version = 4 << 17,
4975
        .mmu_version = 0x41000000,
4976
        .mmu_bm = 0x00004000,
4977
        .mmu_ctpr_mask = 0x007ffff0,
4978
        .mmu_cxr_mask = 0x0000003f,
4979
        .mmu_sfsr_mask = 0x00016fff,
4980
        .mmu_trcr_mask = 0x0000003f,
4981
    },
4982
    {
4983
        .name = "TI MicroSparc II",
4984
        .iu_version = 0x42000000,
4985
        .fpu_version = 4 << 17,
4986
        .mmu_version = 0x02000000,
4987
        .mmu_bm = 0x00004000,
4988
        .mmu_ctpr_mask = 0x00ffffc0,
4989
        .mmu_cxr_mask = 0x000000ff,
4990
        .mmu_sfsr_mask = 0x00016fff,
4991
        .mmu_trcr_mask = 0x00ffffff,
4992
    },
4993
    {
4994
        .name = "TI MicroSparc IIep",
4995
        .iu_version = 0x42000000,
4996
        .fpu_version = 4 << 17,
4997
        .mmu_version = 0x04000000,
4998
        .mmu_bm = 0x00004000,
4999
        .mmu_ctpr_mask = 0x00ffffc0,
5000
        .mmu_cxr_mask = 0x000000ff,
5001
        .mmu_sfsr_mask = 0x00016bff,
5002
        .mmu_trcr_mask = 0x00ffffff,
5003
    },
5004
    {
5005
        .name = "TI SuperSparc 51",
5006
        .iu_version = 0x43000000,
5007
        .fpu_version = 0 << 17,
5008
        .mmu_version = 0x04000000,
5009
        .mmu_bm = 0x00002000,
5010
        .mmu_ctpr_mask = 0xffffffc0,
5011
        .mmu_cxr_mask = 0x0000ffff,
5012
        .mmu_sfsr_mask = 0xffffffff,
5013
        .mmu_trcr_mask = 0xffffffff,
5014
    },
5015
    {
5016
        .name = "TI SuperSparc 61",
5017
        .iu_version = 0x44000000,
5018
        .fpu_version = 0 << 17,
5019
        .mmu_version = 0x04000000,
5020
        .mmu_bm = 0x00002000,
5021
        .mmu_ctpr_mask = 0xffffffc0,
5022
        .mmu_cxr_mask = 0x0000ffff,
5023
        .mmu_sfsr_mask = 0xffffffff,
5024
        .mmu_trcr_mask = 0xffffffff,
5025
    },
5026
    {
5027
        .name = "Ross RT625",
5028
        .iu_version = 0x1e000000,
5029
        .fpu_version = 1 << 17,
5030
        .mmu_version = 0x1e000000,
5031
        .mmu_bm = 0x00004000,
5032
        .mmu_ctpr_mask = 0x007ffff0,
5033
        .mmu_cxr_mask = 0x0000003f,
5034
        .mmu_sfsr_mask = 0xffffffff,
5035
        .mmu_trcr_mask = 0xffffffff,
5036
    },
5037
    {
5038
        .name = "Ross RT620",
5039
        .iu_version = 0x1f000000,
5040
        .fpu_version = 1 << 17,
5041
        .mmu_version = 0x1f000000,
5042
        .mmu_bm = 0x00004000,
5043
        .mmu_ctpr_mask = 0x007ffff0,
5044
        .mmu_cxr_mask = 0x0000003f,
5045
        .mmu_sfsr_mask = 0xffffffff,
5046
        .mmu_trcr_mask = 0xffffffff,
5047
    },
5048
    {
5049
        .name = "BIT B5010",
5050
        .iu_version = 0x20000000,
5051
        .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
5052
        .mmu_version = 0x20000000,
5053
        .mmu_bm = 0x00004000,
5054
        .mmu_ctpr_mask = 0x007ffff0,
5055
        .mmu_cxr_mask = 0x0000003f,
5056
        .mmu_sfsr_mask = 0xffffffff,
5057
        .mmu_trcr_mask = 0xffffffff,
5058
    },
5059
    {
5060
        .name = "Matsushita MN10501",
5061
        .iu_version = 0x50000000,
5062
        .fpu_version = 0 << 17,
5063
        .mmu_version = 0x50000000,
5064
        .mmu_bm = 0x00004000,
5065
        .mmu_ctpr_mask = 0x007ffff0,
5066
        .mmu_cxr_mask = 0x0000003f,
5067
        .mmu_sfsr_mask = 0xffffffff,
5068
        .mmu_trcr_mask = 0xffffffff,
5069
    },
5070
    {
5071
        .name = "Weitek W8601",
5072
        .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
5073
        .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
5074
        .mmu_version = 0x10 << 24,
5075
        .mmu_bm = 0x00004000,
5076
        .mmu_ctpr_mask = 0x007ffff0,
5077
        .mmu_cxr_mask = 0x0000003f,
5078
        .mmu_sfsr_mask = 0xffffffff,
5079
        .mmu_trcr_mask = 0xffffffff,
5080
    },
5081
    {
5082
        .name = "LEON2",
5083
        .iu_version = 0xf2000000,
5084
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
5085
        .mmu_version = 0xf2000000,
5086
        .mmu_bm = 0x00004000,
5087
        .mmu_ctpr_mask = 0x007ffff0,
5088
        .mmu_cxr_mask = 0x0000003f,
5089
        .mmu_sfsr_mask = 0xffffffff,
5090
        .mmu_trcr_mask = 0xffffffff,
5091
    },
5092
    {
5093
        .name = "LEON3",
5094
        .iu_version = 0xf3000000,
5095
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
5096
        .mmu_version = 0xf3000000,
5097
        .mmu_bm = 0x00004000,
5098
        .mmu_ctpr_mask = 0x007ffff0,
5099
        .mmu_cxr_mask = 0x0000003f,
5100
        .mmu_sfsr_mask = 0xffffffff,
5101
        .mmu_trcr_mask = 0xffffffff,
5102
    },
5103
#endif
5104
};
5105

    
5106
static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name)
5107
{
5108
    unsigned int i;
5109

    
5110
    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
5111
        if (strcasecmp(name, sparc_defs[i].name) == 0) {
5112
            return &sparc_defs[i];
5113
        }
5114
    }
5115
    return NULL;
5116
}
5117

    
5118
void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
5119
{
5120
    unsigned int i;
5121

    
5122
    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
5123
        (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x\n",
5124
                       sparc_defs[i].name,
5125
                       sparc_defs[i].iu_version,
5126
                       sparc_defs[i].fpu_version,
5127
                       sparc_defs[i].mmu_version);
5128
    }
5129
}
5130

    
5131
#define GET_FLAG(a,b) ((env->psr & a)?b:'-')
5132

    
5133
void cpu_dump_state(CPUState *env, FILE *f,
5134
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5135
                    int flags)
5136
{
5137
    int i, x;
5138

    
5139
    cpu_fprintf(f, "pc: " TARGET_FMT_lx "  npc: " TARGET_FMT_lx "\n", env->pc, env->npc);
5140
    cpu_fprintf(f, "General Registers:\n");
5141
    for (i = 0; i < 4; i++)
5142
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
5143
    cpu_fprintf(f, "\n");
5144
    for (; i < 8; i++)
5145
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
5146
    cpu_fprintf(f, "\nCurrent Register Window:\n");
5147
    for (x = 0; x < 3; x++) {
5148
        for (i = 0; i < 4; i++)
5149
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
5150
                    (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
5151
                    env->regwptr[i + x * 8]);
5152
        cpu_fprintf(f, "\n");
5153
        for (; i < 8; i++)
5154
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
5155
                    (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
5156
                    env->regwptr[i + x * 8]);
5157
        cpu_fprintf(f, "\n");
5158
    }
5159
    cpu_fprintf(f, "\nFloating Point Registers:\n");
5160
    for (i = 0; i < 32; i++) {
5161
        if ((i & 3) == 0)
5162
            cpu_fprintf(f, "%%f%02d:", i);
5163
        cpu_fprintf(f, " %016lf", env->fpr[i]);
5164
        if ((i & 3) == 3)
5165
            cpu_fprintf(f, "\n");
5166
    }
5167
#ifdef TARGET_SPARC64
5168
    cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d fprs: %d\n",
5169
                env->pstate, GET_CCR(env), env->asi, env->tl, env->fprs);
5170
    cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d cleanwin %d cwp %d\n",
5171
                env->cansave, env->canrestore, env->otherwin, env->wstate,
5172
                env->cleanwin, NWINDOWS - 1 - env->cwp);
5173
#else
5174
    cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n", GET_PSR(env),
5175
            GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
5176
            GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
5177
            env->psrs?'S':'-', env->psrps?'P':'-',
5178
            env->psret?'E':'-', env->wim);
5179
#endif
5180
    cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env));
5181
}
5182

    
5183
#if defined(CONFIG_USER_ONLY)
5184
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
5185
{
5186
    return addr;
5187
}
5188

    
5189
#else
5190
extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
5191
                                 int *access_index, target_ulong address, int rw,
5192
                                 int mmu_idx);
5193

    
5194
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
5195
{
5196
    target_phys_addr_t phys_addr;
5197
    int prot, access_index;
5198

    
5199
    if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2,
5200
                             MMU_KERNEL_IDX) != 0)
5201
        if (get_physical_address(env, &phys_addr, &prot, &access_index, addr,
5202
                                 0, MMU_KERNEL_IDX) != 0)
5203
            return -1;
5204
    if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED)
5205
        return -1;
5206
    return phys_addr;
5207
}
5208
#endif
5209

    
5210
void helper_flush(target_ulong addr)
5211
{
5212
    addr &= ~7;
5213
    tb_invalidate_page_range(addr, addr + 8);
5214
}