Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ 1f5063fb

History | View | Annotate | Download (179.3 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;
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
static void disas_sparc_insn(DisasContext * dc);
116

    
117
#ifdef TARGET_SPARC64
118
#define GEN32(func, NAME) \
119
static GenOpFunc * const NAME ## _table [64] = {                              \
120
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
121
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
122
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
123
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
124
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
125
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
126
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
127
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
128
NAME ## 32, 0, NAME ## 34, 0, NAME ## 36, 0, NAME ## 38, 0,                   \
129
NAME ## 40, 0, NAME ## 42, 0, NAME ## 44, 0, NAME ## 46, 0,                   \
130
NAME ## 48, 0, NAME ## 50, 0, NAME ## 52, 0, NAME ## 54, 0,                   \
131
NAME ## 56, 0, NAME ## 58, 0, NAME ## 60, 0, NAME ## 62, 0,                   \
132
};                                                                            \
133
static inline void func(int n)                                                \
134
{                                                                             \
135
    NAME ## _table[n]();                                                      \
136
}
137
#else
138
#define GEN32(func, NAME) \
139
static GenOpFunc *const NAME ## _table [32] = {                               \
140
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
141
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
142
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
143
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
144
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
145
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
146
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
147
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
148
};                                                                            \
149
static inline void func(int n)                                                \
150
{                                                                             \
151
    NAME ## _table[n]();                                                      \
152
}
153
#endif
154

    
155
/* floating point registers moves */
156
GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fprf);
157
GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fprf);
158
GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fprf);
159
GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fprf);
160

    
161
GEN32(gen_op_load_fpr_DT0, gen_op_load_fpr_DT0_fprf);
162
GEN32(gen_op_load_fpr_DT1, gen_op_load_fpr_DT1_fprf);
163
GEN32(gen_op_store_DT0_fpr, gen_op_store_DT0_fpr_fprf);
164
GEN32(gen_op_store_DT1_fpr, gen_op_store_DT1_fpr_fprf);
165

    
166
#if defined(CONFIG_USER_ONLY)
167
GEN32(gen_op_load_fpr_QT0, gen_op_load_fpr_QT0_fprf);
168
GEN32(gen_op_load_fpr_QT1, gen_op_load_fpr_QT1_fprf);
169
GEN32(gen_op_store_QT0_fpr, gen_op_store_QT0_fpr_fprf);
170
GEN32(gen_op_store_QT1_fpr, gen_op_store_QT1_fpr_fprf);
171
#endif
172

    
173
/* moves */
174
#ifdef CONFIG_USER_ONLY
175
#define supervisor(dc) 0
176
#ifdef TARGET_SPARC64
177
#define hypervisor(dc) 0
178
#endif
179
#define gen_op_ldst(name)        gen_op_##name##_raw()
180
#else
181
#define supervisor(dc) (dc->mem_idx >= 1)
182
#ifdef TARGET_SPARC64
183
#define hypervisor(dc) (dc->mem_idx == 2)
184
#define OP_LD_TABLE(width)                                              \
185
    static GenOpFunc * const gen_op_##width[] = {                       \
186
        &gen_op_##width##_user,                                         \
187
        &gen_op_##width##_kernel,                                       \
188
        &gen_op_##width##_hypv,                                         \
189
    };
190
#else
191
#define OP_LD_TABLE(width)                                              \
192
    static GenOpFunc * const gen_op_##width[] = {                       \
193
        &gen_op_##width##_user,                                         \
194
        &gen_op_##width##_kernel,                                       \
195
    };
196
#endif
197
#define gen_op_ldst(name)        (*gen_op_##name[dc->mem_idx])()
198
#endif
199

    
200
#ifndef CONFIG_USER_ONLY
201
#ifdef __i386__
202
OP_LD_TABLE(std);
203
#endif /* __i386__ */
204
OP_LD_TABLE(stf);
205
OP_LD_TABLE(stdf);
206
OP_LD_TABLE(ldf);
207
OP_LD_TABLE(lddf);
208
#endif
209

    
210
#ifdef TARGET_ABI32
211
#define ABI32_MASK(addr) tcg_gen_andi_i64(addr, addr, 0xffffffffULL);
212
#else
213
#define ABI32_MASK(addr)
214
#endif
215

    
216
static inline void gen_movl_simm_T1(int32_t val)
217
{
218
    tcg_gen_movi_tl(cpu_T[1], val);
219
}
220

    
221
static inline void gen_movl_reg_TN(int reg, TCGv tn)
222
{
223
    if (reg == 0)
224
        tcg_gen_movi_tl(tn, 0);
225
    else if (reg < 8)
226
        tcg_gen_mov_tl(tn, cpu_gregs[reg]);
227
    else {
228
        tcg_gen_ld_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
229
    }
230
}
231

    
232
static inline void gen_movl_reg_T0(int reg)
233
{
234
    gen_movl_reg_TN(reg, cpu_T[0]);
235
}
236

    
237
static inline void gen_movl_reg_T1(int reg)
238
{
239
    gen_movl_reg_TN(reg, cpu_T[1]);
240
}
241

    
242
#ifdef __i386__
243
static inline void gen_movl_reg_T2(int reg)
244
{
245
    gen_movl_reg_TN(reg, cpu_T[2]);
246
}
247

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

    
260
static inline void gen_movl_T0_reg(int reg)
261
{
262
    gen_movl_TN_reg(reg, cpu_T[0]);
263
}
264

    
265
static inline void gen_movl_T1_reg(int reg)
266
{
267
    gen_movl_TN_reg(reg, cpu_T[1]);
268
}
269

    
270
static inline void gen_op_movl_T0_env(size_t offset)
271
{
272
    tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
273
}
274

    
275
static inline void gen_op_movl_env_T0(size_t offset)
276
{
277
    tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
278
}
279

    
280
static inline void gen_op_movtl_T0_env(size_t offset)
281
{
282
    tcg_gen_ld_tl(cpu_T[0], cpu_env, offset);
283
}
284

    
285
static inline void gen_op_movtl_env_T0(size_t offset)
286
{
287
    tcg_gen_st_tl(cpu_T[0], cpu_env, offset);
288
}
289

    
290
static inline void gen_op_add_T1_T0(void)
291
{
292
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
293
}
294

    
295
static inline void gen_op_or_T1_T0(void)
296
{
297
    tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
298
}
299

    
300
static inline void gen_op_xor_T1_T0(void)
301
{
302
    tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
303
}
304

    
305
static inline void gen_jmp_im(target_ulong pc)
306
{
307
    tcg_gen_movi_tl(cpu_pc, pc);
308
}
309

    
310
static inline void gen_movl_npc_im(target_ulong npc)
311
{
312
    tcg_gen_movi_tl(cpu_npc, npc);
313
}
314

    
315
static inline void gen_goto_tb(DisasContext *s, int tb_num,
316
                               target_ulong pc, target_ulong npc)
317
{
318
    TranslationBlock *tb;
319

    
320
    tb = s->tb;
321
    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
322
        (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK))  {
323
        /* jump to same page: we can use a direct jump */
324
        tcg_gen_goto_tb(tb_num);
325
        gen_jmp_im(pc);
326
        gen_movl_npc_im(npc);
327
        tcg_gen_exit_tb((long)tb + tb_num);
328
    } else {
329
        /* jump to another page: currently not optimized */
330
        gen_jmp_im(pc);
331
        gen_movl_npc_im(npc);
332
        tcg_gen_exit_tb(0);
333
    }
334
}
335

    
336
// XXX suboptimal
337
static inline void gen_mov_reg_N(TCGv reg, TCGv src)
338
{
339
    tcg_gen_shri_i32(reg, src, 23);
340
    tcg_gen_andi_tl(reg, reg, 0x1);
341
}
342

    
343
static inline void gen_mov_reg_Z(TCGv reg, TCGv src)
344
{
345
    tcg_gen_shri_i32(reg, src, 22);
346
    tcg_gen_andi_tl(reg, reg, 0x1);
347
}
348

    
349
static inline void gen_mov_reg_V(TCGv reg, TCGv src)
350
{
351
    tcg_gen_shri_i32(reg, src, 21);
352
    tcg_gen_andi_tl(reg, reg, 0x1);
353
}
354

    
355
static inline void gen_mov_reg_C(TCGv reg, TCGv src)
356
{
357
    tcg_gen_shri_i32(reg, src, 20);
358
    tcg_gen_andi_tl(reg, reg, 0x1);
359
}
360

    
361
static inline void gen_op_exception(int exception)
362
{
363
    tcg_gen_movi_i32(cpu_tmp0, exception);
364
    tcg_gen_helper_0_1(raise_exception, cpu_tmp0);
365
}
366

    
367
static inline void gen_cc_clear(void)
368
{
369
    tcg_gen_movi_i32(cpu_psr, 0);
370
#ifdef TARGET_SPARC64
371
    tcg_gen_movi_i32(cpu_xcc, 0);
372
#endif
373
}
374

    
375
/* old op:
376
    if (!T0)
377
        env->psr |= PSR_ZERO;
378
    if ((int32_t) T0 < 0)
379
        env->psr |= PSR_NEG;
380
*/
381
static inline void gen_cc_NZ(TCGv dst)
382
{
383
    int l1, l2;
384

    
385
    l1 = gen_new_label();
386
    l2 = gen_new_label();
387
    tcg_gen_brcond_i32(TCG_COND_NE, dst, tcg_const_i32(0), l1);
388
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_ZERO);
389
    gen_set_label(l1);
390
    tcg_gen_brcond_i32(TCG_COND_GE, dst, tcg_const_i32(0), l2);
391
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_NEG);
392
    gen_set_label(l2);
393
#ifdef TARGET_SPARC64
394
    {
395
        int l3, l4;
396

    
397
        l3 = gen_new_label();
398
        l4 = gen_new_label();
399
        tcg_gen_brcond_tl(TCG_COND_NE, dst, tcg_const_tl(0), l3);
400
        tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_ZERO);
401
        gen_set_label(l3);
402
        tcg_gen_brcond_tl(TCG_COND_GE, dst, tcg_const_tl(0), l4);
403
        tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_NEG);
404
        gen_set_label(l4);
405
    }
406
#endif
407
}
408

    
409
/* old op:
410
    if (T0 < src1)
411
        env->psr |= PSR_CARRY;
412
*/
413
static inline void gen_cc_C_add(TCGv dst, TCGv src1)
414
{
415
    int l1;
416

    
417
    l1 = gen_new_label();
418
    tcg_gen_brcond_i32(TCG_COND_GEU, dst, src1, l1);
419
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
420
    gen_set_label(l1);
421
#ifdef TARGET_SPARC64
422
    {
423
        int l2;
424

    
425
        l2 = gen_new_label();
426
        tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l2);
427
        tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
428
        gen_set_label(l2);
429
    }
430
#endif
431
}
432

    
433
/* old op:
434
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
435
        env->psr |= PSR_OVF;
436
*/
437
static inline void gen_cc_V_add(TCGv dst, TCGv src1, TCGv src2)
438
{
439
    TCGv r_temp;
440
    int l1;
441

    
442
    l1 = gen_new_label();
443

    
444
    r_temp = tcg_temp_new(TCG_TYPE_TL);
445
    tcg_gen_xor_tl(r_temp, src1, src2);
446
    tcg_gen_xori_tl(r_temp, r_temp, -1);
447
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
448
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
449
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
450
    tcg_gen_brcond_i32(TCG_COND_EQ, r_temp, tcg_const_i32(0), l1);
451
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
452
    gen_set_label(l1);
453
#ifdef TARGET_SPARC64
454
    {
455
        int l2;
456

    
457
        l2 = gen_new_label();
458
        tcg_gen_xor_tl(r_temp, src1, src2);
459
        tcg_gen_xori_tl(r_temp, r_temp, -1);
460
        tcg_gen_xor_tl(cpu_tmp0, src1, dst);
461
        tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
462
        tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
463
        tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l2);
464
        tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_OVF);
465
        gen_set_label(l2);
466
    }
467
#endif
468
    tcg_gen_discard_tl(r_temp);
469
}
470

    
471
static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
472
{
473
    TCGv r_temp;
474
    int l1;
475

    
476
    l1 = gen_new_label();
477

    
478
    r_temp = tcg_temp_new(TCG_TYPE_TL);
479
    tcg_gen_xor_tl(r_temp, src1, src2);
480
    tcg_gen_xori_tl(r_temp, r_temp, -1);
481
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
482
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
483
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
484
    tcg_gen_brcond_i32(TCG_COND_EQ, r_temp, tcg_const_i32(0), l1);
485
    gen_op_exception(TT_TOVF);
486
    gen_set_label(l1);
487
#ifdef TARGET_SPARC64
488
    {
489
        int l2;
490

    
491
        l2 = gen_new_label();
492
        tcg_gen_xor_tl(r_temp, src1, src2);
493
        tcg_gen_xori_tl(r_temp, r_temp, -1);
494
        tcg_gen_xor_tl(cpu_tmp0, src1, dst);
495
        tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
496
        tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
497
        tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l2);
498
        gen_op_exception(TT_TOVF);
499
        gen_set_label(l2);
500
    }
501
#endif
502
    tcg_gen_discard_tl(r_temp);
