Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ b25deda7

History | View | Annotate | Download (148.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;
50
/* local register indexes (only used inside old micro ops) */
51
static TCGv cpu_tmp0;
52

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

    
63
typedef struct sparc_def_t sparc_def_t;
64

    
65
struct sparc_def_t {
66
    const unsigned char *name;
67
    target_ulong iu_version;
68
    uint32_t fpu_version;
69
    uint32_t mmu_version;
70
    uint32_t mmu_bm;
71
    uint32_t mmu_ctpr_mask;
72
    uint32_t mmu_cxr_mask;
73
    uint32_t mmu_sfsr_mask;
74
    uint32_t mmu_trcr_mask;
75
};
76

    
77
static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name);
78

    
79
extern FILE *logfile;
80
extern int loglevel;
81

    
82
// This function uses non-native bit order
83
#define GET_FIELD(X, FROM, TO) \
84
  ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
85

    
86
// This function uses the order in the manuals, i.e. bit 0 is 2^0
87
#define GET_FIELD_SP(X, FROM, TO) \
88
    GET_FIELD(X, 31 - (TO), 31 - (FROM))
89

    
90
#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
91
#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
92

    
93
#ifdef TARGET_SPARC64
94
#define DFPREG(r) (((r & 1) << 5) | (r & 0x1e))
95
#define QFPREG(r) (((r & 1) << 5) | (r & 0x1c))
96
#else
97
#define DFPREG(r) (r & 0x1e)
98
#define QFPREG(r) (r & 0x1c)
99
#endif
100

    
101
static int sign_extend(int x, int len)
102
{
103
    len = 32 - len;
104
    return (x << len) >> len;
105
}
106

    
107
#define IS_IMM (insn & (1<<13))
108

    
109
static void disas_sparc_insn(DisasContext * dc);
110

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

    
149
/* floating point registers moves */
150
GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fprf);
151
GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fprf);
152
GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fprf);
153
GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fprf);
154

    
155
GEN32(gen_op_load_fpr_DT0, gen_op_load_fpr_DT0_fprf);
156
GEN32(gen_op_load_fpr_DT1, gen_op_load_fpr_DT1_fprf);
157
GEN32(gen_op_store_DT0_fpr, gen_op_store_DT0_fpr_fprf);
158
GEN32(gen_op_store_DT1_fpr, gen_op_store_DT1_fpr_fprf);
159

    
160
#if defined(CONFIG_USER_ONLY)
161
GEN32(gen_op_load_fpr_QT0, gen_op_load_fpr_QT0_fprf);
162
GEN32(gen_op_load_fpr_QT1, gen_op_load_fpr_QT1_fprf);
163
GEN32(gen_op_store_QT0_fpr, gen_op_store_QT0_fpr_fprf);
164
GEN32(gen_op_store_QT1_fpr, gen_op_store_QT1_fpr_fprf);
165
#endif
166

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

    
194
#ifndef CONFIG_USER_ONLY
195
#ifdef __i386__
196
OP_LD_TABLE(std);
197
#endif /* __i386__ */
198
OP_LD_TABLE(stf);
199
OP_LD_TABLE(stdf);
200
OP_LD_TABLE(ldf);
201
OP_LD_TABLE(lddf);
202
#endif
203

    
204
#ifdef TARGET_ABI32
205
#define ABI32_MASK(addr) tcg_gen_andi_i64(addr, addr, 0xffffffffULL);
206
#else
207
#define ABI32_MASK(addr)
208
#endif
209

    
210
static inline void gen_movl_simm_T1(int32_t val)
211
{
212
    tcg_gen_movi_tl(cpu_T[1], val);
213
}
214

    
215
static inline void gen_movl_reg_TN(int reg, TCGv tn)
216
{
217
    if (reg == 0)
218
        tcg_gen_movi_tl(tn, 0);
219
    else if (reg < 8)
220
        tcg_gen_ld_tl(tn, cpu_env, offsetof(CPUState, gregs[reg]));
221
    else {
222
        tcg_gen_ld_ptr(cpu_regwptr, cpu_env, offsetof(CPUState, regwptr)); // XXX
223
        tcg_gen_ld_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
224
    }
225
}
226

    
227
static inline void gen_movl_reg_T0(int reg)
228
{
229
    gen_movl_reg_TN(reg, cpu_T[0]);
230
}
231

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

    
237
#ifdef __i386__
238
static inline void gen_movl_reg_T2(int reg)
239
{
240
    gen_movl_reg_TN(reg, cpu_T[2]);
241
}
242

    
243
#endif /* __i386__ */
244
static inline void gen_movl_TN_reg(int reg, TCGv tn)
245
{
246
    if (reg == 0)
247
        return;
248
    else if (reg < 8)
249
        tcg_gen_st_tl(tn, cpu_env, offsetof(CPUState, gregs[reg]));
250
    else {
251
        tcg_gen_ld_ptr(cpu_regwptr, cpu_env, offsetof(CPUState, regwptr)); // XXX
252
        tcg_gen_st_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
253
    }
254
}
255

    
256
static inline void gen_movl_T0_reg(int reg)
257
{
258
    gen_movl_TN_reg(reg, cpu_T[0]);
259
}
260

    
261
static inline void gen_movl_T1_reg(int reg)
262
{
263
    gen_movl_TN_reg(reg, cpu_T[1]);
264
}
265

    
266
static inline void gen_op_movl_T0_env(size_t offset)
267
{
268
    tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
269
}
270

    
271
static inline void gen_op_movl_env_T0(size_t offset)
272
{
273
    tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
274
}
275

    
276
static inline void gen_op_movtl_T0_env(size_t offset)
277
{
278
    tcg_gen_ld_tl(cpu_T[0], cpu_env, offset);
279
}
280

    
281
static inline void gen_op_movtl_env_T0(size_t offset)
282
{
283
    tcg_gen_st_tl(cpu_T[0], cpu_env, offset);
284
}
285

    
286
static inline void gen_op_add_T1_T0(void)
287
{
288
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
289
}
290

    
291
static inline void gen_op_or_T1_T0(void)
292
{
293
    tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
294
}
295

    
296
static inline void gen_op_xor_T1_T0(void)
297
{
298
    tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
299
}
300

    
301
static inline void gen_jmp_im(target_ulong pc)
302
{
303
    tcg_gen_movi_tl(cpu_tmp0, pc);
304
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, pc));
305
}
306

    
307
static inline void gen_movl_npc_im(target_ulong npc)
308
{
309
    tcg_gen_movi_tl(cpu_tmp0, npc);
310
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, npc));
311
}
312

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

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

    
334
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
335
                               target_ulong pc2)
336
{
337
    int l1;
338

    
339
    l1 = gen_new_label();
340

    
341
    gen_op_jz_T2_label(l1);
342

    
343
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
344

    
345
    gen_set_label(l1);
346
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
347
}
348

    
349
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
350
                                target_ulong pc2)
351
{
352
    int l1;
353

    
354
    l1 = gen_new_label();
355

    
356
    gen_op_jz_T2_label(l1);
357

    
358
    gen_goto_tb(dc, 0, pc2, pc1);
359

    
360
    gen_set_label(l1);
361
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
362
}
363

    
364
static inline void gen_branch(DisasContext *dc, target_ulong pc,
365
                              target_ulong npc)
366
{
367
    gen_goto_tb(dc, 0, pc, npc);
368
}
369

    
370
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2)
371
{
372
    int l1, l2;
373

    
374
    l1 = gen_new_label();
375
    l2 = gen_new_label();
376
    gen_op_jz_T2_label(l1);
377

    
378
    gen_movl_npc_im(npc1);
379
    gen_op_jmp_label(l2);
380

    
381
    gen_set_label(l1);
382
    gen_movl_npc_im(npc2);
383
    gen_set_label(l2);
384
}
385

    
386
/* call this function before using T2 as it may have been set for a jump */
387
static inline void flush_T2(DisasContext * dc)
388
{
389
    if (dc->npc == JUMP_PC) {
390
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
391
        dc->npc = DYNAMIC_PC;
392
    }
393
}
394

    
395
static inline void save_npc(DisasContext * dc)
396
{
397
    if (dc->npc == JUMP_PC) {
398
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
399
        dc->npc = DYNAMIC_PC;
400
    } else if (dc->npc != DYNAMIC_PC) {
401
        gen_movl_npc_im(dc->npc);
402
    }
403
}
404

    
405
static inline void save_state(DisasContext * dc)
406
{
407
    gen_jmp_im(dc->pc);
408
    save_npc(dc);
409
}
410

    
411
static inline void gen_mov_pc_npc(DisasContext * dc)
412
{
413
    if (dc->npc == JUMP_PC) {
414
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
415
        gen_op_mov_pc_npc();
416
        dc->pc = DYNAMIC_PC;
417
    } else if (dc->npc == DYNAMIC_PC) {
418
        gen_op_mov_pc_npc();
419
        dc->pc = DYNAMIC_PC;
420
    } else {
421
        dc->pc = dc->npc;
422
    }
423
}
424

    
425
static GenOpFunc * const gen_cond[2][16] = {
426
    {
427
        gen_op_eval_bn,
428
        gen_op_eval_be,
429
        gen_op_eval_ble,
430
        gen_op_eval_bl,
431
        gen_op_eval_bleu,
432
        gen_op_eval_bcs,
433
        gen_op_eval_bneg,
434
        gen_op_eval_bvs,
435
        gen_op_eval_ba,
436
        gen_op_eval_bne,
437
        gen_op_eval_bg,
438
        gen_op_eval_bge,
439
        gen_op_eval_bgu,
440
        gen_op_eval_bcc,
441
        gen_op_eval_bpos,
442
        gen_op_eval_bvc,
443
    },
444
    {
445
#ifdef TARGET_SPARC64
446
        gen_op_eval_bn,
447
        gen_op_eval_xbe,
448
        gen_op_eval_xble,
449
        gen_op_eval_xbl,
450
        gen_op_eval_xbleu,
451
        gen_op_eval_xbcs,
452
        gen_op_eval_xbneg,
453
        gen_op_eval_xbvs,
454
        gen_op_eval_ba,
455
        gen_op_eval_xbne,
456
        gen_op_eval_xbg,
457
        gen_op_eval_xbge,
458
        gen_op_eval_xbgu,
459
        gen_op_eval_xbcc,
460
        gen_op_eval_xbpos,
461
        gen_op_eval_xbvc,
462
#endif
463
    },
464
};
465

    
466
static GenOpFunc * const gen_fcond[4][16] = {
467
    {
468
        gen_op_eval_bn,
469
        gen_op_eval_fbne,
470
        gen_op_eval_fblg,
471
        gen_op_eval_fbul,
472
        gen_op_eval_fbl,
473
        gen_op_eval_fbug,
474
        gen_op_eval_fbg,
475
        gen_op_eval_fbu,
476
        gen_op_eval_ba,
477
        gen_op_eval_fbe,
478
        gen_op_eval_fbue,
479
        gen_op_eval_fbge,
480
        gen_op_eval_fbuge,
481
        gen_op_eval_fble,
482
        gen_op_eval_fbule,
483
        gen_op_eval_fbo,
484
    },
485
#ifdef TARGET_SPARC64
486
    {
487
        gen_op_eval_bn,
488
        gen_op_eval_fbne_fcc1,
489
        gen_op_eval_fblg_fcc1,
490
        gen_op_eval_fbul_fcc1,
491
        gen_op_eval_fbl_fcc1,
492
        gen_op_eval_fbug_fcc1,
493
        gen_op_eval_fbg_fcc1,
494
        gen_op_eval_fbu_fcc1,
495
        gen_op_eval_ba,
496
        gen_op_eval_fbe_fcc1,
497
        gen_op_eval_fbue_fcc1,
498
        gen_op_eval_fbge_fcc1,
499
        gen_op_eval_fbuge_fcc1,
500
        gen_op_eval_fble_fcc1,
501
        gen_op_eval_fbule_fcc1,
502
        gen_op_eval_fbo_fcc1,
503
    },
504
    {
505
        gen_op_eval_bn,
506
        gen_op_eval_fbne_fcc2,
507
        gen_op_eval_fblg_fcc2,
508
        gen_op_eval_fbul_fcc2,
509
        gen_op_eval_fbl_fcc2,
510
        gen_op_eval_fbug_fcc2,
511
        gen_op_eval_fbg_fcc2,
512
        gen_op_eval_fbu_fcc2,
513
        gen_op_eval_ba,
514
        gen_op_eval_fbe_fcc2,
515
        gen_op_eval_fbue_fcc2,
516
        gen_op_eval_fbge_fcc2,
517
        gen_op_eval_fbuge_fcc2,
518
        gen_op_eval_fble_fcc2,
519
        gen_op_eval_fbule_fcc2,
520
        gen_op_eval_fbo_fcc2,
521
    },
522
    {
523
        gen_op_eval_bn,
524
        gen_op_eval_fbne_fcc3,
525
        gen_op_eval_fblg_fcc3,
526
        gen_op_eval_fbul_fcc3,
527
        gen_op_eval_fbl_fcc3,
528
        gen_op_eval_fbug_fcc3,
529
        gen_op_eval_fbg_fcc3,
530
        gen_op_eval_fbu_fcc3,
531
        gen_op_eval_ba,
532
        gen_op_eval_fbe_fcc3,
533
        gen_op_eval_fbue_fcc3,
534
        gen_op_eval_fbge_fcc3,
535
        gen_op_eval_fbuge_fcc3,
536
        gen_op_eval_fble_fcc3,
537
        gen_op_eval_fbule_fcc3,
538
        gen_op_eval_fbo_fcc3,
539
    },
540
#else
541
    {}, {}, {},
542
#endif
543
};
544

    
545
#ifdef TARGET_SPARC64
546
static void gen_cond_reg(int cond)
547
{
548
        switch (cond) {
549
        case 0x1:
550
            gen_op_eval_brz();
551
            break;
552
        case 0x2:
553
            gen_op_eval_brlez();
554
            break;
555
        case 0x3:
556
            gen_op_eval_brlz();
557
            break;
558
        case 0x5:
559
            gen_op_eval_brnz();
560
            break;
561
        case 0x6:
562
            gen_op_eval_brgz();
563
            break;
564
        default:
565
        case 0x7:
566
            gen_op_eval_brgez();
567
            break;
568
        }
569
}
570
#endif
571

    
572
/* XXX: potentially incorrect if dynamic npc */
573
static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
574
{
575
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
576
    target_ulong target = dc->pc + offset;
577

    
578
    if (cond == 0x0) {
579
        /* unconditional not taken */
580
        if (a) {
581
            dc->pc = dc->npc + 4;
582
            dc->npc = dc->pc + 4;
583
        } else {
584
            dc->pc = dc->npc;
585
            dc->npc = dc->pc + 4;
586
        }
587
    } else if (cond == 0x8) {
588
        /* unconditional taken */
589
        if (a) {
590
            dc->pc = target;
591
            dc->npc = dc->pc + 4;
592
        } else {
593
            dc->pc = dc->npc;
594
            dc->npc = target;
595
        }
596
    } else {
597
        flush_T2(dc);
598
        gen_cond[cc][cond]();
599
        if (a) {
600
            gen_branch_a(dc, target, dc->npc);
601
            dc->is_br = 1;
602
        } else {
603
            dc->pc = dc->npc;
604
            dc->jump_pc[0] = target;
605
            dc->jump_pc[1] = dc->npc + 4;
606
            dc->npc = JUMP_PC;
607
        }
608
    }
609
}
610

    
611
/* XXX: potentially incorrect if dynamic npc */
612
static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
613
{
614
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
615
    target_ulong target = dc->pc + offset;
616

    
617
    if (cond == 0x0) {
618
        /* unconditional not taken */
619
        if (a) {
620
            dc->pc = dc->npc + 4;
621
            dc->npc = dc->pc + 4;
622
        } else {
623
            dc->pc = dc->npc;
624
            dc->npc = dc->pc + 4;
625
        }
626
    } else if (cond == 0x8) {
627
        /* unconditional taken */
628
        if (a) {
629
            dc->pc = target;
630
            dc->npc = dc->pc + 4;
631
        } else {
632
            dc->pc = dc->npc;
633
            dc->npc = target;
634
        }
635
    } else {
636
        flush_T2(dc);
637
        gen_fcond[cc][cond]();
638
        if (a) {
639
            gen_branch_a(dc, target, dc->npc);
640
            dc->is_br = 1;
641
        } else {
642
            dc->pc = dc->npc;
643
            dc->jump_pc[0] = target;
644
            dc->jump_pc[1] = dc->npc + 4;
645
            dc->npc = JUMP_PC;
646
        }
647
    }
648
}
649

    
650
#ifdef TARGET_SPARC64
651
/* XXX: potentially incorrect if dynamic npc */
652
static void do_branch_reg(DisasContext * dc, int32_t offset, uint32_t insn)
653
{
654
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
655
    target_ulong target = dc->pc + offset;
656

    
657
    flush_T2(dc);
658
    gen_cond_reg(cond);
659
    if (a) {
660
        gen_branch_a(dc, target, dc->npc);
661
        dc->is_br = 1;
662
    } else {
663
        dc->pc = dc->npc;
664
        dc->jump_pc[0] = target;
665
        dc->jump_pc[1] = dc->npc + 4;
666
        dc->npc = JUMP_PC;
667
    }
668
}
669

    
670
static GenOpFunc * const gen_fcmps[4] = {
671
    gen_op_fcmps,
672
    gen_op_fcmps_fcc1,
673
    gen_op_fcmps_fcc2,
674
    gen_op_fcmps_fcc3,
675
};
676

    
677
static GenOpFunc * const gen_fcmpd[4] = {
678
    gen_op_fcmpd,
679
    gen_op_fcmpd_fcc1,
680
    gen_op_fcmpd_fcc2,
681
    gen_op_fcmpd_fcc3,
682
};
683

    
684
#if defined(CONFIG_USER_ONLY)
685
static GenOpFunc * const gen_fcmpq[4] = {
686
    gen_op_fcmpq,
687
    gen_op_fcmpq_fcc1,
688
    gen_op_fcmpq_fcc2,
689
    gen_op_fcmpq_fcc3,
690
};
691
#endif
692

    
693
static GenOpFunc * const gen_fcmpes[4] = {
694
    gen_op_fcmpes,
695
    gen_op_fcmpes_fcc1,
696
    gen_op_fcmpes_fcc2,
697
    gen_op_fcmpes_fcc3,
698
};
699

    
700
static GenOpFunc * const gen_fcmped[4] = {
701
    gen_op_fcmped,
702
    gen_op_fcmped_fcc1,
703
    gen_op_fcmped_fcc2,
704
    gen_op_fcmped_fcc3,
705
};
706

    
707
#if defined(CONFIG_USER_ONLY)
708
static GenOpFunc * const gen_fcmpeq[4] = {
709
    gen_op_fcmpeq,
710
    gen_op_fcmpeq_fcc1,
711
    gen_op_fcmpeq_fcc2,
712
    gen_op_fcmpeq_fcc3,
713
};
714
#endif
715
#endif
716

    
717
static int gen_trap_ifnofpu(DisasContext * dc)
718
{
719
#if !defined(CONFIG_USER_ONLY)
720
    if (!dc->fpu_enabled) {
721
        save_state(dc);
722
        gen_op_exception(TT_NFPU_INSN);
723
        dc->is_br = 1;
724
        return 1;
725
    }
726
#endif
727
    return 0;
728
}
729

    
730
/* asi moves */
731
#ifdef TARGET_SPARC64
732
static inline void gen_ld_asi(int insn, int size, int sign)
733
{
734
    int asi, offset;
735
    TCGv r_size, r_sign;
736

    
737
    r_size = tcg_temp_new(TCG_TYPE_I32);
738
    r_sign = tcg_temp_new(TCG_TYPE_I32);
739
    tcg_gen_movi_i32(r_size, size);
740
    tcg_gen_movi_i32(r_sign, sign);
741
    if (IS_IMM) {
742
        offset = GET_FIELD(insn, 25, 31);
743
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
744
        tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUSPARCState, asi));