503
}
504

    
505
static inline void gen_cc_V_tag(TCGv src1, TCGv src2)
506
{
507
    int l1;
508

    
509
    l1 = gen_new_label();
510
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
511
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
512
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
513
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
514
    gen_set_label(l1);
515
}
516

    
517
static inline void gen_tag_tv(TCGv src1, TCGv src2)
518
{
519
    int l1;
520

    
521
    l1 = gen_new_label();
522
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
523
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
524
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
525
    gen_op_exception(TT_TOVF);
526
    gen_set_label(l1);
527
}
528

    
529
static inline void gen_op_add_T1_T0_cc(void)
530
{
531
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
532
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
533
    gen_cc_clear();
534
    gen_cc_NZ(cpu_T[0]);
535
    gen_cc_C_add(cpu_T[0], cpu_cc_src);
536
    gen_cc_V_add(cpu_T[0], cpu_cc_src, cpu_T[1]);
537
}
538

    
539
static inline void gen_op_addx_T1_T0_cc(void)
540
{
541
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
542
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
543
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
544
    gen_cc_clear();
545
    gen_cc_C_add(cpu_T[0], cpu_cc_src);
546
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
547
    gen_cc_C_add(cpu_T[0], cpu_cc_src);
548
    gen_cc_NZ(cpu_T[0]);
549
    gen_cc_V_add(cpu_T[0], cpu_cc_src, cpu_T[1]);
550
}
551

    
552
static inline void gen_op_tadd_T1_T0_cc(void)
553
{
554
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
555
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
556
    gen_cc_clear();
557
    gen_cc_NZ(cpu_T[0]);
558
    gen_cc_C_add(cpu_T[0], cpu_cc_src);
559
    gen_cc_V_add(cpu_T[0], cpu_cc_src, cpu_T[1]);
560
    gen_cc_V_tag(cpu_cc_src, cpu_T[1]);
561
}
562

    
563
static inline void gen_op_tadd_T1_T0_ccTV(void)
564
{
565
    gen_tag_tv(cpu_T[0], cpu_T[1]);
566
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
567
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
568
    gen_add_tv(cpu_T[0], cpu_cc_src, cpu_T[1]);
569
    gen_cc_clear();
570
    gen_cc_NZ(cpu_T[0]);
571
    gen_cc_C_add(cpu_T[0], cpu_cc_src);
572
}
573

    
574
/* old op:
575
    if (src1 < T1)
576
        env->psr |= PSR_CARRY;
577
*/
578
static inline void gen_cc_C_sub(TCGv src1, TCGv src2)
579
{
580
    int l1;
581

    
582
    l1 = gen_new_label();
583
    tcg_gen_brcond_i32(TCG_COND_GEU, src1, src2, l1);
584
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
585
    gen_set_label(l1);
586
#ifdef TARGET_SPARC64
587
    {
588
        int l2;
589

    
590
        l2 = gen_new_label();
591
        tcg_gen_brcond_tl(TCG_COND_GEU, src1, src2, l2);
592
        tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
593
        gen_set_label(l2);
594
    }
595
#endif
596
}
597

    
598
/* old op:
599
    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
600
        env->psr |= PSR_OVF;
601
*/
602
static inline void gen_cc_V_sub(TCGv dst, TCGv src1, TCGv src2)
603
{
604
    TCGv r_temp;
605
    int l1;
606

    
607
    l1 = gen_new_label();
608

    
609
    r_temp = tcg_temp_new(TCG_TYPE_TL);
610
    tcg_gen_xor_tl(r_temp, src1, src2);
611
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
612
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
613
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
614
    tcg_gen_brcond_i32(TCG_COND_EQ, r_temp, tcg_const_i32(0), l1);
615
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
616
    gen_set_label(l1);
617
#ifdef TARGET_SPARC64
618
    {
619
        int l2;
620

    
621
        l2 = gen_new_label();
622
        tcg_gen_xor_tl(r_temp, src1, src2);
623
        tcg_gen_xor_tl(cpu_tmp0, src1, dst);
624
        tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
625
        tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
626
        tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l2);
627
        tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_OVF);
628
        gen_set_label(l2);
629
    }
630
#endif
631
    tcg_gen_discard_tl(r_temp);
632
}
633

    
634
static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
635
{
636
    TCGv r_temp;
637
    int l1;
638

    
639
    l1 = gen_new_label();
640

    
641
    r_temp = tcg_temp_new(TCG_TYPE_TL);
642
    tcg_gen_xor_tl(r_temp, src1, src2);
643
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
644
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
645
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
646
    tcg_gen_brcond_i32(TCG_COND_EQ, r_temp, tcg_const_i32(0), l1);
647
    gen_op_exception(TT_TOVF);
648
    gen_set_label(l1);
649
#ifdef TARGET_SPARC64
650
    {
651
        int l2;
652

    
653
        l2 = gen_new_label();
654
        tcg_gen_xor_tl(r_temp, src1, src2);
655
        tcg_gen_xor_tl(cpu_tmp0, src1, dst);
656
        tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
657
        tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
658
        tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l2);
659
        gen_op_exception(TT_TOVF);
660
        gen_set_label(l2);
661
    }
662
#endif
663
    tcg_gen_discard_tl(r_temp);
664
}
665

    
666
static inline void gen_op_sub_T1_T0_cc(void)
667
{
668
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
669
    tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
670
    gen_cc_clear();
671
    gen_cc_NZ(cpu_T[0]);
672
    gen_cc_C_sub(cpu_cc_src, cpu_T[1]);
673
    gen_cc_V_sub(cpu_T[0], cpu_cc_src, cpu_T[1]);
674
}
675

    
676
static inline void gen_op_subx_T1_T0_cc(void)
677
{
678
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
679
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
680
    tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
681
    gen_cc_clear();
682
    gen_cc_C_sub(cpu_T[0], cpu_cc_src);
683
    tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
684
    gen_cc_C_sub(cpu_T[0], cpu_cc_src);
685
    gen_cc_NZ(cpu_T[0]);
686
    gen_cc_V_sub(cpu_T[0], cpu_cc_src, cpu_T[1]);
687
}
688

    
689
static inline void gen_op_tsub_T1_T0_cc(void)
690
{
691
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
692
    tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
693
    gen_cc_clear();
694
    gen_cc_NZ(cpu_T[0]);
695
    gen_cc_C_sub(cpu_cc_src, cpu_T[1]);
696
    gen_cc_V_sub(cpu_T[0], cpu_cc_src, cpu_T[1]);
697
    gen_cc_V_tag(cpu_cc_src, cpu_T[1]);
698
}
699

    
700
static inline void gen_op_tsub_T1_T0_ccTV(void)
701
{
702
    gen_tag_tv(cpu_T[0], cpu_T[1]);
703
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
704
    tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
705
    gen_sub_tv(cpu_T[0], cpu_cc_src, cpu_T[1]);
706
    gen_cc_clear();
707
    gen_cc_NZ(cpu_T[0]);
708
    gen_cc_C_sub(cpu_cc_src, cpu_T[1]);
709
}
710

    
711
static inline void gen_op_mulscc_T1_T0(void)
712
{
713
    TCGv r_temp;
714
    int l1, l2;
715

    
716
    l1 = gen_new_label();
717
    l2 = gen_new_label();
718
    r_temp = tcg_temp_new(TCG_TYPE_TL);
719

    
720
    /* old op:
721
    if (!(env->y & 1))
722
        T1 = 0;
723
    */
724
    tcg_gen_ld_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
725
    tcg_gen_andi_i32(r_temp, r_temp, 0x1);
726
    tcg_gen_brcond_i32(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
727
    tcg_gen_mov_tl(cpu_cc_src2, cpu_T[1]);
728
    gen_op_jmp_label(l2);
729
    gen_set_label(l1);
730
    tcg_gen_movi_tl(cpu_cc_src2, 0);
731
    gen_set_label(l2);
732

    
733
    // b2 = T0 & 1;
734
    // env->y = (b2 << 31) | (env->y >> 1);
735
    tcg_gen_shli_i32(r_temp, cpu_T[0], 31);
736
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, y));
737
    tcg_gen_shri_i32(cpu_tmp0, cpu_tmp0, 1);
738
    tcg_gen_or_i32(cpu_tmp0, cpu_tmp0, r_temp);
739
    tcg_gen_st_i32(cpu_tmp0, 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, cpu_T[0], 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(cpu_T[0], cpu_cc_src, cpu_cc_src2);
754
    tcg_gen_discard_tl(r_temp);
755

    
756
    gen_cc_clear();
757
    gen_cc_NZ(cpu_T[0]);
758
    gen_cc_V_add(cpu_T[0], cpu_cc_src, cpu_cc_src2);
759
    gen_cc_C_add(cpu_T[0], cpu_cc_src);
760
}
761

    
762
static inline void gen_op_umul_T1_T0(void)
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_i32_i64(r_temp, cpu_T[1]);
770
    tcg_gen_extu_i32_i64(r_temp2, cpu_T[0]);
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(cpu_T[0], r_temp2);
778
#else
779
    tcg_gen_trunc_i64_i32(cpu_T[0], 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_T1_T0(void)
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_ext32s_i64(r_temp, cpu_T[1]);
794
    tcg_gen_ext32s_i64(r_temp2, cpu_T[0]);
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(cpu_T[0], r_temp2);
802
#else
803
    tcg_gen_trunc_i64_i32(cpu_T[0], 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_i64(TCGv divisor)
812
{
813
    int l1;
814

    
815
    l1 = gen_new_label();
816
    tcg_gen_brcond_i64(TCG_COND_NE, divisor, tcg_const_tl(0), l1);
817
    gen_op_exception(TT_DIV_ZERO);
818
    gen_set_label(l1);
819
}
820

    
821
static inline void gen_op_sdivx_T1_T0(void)
822
{
823
    int l1, l2;
824

    
825
    l1 = gen_new_label();
826
    l2 = gen_new_label();
827
    gen_trap_ifdivzero_i64(cpu_T[1]);
828
    tcg_gen_brcond_i64(TCG_COND_NE, cpu_T[0], tcg_const_i64(INT64_MIN), l1);
829
    tcg_gen_brcond_i64(TCG_COND_NE, cpu_T[1], tcg_const_i64(-1), l1);
830
    tcg_gen_movi_i64(cpu_T[0], INT64_MIN);
831
    gen_op_jmp_label(l2);
832
    gen_set_label(l1);
833
    tcg_gen_div_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
834
    gen_set_label(l2);
835
}
836
#endif
837

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

    
842
    gen_cc_clear();
843
    gen_cc_NZ(cpu_T[0]);
844
    l1 = gen_new_label();
845
    tcg_gen_brcond_i32(TCG_COND_EQ, cpu_T[1], tcg_const_i32(0), l1);
846
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
847
    gen_set_label(l1);
848
}
849

    
850
static inline void gen_op_logic_T0_cc(void)
851
{
852
    gen_cc_clear();
853
    gen_cc_NZ(cpu_T[0]);
854
}
855

    
856
// 1
857
static inline void gen_op_eval_ba(TCGv dst)
858
{
859
    tcg_gen_movi_tl(dst, 1);
860
}
861

    
862
// Z
863
static inline void gen_op_eval_be(TCGv dst, TCGv src)
864
{
865
    gen_mov_reg_Z(dst, src);
866
}
867

    
868
// Z | (N ^ V)
869
static inline void gen_op_eval_ble(TCGv dst, TCGv src)
870
{
871
    gen_mov_reg_N(cpu_tmp0, src);
872
    gen_mov_reg_V(dst, src);
873
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
874
    gen_mov_reg_Z(cpu_tmp0, src);
875
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
876
}
877

    
878
// N ^ V
879
static inline void gen_op_eval_bl(TCGv dst, TCGv src)
880
{
881
    gen_mov_reg_V(cpu_tmp0, src);
882
    gen_mov_reg_N(dst, src);
883
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
884
}
885

    
886
// C | Z
887
static inline void gen_op_eval_bleu(TCGv dst, TCGv src)
888
{
889
    gen_mov_reg_Z(cpu_tmp0, src);
890
    gen_mov_reg_C(dst, src);
891
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
892
}
893

    
894
// C
895
static inline void gen_op_eval_bcs(TCGv dst, TCGv src)
896
{
897
    gen_mov_reg_C(dst, src);
898
}
899

    
900
// V
901
static inline void gen_op_eval_bvs(TCGv dst, TCGv src)
902
{
903
    gen_mov_reg_V(dst, src);
904
}
905

    
906
// 0
907
static inline void gen_op_eval_bn(TCGv dst)
908
{
909
    tcg_gen_movi_tl(dst, 0);
910
}
911

    
912
// N
913
static inline void gen_op_eval_bneg(TCGv dst, TCGv src)
914
{
915
    gen_mov_reg_N(dst, src);
916
}
917

    
918
// !Z
919
static inline void gen_op_eval_bne(TCGv dst, TCGv src)
920
{
921
    gen_mov_reg_Z(dst, src);
922
    tcg_gen_xori_tl(dst, dst, 0x1);
923
}
924

    
925
// !(Z | (N ^ V))
926
static inline void gen_op_eval_bg(TCGv dst, TCGv src)
927
{
928
    gen_mov_reg_N(cpu_tmp0, src);
929
    gen_mov_reg_V(dst, src);
930
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
931
    gen_mov_reg_Z(cpu_tmp0, src);
932
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
933
    tcg_gen_xori_tl(dst, dst, 0x1);
934
}
935

    
936
// !(N ^ V)
937
static inline void gen_op_eval_bge(TCGv dst, TCGv src)
938
{
939
    gen_mov_reg_V(cpu_tmp0, src);
940
    gen_mov_reg_N(dst, src);
941
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
942
    tcg_gen_xori_tl(dst, dst, 0x1);
943
}
944

    
945
// !(C | Z)
946
static inline void gen_op_eval_bgu(TCGv dst, TCGv src)
947
{
948
    gen_mov_reg_Z(cpu_tmp0, src);
949
    gen_mov_reg_C(dst, src);
950
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
951
    tcg_gen_xori_tl(dst, dst, 0x1);
952
}
953

    
954
// !C
955
static inline void gen_op_eval_bcc(TCGv dst, TCGv src)
956
{
957
    gen_mov_reg_C(dst, src);
958
    tcg_gen_xori_tl(dst, dst, 0x1);
959
}
960

    
961
// !N
962
static inline void gen_op_eval_bpos(TCGv dst, TCGv src)
963
{
964
    gen_mov_reg_N(dst, src);
965
    tcg_gen_xori_tl(dst, dst, 0x1);
966
}
967

    
968
// !V
969
static inline void gen_op_eval_bvc(TCGv dst, TCGv src)
970
{
971
    gen_mov_reg_V(dst, src);
972
    tcg_gen_xori_tl(dst, dst, 0x1);
973
}
974

    
975
/*
976
  FPSR bit field FCC1 | FCC0:
977
   0 =
978
   1 <
979
   2 >
980
   3 unordered
981
*/
982
static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src,
983
                                    unsigned int fcc_offset)