745
    } else {
746
        asi = GET_FIELD(insn, 19, 26);
747
        tcg_gen_movi_i32(cpu_T[1], asi);
748
    }
749
    tcg_gen_helper_1_4(helper_ld_asi, cpu_T[1], cpu_T[0], cpu_T[1], r_size,
750
                       r_sign);
751
}
752

    
753
static inline void gen_st_asi(int insn, int size)
754
{
755
    int asi, offset;
756
    TCGv r_asi, r_size;
757

    
758
    r_asi = tcg_temp_new(TCG_TYPE_I32);
759
    r_size = tcg_temp_new(TCG_TYPE_I32);
760
    tcg_gen_movi_i32(r_size, size);
761
    if (IS_IMM) {
762
        offset = GET_FIELD(insn, 25, 31);
763
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
764
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
765
    } else {
766
        asi = GET_FIELD(insn, 19, 26);
767
        tcg_gen_movi_i32(r_asi, asi);
768
    }
769
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], r_asi, r_size);
770
}
771

    
772
static inline void gen_ldf_asi(int insn, int size, int rd)
773
{
774
    int asi, offset;
775
    TCGv r_asi, r_size, r_rd;
776

    
777
    r_asi = tcg_temp_new(TCG_TYPE_I32);
778
    r_size = tcg_temp_new(TCG_TYPE_I32);
779
    r_rd = tcg_temp_new(TCG_TYPE_I32);
780
    tcg_gen_movi_i32(r_size, size);
781
    tcg_gen_movi_i32(r_rd, rd);
782
    if (IS_IMM) {
783
        offset = GET_FIELD(insn, 25, 31);
784
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
785
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
786
    } else {
787
        asi = GET_FIELD(insn, 19, 26);
788
        tcg_gen_movi_i32(r_asi, asi);
789
    }
790
    tcg_gen_helper_0_4(helper_ldf_asi, cpu_T[0], r_asi, r_size, r_rd);
791
}
792

    
793
static inline void gen_stf_asi(int insn, int size, int rd)
794
{
795
    int asi, offset;
796
    TCGv r_asi, r_size, r_rd;
797

    
798
    r_asi = tcg_temp_new(TCG_TYPE_I32);
799
    r_size = tcg_temp_new(TCG_TYPE_I32);
800
    r_rd = tcg_temp_new(TCG_TYPE_I32);
801
    tcg_gen_movi_i32(r_size, size);
802
    tcg_gen_movi_i32(r_rd, rd);
803
    if (IS_IMM) {
804
        offset = GET_FIELD(insn, 25, 31);
805
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
806
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
807
    } else {
808
        asi = GET_FIELD(insn, 19, 26);
809
        tcg_gen_movi_i32(r_asi, asi);
810
    }
811
    tcg_gen_helper_0_4(helper_stf_asi, cpu_T[0], r_asi, r_size, r_rd);
812
}
813

    
814
static inline void gen_swap_asi(int insn)
815
{
816
    int asi, offset;
817
    TCGv r_size, r_sign, r_temp;
818

    
819
    r_size = tcg_temp_new(TCG_TYPE_I32);
820
    r_sign = tcg_temp_new(TCG_TYPE_I32);
821
    r_temp = tcg_temp_new(TCG_TYPE_I32);
822
    tcg_gen_movi_i32(r_size, 4);
823
    tcg_gen_movi_i32(r_sign, 0);
824
    if (IS_IMM) {
825
        offset = GET_FIELD(insn, 25, 31);
826
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
827
        tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUSPARCState, asi));
828
    } else {
829
        asi = GET_FIELD(insn, 19, 26);
830
        tcg_gen_movi_i32(cpu_T[1], asi);
831
    }
832
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, cpu_T[0], cpu_T[1], r_size,
833
                       r_sign);
834
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], r_size, r_sign);
835
    tcg_gen_mov_i32(cpu_T[1], r_temp);
836
}
837

    
838
static inline void gen_ldda_asi(int insn)
839
{
840
    int asi, offset;
841
    TCGv r_size, r_sign, r_dword;
842

    
843
    r_size = tcg_temp_new(TCG_TYPE_I32);
844
    r_sign = tcg_temp_new(TCG_TYPE_I32);
845
    r_dword = tcg_temp_new(TCG_TYPE_I64);
846
    tcg_gen_movi_i32(r_size, 8);
847
    tcg_gen_movi_i32(r_sign, 0);
848
    if (IS_IMM) {
849
        offset = GET_FIELD(insn, 25, 31);
850
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
851
        tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUSPARCState, asi));
852
    } else {
853
        asi = GET_FIELD(insn, 19, 26);
854
        tcg_gen_movi_i32(cpu_T[1], asi);
855
    }
856
    tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], cpu_T[1], r_size,
857
                       r_sign);
858
    tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
859
    tcg_gen_shri_i64(r_dword, r_dword, 32);
860
    tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
861
}
862

    
863
static inline void gen_cas_asi(int insn, int rd)
864
{
865
    int asi, offset;
866
    TCGv r_val1, r_asi;
867

    
868
    r_val1 = tcg_temp_new(TCG_TYPE_I32);
869
    r_asi = tcg_temp_new(TCG_TYPE_I32);
870
    gen_movl_reg_TN(rd, r_val1);
871
    if (IS_IMM) {
872
        offset = GET_FIELD(insn, 25, 31);
873
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
874
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
875
    } else {
876
        asi = GET_FIELD(insn, 19, 26);
877
        tcg_gen_movi_i32(r_asi, asi);
878
    }
879
    tcg_gen_helper_1_4(helper_cas_asi, cpu_T[1], cpu_T[0], r_val1, cpu_T[1],
880
                       r_asi);
881
}
882

    
883
static inline void gen_casx_asi(int insn, int rd)
884
{
885
    int asi, offset;
886
    TCGv r_val1, r_asi;
887

    
888
    r_val1 = tcg_temp_new(TCG_TYPE_I64);
889
    r_asi = tcg_temp_new(TCG_TYPE_I32);
890
    gen_movl_reg_TN(rd, r_val1);
891
    if (IS_IMM) {
892
        offset = GET_FIELD(insn, 25, 31);
893
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
894
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
895
    } else {
896
        asi = GET_FIELD(insn, 19, 26);
897
        tcg_gen_movi_i32(r_asi, asi);
898
    }
899
    tcg_gen_helper_1_4(helper_casx_asi, cpu_T[1], cpu_T[0], r_val1, cpu_T[1],
900
                       r_asi);
901
}
902

    
903
#elif !defined(CONFIG_USER_ONLY)
904

    
905
static inline void gen_ld_asi(int insn, int size, int sign)
906
{
907
    int asi;
908
    TCGv r_size, r_sign, r_dword;
909

    
910
    r_size = tcg_temp_new(TCG_TYPE_I32);
911
    r_sign = tcg_temp_new(TCG_TYPE_I32);
912
    r_dword = tcg_temp_new(TCG_TYPE_I64);
913
    tcg_gen_movi_i32(r_size, size);
914
    tcg_gen_movi_i32(r_sign, sign);
915
    asi = GET_FIELD(insn, 19, 26);
916
    tcg_gen_movi_i32(cpu_T[1], asi);
917
    tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], cpu_T[1], r_size,
918
                       r_sign);
919
    tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
920
}
921

    
922
static inline void gen_st_asi(int insn, int size)
923
{
924
    int asi;
925
    TCGv r_dword, r_asi, r_size;
926

    
927
    r_dword = tcg_temp_new(TCG_TYPE_I64);
928
    tcg_gen_extu_i32_i64(r_dword, cpu_T[1]);
929
    r_asi = tcg_temp_new(TCG_TYPE_I32);
930
    r_size = tcg_temp_new(TCG_TYPE_I32);
931
    asi = GET_FIELD(insn, 19, 26);
932
    tcg_gen_movi_i32(r_asi, asi);
933
    tcg_gen_movi_i32(r_size, size);
934
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, r_asi, r_size);
935
}
936

    
937
static inline void gen_swap_asi(int insn)
938
{
939
    int asi;
940
    TCGv r_size, r_sign, r_temp;
941

    
942
    r_size = tcg_temp_new(TCG_TYPE_I32);
943
    r_sign = tcg_temp_new(TCG_TYPE_I32);
944
    r_temp = tcg_temp_new(TCG_TYPE_I32);
945
    tcg_gen_movi_i32(r_size, 4);
946
    tcg_gen_movi_i32(r_sign, 0);
947
    asi = GET_FIELD(insn, 19, 26);
948
    tcg_gen_movi_i32(cpu_T[1], asi);
949
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, cpu_T[0], cpu_T[1], r_size,
950
                       r_sign);
951
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], r_size, r_sign);
952
    tcg_gen_mov_i32(cpu_T[1], r_temp);
953
}
954

    
955
static inline void gen_ldda_asi(int insn)
956
{
957
    int asi;
958
    TCGv r_size, r_sign, r_dword;
959

    
960
    r_size = tcg_temp_new(TCG_TYPE_I32);
961
    r_sign = tcg_temp_new(TCG_TYPE_I32);
962
    r_dword = tcg_temp_new(TCG_TYPE_I64);
963
    tcg_gen_movi_i32(r_size, 8);
964
    tcg_gen_movi_i32(r_sign, 0);
965
    asi = GET_FIELD(insn, 19, 26);
966
    tcg_gen_movi_i32(cpu_T[1], asi);
967
    tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], cpu_T[1], r_size,
968
                       r_sign);
969
    tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
970
    tcg_gen_shri_i64(r_dword, r_dword, 32);
971
    tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
972
}
973
#endif
974

    
975
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
976
static inline void gen_ldstub_asi(int insn)
977
{
978
    int asi;
979
    TCGv r_dword, r_asi, r_size;
980

    
981
    gen_ld_asi(insn, 1, 0);
982

    
983
    r_dword = tcg_temp_new(TCG_TYPE_I64);
984
    r_asi = tcg_temp_new(TCG_TYPE_I32);
985
    r_size = tcg_temp_new(TCG_TYPE_I32);
986
    asi = GET_FIELD(insn, 19, 26);
987
    tcg_gen_movi_i32(r_dword, 0xff);
988
    tcg_gen_movi_i32(r_asi, asi);
989
    tcg_gen_movi_i32(r_size, 1);
990
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, r_asi, r_size);
991
}
992
#endif
993

    
994
/* before an instruction, dc->pc must be static */
995
static void disas_sparc_insn(DisasContext * dc)
996
{
997
    unsigned int insn, opc, rs1, rs2, rd;
998

    
999
    insn = ldl_code(dc->pc);
1000
    opc = GET_FIELD(insn, 0, 1);
1001

    
1002
    rd = GET_FIELD(insn, 2, 6);
1003
    switch (opc) {
1004
    case 0:                     /* branches/sethi */
1005
        {
1006
            unsigned int xop = GET_FIELD(insn, 7, 9);
1007
            int32_t target;
1008
            switch (xop) {
1009
#ifdef TARGET_SPARC64
1010
            case 0x1:           /* V9 BPcc */
1011
                {
1012
                    int cc;
1013

    
1014
                    target = GET_FIELD_SP(insn, 0, 18);
1015
                    target = sign_extend(target, 18);
1016
                    target <<= 2;
1017
                    cc = GET_FIELD_SP(insn, 20, 21);
1018
                    if (cc == 0)
1019
                        do_branch(dc, target, insn, 0);
1020
                    else if (cc == 2)
1021
                        do_branch(dc, target, insn, 1);
1022
                    else
1023
                        goto illegal_insn;
1024
                    goto jmp_insn;
1025
                }
1026
            case 0x3:           /* V9 BPr */
1027
                {
1028
                    target = GET_FIELD_SP(insn, 0, 13) |
1029
                        (GET_FIELD_SP(insn, 20, 21) << 14);
1030
                    target = sign_extend(target, 16);
1031
                    target <<= 2;
1032
                    rs1 = GET_FIELD(insn, 13, 17);
1033
                    gen_movl_reg_T0(rs1);
1034
                    do_branch_reg(dc, target, insn);
1035
                    goto jmp_insn;
1036
                }
1037
            case 0x5:           /* V9 FBPcc */
1038
                {
1039
                    int cc = GET_FIELD_SP(insn, 20, 21);
1040
                    if (gen_trap_ifnofpu(dc))
1041
                        goto jmp_insn;
1042
                    target = GET_FIELD_SP(insn, 0, 18);
1043
                    target = sign_extend(target, 19);
1044
                    target <<= 2;
1045
                    do_fbranch(dc, target, insn, cc);
1046
                    goto jmp_insn;
1047
                }
1048
#else
1049
            case 0x7:           /* CBN+x */
1050
                {
1051
                    goto ncp_insn;
1052
                }
1053
#endif
1054
            case 0x2:           /* BN+x */
1055
                {
1056
                    target = GET_FIELD(insn, 10, 31);
1057
                    target = sign_extend(target, 22);
1058
                    target <<= 2;
1059
                    do_branch(dc, target, insn, 0);
1060
                    goto jmp_insn;
1061
                }
1062
            case 0x6:           /* FBN+x */
1063
                {
1064
                    if (gen_trap_ifnofpu(dc))
1065
                        goto jmp_insn;
1066
                    target = GET_FIELD(insn, 10, 31);
1067
                    target = sign_extend(target, 22);
1068
                    target <<= 2;
1069
                    do_fbranch(dc, target, insn, 0);
1070
                    goto jmp_insn;
1071
                }
1072
            case 0x4:           /* SETHI */
1073
#define OPTIM
1074
#if defined(OPTIM)
1075
                if (rd) { // nop
1076
#endif
1077
                    uint32_t value = GET_FIELD(insn, 10, 31);
1078
                    tcg_gen_movi_tl(cpu_T[0], value << 10);
1079
                    gen_movl_T0_reg(rd);
1080
#if defined(OPTIM)
1081
                }
1082
#endif
1083
                break;
1084
            case 0x0:           /* UNIMPL */
1085
            default:
1086
                goto illegal_insn;
1087
            }
1088
            break;
1089
        }
1090
        break;
1091
    case 1:
1092
        /*CALL*/ {
1093
            target_long target = GET_FIELDs(insn, 2, 31) << 2;
1094

    
1095
            tcg_gen_movi_tl(cpu_T[0], dc->pc);
1096
            gen_movl_T0_reg(15);
1097
            target += dc->pc;
1098
            gen_mov_pc_npc(dc);
1099
            dc->npc = target;
1100
        }
1101
        goto jmp_insn;
1102
    case 2:                     /* FPU & Logical Operations */
1103
        {
1104
            unsigned int xop = GET_FIELD(insn, 7, 12);
1105
            if (xop == 0x3a) {  /* generate trap */
1106
                int cond;
1107

    
1108
                rs1 = GET_FIELD(insn, 13, 17);
1109
                gen_movl_reg_T0(rs1);
1110
                if (IS_IMM) {
1111
                    rs2 = GET_FIELD(insn, 25, 31);
1112
                    tcg_gen_addi_tl(cpu_T[0], cpu_T[0], rs2);
1113
                } else {
1114
                    rs2 = GET_FIELD(insn, 27, 31);
1115
#if defined(OPTIM)
1116
                    if (rs2 != 0) {
1117
#endif
1118
                        gen_movl_reg_T1(rs2);
1119
                        gen_op_add_T1_T0();
1120
#if defined(OPTIM)
1121
                    }
1122
#endif
1123
                }
1124
                cond = GET_FIELD(insn, 3, 6);
1125
                if (cond == 0x8) {
1126
                    save_state(dc);
1127
                    tcg_gen_helper_0_1(helper_trap, cpu_T[0]);
1128
                } else if (cond != 0) {
1129
#ifdef TARGET_SPARC64
1130
                    /* V9 icc/xcc */
1131
                    int cc = GET_FIELD_SP(insn, 11, 12);
1132
                    flush_T2(dc);
1133
                    save_state(dc);
1134
                    if (cc == 0)
1135
                        gen_cond[0][cond]();
1136
                    else if (cc == 2)
1137
                        gen_cond[1][cond]();
1138
                    else
1139
                        goto illegal_insn;
1140
#else
1141
                    flush_T2(dc);
1142
                    save_state(dc);
1143
                    gen_cond[0][cond]();
1144
#endif
1145
                    tcg_gen_helper_0_2(helper_trapcc, cpu_T[0], cpu_T[2]);
1146
                }
1147
                gen_op_next_insn();
1148
                tcg_gen_exit_tb(0);
1149
                dc->is_br = 1;
1150
                goto jmp_insn;
1151
            } else if (xop == 0x28) {
1152
                rs1 = GET_FIELD(insn, 13, 17);
1153
                switch(rs1) {
1154
                case 0: /* rdy */
1155
#ifndef TARGET_SPARC64
1156
                case 0x01 ... 0x0e: /* undefined in the SPARCv8
1157
                                       manual, rdy on the microSPARC
1158
                                       II */
1159
                case 0x0f:          /* stbar in the SPARCv8 manual,
1160
                                       rdy on the microSPARC II */
1161
                case 0x10 ... 0x1f: /* implementation-dependent in the
1162
                                       SPARCv8 manual, rdy on the
1163
                                       microSPARC II */
1164
#endif
1165
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, y));
1166
                    gen_movl_T0_reg(rd);
1167
                    break;
1168
#ifdef TARGET_SPARC64
1169
                case 0x2: /* V9 rdccr */
1170
                    gen_op_rdccr();
1171
                    gen_movl_T0_reg(rd);
1172
                    break;
1173
                case 0x3: /* V9 rdasi */
1174
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, asi));
1175
                    gen_movl_T0_reg(rd);
1176
                    break;
1177
                case 0x4: /* V9 rdtick */
1178
                    gen_op_rdtick();
1179
                    gen_movl_T0_reg(rd);
1180
                    break;
1181
                case 0x5: /* V9 rdpc */
1182
                    tcg_gen_movi_tl(cpu_T[0], dc->pc);
1183
                    gen_movl_T0_reg(rd);
1184
                    break;
1185
                case 0x6: /* V9 rdfprs */
1186
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, fprs));
1187
                    gen_movl_T0_reg(rd);
1188
                    break;
1189
                case 0xf: /* V9 membar */
1190
                    break; /* no effect */
1191
                case 0x13: /* Graphics Status */
1192
                    if (gen_trap_ifnofpu(dc))
1193
                        goto jmp_insn;
1194
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, gsr));
1195
                    gen_movl_T0_reg(rd);
1196
                    break;
1197
                case 0x17: /* Tick compare */
1198
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, tick_cmpr));
1199
                    gen_movl_T0_reg(rd);
1200
                    break;
1201
                case 0x18: /* System tick */
1202
                    gen_op_rdstick();
1203
                    gen_movl_T0_reg(rd);
1204
                    break;
1205
                case 0x19: /* System tick compare */
1206
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, stick_cmpr));
1207
                    gen_movl_T0_reg(rd);
1208
                    break;
1209
                case 0x10: /* Performance Control */
1210
                case 0x11: /* Performance Instrumentation Counter */
1211
                case 0x12: /* Dispatch Control */
1212
                case 0x14: /* Softint set, WO */
1213
                case 0x15: /* Softint clear, WO */
1214
                case 0x16: /* Softint write */
1215
#endif
1216
                default:
1217
                    goto illegal_insn;
1218
                }