984
{
985
    tcg_gen_shri_i32(reg, src, 10 + fcc_offset);
986
    tcg_gen_andi_tl(reg, reg, 0x1);
987
}
988

    
989
static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
990
                                    unsigned int fcc_offset)
991
{
992
    tcg_gen_shri_i32(reg, src, 11 + fcc_offset);
993
    tcg_gen_andi_tl(reg, reg, 0x1);
994
}
995

    
996
// !0: FCC0 | FCC1
997
static inline void gen_op_eval_fbne(TCGv dst, TCGv src,
998
                                    unsigned int fcc_offset)
999
{
1000
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1001
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1002
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
1003
}
1004

    
1005
// 1 or 2: FCC0 ^ FCC1
1006
static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
1007
                                    unsigned int fcc_offset)
1008
{
1009
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1010
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1011
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1012
}
1013

    
1014
// 1 or 3: FCC0
1015
static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
1016
                                    unsigned int fcc_offset)
1017
{
1018
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1019
}
1020

    
1021
// 1: FCC0 & !FCC1
1022
static inline void gen_op_eval_fbl(TCGv dst, TCGv src,
1023
                                    unsigned int fcc_offset)
1024
{
1025
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1026
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1027
    tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
1028
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1029
}
1030

    
1031
// 2 or 3: FCC1
1032
static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
1033
                                    unsigned int fcc_offset)
1034
{
1035
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1036
}
1037

    
1038
// 2: !FCC0 & FCC1
1039
static inline void gen_op_eval_fbg(TCGv dst, TCGv src,
1040
                                    unsigned int fcc_offset)
1041
{
1042
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1043
    tcg_gen_xori_tl(dst, dst, 0x1);
1044
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1045
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1046
}
1047

    
1048
// 3: FCC0 & FCC1
1049
static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
1050
                                    unsigned int fcc_offset)
1051
{
1052
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1053
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1054
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1055
}
1056

    
1057
// 0: !(FCC0 | FCC1)
1058
static inline void gen_op_eval_fbe(TCGv dst, TCGv src,
1059
                                    unsigned int fcc_offset)
1060
{
1061
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1062
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1063
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
1064
    tcg_gen_xori_tl(dst, dst, 0x1);
1065
}
1066

    
1067
// 0 or 3: !(FCC0 ^ FCC1)
1068
static inline void gen_op_eval_fbue(TCGv dst, TCGv src,
1069
                                    unsigned int fcc_offset)
1070
{
1071
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1072
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1073
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1074
    tcg_gen_xori_tl(dst, dst, 0x1);
1075
}
1076

    
1077
// 0 or 2: !FCC0
1078
static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
1079
                                    unsigned int fcc_offset)
1080
{
1081
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1082
    tcg_gen_xori_tl(dst, dst, 0x1);
1083
}
1084

    
1085
// !1: !(FCC0 & !FCC1)
1086
static inline void gen_op_eval_fbuge(TCGv dst, TCGv src,
1087
                                    unsigned int fcc_offset)
1088
{
1089
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1090
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1091
    tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
1092
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1093
    tcg_gen_xori_tl(dst, dst, 0x1);
1094
}
1095

    
1096
// 0 or 1: !FCC1
1097
static inline void gen_op_eval_fble(TCGv dst, TCGv src,
1098
                                    unsigned int fcc_offset)
1099
{
1100
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1101
    tcg_gen_xori_tl(dst, dst, 0x1);
1102
}
1103

    
1104
// !2: !(!FCC0 & FCC1)
1105
static inline void gen_op_eval_fbule(TCGv dst, TCGv src,
1106
                                    unsigned int fcc_offset)
1107
{
1108
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1109
    tcg_gen_xori_tl(dst, dst, 0x1);
1110
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1111
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1112
    tcg_gen_xori_tl(dst, dst, 0x1);
1113
}
1114

    
1115
// !3: !(FCC0 & FCC1)
1116
static inline void gen_op_eval_fbo(TCGv dst, TCGv src,
1117
                                    unsigned int fcc_offset)
1118
{
1119
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1120
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1121
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1122
    tcg_gen_xori_tl(dst, dst, 0x1);
1123
}
1124

    
1125
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
1126
                               target_ulong pc2, TCGv r_cond)
1127
{
1128
    int l1;
1129

    
1130
    l1 = gen_new_label();
1131

    
1132
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1133

    
1134
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
1135

    
1136
    gen_set_label(l1);
1137
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
1138
}
1139

    
1140
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
1141
                                target_ulong pc2, TCGv r_cond)
1142
{
1143
    int l1;
1144

    
1145
    l1 = gen_new_label();
1146

    
1147
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1148

    
1149
    gen_goto_tb(dc, 0, pc2, pc1);
1150

    
1151
    gen_set_label(l1);
1152
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
1153
}
1154

    
1155
static inline void gen_branch(DisasContext *dc, target_ulong pc,
1156
                              target_ulong npc)
1157
{
1158
    gen_goto_tb(dc, 0, pc, npc);
1159
}
1160

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

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

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

    
1171
    gen_movl_npc_im(npc1);
1172
    gen_op_jmp_label(l2);
1173

    
1174
    gen_set_label(l1);
1175
    gen_movl_npc_im(npc2);
1176
    gen_set_label(l2);
1177
}
1178

    
1179
/* call this function before using T2 as it may have been set for a jump */
1180
static inline void flush_T2(DisasContext * dc)
1181
{
1182
    if (dc->npc == JUMP_PC) {
1183
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
1184
        dc->npc = DYNAMIC_PC;
1185
    }
1186
}
1187

    
1188
static inline void save_npc(DisasContext * dc)
1189
{
1190
    if (dc->npc == JUMP_PC) {
1191
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
1192
        dc->npc = DYNAMIC_PC;
1193
    } else if (dc->npc != DYNAMIC_PC) {
1194
        gen_movl_npc_im(dc->npc);
1195
    }
1196
}
1197

    
1198
static inline void save_state(DisasContext * dc)
1199
{
1200
    gen_jmp_im(dc->pc);
1201
    save_npc(dc);
1202
}
1203

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

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

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

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

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

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

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

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

    
1373
static inline void gen_cond_reg(TCGv r_dst, int cond)
1374
{
1375
    int l1;
1376

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

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

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

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

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

    
1463
#ifdef TARGET_SPARC64
1464
/* XXX: potentially incorrect if dynamic npc */
1465
static void do_branch_reg(DisasContext * dc, int32_t offset, uint32_t insn)
1466
{
1467
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1468
    target_ulong target = dc->pc + offset;
1469

    
1470
    flush_T2(dc);
1471
    gen_cond_reg(cpu_T[2], cond);
1472
    if (a) {
1473
        gen_branch_a(dc, target, dc->npc, cpu_T[2]);
1474
        dc->is_br = 1;
1475
    } else {
1476
        dc->pc = dc->npc;
1477
        dc->jump_pc[0] = target;
1478
        dc->jump_pc[1] = dc->npc + 4;
1479
        dc->npc = JUMP_PC;
1480
    }
1481
}
1482

    
1483
static GenOpFunc * const gen_fcmps[4] = {
1484
    helper_fcmps,
1485
    helper_fcmps_fcc1,
1486
    helper_fcmps_fcc2,
1487
    helper_fcmps_fcc3,
1488
};
1489

    
1490
static GenOpFunc * const gen_fcmpd[4] = {
1491
    helper_fcmpd,
1492
    helper_fcmpd_fcc1,
1493
    helper_fcmpd_fcc2,
1494
    helper_fcmpd_fcc3,
1495
};
1496

    
1497
#if defined(CONFIG_USER_ONLY)
1498
static GenOpFunc * const gen_fcmpq[4] = {
1499
    helper_fcmpq,
1500
    helper_fcmpq_fcc1,
1501
    helper_fcmpq_fcc2,
1502
    helper_fcmpq_fcc3,
1503
};
1504
#endif
1505

    
1506
static GenOpFunc * const gen_fcmpes[4] = {
1507
    helper_fcmpes,
1508
    helper_fcmpes_fcc1,
1509
    helper_fcmpes_fcc2,
1510
    helper_fcmpes_fcc3,
1511
};
1512

    
1513
static GenOpFunc * const gen_fcmped[4] = {
1514
    helper_fcmped,
1515
    helper_fcmped_fcc1,
1516
    helper_fcmped_fcc2,
1517
    helper_fcmped_fcc3,
1518
};
1519

    
1520
#if defined(CONFIG_USER_ONLY)
1521
static GenOpFunc * const gen_fcmpeq[4] = {
1522
    helper_fcmpeq,
1523
    helper_fcmpeq_fcc1,
1524
    helper_fcmpeq_fcc2,
1525
    helper_fcmpeq_fcc3,
1526
};
1527
#endif
1528

    
1529
static inline void gen_op_fcmps(int fccno)
1530
{
1531
    tcg_gen_helper_0_0(gen_fcmps[fccno]);
1532
}
1533

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

    
1539
#if defined(CONFIG_USER_ONLY)
1540
static inline void gen_op_fcmpq(int fccno)
1541
{
1542
    tcg_gen_helper_0_0(gen_fcmpq[fccno]);
1543
}
1544
#endif
1545

    
1546
static inline void gen_op_fcmpes(int fccno)
1547
{
1548
    tcg_gen_helper_0_0(gen_fcmpes[fccno]);
1549
}
1550

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

    
1556
#if defined(CONFIG_USER_ONLY)
1557
static inline void gen_op_fcmpeq(int fccno)
1558
{
1559
    tcg_gen_helper_0_0(gen_fcmpeq[fccno]);
1560
}
1561
#endif
1562

    
1563
#else
1564

    
1565
static inline void gen_op_fcmps(int fccno)
1566
{
1567
    tcg_gen_helper_0_0(helper_fcmps);
1568
}
1569

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

    
1575
#if defined(CONFIG_USER_ONLY)
1576
static inline void gen_op_fcmpq(int fccno)
1577
{
1578
    tcg_gen_helper_0_0(helper_fcmpq);
1579
}
1580
#endif
1581

    
1582
static inline void gen_op_fcmpes(int fccno)
1583
{
1584
    tcg_gen_helper_0_0(helper_fcmpes);
1585
}
1586

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

    
1592
#if defined(CONFIG_USER_ONLY)
1593
static inline void gen_op_fcmpeq(int fccno)
1594
{
1595
    tcg_gen_helper_0_0(helper_fcmpeq);
1596
}
1597
#endif
1598

    
1599
#endif
1600

    
1601
static inline void gen_op_fpexception_im(int fsr_flags)
1602
{
1603
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~FSR_FTT_MASK);
1604
    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
1605
    gen_op_exception(TT_FP_EXCP);
1606
}
1607

    
1608
static int gen_trap_ifnofpu(DisasContext * dc)
1609
{
1610
#if !defined(CONFIG_USER_ONLY)
1611
    if (!dc->fpu_enabled) {
1612
        save_state(dc);
1613
        gen_op_exception(TT_NFPU_INSN);
1614
        dc->is_br = 1;
1615
        return 1;
1616
    }
1617
#endif
1618
    return 0;
1619
}
1620

    
1621
static inline void gen_op_clear_ieee_excp_and_FTT(void)
1622
{
1623
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~(FSR_FTT_MASK | FSR_CEXC_MASK));
1624
}
1625

    
1626
static inline void gen_clear_float_exceptions(void)
1627
{
1628
    tcg_gen_helper_0_0(helper_clear_float_exceptions);
1629
}
1630

    
1631
/* asi moves */
1632
#ifdef TARGET_SPARC64
1633
static inline TCGv gen_get_asi(int insn, TCGv r_addr)
1634
{
1635
    int asi, offset;
1636
    TCGv r_asi;
1637

    
1638
    if (IS_IMM) {
1639
        r_asi = tcg_temp_new(TCG_TYPE_I32);
1640
        offset = GET_FIELD(insn, 25, 31);
1641
        tcg_gen_addi_tl(r_addr, r_addr, offset);
1642
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
1643
    } else {
1644
        asi = GET_FIELD(insn, 19, 26);
1645
        r_asi = tcg_const_i32(asi);
1646
    }
1647
    return r_asi;
1648
}
1649

    
1650
static inline void gen_ld_asi(int insn, int size, int sign)
1651
{
1652
    TCGv r_asi;
1653

    
1654
    r_asi = gen_get_asi(insn, cpu_T[0]);
1655
    tcg_gen_helper_1_4(helper_ld_asi, cpu_T[1], cpu_T[0], r_asi,
1656
                       tcg_const_i32(size), tcg_const_i32(sign));
1657
    tcg_gen_discard_i32(r_asi);
1658
}
1659

    
1660
static inline void gen_st_asi(int insn, int size)
1661
{
1662
    TCGv r_asi;
1663

    
1664
    r_asi = gen_get_asi(insn, cpu_T[0]);
1665
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], r_asi,
1666
                       tcg_const_i32(size));
1667
    tcg_gen_discard_i32(r_asi);