1219
#if !defined(CONFIG_USER_ONLY)
1220
            } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
1221
#ifndef TARGET_SPARC64
1222
                if (!supervisor(dc))
1223
                    goto priv_insn;
1224
                tcg_gen_helper_1_0(helper_rdpsr, cpu_T[0]);
1225
#else
1226
                if (!hypervisor(dc))
1227
                    goto priv_insn;
1228
                rs1 = GET_FIELD(insn, 13, 17);
1229
                switch (rs1) {
1230
                case 0: // hpstate
1231
                    // gen_op_rdhpstate();
1232
                    break;
1233
                case 1: // htstate
1234
                    // gen_op_rdhtstate();
1235
                    break;
1236
                case 3: // hintp
1237
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, hintp));
1238
                    break;
1239
                case 5: // htba
1240
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, htba));
1241
                    break;
1242
                case 6: // hver
1243
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, hver));
1244
                    break;
1245
                case 31: // hstick_cmpr
1246
                    gen_op_movl_env_T0(offsetof(CPUSPARCState, hstick_cmpr));
1247
                    break;
1248
                default:
1249
                    goto illegal_insn;
1250
                }
1251
#endif
1252
                gen_movl_T0_reg(rd);
1253
                break;
1254
            } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
1255
                if (!supervisor(dc))
1256
                    goto priv_insn;
1257
#ifdef TARGET_SPARC64
1258
                rs1 = GET_FIELD(insn, 13, 17);
1259
                switch (rs1) {
1260
                case 0: // tpc
1261
                    gen_op_rdtpc();
1262
                    break;
1263
                case 1: // tnpc
1264
                    gen_op_rdtnpc();
1265
                    break;
1266
                case 2: // tstate
1267
                    gen_op_rdtstate();
1268
                    break;
1269
                case 3: // tt
1270
                    gen_op_rdtt();
1271
                    break;
1272
                case 4: // tick
1273
                    gen_op_rdtick();
1274
                    break;
1275
                case 5: // tba
1276
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
1277
                    break;
1278
                case 6: // pstate
1279
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, pstate));
1280
                    break;
1281
                case 7: // tl
1282
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, tl));
1283
                    break;
1284
                case 8: // pil
1285
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, psrpil));
1286
                    break;
1287
                case 9: // cwp
1288
                    gen_op_rdcwp();
1289
                    break;
1290
                case 10: // cansave
1291
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, cansave));
1292
                    break;
1293
                case 11: // canrestore
1294
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, canrestore));
1295
                    break;
1296
                case 12: // cleanwin
1297
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, cleanwin));
1298
                    break;
1299
                case 13: // otherwin
1300
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, otherwin));
1301
                    break;
1302
                case 14: // wstate
1303
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, wstate));
1304
                    break;
1305
                case 16: // UA2005 gl
1306
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, gl));
1307
                    break;
1308
                case 26: // UA2005 strand status
1309
                    if (!hypervisor(dc))
1310
                        goto priv_insn;
1311
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, ssr));
1312
                    break;
1313
                case 31: // ver
1314
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, version));
1315
                    break;
1316
                case 15: // fq
1317
                default:
1318
                    goto illegal_insn;
1319
                }
1320
#else
1321
                gen_op_movl_T0_env(offsetof(CPUSPARCState, wim));
1322
#endif
1323
                gen_movl_T0_reg(rd);
1324
                break;
1325
            } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
1326
#ifdef TARGET_SPARC64
1327
                gen_op_flushw();
1328
#else
1329
                if (!supervisor(dc))
1330
                    goto priv_insn;
1331
                gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
1332
                gen_movl_T0_reg(rd);
1333
#endif
1334
                break;
1335
#endif
1336
            } else if (xop == 0x34) {   /* FPU Operations */
1337
                if (gen_trap_ifnofpu(dc))
1338
                    goto jmp_insn;
1339
                gen_op_clear_ieee_excp_and_FTT();
1340
                rs1 = GET_FIELD(insn, 13, 17);
1341
                rs2 = GET_FIELD(insn, 27, 31);
1342
                xop = GET_FIELD(insn, 18, 26);
1343
                switch (xop) {
1344
                    case 0x1: /* fmovs */
1345
                        gen_op_load_fpr_FT0(rs2);
1346
                        gen_op_store_FT0_fpr(rd);
1347
                        break;
1348
                    case 0x5: /* fnegs */
1349
                        gen_op_load_fpr_FT1(rs2);
1350
                        gen_op_fnegs();
1351
                        gen_op_store_FT0_fpr(rd);
1352
                        break;
1353
                    case 0x9: /* fabss */
1354
                        gen_op_load_fpr_FT1(rs2);
1355
                        gen_op_fabss();
1356
                        gen_op_store_FT0_fpr(rd);
1357
                        break;
1358
                    case 0x29: /* fsqrts */
1359
                        gen_op_load_fpr_FT1(rs2);
1360
                        gen_op_fsqrts();
1361
                        gen_op_store_FT0_fpr(rd);
1362
                        break;
1363
                    case 0x2a: /* fsqrtd */
1364
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1365
                        gen_op_fsqrtd();
1366
                        gen_op_store_DT0_fpr(DFPREG(rd));
1367
                        break;
1368
                    case 0x2b: /* fsqrtq */
1369
#if defined(CONFIG_USER_ONLY)
1370
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1371
                        gen_op_fsqrtq();
1372
                        gen_op_store_QT0_fpr(QFPREG(rd));
1373
                        break;
1374
#else
1375
                        goto nfpu_insn;
1376
#endif
1377
                    case 0x41:
1378
                        gen_op_load_fpr_FT0(rs1);
1379
                        gen_op_load_fpr_FT1(rs2);
1380
                        gen_op_fadds();
1381
                        gen_op_store_FT0_fpr(rd);
1382
                        break;
1383
                    case 0x42:
1384
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1385
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1386
                        gen_op_faddd();
1387
                        gen_op_store_DT0_fpr(DFPREG(rd));
1388
                        break;
1389
                    case 0x43: /* faddq */
1390
#if defined(CONFIG_USER_ONLY)
1391
                        gen_op_load_fpr_QT0(QFPREG(rs1));
1392
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1393
                        gen_op_faddq();
1394
                        gen_op_store_QT0_fpr(QFPREG(rd));
1395
                        break;
1396
#else
1397
                        goto nfpu_insn;
1398
#endif
1399
                    case 0x45:
1400
                        gen_op_load_fpr_FT0(rs1);
1401
                        gen_op_load_fpr_FT1(rs2);
1402
                        gen_op_fsubs();
1403
                        gen_op_store_FT0_fpr(rd);
1404
                        break;
1405
                    case 0x46:
1406
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1407
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1408
                        gen_op_fsubd();
1409
                        gen_op_store_DT0_fpr(DFPREG(rd));
1410
                        break;
1411
                    case 0x47: /* fsubq */
1412
#if defined(CONFIG_USER_ONLY)
1413
                        gen_op_load_fpr_QT0(QFPREG(rs1));
1414
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1415
                        gen_op_fsubq();
1416
                        gen_op_store_QT0_fpr(QFPREG(rd));
1417
                        break;
1418
#else
1419
                        goto nfpu_insn;
1420
#endif
1421
                    case 0x49:
1422
                        gen_op_load_fpr_FT0(rs1);
1423
                        gen_op_load_fpr_FT1(rs2);
1424
                        gen_op_fmuls();
1425
                        gen_op_store_FT0_fpr(rd);
1426
                        break;
1427
                    case 0x4a:
1428
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1429
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1430
                        gen_op_fmuld();
1431
                        gen_op_store_DT0_fpr(DFPREG(rd));
1432
                        break;
1433
                    case 0x4b: /* fmulq */
1434
#if defined(CONFIG_USER_ONLY)
1435
                        gen_op_load_fpr_QT0(QFPREG(rs1));
1436
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1437
                        gen_op_fmulq();
1438
                        gen_op_store_QT0_fpr(QFPREG(rd));
1439
                        break;
1440
#else
1441
                        goto nfpu_insn;
1442
#endif
1443
                    case 0x4d:
1444
                        gen_op_load_fpr_FT0(rs1);
1445
                        gen_op_load_fpr_FT1(rs2);
1446
                        gen_op_fdivs();
1447
                        gen_op_store_FT0_fpr(rd);
1448
                        break;
1449
                    case 0x4e:
1450
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1451
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1452
                        gen_op_fdivd();
1453
                        gen_op_store_DT0_fpr(DFPREG(rd));
1454
                        break;
1455
                    case 0x4f: /* fdivq */
1456
#if defined(CONFIG_USER_ONLY)
1457
                        gen_op_load_fpr_QT0(QFPREG(rs1));
1458
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1459
                        gen_op_fdivq();
1460
                        gen_op_store_QT0_fpr(QFPREG(rd));
1461
                        break;
1462
#else
1463
                        goto nfpu_insn;
1464
#endif
1465
                    case 0x69:
1466
                        gen_op_load_fpr_FT0(rs1);
1467
                        gen_op_load_fpr_FT1(rs2);
1468
                        gen_op_fsmuld();
1469
                        gen_op_store_DT0_fpr(DFPREG(rd));
1470
                        break;
1471
                    case 0x6e: /* fdmulq */
1472
#if defined(CONFIG_USER_ONLY)
1473
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1474
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1475
                        gen_op_fdmulq();
1476
                        gen_op_store_QT0_fpr(QFPREG(rd));
1477
                        break;
1478
#else
1479
                        goto nfpu_insn;
1480
#endif
1481
                    case 0xc4:
1482
                        gen_op_load_fpr_FT1(rs2);
1483
                        gen_op_fitos();
1484
                        gen_op_store_FT0_fpr(rd);
1485
                        break;
1486
                    case 0xc6:
1487
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1488
                        gen_op_fdtos();
1489
                        gen_op_store_FT0_fpr(rd);
1490
                        break;
1491
                    case 0xc7: /* fqtos */
1492
#if defined(CONFIG_USER_ONLY)
1493
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1494
                        gen_op_fqtos();
1495
                        gen_op_store_FT0_fpr(rd);
1496
                        break;
1497
#else
1498
                        goto nfpu_insn;
1499
#endif
1500
                    case 0xc8:
1501
                        gen_op_load_fpr_FT1(rs2);
1502
                        gen_op_fitod();
1503
                        gen_op_store_DT0_fpr(DFPREG(rd));
1504
                        break;
1505
                    case 0xc9:
1506
                        gen_op_load_fpr_FT1(rs2);
1507
                        gen_op_fstod();
1508
                        gen_op_store_DT0_fpr(DFPREG(rd));
1509
                        break;
1510
                    case 0xcb: /* fqtod */
1511
#if defined(CONFIG_USER_ONLY)
1512
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1513
                        gen_op_fqtod();
1514
                        gen_op_store_DT0_fpr(DFPREG(rd));
1515
                        break;
1516
#else
1517
                        goto nfpu_insn;
1518
#endif
1519
                    case 0xcc: /* fitoq */
1520
#if defined(CONFIG_USER_ONLY)
1521
                        gen_op_load_fpr_FT1(rs2);
1522
                        gen_op_fitoq();
1523
                        gen_op_store_QT0_fpr(QFPREG(rd));
1524
                        break;
1525
#else
1526
                        goto nfpu_insn;
1527
#endif
1528
                    case 0xcd: /* fstoq */
1529
#if defined(CONFIG_USER_ONLY)
1530
                        gen_op_load_fpr_FT1(rs2);
1531
                        gen_op_fstoq();
1532
                        gen_op_store_QT0_fpr(QFPREG(rd));
1533
                        break;
1534
#else
1535
                        goto nfpu_insn;
1536
#endif
1537
                    case 0xce: /* fdtoq */
1538
#if defined(CONFIG_USER_ONLY)
1539
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1540
                        gen_op_fdtoq();
1541
                        gen_op_store_QT0_fpr(QFPREG(rd));
1542
                        break;
1543
#else
1544
                        goto nfpu_insn;
1545
#endif
1546
                    case 0xd1:
1547
                        gen_op_load_fpr_FT1(rs2);
1548
                        gen_op_fstoi();
1549
                        gen_op_store_FT0_fpr(rd);
1550
                        break;
1551
                    case 0xd2:
1552
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1553
                        gen_op_fdtoi();
1554
                        gen_op_store_FT0_fpr(rd);
1555
                        break;
1556
                    case 0xd3: /* fqtoi */
1557
#if defined(CONFIG_USER_ONLY)
1558
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1559
                        gen_op_fqtoi();
1560
                        gen_op_store_FT0_fpr(rd);
1561
                        break;
1562
#else
1563
                        goto nfpu_insn;
1564
#endif
1565
#ifdef TARGET_SPARC64
1566
                    case 0x2: /* V9 fmovd */
1567
                        gen_op_load_fpr_DT0(DFPREG(rs2));
1568
                        gen_op_store_DT0_fpr(DFPREG(rd));
1569
                        break;
1570
                    case 0x3: /* V9 fmovq */
1571
#if defined(CONFIG_USER_ONLY)
1572
                        gen_op_load_fpr_QT0(QFPREG(rs2));
1573
                        gen_op_store_QT0_fpr(QFPREG(rd));
1574
                        break;
1575
#else
1576
                        goto nfpu_insn;
1577
#endif
1578
                    case 0x6: /* V9 fnegd */
1579
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1580
                        gen_op_fnegd();
1581
                        gen_op_store_DT0_fpr(DFPREG(rd));
1582
                        break;
1583
                    case 0x7: /* V9 fnegq */
1584
#if defined(CONFIG_USER_ONLY)
1585
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1586
                        gen_op_fnegq();
1587
                        gen_op_store_QT0_fpr(QFPREG(rd));
1588
                        break;
1589
#else
1590
                        goto nfpu_insn;
1591
#endif
1592
                    case 0xa: /* V9 fabsd */
1593
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1594
                        gen_op_fabsd();
1595
                        gen_op_store_DT0_fpr(DFPREG(rd));
1596
                        break;
1597
                    case 0xb: /* V9 fabsq */
1598
#if defined(CONFIG_USER_ONLY)
1599
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1600
                        gen_op_fabsq();
1601
                        gen_op_store_QT0_fpr(QFPREG(rd));
1602
                        break;
1603
#else
1604
                        goto nfpu_insn;
1605
#endif
1606
                    case 0x81: /* V9 fstox */
1607
                        gen_op_load_fpr_FT1(rs2);
1608
                        gen_op_fstox();
1609
                        gen_op_store_DT0_fpr(DFPREG(rd));
1610
                        break;
1611
                    case 0x82: /* V9 fdtox */
1612
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1613
                        gen_op_fdtox();
1614
                        gen_op_store_DT0_fpr(DFPREG(rd));
1615
                        break;
1616
                    case 0x83: /* V9 fqtox */
1617
#if defined(CONFIG_USER_ONLY)
1618
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1619
                        gen_op_fqtox();
1620
                        gen_op_store_DT0_fpr(DFPREG(rd));
1621
                        break;
1622
#else
1623
                        goto nfpu_insn;
1624
#endif
1625
                    case 0x84: /* V9 fxtos */
1626
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1627
                        gen_op_fxtos();
1628
                        gen_op_store_FT0_fpr(rd);
1629
                        break;
1630
                    case 0x88: /* V9 fxtod */
1631
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1632
                        gen_op_fxtod();
1633
                        gen_op_store_DT0_fpr(DFPREG(rd));
1634
                        break;
1635
                    case 0x8c: /* V9 fxtoq */
1636
#if defined(CONFIG_USER_ONLY)
1637
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1638
                        gen_op_fxtoq();
1639
                        gen_op_store_QT0_fpr(QFPREG(rd));
1640
                        break;
1641
#else
1642
                        goto nfpu_insn;
1643
#endif
1644
#endif
1645
                    default:
1646
                        goto illegal_insn;
1647
                }
1648
            } else if (xop == 0x35) {   /* FPU Operations */
1649
#ifdef TARGET_SPARC64
1650
                int cond;
1651
#endif
1652
                if (gen_trap_ifnofpu(dc))
1653
                    goto jmp_insn;
1654
                gen_op_clear_ieee_excp_and_FTT();
1655
                rs1 = GET_FIELD(insn, 13, 17);
1656
                rs2 = GET_FIELD(insn, 27, 31);
1657
                xop = GET_FIELD(insn, 18, 26);
1658
#ifdef TARGET_SPARC64
1659
                if ((xop & 0x11f) == 0x005) { // V9 fmovsr
1660
                    cond = GET_FIELD_SP(insn, 14, 17);
1661
                    gen_op_load_fpr_FT0(rd);
1662
                    gen_op_load_fpr_FT1(rs2);
1663
                    rs1 = GET_FIELD(insn, 13, 17);
1664
                    gen_movl_reg_T0(rs1);
1665
                    flush_T2(dc);
1666
                    gen_cond_reg(cond);
1667
                    gen_op_fmovs_cc();
1668
                    gen_op_store_FT0_fpr(rd);
1669
                    break;
1670
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
1671
                    cond = GET_FIELD_SP(insn, 14, 17);
1672
                    gen_op_load_fpr_DT0(DFPREG(rd));
1673
                    gen_op_load_fpr_DT1(DFPREG(rs2));
1674
                    flush_T2(dc);
1675
                    rs1 = GET_FIELD(insn, 13, 17);
1676
                    gen_movl_reg_T0(rs1);
1677
                    gen_cond_reg(cond);
1678
                    gen_op_fmovs_cc();
1679
                    gen_op_store_DT0_fpr(DFPREG(rd));
1680
                    break;
1681
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
1682
#if defined(CONFIG_USER_ONLY)
1683
                    cond = GET_FIELD_SP(insn, 14, 17);
1684
                    gen_op_load_fpr_QT0(QFPREG(rd));
1685
                    gen_op_load_fpr_QT1(QFPREG(rs2));
1686
                    flush_T2(dc);
1687
                    rs1 = GET_FIELD(insn, 13, 17);
1688
                    gen_movl_reg_T0(rs1);
1689
                    gen_cond_reg(cond);
1690
                    gen_op_fmovq_cc();
1691
                    gen_op_store_QT0_fpr(QFPREG(rd));
1692
                    break;
1693
#else
1694
                    goto nfpu_insn;
1695
#endif
1696
                }
1697
#endif
1698
                switch (xop) {
1699
#ifdef TARGET_SPARC64
1700
                    case 0x001: /* V9 fmovscc %fcc0 */
1701
                        cond = GET_FIELD_SP(insn, 14, 17);
1702
                        gen_op_load_fpr_FT0(rd);
1703
                        gen_op_load_fpr_FT1(rs2);
1704
                        flush_T2(dc);
1705
                        gen_fcond[0][cond]();
1706
                        gen_op_fmovs_cc();
1707
                        gen_op_store_FT0_fpr(rd);
1708
                        break;
1709
                    case 0x002: /* V9 fmovdcc %fcc0 */
1710
                        cond = GET_FIELD_SP(insn, 14, 17);
1711
                        gen_op_load_fpr_DT0(DFPREG(rd));
1712
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1713
                        flush_T2(dc);
1714
                        gen_fcond[0][cond]();
1715
                        gen_op_fmovd_cc();
1716
                        gen_op_store_DT0_fpr(DFPREG(rd));
1717
                        break;
1718
                    case 0x003: /* V9 fmovqcc %fcc0 */
1719
#if defined(CONFIG_USER_ONLY)
1720
                        cond = GET_FIELD_SP(insn, 14, 17);
1721
                        gen_op_load_fpr_QT0(QFPREG(rd));
1722
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1723
                        flush_T2(dc);
1724
                        gen_fcond[0][cond]();
1725
                        gen_op_fmovq_cc();
1726
                        gen_op_store_QT0_fpr(QFPREG(rd));
1727
                        break;
1728
#else
1729
                        goto nfpu_insn;
1730
#endif
1731
                    case 0x041: /* V9 fmovscc %fcc1 */
1732
                        cond = GET_FIELD_SP(insn, 14, 17);
1733
                        gen_op_load_fpr_FT0(rd);
1734
                        gen_op_load_fpr_FT1(rs2);
1735
                        flush_T2(dc);
1736
                        gen_fcond[1][cond]();
1737
                        gen_op_fmovs_cc();
1738
                        gen_op_store_FT0_fpr(rd);
1739
                        break;
1740
                    case 0x042: /* V9 fmovdcc %fcc1 */
1741
                        cond = GET_FIELD_SP(insn, 14, 17);
1742
                        gen_op_load_fpr_DT0(DFPREG(rd));
1743
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1744
                        flush_T2(dc);
1745
                        gen_fcond[1][cond]();
1746
                        gen_op_fmovd_cc();
1747
                        gen_op_store_DT0_fpr(DFPREG(rd));
1748
                        break;
1749
                    case 0x043: /* V9 fmovqcc %fcc1 */
1750
#if defined(CONFIG_USER_ONLY)
1751
                        cond = GET_FIELD_SP(insn, 14, 17);
1752
                        gen_op_load_fpr_QT0(QFPREG(rd));
1753
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1754
                        flush_T2(dc);
1755
                        gen_fcond[1][cond]();
1756
                        gen_op_fmovq_cc();
1757
                        gen_op_store_QT0_fpr(QFPREG(rd));
1758
                        break;
1759
#else
1760
                        goto nfpu_insn;
1761
#endif
1762
                    case 0x081: /* V9 fmovscc %fcc2 */
1763
                        cond = GET_FIELD_SP(insn, 14, 17);
1764
                        gen_op_load_fpr_FT0(rd);
1765
                        gen_op_load_fpr_FT1(rs2);
1766
                        flush_T2(dc);
1767
                        gen_fcond[2][cond]();
1768
                        gen_op_fmovs_cc();
1769
                        gen_op_store_FT0_fpr(rd);
1770
                        break;
1771
                    case 0x082: /* V9 fmovdcc %fcc2 */
1772
                        cond = GET_FIELD_SP(insn, 14, 17);
1773
                        gen_op_load_fpr_DT0(DFPREG(rd));
1774
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1775
                        flush_T2(dc);
1776
                        gen_fcond[2][cond]();
1777
                        gen_op_fmovd_cc();
1778
                        gen_op_store_DT0_fpr(DFPREG(rd));
1779
                        break;
1780
                    case 0x083: /* V9 fmovqcc %fcc2 */
1781
#if defined(CONFIG_USER_ONLY)
1782
                        cond = GET_FIELD_SP(insn, 14, 17);
1783
                        gen_op_load_fpr_QT0(rd);
1784
                        gen_op_load_fpr_QT1(rs2);
1785
                        flush_T2(dc);
1786
                        gen_fcond[2][cond]();
1787
                        gen_op_fmovq_cc();
1788
                        gen_op_store_QT0_fpr(rd);
1789
                        break;
1790
#else
1791
                        goto nfpu_insn;
1792
#endif
1793
                    case 0x0c1: /* V9 fmovscc %fcc3 */
1794
                        cond = GET_FIELD_SP(insn, 14, 17);
1795
                        gen_op_load_fpr_FT0(rd);
1796
                        gen_op_load_fpr_FT1(rs2);
1797
                        flush_T2(dc);
1798
                        gen_fcond[3][cond]();
1799
                        gen_op_fmovs_cc();
1800
                        gen_op_store_FT0_fpr(rd);
1801
                        break;
1802
                    case 0x0c2: /* V9 fmovdcc %fcc3 */
1803
                        cond = GET_FIELD_SP(insn, 14, 17);
1804
                        gen_op_load_fpr_DT0(DFPREG(rd));
1805
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1806
                        flush_T2(dc);
1807
                        gen_fcond[3][cond]();
1808
                        gen_op_fmovd_cc();
1809
                        gen_op_store_DT0_fpr(DFPREG(rd));
1810
                        break;
1811
                    case 0x0c3: /* V9 fmovqcc %fcc3 */
1812
#if defined(CONFIG_USER_ONLY)
1813
                        cond = GET_FIELD_SP(insn, 14, 17);
1814
                        gen_op_load_fpr_QT0(QFPREG(rd));
1815
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1816
                        flush_T2(dc);
1817
                        gen_fcond[3][cond]();
1818
                        gen_op_fmovq_cc();
1819
                        gen_op_store_QT0_fpr(QFPREG(rd));
1820
                        break;
1821
#else
1822
                        goto nfpu_insn;
1823
#endif
1824
                    case 0x101: /* V9 fmovscc %icc */
1825
                        cond = GET_FIELD_SP(insn, 14, 17);
1826
                        gen_op_load_fpr_FT0(rd);
1827
                        gen_op_load_fpr_FT1(rs2);
1828
                        flush_T2(dc);
1829
                        gen_cond[0][cond]();
1830
                        gen_op_fmovs_cc();
1831
                        gen_op_store_FT0_fpr(rd);
1832
                        break;
1833
                    case 0x102: /* V9 fmovdcc %icc */
1834
                        cond = GET_FIELD_SP(insn, 14, 17);
1835
                        gen_op_load_fpr_DT0(DFPREG(rd));
1836
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1837
                        flush_T2(dc);
1838
                        gen_cond[0][cond]();
1839
                        gen_op_fmovd_cc();
1840
                        gen_op_store_DT0_fpr(DFPREG(rd));
1841
                        break;
1842
                    case 0x103: /* V9 fmovqcc %icc */
1843
#if defined(CONFIG_USER_ONLY)
1844
                        cond = GET_FIELD_SP(insn, 14, 17);
1845
                        gen_op_load_fpr_QT0(rd);
1846
                        gen_op_load_fpr_QT1(rs2);
1847
                        flush_T2(dc);
1848
                        gen_cond[0][cond]();
1849
                        gen_op_fmovq_cc();
1850
                        gen_op_store_QT0_fpr(rd);
1851
                        break;
1852
#else
1853
                        goto nfpu_insn;
1854
#endif
1855
                    case 0x181: /* V9 fmovscc %xcc */
1856
                        cond = GET_FIELD_SP(insn, 14, 17);
1857
                        gen_op_load_fpr_FT0(rd);
1858
                        gen_op_load_fpr_FT1(rs2);
1859
                        flush_T2(dc);
1860
                        gen_cond[1][cond]();
1861
                        gen_op_fmovs_cc();
1862
                        gen_op_store_FT0_fpr(rd);
1863
                        break;
1864
                    case 0x182: /* V9 fmovdcc %xcc */
1865
                        cond = GET_FIELD_SP(insn, 14, 17);
1866
                        gen_op_load_fpr_DT0(DFPREG(rd));
1867
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1868
                        flush_T2(dc);
1869
                        gen_cond[1][cond]();
1870
                        gen_op_fmovd_cc();
1871
                        gen_op_store_DT0_fpr(DFPREG(rd));
1872
                        break;
1873
                    case 0x183: /* V9 fmovqcc %xcc */
1874
#if defined(CONFIG_USER_ONLY)
1875
                        cond = GET_FIELD_SP(insn, 14, 17);
1876
                        gen_op_load_fpr_QT0(rd);
1877
                        gen_op_load_fpr_QT1(rs2);
1878
                        flush_T2(dc);
1879
                        gen_cond[1][cond]();
1880
                        gen_op_fmovq_cc();
1881
                        gen_op_store_QT0_fpr(rd);
1882
                        break;
1883
#else
1884
                        goto nfpu_insn;
1885
#endif
1886
#endif
1887
                    case 0x51: /* fcmps, V9 %fcc */
1888
                        gen_op_load_fpr_FT0(rs1);
1889
                        gen_op_load_fpr_FT1(rs2);
1890
#ifdef TARGET_SPARC64
1891
                        gen_fcmps[rd & 3]();
1892
#else
1893
                        gen_op_fcmps();
1894
#endif
1895
                        break;
1896
                    case 0x52: /* fcmpd, V9 %fcc */
1897
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1898
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1899
#ifdef TARGET_SPARC64
1900
                        gen_fcmpd[rd & 3]();
1901
#else
1902
                        gen_op_fcmpd();
1903
#endif
1904
                        break;
1905
                    case 0x53: /* fcmpq, V9 %fcc */
1906
#if defined(CONFIG_USER_ONLY)
1907
                        gen_op_load_fpr_QT0(QFPREG(rs1));
1908
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1909
#ifdef TARGET_SPARC64
1910
                        gen_fcmpq[rd & 3]();
1911
#else
1912
                        gen_op_fcmpq();
1913
#endif
1914
                        break;
1915
#else /* !defined(CONFIG_USER_ONLY) */
1916
                        goto nfpu_insn;
1917
#endif
1918
                    case 0x55: /* fcmpes, V9 %fcc */
1919
                        gen_op_load_fpr_FT0(rs1);
1920
                        gen_op_load_fpr_FT1(rs2);
1921
#ifdef TARGET_SPARC64
1922
                        gen_fcmpes[rd & 3]();
1923
#else
1924
                        gen_op_fcmpes();
1925
#endif
1926
                        break;
1927
                    case 0x56: /* fcmped, V9 %fcc */
1928
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1929
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1930
#ifdef TARGET_SPARC64
1931
                        gen_fcmped[rd & 3]();
1932
#else
1933
                        gen_op_fcmped();
1934
#endif
1935
                        break;
1936
                    case 0x57: /* fcmpeq, V9 %fcc */
1937
#if defined(CONFIG_USER_ONLY)
1938
                        gen_op_load_fpr_QT0(QFPREG(rs1));
1939
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1940
#ifdef TARGET_SPARC64
1941
                        gen_fcmpeq[rd & 3]();
1942
#else
1943
                        gen_op_fcmpeq();
1944
#endif
1945
                        break;
1946
#else/* !defined(CONFIG_USER_ONLY) */
1947
                        goto nfpu_insn;
1948
#endif
1949
                    default:
1950
                        goto illegal_insn;
1951
                }
1952
#if defined(OPTIM)
1953
            } else if (xop == 0x2) {
1954
                // clr/mov shortcut
1955

    
1956
                rs1 = GET_FIELD(insn, 13, 17);
1957
                if (rs1 == 0) {
1958
                    // or %g0, x, y -> mov T0, x; mov y, T0
1959
                    if (IS_IMM) {       /* immediate */
1960
                        rs2 = GET_FIELDs(insn, 19, 31);
1961
                        tcg_gen_movi_tl(cpu_T[0], (int)rs2);
1962
                    } else {            /* register */
1963
                        rs2 = GET_FIELD(insn, 27, 31);
1964
                        gen_movl_reg_T0(rs2);
1965
                    }
1966
                } else {
1967
                    gen_movl_reg_T0(rs1);
1968
                    if (IS_IMM) {       /* immediate */
1969
                        rs2 = GET_FIELDs(insn, 19, 31);
1970
                        tcg_gen_ori_tl(cpu_T[0], cpu_T[0], (int)rs2);
1971
                    } else {            /* register */
1972
                        // or x, %g0, y -> mov T1, x; mov y, T1
1973
                        rs2 = GET_FIELD(insn, 27, 31);
1974
                        if (rs2 != 0) {
1975
                            gen_movl_reg_T1(rs2);
1976
                            gen_op_or_T1_T0();
1977
                        }
1978
                    }
1979
                }
1980
                gen_movl_T0_reg(rd);
1981
#endif
1982
#ifdef TARGET_SPARC64
1983
            } else if (xop == 0x25) { /* sll, V9 sllx */
1984
                rs1 = GET_FIELD(insn, 13, 17);
1985
                gen_movl_reg_T0(rs1);
1986
                if (IS_IMM) {   /* immediate */
1987
                    rs2 = GET_FIELDs(insn, 20, 31);
1988
                    if (insn & (1 << 12)) {
1989
                        tcg_gen_shli_i64(cpu_T[0], cpu_T[0], rs2 & 0x3f);
1990
                    } else {
1991
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
1992
                        tcg_gen_shli_i64(cpu_T[0], cpu_T[0], rs2 & 0x1f);
1993
                    }
1994
                } else {                /* register */
1995
                    rs2 = GET_FIELD(insn, 27, 31);
1996
                    gen_movl_reg_T1(rs2);
1997
                    if (insn & (1 << 12)) {
1998
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x3f);
1999
                        tcg_gen_shl_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2000
                    } else {
2001
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x1f);
2002
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
2003
                        tcg_gen_shl_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2004
                    }