1668
}
1669

    
1670
static inline void gen_ldf_asi(int insn, int size, int rd)
1671
{
1672
    TCGv r_asi;
1673

    
1674
    r_asi = gen_get_asi(insn, cpu_T[0]);
1675
    tcg_gen_helper_0_4(helper_ldf_asi, cpu_T[0], r_asi, tcg_const_i32(size),
1676
                       tcg_const_i32(rd));
1677
    tcg_gen_discard_i32(r_asi);
1678
}
1679

    
1680
static inline void gen_stf_asi(int insn, int size, int rd)
1681
{
1682
    TCGv r_asi;
1683

    
1684
    r_asi = gen_get_asi(insn, cpu_T[0]);
1685
    tcg_gen_helper_0_4(helper_stf_asi, cpu_T[0], r_asi, tcg_const_i32(size),
1686
                       tcg_const_i32(rd));
1687
    tcg_gen_discard_i32(r_asi);
1688
}
1689

    
1690
static inline void gen_swap_asi(int insn)
1691
{
1692
    TCGv r_temp, r_asi;
1693

    
1694
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1695
    r_asi = gen_get_asi(insn, cpu_T[0]);
1696
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, cpu_T[0], r_asi,
1697
                       tcg_const_i32(4), tcg_const_i32(0));
1698
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_temp, r_asi,
1699
                       tcg_const_i32(4));
1700
    tcg_gen_mov_i32(cpu_T[1], r_temp);
1701
    tcg_gen_discard_i32(r_asi);
1702
    tcg_gen_discard_i32(r_temp);
1703
}
1704

    
1705
static inline void gen_ldda_asi(int insn)
1706
{
1707
    TCGv r_dword, r_asi;
1708

    
1709
    r_dword = tcg_temp_new(TCG_TYPE_I64);
1710
    r_asi = gen_get_asi(insn, cpu_T[0]);
1711
    tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], r_asi,
1712
                       tcg_const_i32(8), tcg_const_i32(0));
1713
    tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
1714
    tcg_gen_shri_i64(r_dword, r_dword, 32);
1715
    tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
1716
    tcg_gen_discard_i32(r_asi);
1717
    tcg_gen_discard_i64(r_dword);
1718
}
1719

    
1720
static inline void gen_stda_asi(int insn, int rd)
1721
{
1722
    TCGv r_dword, r_temp, r_asi;
1723

    
1724
    r_dword = tcg_temp_new(TCG_TYPE_I64);
1725
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1726
    gen_movl_reg_TN(rd + 1, r_temp);
1727
    tcg_gen_helper_1_2(helper_pack64, r_dword, cpu_T[1],
1728
                       r_temp);
1729
    r_asi = gen_get_asi(insn, cpu_T[0]);
1730
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, r_asi,
1731
                       tcg_const_i32(8));
1732
    tcg_gen_discard_i32(r_asi);
1733
    tcg_gen_discard_i32(r_temp);
1734
    tcg_gen_discard_i64(r_dword);
1735
}
1736

    
1737
static inline void gen_cas_asi(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, cpu_T[0]);
1744
    tcg_gen_helper_1_4(helper_cas_asi, cpu_T[1], cpu_T[0], r_val1, cpu_T[1],
1745
                       r_asi);
1746
    tcg_gen_discard_i32(r_asi);
1747
    tcg_gen_discard_i32(r_val1);
1748
}
1749

    
1750
static inline void gen_casx_asi(int insn, int rd)
1751
{
1752
    TCGv r_val1, r_asi;
1753

    
1754
    r_val1 = tcg_temp_new(TCG_TYPE_I64);
1755
    gen_movl_reg_TN(rd, r_val1);
1756
    r_asi = gen_get_asi(insn, cpu_T[0]);
1757
    tcg_gen_helper_1_4(helper_casx_asi, cpu_T[1], cpu_T[0], r_val1, cpu_T[1],
1758
                       r_asi);
1759
    tcg_gen_discard_i32(r_asi);
1760
    tcg_gen_discard_i32(r_val1);
1761
}
1762

    
1763
#elif !defined(CONFIG_USER_ONLY)
1764

    
1765
static inline void gen_ld_asi(int insn, int size, int sign)
1766
{
1767
    int asi;
1768
    TCGv r_dword;
1769

    
1770
    r_dword = tcg_temp_new(TCG_TYPE_I64);
1771
    asi = GET_FIELD(insn, 19, 26);
1772
    tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], tcg_const_i32(asi),
1773
                       tcg_const_i32(size), tcg_const_i32(sign));
1774
    tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
1775
    tcg_gen_discard_i64(r_dword);
1776
}
1777

    
1778
static inline void gen_st_asi(int insn, int size)
1779
{
1780
    int asi;
1781
    TCGv r_dword;
1782

    
1783
    r_dword = tcg_temp_new(TCG_TYPE_I64);
1784
    tcg_gen_extu_i32_i64(r_dword, cpu_T[1]);
1785
    asi = GET_FIELD(insn, 19, 26);
1786
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, tcg_const_i32(asi),
1787
                       tcg_const_i32(size));
1788
    tcg_gen_discard_i64(r_dword);
1789
}
1790

    
1791
static inline void gen_swap_asi(int insn)
1792
{
1793
    int asi;
1794
    TCGv r_temp;
1795

    
1796
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1797
    asi = GET_FIELD(insn, 19, 26);
1798
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, cpu_T[0], tcg_const_i32(asi),
1799
                       tcg_const_i32(4), tcg_const_i32(0));
1800
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], tcg_const_i32(asi),
1801
                       tcg_const_i32(4));
1802
    tcg_gen_mov_i32(cpu_T[1], r_temp);
1803
    tcg_gen_discard_i32(r_temp);
1804
}
1805

    
1806
static inline void gen_ldda_asi(int insn)
1807
{
1808
    int asi;
1809
    TCGv r_dword;
1810

    
1811
    r_dword = tcg_temp_new(TCG_TYPE_I64);
1812
    asi = GET_FIELD(insn, 19, 26);
1813
    tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], tcg_const_i32(asi),
1814
                       tcg_const_i32(8), tcg_const_i32(0));
1815
    tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
1816
    tcg_gen_shri_i64(r_dword, r_dword, 32);
1817
    tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
1818
    tcg_gen_discard_i64(r_dword);
1819
}
1820

    
1821
static inline void gen_stda_asi(int insn, int rd)
1822
{
1823
    int asi;
1824
    TCGv r_dword, r_temp;
1825

    
1826
    r_dword = tcg_temp_new(TCG_TYPE_I64);
1827
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1828
    gen_movl_reg_TN(rd + 1, r_temp);
1829
    tcg_gen_helper_1_2(helper_pack64, r_dword, cpu_T[1], r_temp);
1830
    asi = GET_FIELD(insn, 19, 26);
1831
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, tcg_const_i32(asi),
1832
                       tcg_const_i32(8));
1833
    tcg_gen_discard_i64(r_dword);
1834
}
1835
#endif
1836

    
1837
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1838
static inline void gen_ldstub_asi(int insn)
1839
{
1840
    int asi;
1841

    
1842
    gen_ld_asi(insn, 1, 0);
1843

    
1844
    asi = GET_FIELD(insn, 19, 26);
1845
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], tcg_const_i64(0xff),
1846
                       tcg_const_i32(asi), tcg_const_i32(1));
1847
}
1848
#endif
1849

    
1850
/* before an instruction, dc->pc must be static */
1851
static void disas_sparc_insn(DisasContext * dc)
1852
{
1853
    unsigned int insn, opc, rs1, rs2, rd;
1854

    
1855
    insn = ldl_code(dc->pc);
1856
    opc = GET_FIELD(insn, 0, 1);
1857

    
1858
    rd = GET_FIELD(insn, 2, 6);
1859
    switch (opc) {
1860
    case 0:                     /* branches/sethi */
1861
        {
1862
            unsigned int xop = GET_FIELD(insn, 7, 9);
1863
            int32_t target;
1864
            switch (xop) {
1865
#ifdef TARGET_SPARC64
1866
            case 0x1:           /* V9 BPcc */
1867
                {
1868
                    int cc;
1869

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

    
1951
            gen_movl_TN_reg(15, tcg_const_tl(dc->pc));
1952
            target += dc->pc;
1953
            gen_mov_pc_npc(dc);
1954
            dc->npc = target;
1955
        }
1956
        goto jmp_insn;
1957
    case 2:                     /* FPU & Logical Operations */
1958
        {
1959
            unsigned int xop = GET_FIELD(insn, 7, 12);
1960
            if (xop == 0x3a) {  /* generate trap */
1961
                int cond;
1962

    
1963
                rs1 = GET_FIELD(insn, 13, 17);
1964
                gen_movl_reg_T0(rs1);
1965
                if (IS_IMM) {
1966
                    rs2 = GET_FIELD(insn, 25, 31);
1967
                    tcg_gen_addi_tl(cpu_T[0], cpu_T[0], rs2);
1968
                } else {
1969
                    rs2 = GET_FIELD(insn, 27, 31);
1970
#if defined(OPTIM)
1971
                    if (rs2 != 0) {
1972
#endif
1973
                        gen_movl_reg_T1(rs2);
1974
                        gen_op_add_T1_T0();
1975
#if defined(OPTIM)
1976
                    }
1977
#endif
1978
                }
1979
                cond = GET_FIELD(insn, 3, 6);
1980
                if (cond == 0x8) {
1981
                    save_state(dc);
1982
                    tcg_gen_helper_0_1(helper_trap, cpu_T[0]);
1983
                } else if (cond != 0) {
1984
                    TCGv r_cond = tcg_temp_new(TCG_TYPE_TL);
1985
#ifdef TARGET_SPARC64
1986
                    /* V9 icc/xcc */
1987
                    int cc = GET_FIELD_SP(insn, 11, 12);
1988

    
1989
                    save_state(dc);
1990
                    if (cc == 0)
1991
                        gen_cond(r_cond, 0, cond);
1992
                    else if (cc == 2)
1993
                        gen_cond(r_cond, 1, cond);
1994
                    else
1995
                        goto illegal_insn;
1996
#else
1997
                    save_state(dc);
1998
                    gen_cond(r_cond, 0, cond);
1999
#endif
2000
                    tcg_gen_helper_0_2(helper_trapcc, cpu_T[0], r_cond);
2001
                    tcg_gen_discard_tl(r_cond);
2002
                }
2003
                gen_op_next_insn();
2004
                tcg_gen_exit_tb(0);
2005
                dc->is_br = 1;
2006
                goto jmp_insn;
2007
            } else if (xop == 0x28) {
2008
                rs1 = GET_FIELD(insn, 13, 17);
2009
                switch(rs1) {
2010
                case 0: /* rdy */
2011
#ifndef TARGET_SPARC64
2012
                case 0x01 ... 0x0e: /* undefined in the SPARCv8
2013
                                       manual, rdy on the microSPARC
2014
                                       II */
2015
                case 0x0f:          /* stbar in the SPARCv8 manual,
2016
                                       rdy on the microSPARC II */
2017
                case 0x10 ... 0x1f: /* implementation-dependent in the
2018
                                       SPARCv8 manual, rdy on the
2019
                                       microSPARC II */
2020
#endif
2021
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, y));
2022
                    gen_movl_T0_reg(rd);
2023
                    break;
2024
#ifdef TARGET_SPARC64
2025
                case 0x2: /* V9 rdccr */
2026
                    gen_op_rdccr();
2027
                    gen_movl_T0_reg(rd);
2028
                    break;
2029
                case 0x3: /* V9 rdasi */
2030
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, asi));
2031
                    gen_movl_T0_reg(rd);
2032
                    break;
2033
                case 0x4: /* V9 rdtick */
2034
                    {
2035
                        TCGv r_tickptr;
2036

    
2037
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2038
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2039
                                       offsetof(CPUState, tick));
2040
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_T[0],
2041
                                           r_tickptr);
2042
                        gen_movl_T0_reg(rd);
2043
                        tcg_gen_discard_ptr(r_tickptr);
2044
                    }
2045
                    break;
2046
                case 0x5: /* V9 rdpc */
2047
                    tcg_gen_movi_tl(cpu_T[0], dc->pc);
2048
                    gen_movl_T0_reg(rd);
2049
                    break;
2050
                case 0x6: /* V9 rdfprs */
2051
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, fprs));
2052
                    gen_movl_T0_reg(rd);
2053
                    break;
2054
                case 0xf: /* V9 membar */
2055
                    break; /* no effect */
2056
                case 0x13: /* Graphics Status */
2057
                    if (gen_trap_ifnofpu(dc))
2058
                        goto jmp_insn;
2059
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, gsr));
2060
                    gen_movl_T0_reg(rd);
2061
                    break;
2062
                case 0x17: /* Tick compare */
2063
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, tick_cmpr));
2064
                    gen_movl_T0_reg(rd);
2065
                    break;
2066
                case 0x18: /* System tick */
2067
                    {
2068
                        TCGv r_tickptr;
2069

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

    
2138
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2139
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2140
                                       offsetof(CPUState, tsptr));
2141
                        tcg_gen_ld_tl(cpu_T[0], r_tsptr,
2142
                                      offsetof(trap_state, tpc));
2143
                        tcg_gen_discard_ptr(r_tsptr);
2144
                    }
2145
                    break;
2146
                case 1: // tnpc
2147
                    {
2148
                        TCGv r_tsptr;
2149

    
2150
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2151
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2152
                                       offsetof(CPUState, tsptr));
2153
                        tcg_gen_ld_tl(cpu_T[0], r_tsptr,
2154
                                      offsetof(trap_state, tnpc));
2155
                        tcg_gen_discard_ptr(r_tsptr);
2156
                    }
2157
                    break;
2158
                case 2: // tstate
2159
                    {
2160
                        TCGv r_tsptr;
2161

    
2162
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2163
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2164
                                       offsetof(CPUState, tsptr));
2165
                        tcg_gen_ld_tl(cpu_T[0], r_tsptr,
2166
                                      offsetof(trap_state, tstate));
2167
                        tcg_gen_discard_ptr(r_tsptr);
2168
                    }
2169
                    break;
2170
                case 3: // tt
2171
                    {
2172
                        TCGv r_tsptr;
2173

    
2174
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2175
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2176
                                       offsetof(CPUState, tsptr));
2177
                        tcg_gen_ld_i32(cpu_T[0], r_tsptr,
2178
                                       offsetof(trap_state, tt));
2179
                        tcg_gen_discard_ptr(r_tsptr);
2180
                    }
2181
                    break;
2182
                case 4: // tick
2183
                    {
2184
                        TCGv r_tickptr;
2185

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

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

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

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

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

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

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

    
3169
                                    gen_op_xor_T1_T0();
3170
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3171
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3172
                                                   offsetof(CPUState, stick));
3173
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3174
                                                       r_tickptr, cpu_T[0]);
3175
                                    tcg_gen_discard_ptr(r_tickptr);
3176
                                }
3177
                                break;
3178
                            case 0x19: /* System tick compare */
3179
#if !defined(CONFIG_USER_ONLY)
3180
                                if (!supervisor(dc))
3181
                                    goto illegal_insn;
3182
#endif
3183
                                {
3184
                                    TCGv r_tickptr;
3185

    
3186
                                    gen_op_xor_T1_T0();
3187
                                    gen_op_movtl_env_T0(offsetof(CPUSPARCState,
3188
                                                                 stick_cmpr));
3189
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3190
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3191
                                                   offsetof(CPUState, stick));
3192
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3193
                                                       r_tickptr, cpu_T[0]);
3194
                                    tcg_gen_discard_ptr(r_tickptr);
3195
                                }
3196
                                break;
3197

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

    
3252
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3253
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3254
                                                   offsetof(CPUState, tsptr));
3255
                                    tcg_gen_st_tl(cpu_T[0], r_tsptr,
3256
                                                  offsetof(trap_state, tpc));
3257
                                    tcg_gen_discard_ptr(r_tsptr);
3258
                                }
3259
                                break;
3260
                            case 1: // tnpc
3261
                                {
3262
                                    TCGv r_tsptr;
3263

    
3264
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3265
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3266
                                                   offsetof(CPUState, tsptr));
3267
                                    tcg_gen_st_tl(cpu_T[0], r_tsptr,
3268
                                                  offsetof(trap_state, tnpc));
3269
                                    tcg_gen_discard_ptr(r_tsptr);
3270
                                }
3271
                                break;
3272
                            case 2: // tstate
3273
                                {
3274
                                    TCGv r_tsptr;
3275

    
3276
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3277
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3278
                                                   offsetof(CPUState, tsptr));
3279
                                    tcg_gen_st_tl(cpu_T[0], r_tsptr,
3280
                                                  offsetof(trap_state, tstate));
3281
                                    tcg_gen_discard_ptr(r_tsptr);
3282
                                }
3283
                                break;
3284
                            case 3: // tt
3285
                                {
3286
                                    TCGv r_tsptr;
3287

    
3288
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3289
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3290
                                                   offsetof(CPUState, tsptr));
3291
                                    tcg_gen_st_i32(cpu_T[0], r_tsptr,
3292
                                                   offsetof(trap_state, tt));
3293
                                    tcg_gen_discard_ptr(r_tsptr);
3294
                                }
3295
                                break;
3296
                            case 4: // tick
3297
                                {
3298
                                    TCGv r_tickptr;
3299

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

    
3391
                                    gen_op_movtl_env_T0(offsetof(CPUSPARCState,
3392
                                                                 hstick_cmpr));
3393
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3394
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3395
                                                   offsetof(CPUState, hstick));
3396
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3397
                                                       r_tickptr, cpu_T[0]);
3398
                                    tcg_gen_discard_ptr(r_tickptr);
3399
                                }
3400
                                break;
3401
                            case 6: // hver readonly
3402
                            default:
3403
                                goto illegal_insn;
3404
                            }
3405
#endif
3406
                        }
3407
                        break;
3408
#endif
3409
#ifdef TARGET_SPARC64
3410
                    case 0x2c: /* V9 movcc */
3411
                        {
3412
                            int cc = GET_FIELD_SP(insn, 11, 12);
3413
                            int cond = GET_FIELD_SP(insn, 14, 17);
3414
                            TCGv r_cond;
3415
                            int l1;
3416

    
3417
                            r_cond = tcg_temp_new(TCG_TYPE_TL);
3418
                            if (insn & (1 << 18)) {
3419
                                if (cc == 0)
3420
                                    gen_cond(r_cond, 0, cond);
3421
                                else if (cc == 2)
3422
                                    gen_cond(r_cond, 1, cond);
3423
                                else
3424
                                    goto illegal_insn;
3425
                            } else {
3426
                                gen_fcond(r_cond, cc, cond);
3427
                            }
3428

    
3429
                            l1 = gen_new_label();
3430

    
3431
                            tcg_gen_brcond_tl(TCG_COND_EQ, r_cond,
3432
                                              tcg_const_tl(0), l1);
3433
                            if (IS_IMM) {       /* immediate */
3434
                                rs2 = GET_FIELD_SPs(insn, 0, 10);
3435
                                gen_movl_simm_T1(rs2);
3436
                            } else {
3437
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3438
                                gen_movl_reg_T1(rs2);
3439
                            }
3440
                            gen_movl_T1_reg(rd);
3441
                            gen_set_label(l1);
3442
                            tcg_gen_discard_tl(r_cond);
3443
                            break;
3444
                        }
3445
                    case 0x2d: /* V9 sdivx */
3446
                        gen_op_sdivx_T1_T0();
3447
                        gen_movl_T0_reg(rd);
3448
                        break;
3449
                    case 0x2e: /* V9 popc */
3450
                        {
3451
                            if (IS_IMM) {       /* immediate */
3452
                                rs2 = GET_FIELD_SPs(insn, 0, 12);
3453
                                gen_movl_simm_T1(rs2);
3454
                                // XXX optimize: popc(constant)
3455
                            }
3456
                            else {
3457
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3458
                                gen_movl_reg_T1(rs2);
3459
                            }
3460
                            tcg_gen_helper_1_1(helper_popc, cpu_T[0],
3461
                                               cpu_T[1]);
3462
                            gen_movl_T0_reg(rd);
3463
                        }
3464
                    case 0x2f: /* V9 movr */
3465
                        {
3466
                            int cond = GET_FIELD_SP(insn, 10, 12);
3467
                            int l1;
3468

    
3469
                            rs1 = GET_FIELD(insn, 13, 17);
3470
                            gen_movl_reg_T0(rs1);
3471

    
3472
                            l1 = gen_new_label();
3473

    
3474
                            tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0],
3475
                                              tcg_const_tl(0), l1);
3476
                            if (IS_IMM) {       /* immediate */
3477
                                rs2 = GET_FIELD_SPs(insn, 0, 9);
3478
                                gen_movl_simm_T1(rs2);
3479
                            } else {
3480
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3481
                                gen_movl_reg_T1(rs2);
3482
                            }
3483
                            gen_movl_T1_reg(rd);
3484
                            gen_set_label(l1);
3485
                            break;
3486
                        }
3487
#endif
3488
                    default:
3489
                        goto illegal_insn;
3490
                    }
3491
                }
3492
            } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
3493
#ifdef TARGET_SPARC64
3494
                int opf = GET_FIELD_SP(insn, 5, 13);
3495
                rs1 = GET_FIELD(insn, 13, 17);
3496
                rs2 = GET_FIELD(insn, 27, 31);
3497
                if (gen_trap_ifnofpu(dc))
3498
                    goto jmp_insn;
3499

    
3500
                switch (opf) {
3501
                case 0x000: /* VIS I edge8cc */
3502
                case 0x001: /* VIS II edge8n */
3503
                case 0x002: /* VIS I edge8lcc */
3504
                case 0x003: /* VIS II edge8ln */
3505
                case 0x004: /* VIS I edge16cc */
3506
                case 0x005: /* VIS II edge16n */
3507
                case 0x006: /* VIS I edge16lcc */
3508
                case 0x007: /* VIS II edge16ln */
3509
                case 0x008: /* VIS I edge32cc */
3510
                case 0x009: /* VIS II edge32n */
3511
                case 0x00a: /* VIS I edge32lcc */
3512
                case 0x00b: /* VIS II edge32ln */
3513
                    // XXX
3514
                    goto illegal_insn;
3515
                case 0x010: /* VIS I array8 */
3516
                    gen_movl_reg_T0(rs1);
3517
                    gen_movl_reg_T1(rs2);
3518
                    tcg_gen_helper_1_2(helper_array8, cpu_T[0], cpu_T[0],
3519
                                       cpu_T[1]);
3520
                    gen_movl_T0_reg(rd);
3521
                    break;
3522
                case 0x012: /* VIS I array16 */
3523
                    gen_movl_reg_T0(rs1);
3524
                    gen_movl_reg_T1(rs2);
3525
                    tcg_gen_helper_1_2(helper_array8, cpu_T[0], cpu_T[0],
3526
                                       cpu_T[1]);
3527
                    tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 1);
3528
                    gen_movl_T0_reg(rd);
3529
                    break;
3530
                case 0x014: /* VIS I array32 */
3531
                    gen_movl_reg_T0(rs1);
3532
                    gen_movl_reg_T1(rs2);
3533
                    tcg_gen_helper_1_2(helper_array8, cpu_T[0], cpu_T[0],
3534
                                       cpu_T[1]);
3535
                    tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 2);
3536
                    gen_movl_T0_reg(rd);
3537
                    break;
3538
                case 0x018: /* VIS I alignaddr */
3539
                    gen_movl_reg_T0(rs1);
3540
                    gen_movl_reg_T1(rs2);
3541
                    tcg_gen_helper_1_2(helper_alignaddr, cpu_T[0], cpu_T[0],
3542
                                       cpu_T[1]);
3543
                    gen_movl_T0_reg(rd);
3544
                    break;
3545
                case 0x019: /* VIS II bmask */
3546
                case 0x01a: /* VIS I alignaddrl */
3547
                    // XXX
3548
                    goto illegal_insn;
3549
                case 0x020: /* VIS I fcmple16 */
3550
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3551
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3552
                    gen_op_fcmple16();
3553
                    gen_op_store_DT0_fpr(DFPREG(rd));
3554
                    break;
3555
                case 0x022: /* VIS I fcmpne16 */
3556
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3557
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3558
                    gen_op_fcmpne16();
3559
                    gen_op_store_DT0_fpr(DFPREG(rd));
3560
                    break;
3561
                case 0x024: /* VIS I fcmple32 */
3562
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3563
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3564
                    gen_op_fcmple32();
3565
                    gen_op_store_DT0_fpr(DFPREG(rd));
3566
                    break;
3567
                case 0x026: /* VIS I fcmpne32 */
3568
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3569
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3570
                    gen_op_fcmpne32();
3571
                    gen_op_store_DT0_fpr(DFPREG(rd));
3572
                    break;
3573
                case 0x028: /* VIS I fcmpgt16 */
3574
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3575
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3576
                    gen_op_fcmpgt16();
3577
                    gen_op_store_DT0_fpr(DFPREG(rd));
3578
                    break;
3579
                case 0x02a: /* VIS I fcmpeq16 */
3580
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3581
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3582
                    gen_op_fcmpeq16();
3583
                    gen_op_store_DT0_fpr(DFPREG(rd));
3584
                    break;
3585
                case 0x02c: /* VIS I fcmpgt32 */
3586
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3587
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3588
                    gen_op_fcmpgt32();
3589
                    gen_op_store_DT0_fpr(DFPREG(rd));
3590
                    break;
3591
                case 0x02e: /* VIS I fcmpeq32 */
3592
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3593
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3594
                    gen_op_fcmpeq32();
3595
                    gen_op_store_DT0_fpr(DFPREG(rd));
3596
                    break;
3597
                case 0x031: /* VIS I fmul8x16 */
3598
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3599
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3600
                    gen_op_fmul8x16();
3601
                    gen_op_store_DT0_fpr(DFPREG(rd));
3602
                    break;
3603
                case 0x033: /* VIS I fmul8x16au */
3604
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3605
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3606
                    gen_op_fmul8x16au();
3607
                    gen_op_store_DT0_fpr(DFPREG(rd));
3608
                    break;
3609
                case 0x035: /* VIS I fmul8x16al */
3610
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3611
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3612
                    gen_op_fmul8x16al();
3613
                    gen_op_store_DT0_fpr(DFPREG(rd));
3614
                    break;
3615
                case 0x036: /* VIS I fmul8sux16 */
3616
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3617
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3618
                    gen_op_fmul8sux16();
3619
                    gen_op_store_DT0_fpr(DFPREG(rd));
3620
                    break;
3621
                case 0x037: /* VIS I fmul8ulx16 */
3622
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3623
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3624
                    gen_op_fmul8ulx16();
3625
                    gen_op_store_DT0_fpr(DFPREG(rd));
3626
                    break;
3627
                case 0x038: /* VIS I fmuld8sux16 */
3628
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3629
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3630
                    gen_op_fmuld8sux16();
3631
                    gen_op_store_DT0_fpr(DFPREG(rd));
3632
                    break;
3633
                case 0x039: /* VIS I fmuld8ulx16 */
3634
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3635
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3636
                    gen_op_fmuld8ulx16();
3637
                    gen_op_store_DT0_fpr(DFPREG(rd));
3638
                    break;
3639
                case 0x03a: /* VIS I fpack32 */
3640
                case 0x03b: /* VIS I fpack16 */
3641
                case 0x03d: /* VIS I fpackfix */
3642
                case 0x03e: /* VIS I pdist */
3643
                    // XXX
3644
                    goto illegal_insn;
3645
                case 0x048: /* VIS I faligndata */
3646
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3647
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3648
                    gen_op_faligndata();