2005
                }
2006
                gen_movl_T0_reg(rd);
2007
            } else if (xop == 0x26) { /* srl, V9 srlx */
2008
                rs1 = GET_FIELD(insn, 13, 17);
2009
                gen_movl_reg_T0(rs1);
2010
                if (IS_IMM) {   /* immediate */
2011
                    rs2 = GET_FIELDs(insn, 20, 31);
2012
                    if (insn & (1 << 12)) {
2013
                        tcg_gen_shri_i64(cpu_T[0], cpu_T[0], rs2 & 0x3f);
2014
                    } else {
2015
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
2016
                        tcg_gen_shri_i64(cpu_T[0], cpu_T[0], rs2 & 0x1f);
2017
                    }
2018
                } else {                /* register */
2019
                    rs2 = GET_FIELD(insn, 27, 31);
2020
                    gen_movl_reg_T1(rs2);
2021
                    if (insn & (1 << 12)) {
2022
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x3f);
2023
                        tcg_gen_shr_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2024
                    } else {
2025
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x1f);
2026
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
2027
                        tcg_gen_shr_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2028
                    }
2029
                }
2030
                gen_movl_T0_reg(rd);
2031
            } else if (xop == 0x27) { /* sra, V9 srax */
2032
                rs1 = GET_FIELD(insn, 13, 17);
2033
                gen_movl_reg_T0(rs1);
2034
                if (IS_IMM) {   /* immediate */
2035
                    rs2 = GET_FIELDs(insn, 20, 31);
2036
                    if (insn & (1 << 12)) {
2037
                        tcg_gen_sari_i64(cpu_T[0], cpu_T[0], rs2 & 0x3f);
2038
                    } else {
2039
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
2040
                        tcg_gen_ext_i32_i64(cpu_T[0], cpu_T[0]);
2041
                        tcg_gen_sari_i64(cpu_T[0], cpu_T[0], rs2 & 0x1f);
2042
                    }
2043
                } else {                /* register */
2044
                    rs2 = GET_FIELD(insn, 27, 31);
2045
                    gen_movl_reg_T1(rs2);
2046
                    if (insn & (1 << 12)) {
2047
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x3f);
2048
                        tcg_gen_sar_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2049
                    } else {
2050
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x1f);
2051
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
2052
                        tcg_gen_sar_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2053
                    }
2054
                }
2055
                gen_movl_T0_reg(rd);
2056
#endif
2057
            } else if (xop < 0x36) {
2058
                rs1 = GET_FIELD(insn, 13, 17);
2059
                gen_movl_reg_T0(rs1);
2060
                if (IS_IMM) {   /* immediate */
2061
                    rs2 = GET_FIELDs(insn, 19, 31);
2062
                    gen_movl_simm_T1(rs2);
2063
                } else {                /* register */
2064
                    rs2 = GET_FIELD(insn, 27, 31);
2065
                    gen_movl_reg_T1(rs2);
2066
                }
2067
                if (xop < 0x20) {
2068
                    switch (xop & ~0x10) {
2069
                    case 0x0:
2070
                        if (xop & 0x10)
2071
                            gen_op_add_T1_T0_cc();
2072
                        else
2073
                            gen_op_add_T1_T0();
2074
                        break;
2075
                    case 0x1:
2076
                        tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2077
                        if (xop & 0x10)
2078
                            gen_op_logic_T0_cc();
2079
                        break;
2080
                    case 0x2:
2081
                        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2082
                        if (xop & 0x10)
2083
                            gen_op_logic_T0_cc();
2084
                        break;
2085
                    case 0x3:
2086
                        tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2087
                        if (xop & 0x10)
2088
                            gen_op_logic_T0_cc();
2089
                        break;
2090
                    case 0x4:
2091
                        if (xop & 0x10)
2092
                            gen_op_sub_T1_T0_cc();
2093
                        else
2094
                            tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2095
                        break;
2096
                    case 0x5:
2097
                        gen_op_andn_T1_T0();
2098
                        if (xop & 0x10)
2099
                            gen_op_logic_T0_cc();
2100
                        break;
2101
                    case 0x6:
2102
                        gen_op_orn_T1_T0();
2103
                        if (xop & 0x10)
2104
                            gen_op_logic_T0_cc();
2105
                        break;
2106
                    case 0x7:
2107
                        gen_op_xnor_T1_T0();
2108
                        if (xop & 0x10)
2109
                            gen_op_logic_T0_cc();
2110
                        break;
2111
                    case 0x8:
2112
                        if (xop & 0x10)
2113
                            gen_op_addx_T1_T0_cc();
2114
                        else
2115
                            gen_op_addx_T1_T0();
2116
                        break;
2117
#ifdef TARGET_SPARC64
2118
                    case 0x9: /* V9 mulx */
2119
                        tcg_gen_mul_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2120
                        break;
2121
#endif
2122
                    case 0xa:
2123
                        gen_op_umul_T1_T0();
2124
                        if (xop & 0x10)
2125
                            gen_op_logic_T0_cc();
2126
                        break;
2127
                    case 0xb:
2128
                        gen_op_smul_T1_T0();
2129
                        if (xop & 0x10)
2130
                            gen_op_logic_T0_cc();
2131
                        break;
2132
                    case 0xc:
2133
                        if (xop & 0x10)
2134
                            gen_op_subx_T1_T0_cc();
2135
                        else
2136
                            gen_op_subx_T1_T0();
2137
                        break;
2138
#ifdef TARGET_SPARC64
2139
                    case 0xd: /* V9 udivx */
2140
                        gen_op_udivx_T1_T0();
2141
                        break;
2142
#endif
2143
                    case 0xe:
2144
                        gen_op_udiv_T1_T0();
2145
                        if (xop & 0x10)
2146
                            gen_op_div_cc();
2147
                        break;
2148
                    case 0xf:
2149
                        gen_op_sdiv_T1_T0();
2150
                        if (xop & 0x10)
2151
                            gen_op_div_cc();
2152
                        break;
2153
                    default:
2154
                        goto illegal_insn;
2155
                    }
2156
                    gen_movl_T0_reg(rd);
2157
                } else {
2158
                    switch (xop) {
2159
                    case 0x20: /* taddcc */
2160
                        gen_op_tadd_T1_T0_cc();
2161
                        gen_movl_T0_reg(rd);
2162
                        break;
2163
                    case 0x21: /* tsubcc */
2164
                        gen_op_tsub_T1_T0_cc();
2165
                        gen_movl_T0_reg(rd);
2166
                        break;
2167
                    case 0x22: /* taddcctv */
2168
                        save_state(dc);
2169
                        gen_op_tadd_T1_T0_ccTV();
2170
                        gen_movl_T0_reg(rd);
2171
                        break;
2172
                    case 0x23: /* tsubcctv */
2173
                        save_state(dc);
2174
                        gen_op_tsub_T1_T0_ccTV();
2175
                        gen_movl_T0_reg(rd);
2176
                        break;
2177
                    case 0x24: /* mulscc */
2178
                        gen_op_mulscc_T1_T0();
2179
                        gen_movl_T0_reg(rd);
2180
                        break;
2181
#ifndef TARGET_SPARC64
2182
                    case 0x25:  /* sll */
2183
                        tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0x1f);
2184
                        tcg_gen_shl_i32(cpu_T[0], cpu_T[0], cpu_T[1]);
2185
                        gen_movl_T0_reg(rd);
2186
                        break;
2187
                    case 0x26:  /* srl */
2188
                        tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0x1f);
2189
                        tcg_gen_shr_i32(cpu_T[0], cpu_T[0], cpu_T[1]);
2190
                        gen_movl_T0_reg(rd);
2191
                        break;
2192
                    case 0x27:  /* sra */
2193
                        tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0x1f);