3649
                    gen_op_store_DT0_fpr(DFPREG(rd));
3650
                    break;
3651
                case 0x04b: /* VIS I fpmerge */
3652
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3653
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3654
                    gen_op_fpmerge();
3655
                    gen_op_store_DT0_fpr(DFPREG(rd));
3656
                    break;
3657
                case 0x04c: /* VIS II bshuffle */
3658
                    // XXX
3659
                    goto illegal_insn;
3660
                case 0x04d: /* VIS I fexpand */
3661
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3662
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3663
                    gen_op_fexpand();
3664
                    gen_op_store_DT0_fpr(DFPREG(rd));
3665
                    break;
3666
                case 0x050: /* VIS I fpadd16 */
3667
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3668
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3669
                    gen_op_fpadd16();
3670
                    gen_op_store_DT0_fpr(DFPREG(rd));
3671
                    break;
3672
                case 0x051: /* VIS I fpadd16s */
3673
                    gen_op_load_fpr_FT0(rs1);
3674
                    gen_op_load_fpr_FT1(rs2);
3675
                    gen_op_fpadd16s();
3676
                    gen_op_store_FT0_fpr(rd);
3677
                    break;
3678
                case 0x052: /* VIS I fpadd32 */
3679
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3680
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3681
                    gen_op_fpadd32();
3682
                    gen_op_store_DT0_fpr(DFPREG(rd));
3683
                    break;
3684
                case 0x053: /* VIS I fpadd32s */
3685
                    gen_op_load_fpr_FT0(rs1);
3686
                    gen_op_load_fpr_FT1(rs2);
3687
                    gen_op_fpadd32s();
3688
                    gen_op_store_FT0_fpr(rd);
3689
                    break;
3690
                case 0x054: /* VIS I fpsub16 */
3691
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3692
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3693
                    gen_op_fpsub16();
3694
                    gen_op_store_DT0_fpr(DFPREG(rd));
3695
                    break;
3696
                case 0x055: /* VIS I fpsub16s */
3697
                    gen_op_load_fpr_FT0(rs1);
3698
                    gen_op_load_fpr_FT1(rs2);
3699
                    gen_op_fpsub16s();
3700
                    gen_op_store_FT0_fpr(rd);
3701
                    break;
3702
                case 0x056: /* VIS I fpsub32 */
3703
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3704
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3705
                    gen_op_fpadd32();
3706
                    gen_op_store_DT0_fpr(DFPREG(rd));
3707
                    break;
3708
                case 0x057: /* VIS I fpsub32s */
3709
                    gen_op_load_fpr_FT0(rs1);
3710
                    gen_op_load_fpr_FT1(rs2);
3711
                    gen_op_fpsub32s();
3712
                    gen_op_store_FT0_fpr(rd);
3713
                    break;
3714
                case 0x060: /* VIS I fzero */
3715
                    gen_op_movl_DT0_0();
3716
                    gen_op_store_DT0_fpr(DFPREG(rd));
3717
                    break;
3718
                case 0x061: /* VIS I fzeros */
3719
                    gen_op_movl_FT0_0();
3720
                    gen_op_store_FT0_fpr(rd);
3721
                    break;
3722
                case 0x062: /* VIS I fnor */
3723
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3724
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3725
                    gen_op_fnor();
3726
                    gen_op_store_DT0_fpr(DFPREG(rd));
3727
                    break;
3728
                case 0x063: /* VIS I fnors */
3729
                    gen_op_load_fpr_FT0(rs1);
3730
                    gen_op_load_fpr_FT1(rs2);
3731
                    gen_op_fnors();
3732
                    gen_op_store_FT0_fpr(rd);
3733
                    break;
3734
                case 0x064: /* VIS I fandnot2 */
3735
                    gen_op_load_fpr_DT1(DFPREG(rs1));
3736
                    gen_op_load_fpr_DT0(DFPREG(rs2));
3737
                    gen_op_fandnot();
3738
                    gen_op_store_DT0_fpr(DFPREG(rd));
3739
                    break;
3740
                case 0x065: /* VIS I fandnot2s */
3741
                    gen_op_load_fpr_FT1(rs1);
3742
                    gen_op_load_fpr_FT0(rs2);
3743
                    gen_op_fandnots();
3744
                    gen_op_store_FT0_fpr(rd);
3745
                    break;
3746
                case 0x066: /* VIS I fnot2 */
3747
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3748
                    gen_op_fnot();
3749
                    gen_op_store_DT0_fpr(DFPREG(rd));
3750
                    break;
3751
                case 0x067: /* VIS I fnot2s */
3752
                    gen_op_load_fpr_FT1(rs2);
3753
                    gen_op_fnot();
3754
                    gen_op_store_FT0_fpr(rd);
3755
                    break;
3756
                case 0x068: /* VIS I fandnot1 */
3757
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3758
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3759
                    gen_op_fandnot();
3760
                    gen_op_store_DT0_fpr(DFPREG(rd));
3761
                    break;
3762
                case 0x069: /* VIS I fandnot1s */
3763
                    gen_op_load_fpr_FT0(rs1);
3764
                    gen_op_load_fpr_FT1(rs2);
3765
                    gen_op_fandnots();
3766
                    gen_op_store_FT0_fpr(rd);
3767
                    break;
3768
                case 0x06a: /* VIS I fnot1 */
3769
                    gen_op_load_fpr_DT1(DFPREG(rs1));
3770
                    gen_op_fnot();
3771
                    gen_op_store_DT0_fpr(DFPREG(rd));
3772
                    break;
3773
                case 0x06b: /* VIS I fnot1s */
3774
                    gen_op_load_fpr_FT1(rs1);
3775
                    gen_op_fnot();
3776
                    gen_op_store_FT0_fpr(rd);
3777
                    break;
3778
                case 0x06c: /* VIS I fxor */
3779
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3780
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3781
                    gen_op_fxor();
3782
                    gen_op_store_DT0_fpr(DFPREG(rd));
3783
                    break;
3784
                case 0x06d: /* VIS I fxors */
3785
                    gen_op_load_fpr_FT0(rs1);
3786
                    gen_op_load_fpr_FT1(rs2);
3787
                    gen_op_fxors();
3788
                    gen_op_store_FT0_fpr(rd);
3789
                    break;
3790
                case 0x06e: /* VIS I fnand */
3791
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3792
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3793
                    gen_op_fnand();
3794
                    gen_op_store_DT0_fpr(DFPREG(rd));
3795
                    break;
3796
                case 0x06f: /* VIS I fnands */
3797
                    gen_op_load_fpr_FT0(rs1);
3798
                    gen_op_load_fpr_FT1(rs2);
3799
                    gen_op_fnands();
3800
                    gen_op_store_FT0_fpr(rd);
3801
                    break;
3802
                case 0x070: /* VIS I fand */
3803
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3804
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3805
                    gen_op_fand();
3806
                    gen_op_store_DT0_fpr(DFPREG(rd));
3807
                    break;
3808
                case 0x071: /* VIS I fands */
3809
                    gen_op_load_fpr_FT0(rs1);
3810
                    gen_op_load_fpr_FT1(rs2);
3811
                    gen_op_fands();
3812
                    gen_op_store_FT0_fpr(rd);
3813
                    break;
3814
                case 0x072: /* VIS I fxnor */
3815
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3816
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3817
                    gen_op_fxnor();
3818
                    gen_op_store_DT0_fpr(DFPREG(rd));
3819
                    break;
3820
                case 0x073: /* VIS I fxnors */
3821
                    gen_op_load_fpr_FT0(rs1);
3822
                    gen_op_load_fpr_FT1(rs2);
3823
                    gen_op_fxnors();
3824
                    gen_op_store_FT0_fpr(rd);
3825
                    break;
3826
                case 0x074: /* VIS I fsrc1 */
3827
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3828
                    gen_op_store_DT0_fpr(DFPREG(rd));
3829
                    break;
3830
                case 0x075: /* VIS I fsrc1s */
3831
                    gen_op_load_fpr_FT0(rs1);
3832
                    gen_op_store_FT0_fpr(rd);
3833
                    break;
3834
                case 0x076: /* VIS I fornot2 */
3835
                    gen_op_load_fpr_DT1(DFPREG(rs1));
3836
                    gen_op_load_fpr_DT0(DFPREG(rs2));
3837
                    gen_op_fornot();
3838
                    gen_op_store_DT0_fpr(DFPREG(rd));
3839
                    break;
3840
                case 0x077: /* VIS I fornot2s */
3841
                    gen_op_load_fpr_FT1(rs1);
3842
                    gen_op_load_fpr_FT0(rs2);
3843
                    gen_op_fornots();
3844
                    gen_op_store_FT0_fpr(rd);
3845
                    break;
3846
                case 0x078: /* VIS I fsrc2 */
3847
                    gen_op_load_fpr_DT0(DFPREG(rs2));
3848
                    gen_op_store_DT0_fpr(DFPREG(rd));
3849
                    break;
3850
                case 0x079: /* VIS I fsrc2s */
3851
                    gen_op_load_fpr_FT0(rs2);
3852
                    gen_op_store_FT0_fpr(rd);
3853
                    break;
3854
                case 0x07a: /* VIS I fornot1 */
3855
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3856
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3857
                    gen_op_fornot();
3858
                    gen_op_store_DT0_fpr(DFPREG(rd));
3859
                    break;
3860
                case 0x07b: /* VIS I fornot1s */
3861
                    gen_op_load_fpr_FT0(rs1);
3862
                    gen_op_load_fpr_FT1(rs2);
3863
                    gen_op_fornots();
3864
                    gen_op_store_FT0_fpr(rd);
3865
                    break;
3866
                case 0x07c: /* VIS I for */
3867
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3868
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3869
                    gen_op_for();
3870
                    gen_op_store_DT0_fpr(DFPREG(rd));
3871
                    break;
3872
                case 0x07d: /* VIS I fors */
3873
                    gen_op_load_fpr_FT0(rs1);
3874
                    gen_op_load_fpr_FT1(rs2);
3875
                    gen_op_fors();
3876
                    gen_op_store_FT0_fpr(rd);
3877
                    break;
3878
                case 0x07e: /* VIS I fone */
3879
                    gen_op_movl_DT0_1();
3880
                    gen_op_store_DT0_fpr(DFPREG(rd));
3881
                    break;
3882
                case 0x07f: /* VIS I fones */
3883
                    gen_op_movl_FT0_1();
3884
                    gen_op_store_FT0_fpr(rd);
3885
                    break;
3886
                case 0x080: /* VIS I shutdown */
3887
                case 0x081: /* VIS II siam */
3888
                    // XXX
3889
                    goto illegal_insn;
3890
                default:
3891
                    goto illegal_insn;
3892
                }
3893
#else
3894
                goto ncp_insn;
3895
#endif
3896
            } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
3897
#ifdef TARGET_SPARC64
3898
                goto illegal_insn;
3899
#else
3900
                goto ncp_insn;
3901
#endif
3902
#ifdef TARGET_SPARC64
3903
            } else if (xop == 0x39) { /* V9 return */
3904
                rs1 = GET_FIELD(insn, 13, 17);
3905
                save_state(dc);
3906
                gen_movl_reg_T0(rs1);
3907
                if (IS_IMM) {   /* immediate */
3908
                    rs2 = GET_FIELDs(insn, 19, 31);
3909
                    tcg_gen_addi_tl(cpu_T[0], cpu_T[0], (int)rs2);
3910
                } else {                /* register */
3911
                    rs2 = GET_FIELD(insn, 27, 31);
3912
#if defined(OPTIM)
3913
                    if (rs2) {
3914
#endif
3915
                        gen_movl_reg_T1(rs2);
3916
                        gen_op_add_T1_T0();
3917
#if defined(OPTIM)
3918
                    }
3919
#endif
3920
                }
3921
                gen_op_restore();
3922
                gen_mov_pc_npc(dc);
3923
                gen_op_check_align_T0_3();
3924
                tcg_gen_mov_tl(cpu_npc, cpu_T[0]);
3925
                dc->npc = DYNAMIC_PC;
3926
                goto jmp_insn;
3927
#endif
3928
            } else {
3929
                rs1 = GET_FIELD(insn, 13, 17);
3930
                gen_movl_reg_T0(rs1);
3931
                if (IS_IMM) {   /* immediate */
3932
                    rs2 = GET_FIELDs(insn, 19, 31);
3933
                    tcg_gen_addi_tl(cpu_T[0], cpu_T[0], (int)rs2);
3934
                } else {                /* register */
3935
                    rs2 = GET_FIELD(insn, 27, 31);
3936
#if defined(OPTIM)
3937
                    if (rs2) {
3938
#endif
3939
                        gen_movl_reg_T1(rs2);
3940
                        gen_op_add_T1_T0();
3941
#if defined(OPTIM)
3942
                    }
3943
#endif
3944
                }
3945
                switch (xop) {
3946
                case 0x38:      /* jmpl */
3947
                    {
3948
                        if (rd != 0) {
3949
                            tcg_gen_movi_tl(cpu_T[1], dc->pc);
3950
                            gen_movl_T1_reg(rd);
3951
                        }
3952
                        gen_mov_pc_npc(dc);
3953
                        gen_op_check_align_T0_3();
3954
                        tcg_gen_mov_tl(cpu_npc, cpu_T[0]);
3955
                        dc->npc = DYNAMIC_PC;
3956
                    }
3957
                    goto jmp_insn;
3958
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
3959
                case 0x39:      /* rett, V9 return */
3960
                    {
3961
                        if (!supervisor(dc))
3962
                            goto priv_insn;
3963
                        gen_mov_pc_npc(dc);
3964
                        gen_op_check_align_T0_3();
3965
                        tcg_gen_mov_tl(cpu_npc, cpu_T[0]);
3966
                        dc->npc = DYNAMIC_PC;
3967
                        tcg_gen_helper_0_0(helper_rett);
3968
                    }
3969
                    goto jmp_insn;
3970
#endif
3971
                case 0x3b: /* flush */
3972
                    tcg_gen_helper_0_1(helper_flush, cpu_T[0]);
3973
                    break;
3974
                case 0x3c:      /* save */
3975
                    save_state(dc);
3976
                    gen_op_save();
3977
                    gen_movl_T0_reg(rd);
3978
                    break;
3979
                case 0x3d:      /* restore */
3980
                    save_state(dc);
3981
                    gen_op_restore();
3982
                    gen_movl_T0_reg(rd);
3983
                    break;
3984
#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
3985
                case 0x3e:      /* V9 done/retry */
3986
                    {
3987
                        switch (rd) {
3988
                        case 0:
3989
                            if (!supervisor(dc))
3990
                                goto priv_insn;
3991
                            dc->npc = DYNAMIC_PC;
3992
                            dc->pc = DYNAMIC_PC;
3993
                            tcg_gen_helper_0_0(helper_done);
3994
                            goto jmp_insn;
3995
                        case 1:
3996
                            if (!supervisor(dc))
3997
                                goto priv_insn;
3998
                            dc->npc = DYNAMIC_PC;
3999
                            dc->pc = DYNAMIC_PC;
4000
                            tcg_gen_helper_0_0(helper_retry);
4001
                            goto jmp_insn;
4002
                        default:
4003
                            goto illegal_insn;
4004
                        }
4005
                    }
4006
                    break;
4007
#endif
4008
                default:
4009
                    goto illegal_insn;
4010
                }
4011
            }
4012
            break;
4013
        }
4014
        break;
4015
    case 3:                     /* load/store instructions */
4016
        {
4017
            unsigned int xop = GET_FIELD(insn, 7, 12);
4018
            rs1 = GET_FIELD(insn, 13, 17);
4019
            save_state(dc);
4020
            gen_movl_reg_T0(rs1);
4021
            if (xop == 0x3c || xop == 0x3e)
4022
            {
4023
                rs2 = GET_FIELD(insn, 27, 31);
4024
                gen_movl_reg_T1(rs2);
4025
            }
4026
            else if (IS_IMM) {       /* immediate */
4027
                rs2 = GET_FIELDs(insn, 19, 31);
4028
                tcg_gen_addi_tl(cpu_T[0], cpu_T[0], (int)rs2);
4029
            } else {            /* register */
4030
                rs2 = GET_FIELD(insn, 27, 31);
4031
#if defined(OPTIM)
4032
                if (rs2 != 0) {
4033
#endif
4034
                    gen_movl_reg_T1(rs2);
4035
                    gen_op_add_T1_T0();
4036
#if defined(OPTIM)
4037
                }
4038
#endif
4039
            }
4040
            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
4041
                (xop > 0x17 && xop <= 0x1d ) ||
4042
                (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
4043
                switch (xop) {
4044
                case 0x0:       /* load unsigned word */
4045
                    gen_op_check_align_T0_3();
4046
                    ABI32_MASK(cpu_T[0]);
4047
                    tcg_gen_qemu_ld32u(cpu_T[1], cpu_T[0], dc->mem_idx);
4048
                    break;
4049
                case 0x1:       /* load unsigned byte */
4050
                    ABI32_MASK(cpu_T[0]);
4051
                    tcg_gen_qemu_ld8u(cpu_T[1], cpu_T[0], dc->mem_idx);
4052
                    break;
4053
                case 0x2:       /* load unsigned halfword */
4054
                    gen_op_check_align_T0_1();
4055
                    ABI32_MASK(cpu_T[0]);
4056
                    tcg_gen_qemu_ld16u(cpu_T[1], cpu_T[0], dc->mem_idx);
4057
                    break;
4058
                case 0x3:       /* load double word */
4059
                    if (rd & 1)
4060
                        goto illegal_insn;
4061
                    else {
4062
                        TCGv r_dword;
4063

    
4064
                        r_dword = tcg_temp_new(TCG_TYPE_I64);
4065
                        gen_op_check_align_T0_7();
4066
                        ABI32_MASK(cpu_T[0]);
4067
                        tcg_gen_qemu_ld64(r_dword, cpu_T[0], dc->mem_idx);
4068
                        tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
4069
                        gen_movl_T0_reg(rd + 1);
4070
                        tcg_gen_shri_i64(r_dword, r_dword, 32);
4071
                        tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
4072
                        tcg_gen_discard_i64(r_dword);
4073
                    }
4074
                    break;
4075
                case 0x9:       /* load signed byte */
4076
                    ABI32_MASK(cpu_T[0]);
4077
                    tcg_gen_qemu_ld8s(cpu_T[1], cpu_T[0], dc->mem_idx);
4078
                    break;
4079
                case 0xa:       /* load signed halfword */
4080
                    gen_op_check_align_T0_1();
4081
                    ABI32_MASK(cpu_T[0]);
4082
                    tcg_gen_qemu_ld16s(cpu_T[1], cpu_T[0], dc->mem_idx);
4083
                    break;
4084
                case 0xd:       /* ldstub -- XXX: should be atomically */
4085
                    tcg_gen_movi_i32(cpu_tmp0, 0xff);
4086
                    ABI32_MASK(cpu_T[0]);
4087
                    tcg_gen_qemu_ld8s(cpu_T[1], cpu_T[0], dc->mem_idx);
4088
                    tcg_gen_qemu_st8(cpu_tmp0, cpu_T[0], dc->mem_idx);
4089
                    break;
4090
                case 0x0f:      /* swap register with memory. Also atomically */
4091
                    gen_op_check_align_T0_3();
4092
                    gen_movl_reg_T1(rd);
4093
                    ABI32_MASK(cpu_T[0]);
4094
                    tcg_gen_qemu_ld32u(cpu_tmp0, cpu_T[0], dc->mem_idx);
4095
                    tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], dc->mem_idx);
4096
                    tcg_gen_mov_i32(cpu_T[1], cpu_tmp0);
4097
                    break;
4098
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4099
                case 0x10:      /* load word alternate */
4100
#ifndef TARGET_SPARC64
4101
                    if (IS_IMM)
4102
                        goto illegal_insn;
4103
                    if (!supervisor(dc))
4104
                        goto priv_insn;
4105
#endif
4106
                    gen_op_check_align_T0_3();
4107
                    gen_ld_asi(insn, 4, 0);
4108
                    break;
4109
                case 0x11:      /* load unsigned byte alternate */
4110
#ifndef TARGET_SPARC64
4111
                    if (IS_IMM)
4112
                        goto illegal_insn;
4113
                    if (!supervisor(dc))
4114
                        goto priv_insn;
4115
#endif
4116
                    gen_ld_asi(insn, 1, 0);
4117
                    break;
4118
                case 0x12:      /* load unsigned halfword alternate */
4119
#ifndef TARGET_SPARC64
4120
                    if (IS_IMM)
4121
                        goto illegal_insn;
4122
                    if (!supervisor(dc))
4123
                        goto priv_insn;
4124
#endif
4125
                    gen_op_check_align_T0_1();
4126
                    gen_ld_asi(insn, 2, 0);
4127
                    break;
4128
                case 0x13:      /* load double word alternate */
4129
#ifndef TARGET_SPARC64
4130
                    if (IS_IMM)
4131
                        goto illegal_insn;
4132
                    if (!supervisor(dc))
4133
                        goto priv_insn;
4134
#endif
4135
                    if (rd & 1)
4136
                        goto illegal_insn;
4137
                    gen_op_check_align_T0_7();
4138
                    gen_ldda_asi(insn);
4139
                    gen_movl_T0_reg(rd + 1);
4140
                    break;
4141
                case 0x19:      /* load signed byte alternate */
4142
#ifndef TARGET_SPARC64
4143
                    if (IS_IMM)
4144
                        goto illegal_insn;
4145
                    if (!supervisor(dc))
4146
                        goto priv_insn;
4147
#endif
4148
                    gen_ld_asi(insn, 1, 1);
4149
                    break;
4150
                case 0x1a:      /* load signed halfword alternate */
4151
#ifndef TARGET_SPARC64
4152
                    if (IS_IMM)
4153
                        goto illegal_insn;
4154
                    if (!supervisor(dc))
4155
                        goto priv_insn;
4156
#endif
4157
                    gen_op_check_align_T0_1();
4158
                    gen_ld_asi(insn, 2, 1);
4159
                    break;
4160
                case 0x1d:      /* ldstuba -- XXX: should be atomically */
4161
#ifndef TARGET_SPARC64
4162
                    if (IS_IMM)
4163
                        goto illegal_insn;
4164
                    if (!supervisor(dc))
4165
                        goto priv_insn;
4166
#endif
4167
                    gen_ldstub_asi(insn);
4168
                    break;
4169
                case 0x1f:      /* swap reg with alt. memory. Also atomically */
4170
#ifndef TARGET_SPARC64
4171
                    if (IS_IMM)
4172
                        goto illegal_insn;
4173
                    if (!supervisor(dc))
4174
                        goto priv_insn;
4175
#endif
4176
                    gen_op_check_align_T0_3();
4177
                    gen_movl_reg_T1(rd);
4178
                    gen_swap_asi(insn);
4179
                    break;
4180

    
4181
#ifndef TARGET_SPARC64
4182
                case 0x30: /* ldc */
4183
                case 0x31: /* ldcsr */
4184
                case 0x33: /* lddc */
4185
                    goto ncp_insn;
4186
#endif
4187
#endif
4188
#ifdef TARGET_SPARC64
4189
                case 0x08: /* V9 ldsw */
4190
                    gen_op_check_align_T0_3();
4191
                    ABI32_MASK(cpu_T[0]);
4192
                    tcg_gen_qemu_ld32s(cpu_T[1], cpu_T[0], dc->mem_idx);
4193
                    break;
4194
                case 0x0b: /* V9 ldx */
4195
                    gen_op_check_align_T0_7();
4196
                    ABI32_MASK(cpu_T[0]);
4197
                    tcg_gen_qemu_ld64(cpu_T[1], cpu_T[0], dc->mem_idx);
4198
                    break;
4199
                case 0x18: /* V9 ldswa */
4200
                    gen_op_check_align_T0_3();
4201
                    gen_ld_asi(insn, 4, 1);
4202
                    break;
4203
                case 0x1b: /* V9 ldxa */
4204
                    gen_op_check_align_T0_7();
4205
                    gen_ld_asi(insn, 8, 0);
4206
                    break;
4207
                case 0x2d: /* V9 prefetch, no effect */
4208
                    goto skip_move;
4209
                case 0x30: /* V9 ldfa */
4210
                    gen_op_check_align_T0_3();
4211
                    gen_ldf_asi(insn, 4, rd);
4212
                    goto skip_move;
4213
                case 0x33: /* V9 lddfa */
4214
                    gen_op_check_align_T0_3();
4215
                    gen_ldf_asi(insn, 8, DFPREG(rd));
4216
                    goto skip_move;
4217
                case 0x3d: /* V9 prefetcha, no effect */
4218
                    goto skip_move;
4219
                case 0x32: /* V9 ldqfa */
4220
#if defined(CONFIG_USER_ONLY)
4221
                    gen_op_check_align_T0_3();
4222
                    gen_ldf_asi(insn, 16, QFPREG(rd));
4223
                    goto skip_move;
4224
#else
4225
                    goto nfpu_insn;
4226
#endif
4227
#endif
4228
                default:
4229
                    goto illegal_insn;
4230
                }
4231
                gen_movl_T1_reg(rd);
4232
#ifdef TARGET_SPARC64
4233
            skip_move: ;
4234
#endif
4235
            } else if (xop >= 0x20 && xop < 0x24) {
4236
                if (gen_trap_ifnofpu(dc))
4237
                    goto jmp_insn;
4238
                switch (xop) {
4239
                case 0x20:      /* load fpreg */
4240
                    gen_op_check_align_T0_3();
4241
                    gen_op_ldst(ldf);
4242
                    gen_op_store_FT0_fpr(rd);
4243
                    break;
4244
                case 0x21:      /* load fsr */
4245
                    gen_op_check_align_T0_3();
4246
                    gen_op_ldst(ldf);
4247
                    tcg_gen_helper_0_0(helper_ldfsr);
4248
                    break;
4249
                case 0x22:      /* load quad fpreg */
4250
#if defined(CONFIG_USER_ONLY)
4251
                    gen_op_check_align_T0_7();
4252
                    gen_op_ldst(ldqf);
4253
                    gen_op_store_QT0_fpr(QFPREG(rd));
4254
                    break;
4255
#else
4256
                    goto nfpu_insn;
4257
#endif
4258
                case 0x23:      /* load double fpreg */
4259
                    gen_op_check_align_T0_7();
4260
                    gen_op_ldst(lddf);
4261
                    gen_op_store_DT0_fpr(DFPREG(rd));
4262
                    break;
4263
                default:
4264
                    goto illegal_insn;
4265
                }
4266
            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) || \
4267
                       xop == 0xe || xop == 0x1e) {
4268
                gen_movl_reg_T1(rd);
4269
                switch (xop) {
4270
                case 0x4: /* store word */
4271
                    gen_op_check_align_T0_3();
4272
                    ABI32_MASK(cpu_T[0]);
4273
                    tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], dc->mem_idx);
4274
                    break;
4275
                case 0x5: /* store byte */
4276
                    ABI32_MASK(cpu_T[0]);
4277
                    tcg_gen_qemu_st8(cpu_T[1], cpu_T[0], dc->mem_idx);
4278
                    break;
4279
                case 0x6: /* store halfword */
4280
                    gen_op_check_align_T0_1();
4281
                    ABI32_MASK(cpu_T[0]);
4282
                    tcg_gen_qemu_st16(cpu_T[1], cpu_T[0], dc->mem_idx);