2194
                        tcg_gen_sar_i32(cpu_T[0], cpu_T[0], cpu_T[1]);
2195
                        gen_movl_T0_reg(rd);
2196
                        break;
2197
#endif
2198
                    case 0x30:
2199
                        {
2200
                            switch(rd) {
2201
                            case 0: /* wry */
2202
                                gen_op_xor_T1_T0();
2203
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, y));
2204
                                break;
2205
#ifndef TARGET_SPARC64
2206
                            case 0x01 ... 0x0f: /* undefined in the
2207
                                                   SPARCv8 manual, nop
2208
                                                   on the microSPARC
2209
                                                   II */
2210
                            case 0x10 ... 0x1f: /* implementation-dependent
2211
                                                   in the SPARCv8
2212
                                                   manual, nop on the
2213
                                                   microSPARC II */
2214
                                break;
2215
#else
2216
                            case 0x2: /* V9 wrccr */
2217
                                gen_op_xor_T1_T0();
2218
                                gen_op_wrccr();
2219
                                break;
2220
                            case 0x3: /* V9 wrasi */
2221
                                gen_op_xor_T1_T0();
2222
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, asi));
2223
                                break;
2224
                            case 0x6: /* V9 wrfprs */
2225
                                gen_op_xor_T1_T0();
2226
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, fprs));
2227
                                save_state(dc);
2228
                                gen_op_next_insn();
2229
                                tcg_gen_exit_tb(0);
2230
                                dc->is_br = 1;
2231
                                break;
2232
                            case 0xf: /* V9 sir, nop if user */
2233
#if !defined(CONFIG_USER_ONLY)
2234
                                if (supervisor(dc))
2235
                                    ; // XXX
2236
#endif
2237
                                break;
2238
                            case 0x13: /* Graphics Status */
2239
                                if (gen_trap_ifnofpu(dc))
2240
                                    goto jmp_insn;
2241
                                gen_op_xor_T1_T0();
2242
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, gsr));
2243
                                break;
2244
                            case 0x17: /* Tick compare */
2245
#if !defined(CONFIG_USER_ONLY)
2246
                                if (!supervisor(dc))
2247
                                    goto illegal_insn;
2248
#endif
2249
                                gen_op_xor_T1_T0();
2250
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, tick_cmpr));
2251
                                gen_op_wrtick_cmpr();
2252
                                break;
2253
                            case 0x18: /* System tick */
2254
#if !defined(CONFIG_USER_ONLY)
2255
                                if (!supervisor(dc))
2256
                                    goto illegal_insn;
2257
#endif
2258
                                gen_op_xor_T1_T0();
2259
                                gen_op_wrstick();
2260
                                break;
2261
                            case 0x19: /* System tick compare */
2262
#if !defined(CONFIG_USER_ONLY)
2263
                                if (!supervisor(dc))
2264
                                    goto illegal_insn;
2265
#endif
2266
                                gen_op_xor_T1_T0();
2267
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, stick_cmpr));
2268
                                gen_op_wrstick_cmpr();
2269
                                break;
2270

    
2271
                            case 0x10: /* Performance Control */
2272
                            case 0x11: /* Performance Instrumentation Counter */
2273
                            case 0x12: /* Dispatch Control */
2274
                            case 0x14: /* Softint set */
2275
                            case 0x15: /* Softint clear */
2276
                            case 0x16: /* Softint write */
2277
#endif
2278
                            default:
2279
                                goto illegal_insn;
2280
                            }
2281
                        }
2282
                        break;
2283
#if !defined(CONFIG_USER_ONLY)
2284
                    case 0x31: /* wrpsr, V9 saved, restored */
2285
                        {
2286
                            if (!supervisor(dc))
2287
                                goto priv_insn;
2288
#ifdef TARGET_SPARC64
2289
                            switch (rd) {
2290
                            case 0:
2291
                                gen_op_saved();
2292
                                break;
2293
                            case 1:
2294
                                gen_op_restored();
2295
                                break;
2296
                            case 2: /* UA2005 allclean */
2297
                            case 3: /* UA2005 otherw */
2298
                            case 4: /* UA2005 normalw */
2299
                            case 5: /* UA2005 invalw */
2300
                                // XXX
2301
                            default:
2302
                                goto illegal_insn;
2303
                            }
2304
#else
2305
                            gen_op_xor_T1_T0();
2306
                            tcg_gen_helper_0_1(helper_wrpsr, cpu_T[0]);
2307
                            save_state(dc);
2308
                            gen_op_next_insn();
2309
                            tcg_gen_exit_tb(0);
2310
                            dc->is_br = 1;
2311
#endif
2312
                        }
2313
                        break;
2314
                    case 0x32: /* wrwim, V9 wrpr */
2315
                        {
2316
                            if (!supervisor(dc))
2317
                                goto priv_insn;
2318
                            gen_op_xor_T1_T0();
2319
#ifdef TARGET_SPARC64
2320
                            switch (rd) {
2321
                            case 0: // tpc
2322
                                gen_op_wrtpc();
2323
                                break;
2324
                            case 1: // tnpc
2325
                                gen_op_wrtnpc();
2326
                                break;
2327
                            case 2: // tstate
2328
                                gen_op_wrtstate();
2329
                                break;
2330
                            case 3: // tt
2331
                                gen_op_wrtt();
2332
                                break;
2333
                            case 4: // tick
2334
                                gen_op_wrtick();
2335
                                break;
2336
                            case 5: // tba
2337
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
2338
                                break;
2339
                            case 6: // pstate
2340
                                save_state(dc);
2341
                                tcg_gen_helper_0_1(helper_wrpstate, cpu_T[0]);
2342
                                gen_op_next_insn();
2343
                                tcg_gen_exit_tb(0);
2344
                                dc->is_br = 1;
2345
                                break;
2346
                            case 7: // tl
2347
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, tl));
2348
                                break;
2349
                            case 8: // pil
2350
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, psrpil));
2351
                                break;
2352
                            case 9: // cwp
2353
                                gen_op_wrcwp();
2354
                                break;
2355
                            case 10: // cansave
2356
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, cansave));
2357
                                break;
2358
                            case 11: // canrestore
2359
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, canrestore));
2360
                                break;
2361
                            case 12: // cleanwin
2362
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, cleanwin));
2363
                                break;
2364
                            case 13: // otherwin
2365
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, otherwin));
2366
                                break;
2367
                            case 14: // wstate
2368
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, wstate));
2369
                                break;
2370
                            case 16: // UA2005 gl
2371
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, gl));
2372
                                break;
2373
                            case 26: // UA2005 strand status
2374
                                if (!hypervisor(dc))
2375
                                    goto priv_insn;
2376
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, ssr));
2377
                                break;
2378
                            default:
2379
                                goto illegal_insn;
2380
                            }
2381
#else
2382
                            tcg_gen_andi_i32(cpu_T[0], cpu_T[0], ((1 << NWINDOWS) - 1));
2383
                            gen_op_movl_env_T0(offsetof(CPUSPARCState, wim));
2384
#endif
2385
                        }
2386
                        break;
2387
                    case 0x33: /* wrtbr, UA2005 wrhpr */
2388
                        {
2389
#ifndef TARGET_SPARC64
2390
                            if (!supervisor(dc))
2391
                                goto priv_insn;
2392
                            gen_op_xor_T1_T0();
2393
                            gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
2394
#else
2395
                            if (!hypervisor(dc))
2396
                                goto priv_insn;
2397
                            gen_op_xor_T1_T0();
2398
                            switch (rd) {
2399
                            case 0: // hpstate
2400
                                // XXX gen_op_wrhpstate();
2401
                                save_state(dc);
2402
                                gen_op_next_insn();
2403
                                tcg_gen_exit_tb(0);
2404
                                dc->is_br = 1;
2405
                                break;
2406
                            case 1: // htstate
2407
                                // XXX gen_op_wrhtstate();
2408
                                break;
2409
                            case 3: // hintp
2410
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, hintp));
2411
                                break;
2412
                            case 5: // htba
2413
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, htba));
2414
                                break;
2415
                            case 31: // hstick_cmpr
2416
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, hstick_cmpr));
2417
                                gen_op_wrhstick_cmpr();
2418
                                break;
2419
                            case 6: // hver readonly
2420
                            default:
2421
                                goto illegal_insn;
2422
                            }
2423
#endif
2424
                        }
2425
                        break;
2426
#endif
2427
#ifdef TARGET_SPARC64
2428
                    case 0x2c: /* V9 movcc */
2429
                        {
2430
                            int cc = GET_FIELD_SP(insn, 11, 12);
2431
                            int cond = GET_FIELD_SP(insn, 14, 17);
2432
                            if (IS_IMM) {       /* immediate */
2433
                                rs2 = GET_FIELD_SPs(insn, 0, 10);
2434
                                gen_movl_simm_T1(rs2);
2435
                            }
2436
                            else {
2437
                                rs2 = GET_FIELD_SP(insn, 0, 4);
2438
                                gen_movl_reg_T1(rs2);
2439
                            }
2440
                            gen_movl_reg_T0(rd);
2441
                            flush_T2(dc);
2442
                            if (insn & (1 << 18)) {
2443
                                if (cc == 0)
2444
                                    gen_cond[0][cond]();
2445
                                else if (cc == 2)
2446
                                    gen_cond[1][cond]();
2447
                                else
2448
                                    goto illegal_insn;
2449
                            } else {
2450
                                gen_fcond[cc][cond]();
2451
                            }
2452
                            gen_op_mov_cc();
2453
                            gen_movl_T0_reg(rd);
2454
                            break;
2455
                        }
2456
                    case 0x2d: /* V9 sdivx */
2457
                        gen_op_sdivx_T1_T0();
2458
                        gen_movl_T0_reg(rd);
2459
                        break;
2460
                    case 0x2e: /* V9 popc */
2461
                        {
2462
                            if (IS_IMM) {       /* immediate */
2463
                                rs2 = GET_FIELD_SPs(insn, 0, 12);
2464
                                gen_movl_simm_T1(rs2);
2465
                                // XXX optimize: popc(constant)
2466
                            }
2467
                            else {
2468
                                rs2 = GET_FIELD_SP(insn, 0, 4);
2469
                                gen_movl_reg_T1(rs2);
2470
                            }
2471
                            tcg_gen_helper_1_1(helper_popc, cpu_T[0],
2472
                                               cpu_T[1]);
2473
                            gen_movl_T0_reg(rd);
2474
                        }
2475
                    case 0x2f: /* V9 movr */
2476
                        {
2477
                            int cond = GET_FIELD_SP(insn, 10, 12);
2478
                            rs1 = GET_FIELD(insn, 13, 17);
2479
                            flush_T2(dc);
2480
                            gen_movl_reg_T0(rs1);
2481
                            gen_cond_reg(cond);
2482
                            if (IS_IMM) {       /* immediate */
2483
                                rs2 = GET_FIELD_SPs(insn, 0, 9);
2484
                                gen_movl_simm_T1(rs2);
2485
                            }
2486
                            else {
2487
                                rs2 = GET_FIELD_SP(insn, 0, 4);
2488
                                gen_movl_reg_T1(rs2);
2489
                            }
2490
                            gen_movl_reg_T0(rd);
2491
                            gen_op_mov_cc();
2492
                            gen_movl_T0_reg(rd);
2493
                            break;
2494
                        }
2495
#endif
2496
                    default:
2497
                        goto illegal_insn;
2498
                    }
2499
                }
2500
            } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
2501
#ifdef TARGET_SPARC64
2502
                int opf = GET_FIELD_SP(insn, 5, 13);
2503
                rs1 = GET_FIELD(insn, 13, 17);
2504
                rs2 = GET_FIELD(insn, 27, 31);
2505
                if (gen_trap_ifnofpu(dc))
2506
                    goto jmp_insn;