4283
                    break;
4284
                case 0x7: /* store double word */
4285
                    if (rd & 1)
4286
                        goto illegal_insn;
4287
#ifndef __i386__
4288
                    else {
4289
                        TCGv r_dword, r_low;
4290

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

    
4508
static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
4509
{
4510
}
4511

    
4512
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
4513
                                                 int spc, CPUSPARCState *env)
4514
{
4515
    target_ulong pc_start, last_pc;
4516
    uint16_t *gen_opc_end;
4517
    DisasContext dc1, *dc = &dc1;
4518
    int j, lj = -1;
4519

    
4520
    memset(dc, 0, sizeof(DisasContext));
4521
    dc->tb = tb;
4522
    pc_start = tb->pc;
4523
    dc->pc = pc_start;
4524
    last_pc = dc->pc;
4525
    dc->npc = (target_ulong) tb->cs_base;
4526
    dc->mem_idx = cpu_mmu_index(env);
4527
    dc->fpu_enabled = cpu_fpu_enabled(env);
4528
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4529

    
4530
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
4531

    
4532
    do {
4533
        if (env->nb_breakpoints > 0) {
4534
            for(j = 0; j < env->nb_breakpoints; j++) {
4535
                if (env->breakpoints[j] == dc->pc) {
4536
                    if (dc->pc != pc_start)
4537
                        save_state(dc);
4538
                    tcg_gen_helper_0_0(helper_debug);
4539
                    tcg_gen_exit_tb(0);
4540
                    dc->is_br = 1;
4541
                    goto exit_gen_loop;
4542
                }
4543
            }
4544
        }
4545
        if (spc) {
4546
            if (loglevel > 0)
4547
                fprintf(logfile, "Search PC...\n");
4548
            j = gen_opc_ptr - gen_opc_buf;
4549
            if (lj < j) {
4550
                lj++;
4551
                while (lj < j)
4552
                    gen_opc_instr_start[lj++] = 0;
4553
                gen_opc_pc[lj] = dc->pc;
4554
                gen_opc_npc[lj] = dc->npc;
4555
                gen_opc_instr_start[lj] = 1;
4556
            }
4557
        }
4558
        last_pc = dc->pc;
4559
        disas_sparc_insn(dc);
4560

    
4561
        if (dc->is_br)
4562
            break;
4563
        /* if the next PC is different, we abort now */
4564
        if (dc->pc != (last_pc + 4))
4565
            break;
4566
        /* if we reach a page boundary, we stop generation so that the
4567
           PC of a TT_TFAULT exception is always in the right page */
4568
        if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
4569
            break;
4570
        /* if single step mode, we generate only one instruction and
4571
           generate an exception */
4572
        if (env->singlestep_enabled) {
4573
            gen_jmp_im(dc->pc);
4574
            tcg_gen_exit_tb(0);
4575
            break;
4576
        }
4577
    } while ((gen_opc_ptr < gen_opc_end) &&
4578
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
4579

    
4580
 exit_gen_loop:
4581
    if (!dc->is_br) {
4582
        if (dc->pc != DYNAMIC_PC &&
4583
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
4584
            /* static PC and NPC: we can use direct chaining */
4585
            gen_branch(dc, dc->pc, dc->npc);
4586
        } else {
4587
            if (dc->pc != DYNAMIC_PC)
4588
                gen_jmp_im(dc->pc);
4589
            save_npc(dc);
4590
            tcg_gen_exit_tb(0);
4591
        }
4592
    }
4593
    *gen_opc_ptr = INDEX_op_end;
4594
    if (spc) {
4595
        j = gen_opc_ptr - gen_opc_buf;
4596
        lj++;
4597
        while (lj <= j)
4598
            gen_opc_instr_start[lj++] = 0;
4599
#if 0
4600
        if (loglevel > 0) {
4601
            page_dump(logfile);
4602
        }
4603
#endif
4604
        gen_opc_jump_pc[0] = dc->jump_pc[0];
4605
        gen_opc_jump_pc[1] = dc->jump_pc[1];
4606
    } else {
4607
        tb->size = last_pc + 4 - pc_start;
4608
    }
4609
#ifdef DEBUG_DISAS
4610
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4611
        fprintf(logfile, "--------------\n");
4612
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
4613
        target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
4614
        fprintf(logfile, "\n");
4615
    }
4616
#endif
4617
    return 0;
4618
}
4619

    
4620
int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
4621
{
4622
    return gen_intermediate_code_internal(tb, 0, env);
4623
}
4624

    
4625
int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
4626
{
4627
    return gen_intermediate_code_internal(tb, 1, env);
4628
}
4629

    
4630
void cpu_reset(CPUSPARCState *env)
4631
{
4632
    tlb_flush(env, 1);
4633
    env->cwp = 0;
4634
    env->wim = 1;
4635
    env->regwptr = env->regbase + (env->cwp * 16);
4636
#if defined(CONFIG_USER_ONLY)
4637
    env->user_mode_only = 1;
4638
#ifdef TARGET_SPARC64
4639
    env->cleanwin = NWINDOWS - 2;
4640
    env->cansave = NWINDOWS - 2;
4641
    env->pstate = PS_RMO | PS_PEF | PS_IE;
4642
    env->asi = 0x82; // Primary no-fault
4643
#endif
4644
#else
4645
    env->psret = 0;
4646
    env->psrs = 1;
4647
    env->psrps = 1;
4648
#ifdef TARGET_SPARC64
4649
    env->pstate = PS_PRIV;
4650
    env->hpstate = HS_PRIV;
4651
    env->pc = 0x1fff0000000ULL;
4652
    env->tsptr = &env->ts[env->tl];
4653
#else
4654
    env->pc = 0;
4655
    env->mmuregs[0] &= ~(MMU_E | MMU_NF);
4656
    env->mmuregs[0] |= env->mmu_bm;
4657
#endif
4658
    env->npc = env->pc + 4;
4659
#endif
4660
}
4661

    
4662
CPUSPARCState *cpu_sparc_init(const char *cpu_model)
4663
{
4664
    CPUSPARCState *env;
4665
    const sparc_def_t *def;
4666
    static int inited;
4667
    unsigned int i;
4668
    static const char * const gregnames[8] = {
4669
        NULL, // g0 not used
4670
        "g1",
4671
        "g2",
4672
        "g3",
4673
        "g4",
4674
        "g5",
4675
        "g6",
4676
        "g7",
4677
    };
4678

    
4679
    def = cpu_sparc_find_by_name(cpu_model);
4680
    if (!def)
4681
        return NULL;
4682

    
4683
    env = qemu_mallocz(sizeof(CPUSPARCState));
4684
    if (!env)
4685
        return NULL;
4686
    cpu_exec_init(env);
4687
    env->cpu_model_str = cpu_model;
4688
    env->version = def->iu_version;
4689
    env->fsr = def->fpu_version;
4690
#if !defined(TARGET_SPARC64)
4691
    env->mmu_bm = def->mmu_bm;
4692
    env->mmu_ctpr_mask = def->mmu_ctpr_mask;
4693
    env->mmu_cxr_mask = def->mmu_cxr_mask;
4694
    env->mmu_sfsr_mask = def->mmu_sfsr_mask;
4695
    env->mmu_trcr_mask = def->mmu_trcr_mask;
4696
    env->mmuregs[0] |= def->mmu_version;
4697
    cpu_sparc_set_id(env, 0);
4698
#endif
4699

    
4700
    /* init various static tables */
4701
    if (!inited) {
4702
        inited = 1;
4703

    
4704
        tcg_set_macro_func(&tcg_ctx, tcg_macro_func);
4705
        cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
4706
        cpu_regwptr = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
4707
                                         offsetof(CPUState, regwptr),
4708
                                         "regwptr");
4709
        //#if TARGET_LONG_BITS > HOST_LONG_BITS
4710
#ifdef TARGET_SPARC64
4711
        cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
4712
                                      TCG_AREG0, offsetof(CPUState, t0), "T0");
4713
        cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
4714
                                      TCG_AREG0, offsetof(CPUState, t1), "T1");
4715
        cpu_T[2] = tcg_global_mem_new(TCG_TYPE_TL,
4716
                                      TCG_AREG0, offsetof(CPUState, t2), "T2");
4717
        cpu_xcc = tcg_global_mem_new(TCG_TYPE_I32,
4718
                                     TCG_AREG0, offsetof(CPUState, xcc),
4719
                                     "xcc");
4720
#else
4721
        cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
4722
        cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
4723
        cpu_T[2] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T2");
4724
#endif
4725
        cpu_cc_src = tcg_global_mem_new(TCG_TYPE_TL,
4726
                                        TCG_AREG0, offsetof(CPUState, cc_src),
4727
                                        "cc_src");
4728
        cpu_cc_src2 = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4729
                                         offsetof(CPUState, cc_src2),
4730
                                         "cc_src2");
4731
        cpu_cc_dst = tcg_global_mem_new(TCG_TYPE_TL,
4732
                                        TCG_AREG0, offsetof(CPUState, cc_dst),
4733
                                        "cc_dst");
4734
        cpu_psr = tcg_global_mem_new(TCG_TYPE_I32,
4735
                                     TCG_AREG0, offsetof(CPUState, psr),
4736
                                     "psr");
4737
        cpu_fsr = tcg_global_mem_new(TCG_TYPE_TL,
4738
                                     TCG_AREG0, offsetof(CPUState, fsr),
4739
                                     "fsr");
4740
        cpu_pc = tcg_global_mem_new(TCG_TYPE_TL,
4741
                                    TCG_AREG0, offsetof(CPUState, pc),
4742
                                    "pc");
4743
        cpu_npc = tcg_global_mem_new(TCG_TYPE_TL,
4744
                                    TCG_AREG0, offsetof(CPUState, npc),
4745
                                    "npc");
4746
        for (i = 1; i < 8; i++)
4747
            cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4748
                                              offsetof(CPUState, gregs[i]),
4749
                                              gregnames[i]);
4750
    }
4751

    
4752
    cpu_reset(env);
4753
    
4754
    return env;
4755
}
4756

    
4757
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
4758
{
4759
#if !defined(TARGET_SPARC64)
4760
    env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
4761
#endif
4762
}
4763

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

    
5084
static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name)
5085
{
5086
    unsigned int i;
5087

    
5088
    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
5089
        if (strcasecmp(name, sparc_defs[i].name) == 0) {
5090
            return &sparc_defs[i];
5091
        }
5092
    }
5093
    return NULL;
5094
}
5095

    
5096
void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
5097
{
5098
    unsigned int i;
5099

    
5100
    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
5101
        (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x\n",
5102
                       sparc_defs[i].name,
5103
                       sparc_defs[i].iu_version,
5104
                       sparc_defs[i].fpu_version,
5105
                       sparc_defs[i].mmu_version);
5106
    }
5107
}
5108

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

    
5111
void cpu_dump_state(CPUState *env, FILE *f,
5112
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5113
                    int flags)
5114
{
5115
    int i, x;
5116

    
5117
    cpu_fprintf(f, "pc: " TARGET_FMT_lx "  npc: " TARGET_FMT_lx "\n", env->pc, env->npc);
5118
    cpu_fprintf(f, "General Registers:\n");
5119
    for (i = 0; i < 4; i++)
5120
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
5121
    cpu_fprintf(f, "\n");
5122
    for (; i < 8; i++)
5123
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
5124
    cpu_fprintf(f, "\nCurrent Register Window:\n");
5125
    for (x = 0; x < 3; x++) {
5126
        for (i = 0; i < 4; i++)
5127
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
5128
                    (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
5129
                    env->regwptr[i + x * 8]);
5130
        cpu_fprintf(f, "\n");
5131
        for (; i < 8; i++)
5132
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
5133
                    (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
5134
                    env->regwptr[i + x * 8]);
5135
        cpu_fprintf(f, "\n");
5136
    }
5137
    cpu_fprintf(f, "\nFloating Point Registers:\n");
5138
    for (i = 0; i < 32; i++) {
5139
        if ((i & 3) == 0)
5140
            cpu_fprintf(f, "%%f%02d:", i);
5141
        cpu_fprintf(f, " %016lf", env->fpr[i]);
5142
        if ((i & 3) == 3)
5143
            cpu_fprintf(f, "\n");
5144
    }
5145
#ifdef TARGET_SPARC64
5146
    cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d fprs: %d\n",
5147
                env->pstate, GET_CCR(env), env->asi, env->tl, env->fprs);
5148
    cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d cleanwin %d cwp %d\n",
5149
                env->cansave, env->canrestore, env->otherwin, env->wstate,
5150
                env->cleanwin, NWINDOWS - 1 - env->cwp);
5151
#else
5152
    cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n", GET_PSR(env),
5153
            GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
5154
            GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
5155
            env->psrs?'S':'-', env->psrps?'P':'-',
5156
            env->psret?'E':'-', env->wim);
5157
#endif
5158
    cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env));
5159
}
5160

    
5161
#if defined(CONFIG_USER_ONLY)
5162
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
5163
{
5164
    return addr;
5165
}
5166

    
5167
#else
5168
extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
5169
                                 int *access_index, target_ulong address, int rw,
5170
                                 int mmu_idx);
5171

    
5172
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
5173
{
5174
    target_phys_addr_t phys_addr;
5175
    int prot, access_index;
5176

    
5177
    if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2,
5178
                             MMU_KERNEL_IDX) != 0)
5179
        if (get_physical_address(env, &phys_addr, &prot, &access_index, addr,
5180
                                 0, MMU_KERNEL_IDX) != 0)
5181
            return -1;
5182
    if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED)
5183
        return -1;
5184
    return phys_addr;
5185
}
5186
#endif
5187

    
5188
void helper_flush(target_ulong addr)
5189
{
5190
    addr &= ~7;
5191
    tb_invalidate_page_range(addr, addr + 8);
5192
}