2507

    
2508
                switch (opf) {
2509
                case 0x000: /* VIS I edge8cc */
2510
                case 0x001: /* VIS II edge8n */
2511
                case 0x002: /* VIS I edge8lcc */
2512
                case 0x003: /* VIS II edge8ln */
2513
                case 0x004: /* VIS I edge16cc */
2514
                case 0x005: /* VIS II edge16n */
2515
                case 0x006: /* VIS I edge16lcc */
2516
                case 0x007: /* VIS II edge16ln */
2517
                case 0x008: /* VIS I edge32cc */
2518
                case 0x009: /* VIS II edge32n */
2519
                case 0x00a: /* VIS I edge32lcc */
2520
                case 0x00b: /* VIS II edge32ln */
2521
                    // XXX
2522
                    goto illegal_insn;
2523
                case 0x010: /* VIS I array8 */
2524
                    gen_movl_reg_T0(rs1);
2525
                    gen_movl_reg_T1(rs2);
2526
                    gen_op_array8();
2527
                    gen_movl_T0_reg(rd);
2528
                    break;
2529
                case 0x012: /* VIS I array16 */
2530
                    gen_movl_reg_T0(rs1);
2531
                    gen_movl_reg_T1(rs2);
2532
                    gen_op_array16();
2533
                    gen_movl_T0_reg(rd);
2534
                    break;
2535
                case 0x014: /* VIS I array32 */
2536
                    gen_movl_reg_T0(rs1);
2537
                    gen_movl_reg_T1(rs2);
2538
                    gen_op_array32();
2539
                    gen_movl_T0_reg(rd);
2540
                    break;
2541
                case 0x018: /* VIS I alignaddr */
2542
                    gen_movl_reg_T0(rs1);
2543
                    gen_movl_reg_T1(rs2);
2544
                    gen_op_alignaddr();
2545
                    gen_movl_T0_reg(rd);
2546
                    break;
2547
                case 0x019: /* VIS II bmask */
2548
                case 0x01a: /* VIS I alignaddrl */
2549
                    // XXX
2550
                    goto illegal_insn;
2551
                case 0x020: /* VIS I fcmple16 */
2552
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2553
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2554
                    gen_op_fcmple16();
2555
                    gen_op_store_DT0_fpr(DFPREG(rd));
2556
                    break;
2557
                case 0x022: /* VIS I fcmpne16 */
2558
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2559
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2560
                    gen_op_fcmpne16();
2561
                    gen_op_store_DT0_fpr(DFPREG(rd));
2562
                    break;
2563
                case 0x024: /* VIS I fcmple32 */
2564
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2565
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2566
                    gen_op_fcmple32();
2567
                    gen_op_store_DT0_fpr(DFPREG(rd));
2568
                    break;
2569
                case 0x026: /* VIS I fcmpne32 */
2570
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2571
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2572
                    gen_op_fcmpne32();
2573
                    gen_op_store_DT0_fpr(DFPREG(rd));
2574
                    break;
2575
                case 0x028: /* VIS I fcmpgt16 */
2576
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2577
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2578
                    gen_op_fcmpgt16();
2579
                    gen_op_store_DT0_fpr(DFPREG(rd));
2580
                    break;
2581
                case 0x02a: /* VIS I fcmpeq16 */
2582
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2583
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2584
                    gen_op_fcmpeq16();
2585
                    gen_op_store_DT0_fpr(DFPREG(rd));
2586
                    break;
2587
                case 0x02c: /* VIS I fcmpgt32 */
2588
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2589
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2590
                    gen_op_fcmpgt32();
2591
                    gen_op_store_DT0_fpr(DFPREG(rd));
2592
                    break;
2593
                case 0x02e: /* VIS I fcmpeq32 */
2594
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2595
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2596
                    gen_op_fcmpeq32();
2597
                    gen_op_store_DT0_fpr(DFPREG(rd));
2598
                    break;
2599
                case 0x031: /* VIS I fmul8x16 */
2600
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2601
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2602
                    gen_op_fmul8x16();
2603
                    gen_op_store_DT0_fpr(DFPREG(rd));
2604
                    break;
2605
                case 0x033: /* VIS I fmul8x16au */
2606
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2607
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2608
                    gen_op_fmul8x16au();
2609
                    gen_op_store_DT0_fpr(DFPREG(rd));
2610
                    break;
2611
                case 0x035: /* VIS I fmul8x16al */
2612
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2613
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2614
                    gen_op_fmul8x16al();
2615
                    gen_op_store_DT0_fpr(DFPREG(rd));
2616
                    break;
2617
                case 0x036: /* VIS I fmul8sux16 */
2618
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2619
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2620
                    gen_op_fmul8sux16();
2621
                    gen_op_store_DT0_fpr(DFPREG(rd));
2622
                    break;
2623
                case 0x037: /* VIS I fmul8ulx16 */
2624
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2625
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2626
                    gen_op_fmul8ulx16();
2627
                    gen_op_store_DT0_fpr(DFPREG(rd));
2628
                    break;
2629
                case 0x038: /* VIS I fmuld8sux16 */
2630
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2631
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2632
                    gen_op_fmuld8sux16();
2633
                    gen_op_store_DT0_fpr(DFPREG(rd));
2634
                    break;
2635
                case 0x039: /* VIS I fmuld8ulx16 */
2636
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2637
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2638
                    gen_op_fmuld8ulx16();
2639
                    gen_op_store_DT0_fpr(DFPREG(rd));
2640
                    break;
2641
                case 0x03a: /* VIS I fpack32 */
2642
                case 0x03b: /* VIS I fpack16 */
2643
                case 0x03d: /* VIS I fpackfix */
2644
                case 0x03e: /* VIS I pdist */
2645
                    // XXX
2646
                    goto illegal_insn;
2647
                case 0x048: /* VIS I faligndata */
2648
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2649
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2650
                    gen_op_faligndata();
2651
                    gen_op_store_DT0_fpr(DFPREG(rd));
2652
                    break;
2653
                case 0x04b: /* VIS I fpmerge */
2654
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2655
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2656
                    gen_op_fpmerge();
2657
                    gen_op_store_DT0_fpr(DFPREG(rd));
2658
                    break;
2659
                case 0x04c: /* VIS II bshuffle */
2660
                    // XXX
2661
                    goto illegal_insn;
2662
                case 0x04d: /* VIS I fexpand */
2663
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2664
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2665
                    gen_op_fexpand();
2666
                    gen_op_store_DT0_fpr(DFPREG(rd));
2667
                    break;
2668
                case 0x050: /* VIS I fpadd16 */
2669
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2670
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2671
                    gen_op_fpadd16();
2672
                    gen_op_store_DT0_fpr(DFPREG(rd));
2673
                    break;
2674
                case 0x051: /* VIS I fpadd16s */
2675
                    gen_op_load_fpr_FT0(rs1);
2676
                    gen_op_load_fpr_FT1(rs2);
2677
                    gen_op_fpadd16s();
2678
                    gen_op_store_FT0_fpr(rd);
2679
                    break;
2680
                case 0x052: /* VIS I fpadd32 */
2681
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2682
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2683
                    gen_op_fpadd32();
2684
                    gen_op_store_DT0_fpr(DFPREG(rd));
2685
                    break;
2686
                case 0x053: /* VIS I fpadd32s */
2687
                    gen_op_load_fpr_FT0(rs1);
2688
                    gen_op_load_fpr_FT1(rs2);
2689
                    gen_op_fpadd32s();
2690
                    gen_op_store_FT0_fpr(rd);
2691
                    break;
2692
                case 0x054: /* VIS I fpsub16 */
2693
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2694
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2695
                    gen_op_fpsub16();
2696
                    gen_op_store_DT0_fpr(DFPREG(rd));
2697
                    break;
2698
                case 0x055: /* VIS I fpsub16s */
2699
                    gen_op_load_fpr_FT0(rs1);
2700
                    gen_op_load_fpr_FT1(rs2);
2701
                    gen_op_fpsub16s();
2702
                    gen_op_store_FT0_fpr(rd);
2703
                    break;
2704
                case 0x056: /* VIS I fpsub32 */
2705
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2706
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2707
                    gen_op_fpadd32();
2708
                    gen_op_store_DT0_fpr(DFPREG(rd));
2709
                    break;
2710
                case 0x057: /* VIS I fpsub32s */
2711
                    gen_op_load_fpr_FT0(rs1);
2712
                    gen_op_load_fpr_FT1(rs2);
2713
                    gen_op_fpsub32s();
2714
                    gen_op_store_FT0_fpr(rd);
2715
                    break;
2716
                case 0x060: /* VIS I fzero */
2717
                    gen_op_movl_DT0_0();
2718
                    gen_op_store_DT0_fpr(DFPREG(rd));
2719
                    break;
2720
                case 0x061: /* VIS I fzeros */
2721
                    gen_op_movl_FT0_0();
2722
                    gen_op_store_FT0_fpr(rd);
2723
                    break;
2724
                case 0x062: /* VIS I fnor */
2725
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2726
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2727
                    gen_op_fnor();
2728
                    gen_op_store_DT0_fpr(DFPREG(rd));
2729
                    break;
2730
                case 0x063: /* VIS I fnors */
2731
                    gen_op_load_fpr_FT0(rs1);
2732
                    gen_op_load_fpr_FT1(rs2);
2733
                    gen_op_fnors();
2734
                    gen_op_store_FT0_fpr(rd);
2735
                    break;
2736
                case 0x064: /* VIS I fandnot2 */
2737
                    gen_op_load_fpr_DT1(DFPREG(rs1));
2738
                    gen_op_load_fpr_DT0(DFPREG(rs2));
2739
                    gen_op_fandnot();
2740
                    gen_op_store_DT0_fpr(DFPREG(rd));
2741
                    break;
2742
                case 0x065: /* VIS I fandnot2s */
2743
                    gen_op_load_fpr_FT1(rs1);
2744
                    gen_op_load_fpr_FT0(rs2);
2745
                    gen_op_fandnots();
2746
                    gen_op_store_FT0_fpr(rd);
2747
                    break;
2748
                case 0x066: /* VIS I fnot2 */
2749
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2750
                    gen_op_fnot();
2751
                    gen_op_store_DT0_fpr(DFPREG(rd));
2752
                    break;
2753
                case 0x067: /* VIS I fnot2s */
2754
                    gen_op_load_fpr_FT1(rs2);
2755
                    gen_op_fnot();
2756
                    gen_op_store_FT0_fpr(rd);
2757
                    break;
2758
                case 0x068: /* VIS I fandnot1 */
2759
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2760
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2761
                    gen_op_fandnot();
2762
                    gen_op_store_DT0_fpr(DFPREG(rd));
2763
                    break;
2764
                case 0x069: /* VIS I fandnot1s */
2765
                    gen_op_load_fpr_FT0(rs1);
2766
                    gen_op_load_fpr_FT1(rs2);
2767
                    gen_op_fandnots();
2768
                    gen_op_store_FT0_fpr(rd);
2769
                    break;
2770
                case 0x06a: /* VIS I fnot1 */
2771
                    gen_op_load_fpr_DT1(DFPREG(rs1));
2772
                    gen_op_fnot();
2773
                    gen_op_store_DT0_fpr(DFPREG(rd));
2774
                    break;
2775
                case 0x06b: /* VIS I fnot1s */
2776
                    gen_op_load_fpr_FT1(rs1);
2777
                    gen_op_fnot();
2778
                    gen_op_store_FT0_fpr(rd);
2779
                    break;
2780
                case 0x06c: /* VIS I fxor */
2781
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2782
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2783
                    gen_op_fxor();
2784
                    gen_op_store_DT0_fpr(DFPREG(rd));
2785
                    break;
2786
                case 0x06d: /* VIS I fxors */
2787
                    gen_op_load_fpr_FT0(rs1);
2788
                    gen_op_load_fpr_FT1(rs2);
2789
                    gen_op_fxors();
2790
                    gen_op_store_FT0_fpr(rd);
2791
                    break;
2792
                case 0x06e: /* VIS I fnand */
2793
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2794
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2795
                    gen_op_fnand();
2796
                    gen_op_store_DT0_fpr(DFPREG(rd));
2797
                    break;
2798
                case 0x06f: /* VIS I fnands */
2799
                    gen_op_load_fpr_FT0(rs1);
2800
                    gen_op_load_fpr_FT1(rs2);
2801
                    gen_op_fnands();
2802
                    gen_op_store_FT0_fpr(rd);
2803
                    break;
2804
                case 0x070: /* VIS I fand */
2805
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2806
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2807
                    gen_op_fand();
2808
                    gen_op_store_DT0_fpr(DFPREG(rd));
2809
                    break;
2810
                case 0x071: /* VIS I fands */
2811
                    gen_op_load_fpr_FT0(rs1);
2812
                    gen_op_load_fpr_FT1(rs2);
2813
                    gen_op_fands();
2814
                    gen_op_store_FT0_fpr(rd);
2815
                    break;
2816
                case 0x072: /* VIS I fxnor */
2817
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2818
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2819
                    gen_op_fxnor();
2820
                    gen_op_store_DT0_fpr(DFPREG(rd));
2821
                    break;
2822
                case 0x073: /* VIS I fxnors */
2823
                    gen_op_load_fpr_FT0(rs1);
2824
                    gen_op_load_fpr_FT1(rs2);
2825
                    gen_op_fxnors();
2826
                    gen_op_store_FT0_fpr(rd);
2827
                    break;
2828
                case 0x074: /* VIS I fsrc1 */
2829
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2830
                    gen_op_store_DT0_fpr(DFPREG(rd));
2831
                    break;
2832
                case 0x075: /* VIS I fsrc1s */
2833
                    gen_op_load_fpr_FT0(rs1);
2834
                    gen_op_store_FT0_fpr(rd);
2835
                    break;
2836
                case 0x076: /* VIS I fornot2 */
2837
                    gen_op_load_fpr_DT1(DFPREG(rs1));
2838
                    gen_op_load_fpr_DT0(DFPREG(rs2));
2839
                    gen_op_fornot();
2840
                    gen_op_store_DT0_fpr(DFPREG(rd));
2841
                    break;
2842
                case 0x077: /* VIS I fornot2s */
2843
                    gen_op_load_fpr_FT1(rs1);
2844
                    gen_op_load_fpr_FT0(rs2);
2845
                    gen_op_fornots();
2846
                    gen_op_store_FT0_fpr(rd);
2847
                    break;
2848
                case 0x078: /* VIS I fsrc2 */
2849
                    gen_op_load_fpr_DT0(DFPREG(rs2));
2850
                    gen_op_store_DT0_fpr(DFPREG(rd));
2851
                    break;
2852
                case 0x079: /* VIS I fsrc2s */
2853
                    gen_op_load_fpr_FT0(rs2);
2854
                    gen_op_store_FT0_fpr(rd);
2855
                    break;
2856
                case 0x07a: /* VIS I fornot1 */
2857
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2858
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2859
                    gen_op_fornot();
2860
                    gen_op_store_DT0_fpr(DFPREG(rd));
2861
                    break;
2862
                case 0x07b: /* VIS I fornot1s */
2863
                    gen_op_load_fpr_FT0(rs1);
2864
                    gen_op_load_fpr_FT1(rs2);
2865
                    gen_op_fornots();
2866
                    gen_op_store_FT0_fpr(rd);
2867
                    break;
2868
                case 0x07c: /* VIS I for */
2869
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2870
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2871
                    gen_op_for();
2872
                    gen_op_store_DT0_fpr(DFPREG(rd));
2873
                    break;
2874
                case 0x07d: /* VIS I fors */
2875
                    gen_op_load_fpr_FT0(rs1);
2876
                    gen_op_load_fpr_FT1(rs2);
2877
                    gen_op_fors();
2878
                    gen_op_store_FT0_fpr(rd);
2879
                    break;
2880
                case 0x07e: /* VIS I fone */
2881
                    gen_op_movl_DT0_1();
2882
                    gen_op_store_DT0_fpr(DFPREG(rd));
2883
                    break;
2884
                case 0x07f: /* VIS I fones */
2885
                    gen_op_movl_FT0_1();
2886
                    gen_op_store_FT0_fpr(rd);
2887
                    break;
2888
                case 0x080: /* VIS I shutdown */
2889
                case 0x081: /* VIS II siam */
2890
                    // XXX
2891
                    goto illegal_insn;
2892
                default:
2893
                    goto illegal_insn;
2894
                }
2895
#else
2896
                goto ncp_insn;
2897
#endif
2898
            } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
2899
#ifdef TARGET_SPARC64
2900
                goto illegal_insn;
2901
#else
2902
                goto ncp_insn;
2903
#endif
2904
#ifdef TARGET_SPARC64
2905
            } else if (xop == 0x39) { /* V9 return */
2906
                rs1 = GET_FIELD(insn, 13, 17);
2907
                save_state(dc);
2908
                gen_movl_reg_T0(rs1);
2909
                if (IS_IMM) {   /* immediate */
2910
                    rs2 = GET_FIELDs(insn, 19, 31);
2911
                    tcg_gen_addi_tl(cpu_T[0], cpu_T[0], (int)rs2);
2912
                } else {                /* register */
2913
                    rs2 = GET_FIELD(insn, 27, 31);
2914
#if defined(OPTIM)
2915
                    if (rs2) {
2916
#endif
2917
                        gen_movl_reg_T1(rs2);
2918
                        gen_op_add_T1_T0();
2919
#if defined(OPTIM)
2920
                    }
2921
#endif
2922
                }
2923
                gen_op_restore();
2924
                gen_mov_pc_npc(dc);
2925
                gen_op_check_align_T0_3();
2926
                tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, npc));
2927
                dc->npc = DYNAMIC_PC;
2928
                goto jmp_insn;
2929
#endif
2930
            } else {
2931
                rs1 = GET_FIELD(insn, 13, 17);
2932
                gen_movl_reg_T0(rs1);
2933
                if (IS_IMM) {   /* immediate */
2934
                    rs2 = GET_FIELDs(insn, 19, 31);
2935
                    tcg_gen_addi_tl(cpu_T[0], cpu_T[0], (int)rs2);
2936
                } else {                /* register */
2937
                    rs2 = GET_FIELD(insn, 27, 31);
2938
#if defined(OPTIM)
2939
                    if (rs2) {
2940
#endif
2941
                        gen_movl_reg_T1(rs2);
2942
                        gen_op_add_T1_T0();
2943
#if defined(OPTIM)
2944
                    }
2945
#endif
2946
                }
2947
                switch (xop) {
2948
                case 0x38:      /* jmpl */
2949
                    {
2950
                        if (rd != 0) {
2951
                            tcg_gen_movi_tl(cpu_T[1], dc->pc);
2952
                            gen_movl_T1_reg(rd);
2953
                        }
2954
                        gen_mov_pc_npc(dc);
2955
                        gen_op_check_align_T0_3();
2956
                        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, npc));
2957
                        dc->npc = DYNAMIC_PC;
2958
                    }
2959
                    goto jmp_insn;
2960
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
2961
                case 0x39:      /* rett, V9 return */
2962
                    {
2963
                        if (!supervisor(dc))
2964
                            goto priv_insn;
2965
                        gen_mov_pc_npc(dc);
2966
                        gen_op_check_align_T0_3();
2967
                        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, npc));
2968
                        dc->npc = DYNAMIC_PC;
2969
                        tcg_gen_helper_0_0(helper_rett);
2970
                    }
2971
                    goto jmp_insn;
2972
#endif
2973
                case 0x3b: /* flush */
2974
                    tcg_gen_helper_0_1(helper_flush, cpu_T[0]);
2975
                    break;
2976
                case 0x3c:      /* save */
2977
                    save_state(dc);
2978
                    gen_op_save();
2979
                    gen_movl_T0_reg(rd);
2980
                    break;
2981
                case 0x3d:      /* restore */
2982
                    save_state(dc);
2983
                    gen_op_restore();
2984
                    gen_movl_T0_reg(rd);
2985
                    break;
2986
#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
2987
                case 0x3e:      /* V9 done/retry */
2988
                    {
2989
                        switch (rd) {
2990
                        case 0:
2991
                            if (!supervisor(dc))
2992
                                goto priv_insn;
2993
                            dc->npc = DYNAMIC_PC;
2994
                            dc->pc = DYNAMIC_PC;
2995
                            tcg_gen_helper_0_0(helper_done);
2996
                            goto jmp_insn;
2997
                        case 1:
2998
                            if (!supervisor(dc))
2999
                                goto priv_insn;
3000
                            dc->npc = DYNAMIC_PC;
3001
                            dc->pc = DYNAMIC_PC;
3002
                            tcg_gen_helper_0_0(helper_retry);
3003
                            goto jmp_insn;
3004
                        default:
3005
                            goto illegal_insn;
3006
                        }
3007
                    }
3008
                    break;
3009
#endif
3010
                default:
3011
                    goto illegal_insn;
3012
                }
3013
            }
3014
            break;
3015
        }
3016
        break;
3017
    case 3:                     /* load/store instructions */
3018
        {
3019
            unsigned int xop = GET_FIELD(insn, 7, 12);
3020
            rs1 = GET_FIELD(insn, 13, 17);
3021
            save_state(dc);
3022
            gen_movl_reg_T0(rs1);
3023
            if (xop == 0x3c || xop == 0x3e)
3024
            {
3025
                rs2 = GET_FIELD(insn, 27, 31);
3026
                gen_movl_reg_T1(rs2);
3027
            }
3028
            else if (IS_IMM) {       /* immediate */
3029
                rs2 = GET_FIELDs(insn, 19, 31);
3030
                tcg_gen_addi_tl(cpu_T[0], cpu_T[0], (int)rs2);
3031
            } else {            /* register */
3032
                rs2 = GET_FIELD(insn, 27, 31);
3033
#if defined(OPTIM)
3034
                if (rs2 != 0) {
3035
#endif
3036
                    gen_movl_reg_T1(rs2);
3037
                    gen_op_add_T1_T0();
3038
#if defined(OPTIM)
3039
                }
3040
#endif
3041
            }
3042
            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
3043
                (xop > 0x17 && xop <= 0x1d ) ||
3044
                (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
3045
                switch (xop) {
3046
                case 0x0:       /* load unsigned word */
3047
                    gen_op_check_align_T0_3();
3048
                    ABI32_MASK(cpu_T[0]);
3049
                    tcg_gen_qemu_ld32u(cpu_T[1], cpu_T[0], dc->mem_idx);
3050
                    break;
3051
                case 0x1:       /* load unsigned byte */
3052
                    ABI32_MASK(cpu_T[0]);
3053
                    tcg_gen_qemu_ld8u(cpu_T[1], cpu_T[0], dc->mem_idx);
3054
                    break;
3055
                case 0x2:       /* load unsigned halfword */
3056
                    gen_op_check_align_T0_1();
3057
                    ABI32_MASK(cpu_T[0]);
3058
                    tcg_gen_qemu_ld16u(cpu_T[1], cpu_T[0], dc->mem_idx);
3059
                    break;
3060
                case 0x3:       /* load double word */
3061
                    if (rd & 1)
3062
                        goto illegal_insn;
3063
                    else {
3064
                        TCGv r_dword;
3065

    
3066
                        r_dword = tcg_temp_new(TCG_TYPE_I64);
3067
                        gen_op_check_align_T0_7();
3068
                        ABI32_MASK(cpu_T[0]);
3069
                        tcg_gen_qemu_ld64(r_dword, cpu_T[0], dc->mem_idx);
3070
                        tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
3071
                        gen_movl_T0_reg(rd + 1);
3072
                        tcg_gen_shri_i64(r_dword, r_dword, 32);
3073
                        tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
3074
                    }
3075
                    break;
3076
                case 0x9:       /* load signed byte */
3077
                    ABI32_MASK(cpu_T[0]);
3078
                    tcg_gen_qemu_ld8s(cpu_T[1], cpu_T[0], dc->mem_idx);
3079
                    break;
3080
                case 0xa:       /* load signed halfword */
3081
                    gen_op_check_align_T0_1();
3082
                    ABI32_MASK(cpu_T[0]);
3083
                    tcg_gen_qemu_ld16s(cpu_T[1], cpu_T[0], dc->mem_idx);
3084
                    break;
3085
                case 0xd:       /* ldstub -- XXX: should be atomically */
3086
                    tcg_gen_movi_i32(cpu_tmp0, 0xff);
3087
                    ABI32_MASK(cpu_T[0]);
3088
                    tcg_gen_qemu_ld8s(cpu_T[1], cpu_T[0], dc->mem_idx);
3089
                    tcg_gen_qemu_st8(cpu_tmp0, cpu_T[0], dc->mem_idx);
3090
                    break;
3091
                case 0x0f:      /* swap register with memory. Also atomically */
3092
                    gen_op_check_align_T0_3();
3093
                    gen_movl_reg_T1(rd);
3094
                    ABI32_MASK(cpu_T[0]);
3095
                    tcg_gen_qemu_ld32u(cpu_tmp0, cpu_T[0], dc->mem_idx);
3096
                    tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], dc->mem_idx);
3097
                    tcg_gen_mov_i32(cpu_T[1], cpu_tmp0);
3098
                    break;
3099
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
3100
                case 0x10:      /* load word alternate */
3101
#ifndef TARGET_SPARC64
3102
                    if (IS_IMM)
3103
                        goto illegal_insn;
3104
                    if (!supervisor(dc))
3105
                        goto priv_insn;
3106
#endif
3107
                    gen_op_check_align_T0_3();
3108
                    gen_ld_asi(insn, 4, 0);
3109
                    break;
3110
                case 0x11:      /* load unsigned byte alternate */
3111
#ifndef TARGET_SPARC64
3112
                    if (IS_IMM)
3113
                        goto illegal_insn;
3114
                    if (!supervisor(dc))
3115
                        goto priv_insn;
3116
#endif
3117
                    gen_ld_asi(insn, 1, 0);
3118
                    break;
3119
                case 0x12:      /* load unsigned halfword alternate */
3120
#ifndef TARGET_SPARC64
3121
                    if (IS_IMM)
3122
                        goto illegal_insn;
3123
                    if (!supervisor(dc))
3124
                        goto priv_insn;
3125
#endif
3126
                    gen_op_check_align_T0_1();
3127
                    gen_ld_asi(insn, 2, 0);
3128
                    break;
3129
                case 0x13:      /* load double word alternate */
3130
#ifndef TARGET_SPARC64
3131
                    if (IS_IMM)
3132
                        goto illegal_insn;
3133
                    if (!supervisor(dc))
3134
                        goto priv_insn;
3135
#endif
3136
                    if (rd & 1)
3137
                        goto illegal_insn;
3138
                    gen_op_check_align_T0_7();
3139
                    gen_ldda_asi(insn);
3140
                    gen_movl_T0_reg(rd + 1);
3141
                    break;
3142
                case 0x19:      /* load signed byte alternate */
3143
#ifndef TARGET_SPARC64
3144
                    if (IS_IMM)
3145
                        goto illegal_insn;
3146
                    if (!supervisor(dc))
3147
                        goto priv_insn;
3148
#endif
3149
                    gen_ld_asi(insn, 1, 1);
3150
                    break;
3151
                case 0x1a:      /* load signed halfword alternate */
3152
#ifndef TARGET_SPARC64
3153
                    if (IS_IMM)
3154
                        goto illegal_insn;
3155
                    if (!supervisor(dc))
3156
                        goto priv_insn;
3157
#endif
3158
                    gen_op_check_align_T0_1();
3159
                    gen_ld_asi(insn, 2, 1);
3160
                    break;
3161
                case 0x1d:      /* ldstuba -- XXX: should be atomically */
3162
#ifndef TARGET_SPARC64
3163
                    if (IS_IMM)
3164
                        goto illegal_insn;
3165
                    if (!supervisor(dc))
3166
                        goto priv_insn;
3167
#endif
3168
                    gen_ldstub_asi(insn);
3169
                    break;
3170
                case 0x1f:      /* swap reg with alt. memory. Also atomically */
3171
#ifndef TARGET_SPARC64
3172
                    if (IS_IMM)
3173
                        goto illegal_insn;
3174
                    if (!supervisor(dc))
3175
                        goto priv_insn;
3176
#endif
3177
                    gen_op_check_align_T0_3();
3178
                    gen_movl_reg_T1(rd);
3179
                    gen_swap_asi(insn);
3180
                    break;
3181

    
3182
#ifndef TARGET_SPARC64
3183
                case 0x30: /* ldc */
3184
                case 0x31: /* ldcsr */
3185
                case 0x33: /* lddc */
3186
                    goto ncp_insn;
3187
#endif
3188
#endif
3189
#ifdef TARGET_SPARC64
3190
                case 0x08: /* V9 ldsw */
3191
                    gen_op_check_align_T0_3();
3192
                    ABI32_MASK(cpu_T[0]);
3193
                    tcg_gen_qemu_ld32s(cpu_T[1], cpu_T[0], dc->mem_idx);
3194
                    break;
3195
                case 0x0b: /* V9 ldx */
3196
                    gen_op_check_align_T0_7();
3197
                    ABI32_MASK(cpu_T[0]);
3198
                    tcg_gen_qemu_ld64(cpu_T[1], cpu_T[0], dc->mem_idx);
3199
                    break;
3200
                case 0x18: /* V9 ldswa */
3201
                    gen_op_check_align_T0_3();
3202
                    gen_ld_asi(insn, 4, 1);
3203
                    break;
3204
                case 0x1b: /* V9 ldxa */
3205
                    gen_op_check_align_T0_7();
3206
                    gen_ld_asi(insn, 8, 0);
3207
                    break;
3208
                case 0x2d: /* V9 prefetch, no effect */
3209
                    goto skip_move;
3210
                case 0x30: /* V9 ldfa */
3211
                    gen_op_check_align_T0_3();
3212
                    gen_ldf_asi(insn, 4, rd);
3213
                    goto skip_move;
3214
                case 0x33: /* V9 lddfa */
3215
                    gen_op_check_align_T0_3();
3216
                    gen_ldf_asi(insn, 8, DFPREG(rd));
3217
                    goto skip_move;
3218
                case 0x3d: /* V9 prefetcha, no effect */
3219
                    goto skip_move;
3220
                case 0x32: /* V9 ldqfa */
3221
#if defined(CONFIG_USER_ONLY)
3222
                    gen_op_check_align_T0_3();
3223
                    gen_ldf_asi(insn, 16, QFPREG(rd));
3224
                    goto skip_move;
3225
#else
3226
                    goto nfpu_insn;
3227
#endif
3228
#endif
3229
                default:
3230
                    goto illegal_insn;
3231
                }
3232
                gen_movl_T1_reg(rd);
3233
#ifdef TARGET_SPARC64
3234
            skip_move: ;
3235
#endif
3236
            } else if (xop >= 0x20 && xop < 0x24) {
3237
                if (gen_trap_ifnofpu(dc))
3238
                    goto jmp_insn;
3239
                switch (xop) {
3240
                case 0x20:      /* load fpreg */
3241
                    gen_op_check_align_T0_3();
3242
                    gen_op_ldst(ldf);
3243
                    gen_op_store_FT0_fpr(rd);
3244
                    break;
3245
                case 0x21:      /* load fsr */
3246
                    gen_op_check_align_T0_3();
3247
                    gen_op_ldst(ldf);
3248
                    gen_op_ldfsr();
3249
                    break;
3250
                case 0x22:      /* load quad fpreg */
3251
#if defined(CONFIG_USER_ONLY)
3252
                    gen_op_check_align_T0_7();
3253
                    gen_op_ldst(ldqf);
3254
                    gen_op_store_QT0_fpr(QFPREG(rd));
3255
                    break;
3256
#else
3257
                    goto nfpu_insn;
3258
#endif
3259
                case 0x23:      /* load double fpreg */
3260
                    gen_op_check_align_T0_7();
3261
                    gen_op_ldst(lddf);
3262
                    gen_op_store_DT0_fpr(DFPREG(rd));
3263
                    break;
3264
                default:
3265
                    goto illegal_insn;
3266
                }
3267
            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) || \
3268
                       xop == 0xe || xop == 0x1e) {
3269
                gen_movl_reg_T1(rd);
3270
                switch (xop) {
3271
                case 0x4: /* store word */
3272
                    gen_op_check_align_T0_3();
3273
                    ABI32_MASK(cpu_T[0]);
3274
                    tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], dc->mem_idx);
3275
                    break;
3276
                case 0x5: /* store byte */
3277
                    ABI32_MASK(cpu_T[0]);
3278
                    tcg_gen_qemu_st8(cpu_T[1], cpu_T[0], dc->mem_idx);
3279
                    break;
3280
                case 0x6: /* store halfword */
3281
                    gen_op_check_align_T0_1();
3282
                    ABI32_MASK(cpu_T[0]);
3283
                    tcg_gen_qemu_st16(cpu_T[1], cpu_T[0], dc->mem_idx);
3284
                    break;
3285
                case 0x7: /* store double word */
3286
                    if (rd & 1)
3287
                        goto illegal_insn;
3288
#ifndef __i386__
3289
                    else {
3290
                        TCGv r_dword, r_low;
3291

    
3292
                        gen_op_check_align_T0_7();
3293
                        r_dword = tcg_temp_new(TCG_TYPE_I64);
3294
                        r_low = tcg_temp_new(TCG_TYPE_I32);
3295
                        gen_movl_reg_TN(rd + 1, r_low);
3296
                        tcg_gen_helper_1_2(helper_pack64, r_dword, cpu_T[1],
3297
                                           r_low);
3298
                        tcg_gen_qemu_st64(r_dword, cpu_T[0], dc->mem_idx);
3299
                    }
3300
#else /* __i386__ */
3301
                    gen_op_check_align_T0_7();
3302
                    flush_T2(dc);
3303
                    gen_movl_reg_T2(rd + 1);
3304
                    gen_op_ldst(std);
3305
#endif /* __i386__ */
3306
                    break;
3307
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
3308
                case 0x14: /* store word alternate */
3309
#ifndef TARGET_SPARC64
3310
                    if (IS_IMM)
3311
                        goto illegal_insn;
3312
                    if (!supervisor(dc))
3313
                        goto priv_insn;
3314
#endif
3315
                    gen_op_check_align_T0_3();
3316
                    gen_st_asi(insn, 4);
3317
                    break;
3318
                case 0x15: /* store byte alternate */
3319
#ifndef TARGET_SPARC64
3320
                    if (IS_IMM)
3321
                        goto illegal_insn;
3322
                    if (!supervisor(dc))
3323
                        goto priv_insn;
3324
#endif
3325
                    gen_st_asi(insn, 1);
3326
                    break;
3327
                case 0x16: /* store halfword alternate */
3328
#ifndef TARGET_SPARC64
3329
                    if (IS_IMM)
3330
                        goto illegal_insn;
3331
                    if (!supervisor(dc))
3332
                        goto priv_insn;
3333
#endif
3334
                    gen_op_check_align_T0_1();
3335
                    gen_st_asi(insn, 2);
3336
                    break;
3337
                case 0x17: /* store double word alternate */
3338
#ifndef TARGET_SPARC64
3339
                    if (IS_IMM)
3340
                        goto illegal_insn;
3341
                    if (!supervisor(dc))
3342
                        goto priv_insn;
3343
#endif
3344
                    if (rd & 1)
3345
                        goto illegal_insn;
3346
                    else {
3347
                        int asi;
3348
                        TCGv r_dword, r_temp, r_size;
3349

    
3350
                        gen_op_check_align_T0_7();
3351
                        r_dword = tcg_temp_new(TCG_TYPE_I64);
3352
                        r_temp = tcg_temp_new(TCG_TYPE_I32);
3353
                        r_size = tcg_temp_new(TCG_TYPE_I32);
3354
                        gen_movl_reg_TN(rd + 1, r_temp);
3355
                        tcg_gen_helper_1_2(helper_pack64, r_dword, cpu_T[1],
3356
                                           r_temp);
3357
#ifdef TARGET_SPARC64
3358
                        if (IS_IMM) {
3359
                            int offset;
3360

    
3361
                            offset = GET_FIELD(insn, 25, 31);
3362
                            tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
3363
                            tcg_gen_ld_i32(r_dword, cpu_env, offsetof(CPUSPARCState, asi));
3364
                        } else {
3365
#endif
3366
                            asi = GET_FIELD(insn, 19, 26);
3367
                            tcg_gen_movi_i32(r_temp, asi);
3368
#ifdef TARGET_SPARC64
3369
                        }
3370
#endif
3371
                        tcg_gen_movi_i32(r_size, 8);
3372
                        tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, r_temp, r_size);
3373
                    }
3374
                    break;
3375
#endif
3376
#ifdef TARGET_SPARC64
3377
                case 0x0e: /* V9 stx */
3378
                    gen_op_check_align_T0_7();
3379
                    ABI32_MASK(cpu_T[0]);
3380
                    tcg_gen_qemu_st64(cpu_T[1], cpu_T[0], dc->mem_idx);
3381
                    break;
3382
                case 0x1e: /* V9 stxa */
3383
                    gen_op_check_align_T0_7();
3384
                    gen_st_asi(insn, 8);
3385
                    break;
3386
#endif
3387
                default:
3388
                    goto illegal_insn;
3389
                }
3390
            } else if (xop > 0x23 && xop < 0x28) {
3391
                if (gen_trap_ifnofpu(dc))
3392
                    goto jmp_insn;
3393
                switch (xop) {
3394
                case 0x24:
3395
                    gen_op_check_align_T0_3();
3396
                    gen_op_load_fpr_FT0(rd);
3397
                    gen_op_ldst(stf);
3398
                    break;
3399
                case 0x25: /* stfsr, V9 stxfsr */
3400
#ifdef CONFIG_USER_ONLY
3401
                    gen_op_check_align_T0_3();
3402
#endif
3403
                    gen_op_stfsr();
3404
                    gen_op_ldst(stf);
3405
                    break;
3406
                case 0x26:
3407
#ifdef TARGET_SPARC64
3408
#if defined(CONFIG_USER_ONLY)
3409
                    /* V9 stqf, store quad fpreg */
3410
                    gen_op_check_align_T0_7();
3411
                    gen_op_load_fpr_QT0(QFPREG(rd));
3412
                    gen_op_ldst(stqf);
3413
                    break;
3414
#else
3415
                    goto nfpu_insn;
3416
#endif
3417
#else /* !TARGET_SPARC64 */
3418
                    /* stdfq, store floating point queue */
3419
#if defined(CONFIG_USER_ONLY)
3420
                    goto illegal_insn;
3421
#else
3422
                    if (!supervisor(dc))
3423
                        goto priv_insn;
3424
                    if (gen_trap_ifnofpu(dc))
3425
                        goto jmp_insn;
3426
                    goto nfq_insn;
3427
#endif
3428
#endif
3429
                case 0x27:
3430
                    gen_op_check_align_T0_7();
3431
                    gen_op_load_fpr_DT0(DFPREG(rd));
3432
                    gen_op_ldst(stdf);
3433
                    break;
3434
                default:
3435
                    goto illegal_insn;
3436
                }
3437
            } else if (xop > 0x33 && xop < 0x3f) {
3438
                switch (xop) {
3439
#ifdef TARGET_SPARC64
3440
                case 0x34: /* V9 stfa */
3441
                    gen_op_check_align_T0_3();
3442
                    gen_op_load_fpr_FT0(rd);
3443
                    gen_stf_asi(insn, 4, rd);
3444
                    break;
3445
                case 0x36: /* V9 stqfa */
3446
#if defined(CONFIG_USER_ONLY)
3447
                    gen_op_check_align_T0_7();
3448
                    gen_op_load_fpr_QT0(QFPREG(rd));
3449
                    gen_stf_asi(insn, 16, QFPREG(rd));
3450
                    break;
3451
#else
3452
                    goto nfpu_insn;
3453
#endif
3454
                case 0x37: /* V9 stdfa */
3455
                    gen_op_check_align_T0_3();
3456
                    gen_op_load_fpr_DT0(DFPREG(rd));
3457
                    gen_stf_asi(insn, 8, DFPREG(rd));
3458
                    break;
3459
                case 0x3c: /* V9 casa */
3460
                    gen_op_check_align_T0_3();
3461
                    gen_cas_asi(insn, rd);
3462
                    gen_movl_T1_reg(rd);
3463
                    break;
3464
                case 0x3e: /* V9 casxa */
3465
                    gen_op_check_align_T0_7();
3466
                    gen_casx_asi(insn, rd);
3467
                    gen_movl_T1_reg(rd);
3468
                    break;
3469
#else
3470
                case 0x34: /* stc */
3471
                case 0x35: /* stcsr */
3472
                case 0x36: /* stdcq */
3473
                case 0x37: /* stdc */
3474
                    goto ncp_insn;
3475
#endif
3476
                default:
3477
                    goto illegal_insn;
3478
                }
3479
            }
3480
            else
3481
                goto illegal_insn;
3482
        }
3483
        break;
3484
    }
3485
    /* default case for non jump instructions */
3486
    if (dc->npc == DYNAMIC_PC) {
3487
        dc->pc = DYNAMIC_PC;
3488
        gen_op_next_insn();
3489
    } else if (dc->npc == JUMP_PC) {
3490
        /* we can do a static jump */
3491
        gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1]);
3492
        dc->is_br = 1;
3493
    } else {
3494
        dc->pc = dc->npc;
3495
        dc->npc = dc->npc + 4;
3496
    }
3497
 jmp_insn:
3498
    return;
3499
 illegal_insn:
3500
    save_state(dc);
3501
    gen_op_exception(TT_ILL_INSN);
3502
    dc->is_br = 1;
3503
    return;
3504
#if !defined(CONFIG_USER_ONLY)
3505
 priv_insn:
3506
    save_state(dc);
3507
    gen_op_exception(TT_PRIV_INSN);
3508
    dc->is_br = 1;
3509
    return;
3510
 nfpu_insn:
3511
    save_state(dc);
3512
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
3513
    dc->is_br = 1;
3514
    return;
3515
#ifndef TARGET_SPARC64
3516
 nfq_insn:
3517
    save_state(dc);
3518
    gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
3519
    dc->is_br = 1;
3520
    return;
3521
#endif
3522
#endif
3523
#ifndef TARGET_SPARC64
3524
 ncp_insn:
3525
    save_state(dc);
3526
    gen_op_exception(TT_NCP_INSN);
3527
    dc->is_br = 1;
3528
    return;
3529
#endif
3530
}
3531

    
3532
static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
3533
{
3534
}
3535

    
3536
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
3537
                                                 int spc, CPUSPARCState *env)
3538
{
3539
    target_ulong pc_start, last_pc;
3540
    uint16_t *gen_opc_end;
3541
    DisasContext dc1, *dc = &dc1;
3542
    int j, lj = -1;
3543

    
3544
    memset(dc, 0, sizeof(DisasContext));
3545
    dc->tb = tb;
3546
    pc_start = tb->pc;
3547
    dc->pc = pc_start;
3548
    last_pc = dc->pc;
3549
    dc->npc = (target_ulong) tb->cs_base;
3550
    dc->mem_idx = cpu_mmu_index(env);
3551
    dc->fpu_enabled = cpu_fpu_enabled(env);
3552
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
3553

    
3554
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
3555
    cpu_regwptr = tcg_temp_new(TCG_TYPE_PTR); // XXX
3556

    
3557
    do {
3558
        if (env->nb_breakpoints > 0) {
3559
            for(j = 0; j < env->nb_breakpoints; j++) {
3560
                if (env->breakpoints[j] == dc->pc) {
3561
                    if (dc->pc != pc_start)
3562
                        save_state(dc);
3563
                    tcg_gen_helper_0_0(helper_debug);
3564
                    tcg_gen_exit_tb(0);
3565
                    dc->is_br = 1;
3566
                    goto exit_gen_loop;
3567
                }
3568
            }
3569
        }
3570
        if (spc) {
3571
            if (loglevel > 0)
3572
                fprintf(logfile, "Search PC...\n");
3573
            j = gen_opc_ptr - gen_opc_buf;
3574
            if (lj < j) {
3575
                lj++;
3576
                while (lj < j)
3577
                    gen_opc_instr_start[lj++] = 0;
3578
                gen_opc_pc[lj] = dc->pc;
3579
                gen_opc_npc[lj] = dc->npc;
3580
                gen_opc_instr_start[lj] = 1;
3581
            }
3582
        }
3583
        last_pc = dc->pc;
3584
        disas_sparc_insn(dc);
3585

    
3586
        if (dc->is_br)
3587
            break;
3588
        /* if the next PC is different, we abort now */
3589
        if (dc->pc != (last_pc + 4))
3590
            break;
3591
        /* if we reach a page boundary, we stop generation so that the
3592
           PC of a TT_TFAULT exception is always in the right page */
3593
        if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
3594
            break;
3595
        /* if single step mode, we generate only one instruction and
3596
           generate an exception */
3597
        if (env->singlestep_enabled) {
3598
            gen_jmp_im(dc->pc);
3599
            tcg_gen_exit_tb(0);
3600
            break;
3601
        }
3602
    } while ((gen_opc_ptr < gen_opc_end) &&
3603
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
3604

    
3605
 exit_gen_loop:
3606
    if (!dc->is_br) {
3607
        if (dc->pc != DYNAMIC_PC &&
3608
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
3609
            /* static PC and NPC: we can use direct chaining */
3610
            gen_branch(dc, dc->pc, dc->npc);
3611
        } else {
3612
            if (dc->pc != DYNAMIC_PC)
3613
                gen_jmp_im(dc->pc);
3614
            save_npc(dc);
3615
            tcg_gen_exit_tb(0);
3616
        }
3617
    }
3618
    *gen_opc_ptr = INDEX_op_end;
3619
    if (spc) {
3620
        j = gen_opc_ptr - gen_opc_buf;
3621
        lj++;
3622
        while (lj <= j)
3623
            gen_opc_instr_start[lj++] = 0;
3624
#if 0
3625
        if (loglevel > 0) {
3626
            page_dump(logfile);
3627
        }
3628
#endif
3629
        gen_opc_jump_pc[0] = dc->jump_pc[0];
3630
        gen_opc_jump_pc[1] = dc->jump_pc[1];
3631
    } else {
3632
        tb->size = last_pc + 4 - pc_start;
3633
    }
3634
#ifdef DEBUG_DISAS
3635
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3636
        fprintf(logfile, "--------------\n");
3637
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
3638
        target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
3639
        fprintf(logfile, "\n");
3640
    }
3641
#endif
3642
    return 0;
3643
}
3644

    
3645
int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
3646
{
3647
    return gen_intermediate_code_internal(tb, 0, env);
3648
}
3649

    
3650
int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
3651
{
3652
    return gen_intermediate_code_internal(tb, 1, env);
3653
}
3654

    
3655
void cpu_reset(CPUSPARCState *env)
3656
{
3657
    tlb_flush(env, 1);
3658
    env->cwp = 0;
3659
    env->wim = 1;
3660
    env->regwptr = env->regbase + (env->cwp * 16);
3661
#if defined(CONFIG_USER_ONLY)
3662
    env->user_mode_only = 1;
3663
#ifdef TARGET_SPARC64
3664
    env->cleanwin = NWINDOWS - 2;
3665
    env->cansave = NWINDOWS - 2;
3666
    env->pstate = PS_RMO | PS_PEF | PS_IE;
3667
    env->asi = 0x82; // Primary no-fault
3668
#endif
3669
#else
3670
    env->psret = 0;
3671
    env->psrs = 1;
3672
    env->psrps = 1;
3673
#ifdef TARGET_SPARC64
3674
    env->pstate = PS_PRIV;
3675
    env->hpstate = HS_PRIV;
3676
    env->pc = 0x1fff0000000ULL;
3677
#else
3678
    env->pc = 0;
3679
    env->mmuregs[0] &= ~(MMU_E | MMU_NF);
3680
    env->mmuregs[0] |= env->mmu_bm;
3681
#endif
3682
    env->npc = env->pc + 4;
3683
#endif
3684
}
3685

    
3686
CPUSPARCState *cpu_sparc_init(const char *cpu_model)
3687
{
3688
    CPUSPARCState *env;
3689
    const sparc_def_t *def;
3690
    static int inited;
3691

    
3692
    def = cpu_sparc_find_by_name(cpu_model);
3693
    if (!def)
3694
        return NULL;
3695

    
3696
    env = qemu_mallocz(sizeof(CPUSPARCState));
3697
    if (!env)
3698
        return NULL;
3699
    cpu_exec_init(env);
3700
    env->cpu_model_str = cpu_model;
3701
    env->version = def->iu_version;
3702
    env->fsr = def->fpu_version;
3703
#if !defined(TARGET_SPARC64)
3704
    env->mmu_bm = def->mmu_bm;
3705
    env->mmu_ctpr_mask = def->mmu_ctpr_mask;
3706
    env->mmu_cxr_mask = def->mmu_cxr_mask;
3707
    env->mmu_sfsr_mask = def->mmu_sfsr_mask;
3708
    env->mmu_trcr_mask = def->mmu_trcr_mask;
3709
    env->mmuregs[0] |= def->mmu_version;
3710
    cpu_sparc_set_id(env, 0);
3711
#endif
3712

    
3713
    /* init various static tables */
3714
    if (!inited) {
3715
        inited = 1;
3716

    
3717
        tcg_set_macro_func(&tcg_ctx, tcg_macro_func);
3718
        cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
3719
        //#if TARGET_LONG_BITS > HOST_LONG_BITS
3720
#ifdef TARGET_SPARC64
3721
        cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
3722
                                      TCG_AREG0, offsetof(CPUState, t0), "T0");
3723
        cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
3724
                                      TCG_AREG0, offsetof(CPUState, t1), "T1");
3725
        cpu_T[2] = tcg_global_mem_new(TCG_TYPE_TL,
3726
                                      TCG_AREG0, offsetof(CPUState, t2), "T2");
3727
#else
3728
        cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
3729
        cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
3730
        cpu_T[2] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T2");
3731
#endif
3732
    }
3733

    
3734
    cpu_reset(env);
3735
    
3736
    return env;
3737
}
3738

    
3739
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
3740
{
3741
#if !defined(TARGET_SPARC64)
3742
    env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
3743
#endif
3744
}
3745

    
3746
static const sparc_def_t sparc_defs[] = {
3747
#ifdef TARGET_SPARC64
3748
    {
3749
        .name = "Fujitsu Sparc64",
3750
        .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)
3751
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3752
        .fpu_version = 0x00000000,
3753
        .mmu_version = 0,
3754
    },
3755
    {
3756
        .name = "Fujitsu Sparc64 III",
3757
        .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)
3758
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3759
        .fpu_version = 0x00000000,
3760
        .mmu_version = 0,
3761
    },
3762
    {
3763
        .name = "Fujitsu Sparc64 IV",
3764
        .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)
3765
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3766
        .fpu_version = 0x00000000,
3767
        .mmu_version = 0,
3768
    },
3769
    {
3770
        .name = "Fujitsu Sparc64 V",
3771
        .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)
3772
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3773
        .fpu_version = 0x00000000,
3774
        .mmu_version = 0,
3775
    },
3776
    {
3777
        .name = "TI UltraSparc I",
3778
        .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)
3779
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3780
        .fpu_version = 0x00000000,
3781
        .mmu_version = 0,
3782
    },
3783
    {
3784
        .name = "TI UltraSparc II",
3785
        .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)
3786
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3787
        .fpu_version = 0x00000000,
3788
        .mmu_version = 0,
3789
    },
3790
    {
3791
        .name = "TI UltraSparc IIi",
3792
        .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)
3793
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3794
        .fpu_version = 0x00000000,
3795
        .mmu_version = 0,
3796
    },
3797
    {
3798
        .name = "TI UltraSparc IIe",
3799
        .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)
3800
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3801
        .fpu_version = 0x00000000,
3802
        .mmu_version = 0,
3803
    },
3804
    {
3805
        .name = "Sun UltraSparc III",
3806
        .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)
3807
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3808
        .fpu_version = 0x00000000,
3809
        .mmu_version = 0,
3810
    },
3811
    {
3812
        .name = "Sun UltraSparc III Cu",
3813
        .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)
3814
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3815
        .fpu_version = 0x00000000,
3816
        .mmu_version = 0,
3817
    },
3818
    {
3819
        .name = "Sun UltraSparc IIIi",
3820
        .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)
3821
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3822
        .fpu_version = 0x00000000,
3823
        .mmu_version = 0,
3824
    },
3825
    {
3826
        .name = "Sun UltraSparc IV",
3827
        .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)
3828
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3829
        .fpu_version = 0x00000000,
3830
        .mmu_version = 0,
3831
    },
3832
    {
3833
        .name = "Sun UltraSparc IV+",
3834
        .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)
3835
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3836
        .fpu_version = 0x00000000,
3837
        .mmu_version = 0,
3838
    },
3839
    {
3840
        .name = "Sun UltraSparc IIIi+",
3841
        .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)
3842
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3843
        .fpu_version = 0x00000000,
3844
        .mmu_version = 0,
3845
    },
3846
    {
3847
        .name = "NEC UltraSparc I",
3848
        .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)
3849
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3850
        .fpu_version = 0x00000000,
3851
        .mmu_version = 0,
3852
    },
3853
#else
3854
    {
3855
        .name = "Fujitsu MB86900",
3856
        .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
3857
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
3858
        .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
3859
        .mmu_bm = 0x00004000,
3860
        .mmu_ctpr_mask = 0x007ffff0,
3861
        .mmu_cxr_mask = 0x0000003f,
3862
        .mmu_sfsr_mask = 0xffffffff,
3863
        .mmu_trcr_mask = 0xffffffff,
3864
    },
3865
    {
3866
        .name = "Fujitsu MB86904",
3867
        .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
3868
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
3869
        .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
3870
        .mmu_bm = 0x00004000,
3871
        .mmu_ctpr_mask = 0x00ffffc0,
3872
        .mmu_cxr_mask = 0x000000ff,
3873
        .mmu_sfsr_mask = 0x00016fff,
3874
        .mmu_trcr_mask = 0x00ffffff,
3875
    },
3876
    {
3877
        .name = "Fujitsu MB86907",
3878
        .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
3879
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
3880
        .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
3881
        .mmu_bm = 0x00004000,
3882
        .mmu_ctpr_mask = 0xffffffc0,
3883
        .mmu_cxr_mask = 0x000000ff,
3884
        .mmu_sfsr_mask = 0x00016fff,
3885
        .mmu_trcr_mask = 0xffffffff,
3886
    },
3887
    {
3888
        .name = "LSI L64811",
3889
        .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
3890
        .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
3891
        .mmu_version = 0x10 << 24,
3892
        .mmu_bm = 0x00004000,
3893
        .mmu_ctpr_mask = 0x007ffff0,
3894
        .mmu_cxr_mask = 0x0000003f,
3895
        .mmu_sfsr_mask = 0xffffffff,
3896
        .mmu_trcr_mask = 0xffffffff,
3897
    },
3898
    {
3899
        .name = "Cypress CY7C601",
3900
        .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
3901
        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
3902
        .mmu_version = 0x10 << 24,
3903
        .mmu_bm = 0x00004000,
3904
        .mmu_ctpr_mask = 0x007ffff0,
3905
        .mmu_cxr_mask = 0x0000003f,
3906
        .mmu_sfsr_mask = 0xffffffff,
3907
        .mmu_trcr_mask = 0xffffffff,
3908
    },
3909
    {
3910
        .name = "Cypress CY7C611",
3911
        .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
3912
        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
3913
        .mmu_version = 0x10 << 24,
3914
        .mmu_bm = 0x00004000,
3915
        .mmu_ctpr_mask = 0x007ffff0,
3916
        .mmu_cxr_mask = 0x0000003f,
3917
        .mmu_sfsr_mask = 0xffffffff,
3918
        .mmu_trcr_mask = 0xffffffff,
3919
    },
3920
    {
3921
        .name = "TI SuperSparc II",
3922
        .iu_version = 0x40000000,
3923
        .fpu_version = 0 << 17,
3924
        .mmu_version = 0x04000000,
3925
        .mmu_bm = 0x00002000,
3926
        .mmu_ctpr_mask = 0xffffffc0,
3927
        .mmu_cxr_mask = 0x0000ffff,
3928
        .mmu_sfsr_mask = 0xffffffff,
3929
        .mmu_trcr_mask = 0xffffffff,
3930
    },
3931
    {
3932
        .name = "TI MicroSparc I",
3933
        .iu_version = 0x41000000,
3934
        .fpu_version = 4 << 17,
3935
        .mmu_version = 0x41000000,
3936
        .mmu_bm = 0x00004000,
3937
        .mmu_ctpr_mask = 0x007ffff0,
3938
        .mmu_cxr_mask = 0x0000003f,
3939
        .mmu_sfsr_mask = 0x00016fff,
3940
        .mmu_trcr_mask = 0x0000003f,
3941
    },
3942
    {
3943
        .name = "TI MicroSparc II",
3944
        .iu_version = 0x42000000,
3945
        .fpu_version = 4 << 17,
3946
        .mmu_version = 0x02000000,
3947
        .mmu_bm = 0x00004000,
3948
        .mmu_ctpr_mask = 0x00ffffc0,
3949
        .mmu_cxr_mask = 0x000000ff,
3950
        .mmu_sfsr_mask = 0x00016bff,
3951
        .mmu_trcr_mask = 0x00ffffff,
3952
    },
3953
    {
3954
        .name = "TI MicroSparc IIep",
3955
        .iu_version = 0x42000000,
3956
        .fpu_version = 4 << 17,
3957
        .mmu_version = 0x04000000,
3958
        .mmu_bm = 0x00004000,
3959
        .mmu_ctpr_mask = 0x00ffffc0,
3960
        .mmu_cxr_mask = 0x000000ff,
3961
        .mmu_sfsr_mask = 0x00016bff,
3962
        .mmu_trcr_mask = 0x00ffffff,
3963
    },
3964
    {
3965
        .name = "TI SuperSparc 51",
3966
        .iu_version = 0x43000000,
3967
        .fpu_version = 0 << 17,
3968
        .mmu_version = 0x04000000,
3969
        .mmu_bm = 0x00002000,
3970
        .mmu_ctpr_mask = 0xffffffc0,
3971
        .mmu_cxr_mask = 0x0000ffff,
3972
        .mmu_sfsr_mask = 0xffffffff,
3973
        .mmu_trcr_mask = 0xffffffff,
3974
    },
3975
    {
3976
        .name = "TI SuperSparc 61",
3977
        .iu_version = 0x44000000,
3978
        .fpu_version = 0 << 17,
3979
        .mmu_version = 0x04000000,
3980
        .mmu_bm = 0x00002000,
3981
        .mmu_ctpr_mask = 0xffffffc0,
3982
        .mmu_cxr_mask = 0x0000ffff,
3983
        .mmu_sfsr_mask = 0xffffffff,
3984
        .mmu_trcr_mask = 0xffffffff,
3985
    },
3986
    {
3987
        .name = "Ross RT625",
3988
        .iu_version = 0x1e000000,
3989
        .fpu_version = 1 << 17,
3990
        .mmu_version = 0x1e000000,
3991
        .mmu_bm = 0x00004000,
3992
        .mmu_ctpr_mask = 0x007ffff0,
3993
        .mmu_cxr_mask = 0x0000003f,
3994
        .mmu_sfsr_mask = 0xffffffff,
3995
        .mmu_trcr_mask = 0xffffffff,
3996
    },
3997
    {
3998
        .name = "Ross RT620",
3999
        .iu_version = 0x1f000000,
4000
        .fpu_version = 1 << 17,
4001
        .mmu_version = 0x1f000000,
4002
        .mmu_bm = 0x00004000,
4003
        .mmu_ctpr_mask = 0x007ffff0,
4004
        .mmu_cxr_mask = 0x0000003f,
4005
        .mmu_sfsr_mask = 0xffffffff,
4006
        .mmu_trcr_mask = 0xffffffff,
4007
    },
4008
    {
4009
        .name = "BIT B5010",
4010
        .iu_version = 0x20000000,
4011
        .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
4012
        .mmu_version = 0x20000000,
4013
        .mmu_bm = 0x00004000,
4014
        .mmu_ctpr_mask = 0x007ffff0,
4015
        .mmu_cxr_mask = 0x0000003f,
4016
        .mmu_sfsr_mask = 0xffffffff,
4017
        .mmu_trcr_mask = 0xffffffff,
4018
    },
4019
    {
4020
        .name = "Matsushita MN10501",
4021
        .iu_version = 0x50000000,
4022
        .fpu_version = 0 << 17,
4023
        .mmu_version = 0x50000000,
4024
        .mmu_bm = 0x00004000,
4025
        .mmu_ctpr_mask = 0x007ffff0,
4026
        .mmu_cxr_mask = 0x0000003f,
4027
        .mmu_sfsr_mask = 0xffffffff,
4028
        .mmu_trcr_mask = 0xffffffff,
4029
    },
4030
    {
4031
        .name = "Weitek W8601",
4032
        .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
4033
        .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
4034
        .mmu_version = 0x10 << 24,
4035
        .mmu_bm = 0x00004000,
4036
        .mmu_ctpr_mask = 0x007ffff0,
4037
        .mmu_cxr_mask = 0x0000003f,
4038
        .mmu_sfsr_mask = 0xffffffff,
4039
        .mmu_trcr_mask = 0xffffffff,
4040
    },
4041
    {
4042
        .name = "LEON2",
4043
        .iu_version = 0xf2000000,
4044
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
4045
        .mmu_version = 0xf2000000,
4046
        .mmu_bm = 0x00004000,
4047
        .mmu_ctpr_mask = 0x007ffff0,
4048
        .mmu_cxr_mask = 0x0000003f,
4049
        .mmu_sfsr_mask = 0xffffffff,
4050
        .mmu_trcr_mask = 0xffffffff,
4051
    },
4052
    {
4053
        .name = "LEON3",
4054
        .iu_version = 0xf3000000,
4055
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
4056
        .mmu_version = 0xf3000000,
4057
        .mmu_bm = 0x00004000,
4058
        .mmu_ctpr_mask = 0x007ffff0,
4059
        .mmu_cxr_mask = 0x0000003f,
4060
        .mmu_sfsr_mask = 0xffffffff,
4061
        .mmu_trcr_mask = 0xffffffff,
4062
    },
4063
#endif
4064
};
4065

    
4066
static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name)
4067
{
4068
    unsigned int i;
4069

    
4070
    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
4071
        if (strcasecmp(name, sparc_defs[i].name) == 0) {
4072
            return &sparc_defs[i];
4073
        }
4074
    }
4075
    return NULL;
4076
}
4077

    
4078
void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
4079
{
4080
    unsigned int i;
4081

    
4082
    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
4083
        (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x\n",
4084
                       sparc_defs[i].name,
4085
                       sparc_defs[i].iu_version,
4086
                       sparc_defs[i].fpu_version,
4087
                       sparc_defs[i].mmu_version);
4088
    }
4089
}
4090

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

    
4093
void cpu_dump_state(CPUState *env, FILE *f,
4094
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
4095
                    int flags)
4096
{
4097
    int i, x;
4098

    
4099
    cpu_fprintf(f, "pc: " TARGET_FMT_lx "  npc: " TARGET_FMT_lx "\n", env->pc, env->npc);
4100
    cpu_fprintf(f, "General Registers:\n");
4101
    for (i = 0; i < 4; i++)
4102
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
4103
    cpu_fprintf(f, "\n");
4104
    for (; i < 8; i++)
4105
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
4106
    cpu_fprintf(f, "\nCurrent Register Window:\n");
4107
    for (x = 0; x < 3; x++) {
4108
        for (i = 0; i < 4; i++)
4109
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
4110
                    (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
4111
                    env->regwptr[i + x * 8]);
4112
        cpu_fprintf(f, "\n");
4113
        for (; i < 8; i++)
4114
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
4115
                    (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
4116
                    env->regwptr[i + x * 8]);
4117
        cpu_fprintf(f, "\n");
4118
    }
4119
    cpu_fprintf(f, "\nFloating Point Registers:\n");
4120
    for (i = 0; i < 32; i++) {
4121
        if ((i & 3) == 0)
4122
            cpu_fprintf(f, "%%f%02d:", i);
4123
        cpu_fprintf(f, " %016lf", env->fpr[i]);
4124
        if ((i & 3) == 3)
4125
            cpu_fprintf(f, "\n");
4126
    }
4127
#ifdef TARGET_SPARC64
4128
    cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d fprs: %d\n",
4129
                env->pstate, GET_CCR(env), env->asi, env->tl, env->fprs);
4130
    cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d cleanwin %d cwp %d\n",
4131
                env->cansave, env->canrestore, env->otherwin, env->wstate,
4132
                env->cleanwin, NWINDOWS - 1 - env->cwp);
4133
#else
4134
    cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n", GET_PSR(env),
4135
            GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
4136
            GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
4137
            env->psrs?'S':'-', env->psrps?'P':'-',
4138
            env->psret?'E':'-', env->wim);
4139
#endif
4140
    cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env));
4141
}
4142

    
4143
#if defined(CONFIG_USER_ONLY)
4144
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
4145
{
4146
    return addr;
4147
}
4148

    
4149
#else
4150
extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
4151
                                 int *access_index, target_ulong address, int rw,
4152
                                 int mmu_idx);
4153

    
4154
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
4155
{
4156
    target_phys_addr_t phys_addr;
4157
    int prot, access_index;
4158

    
4159
    if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2,
4160
                             MMU_KERNEL_IDX) != 0)
4161
        if (get_physical_address(env, &phys_addr, &prot, &access_index, addr,
4162
                                 0, MMU_KERNEL_IDX) != 0)
4163
            return -1;
4164
    if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED)
4165
        return -1;
4166
    return phys_addr;
4167
}
4168
#endif
4169

    
4170
void helper_flush(target_ulong addr)
4171
{
4172
    addr &= ~7;
4173
    tb_invalidate_page_range(addr, addr + 8);
4174
}