Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (147.9 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
OP_LD_TABLE(stf);
196
OP_LD_TABLE(stdf);
197
OP_LD_TABLE(ldf);
198
OP_LD_TABLE(lddf);
199
#endif
200

    
201
#ifdef TARGET_ABI32
202
#define ABI32_MASK(addr) tcg_gen_andi_i64(addr, addr, 0xffffffffULL);
203
#else
204
#define ABI32_MASK(addr)
205
#endif
206

    
207
static inline void gen_movl_simm_T1(int32_t val)
208
{
209
    tcg_gen_movi_tl(cpu_T[1], val);
210
}
211

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

    
224
static inline void gen_movl_reg_T0(int reg)
225
{
226
    gen_movl_reg_TN(reg, cpu_T[0]);
227
}
228

    
229
static inline void gen_movl_reg_T1(int reg)
230
{
231
    gen_movl_reg_TN(reg, cpu_T[1]);
232
}
233

    
234
static inline void gen_movl_TN_reg(int reg, TCGv tn)
235
{
236
    if (reg == 0)
237
        return;
238
    else if (reg < 8)
239
        tcg_gen_st_tl(tn, cpu_env, offsetof(CPUState, gregs[reg]));
240
    else {
241
        tcg_gen_ld_ptr(cpu_regwptr, cpu_env, offsetof(CPUState, regwptr)); // XXX
242
        tcg_gen_st_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
243
    }
244
}
245

    
246
static inline void gen_movl_T0_reg(int reg)
247
{
248
    gen_movl_TN_reg(reg, cpu_T[0]);
249
}
250

    
251
static inline void gen_movl_T1_reg(int reg)
252
{
253
    gen_movl_TN_reg(reg, cpu_T[1]);
254
}
255

    
256
static inline void gen_op_movl_T0_env(size_t offset)
257
{
258
    tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
259
}
260

    
261
static inline void gen_op_movl_env_T0(size_t offset)
262
{
263
    tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
264
}
265

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

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

    
276
static inline void gen_op_add_T1_T0(void)
277
{
278
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
279
}
280

    
281
static inline void gen_op_or_T1_T0(void)
282
{
283
    tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
284
}
285

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

    
291
static inline void gen_jmp_im(target_ulong pc)
292
{
293
    tcg_gen_movi_tl(cpu_tmp0, pc);
294
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, pc));
295
}
296

    
297
static inline void gen_movl_npc_im(target_ulong npc)
298
{
299
    tcg_gen_movi_tl(cpu_tmp0, npc);
300
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, npc));
301
}
302

    
303
static inline void gen_goto_tb(DisasContext *s, int tb_num,
304
                               target_ulong pc, target_ulong npc)
305
{
306
    TranslationBlock *tb;
307

    
308
    tb = s->tb;
309
    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
310
        (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK))  {
311
        /* jump to same page: we can use a direct jump */
312
        tcg_gen_goto_tb(tb_num);
313
        gen_jmp_im(pc);
314
        gen_movl_npc_im(npc);
315
        tcg_gen_exit_tb((long)tb + tb_num);
316
    } else {
317
        /* jump to another page: currently not optimized */
318
        gen_jmp_im(pc);
319
        gen_movl_npc_im(npc);
320
        tcg_gen_exit_tb(0);
321
    }
322
}
323

    
324
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
325
                               target_ulong pc2)
326
{
327
    int l1;
328

    
329
    l1 = gen_new_label();
330

    
331
    gen_op_jz_T2_label(l1);
332

    
333
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
334

    
335
    gen_set_label(l1);
336
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
337
}
338

    
339
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
340
                                target_ulong pc2)
341
{
342
    int l1;
343

    
344
    l1 = gen_new_label();
345

    
346
    gen_op_jz_T2_label(l1);
347

    
348
    gen_goto_tb(dc, 0, pc2, pc1);
349

    
350
    gen_set_label(l1);
351
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
352
}
353

    
354
static inline void gen_branch(DisasContext *dc, target_ulong pc,
355
                              target_ulong npc)
356
{
357
    gen_goto_tb(dc, 0, pc, npc);
358
}
359

    
360
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2)
361
{
362
    int l1, l2;
363

    
364
    l1 = gen_new_label();
365
    l2 = gen_new_label();
366
    gen_op_jz_T2_label(l1);
367

    
368
    gen_movl_npc_im(npc1);
369
    gen_op_jmp_label(l2);
370

    
371
    gen_set_label(l1);
372
    gen_movl_npc_im(npc2);
373
    gen_set_label(l2);
374
}
375

    
376
/* call this function before using T2 as it may have been set for a jump */
377
static inline void flush_T2(DisasContext * dc)
378
{
379
    if (dc->npc == JUMP_PC) {
380
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
381
        dc->npc = DYNAMIC_PC;
382
    }
383
}
384

    
385
static inline void save_npc(DisasContext * dc)
386
{
387
    if (dc->npc == JUMP_PC) {
388
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
389
        dc->npc = DYNAMIC_PC;
390
    } else if (dc->npc != DYNAMIC_PC) {
391
        gen_movl_npc_im(dc->npc);
392
    }
393
}
394

    
395
static inline void save_state(DisasContext * dc)
396
{
397
    gen_jmp_im(dc->pc);
398
    save_npc(dc);
399
}
400

    
401
static inline void gen_mov_pc_npc(DisasContext * dc)
402
{
403
    if (dc->npc == JUMP_PC) {
404
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
405
        gen_op_mov_pc_npc();
406
        dc->pc = DYNAMIC_PC;
407
    } else if (dc->npc == DYNAMIC_PC) {
408
        gen_op_mov_pc_npc();
409
        dc->pc = DYNAMIC_PC;
410
    } else {
411
        dc->pc = dc->npc;
412
    }
413
}
414

    
415
static GenOpFunc * const gen_cond[2][16] = {
416
    {
417
        gen_op_eval_bn,
418
        gen_op_eval_be,
419
        gen_op_eval_ble,
420
        gen_op_eval_bl,
421
        gen_op_eval_bleu,
422
        gen_op_eval_bcs,
423
        gen_op_eval_bneg,
424
        gen_op_eval_bvs,
425
        gen_op_eval_ba,
426
        gen_op_eval_bne,
427
        gen_op_eval_bg,
428
        gen_op_eval_bge,
429
        gen_op_eval_bgu,
430
        gen_op_eval_bcc,
431
        gen_op_eval_bpos,
432
        gen_op_eval_bvc,
433
    },
434
    {
435
#ifdef TARGET_SPARC64
436
        gen_op_eval_bn,
437
        gen_op_eval_xbe,
438
        gen_op_eval_xble,
439
        gen_op_eval_xbl,
440
        gen_op_eval_xbleu,
441
        gen_op_eval_xbcs,
442
        gen_op_eval_xbneg,
443
        gen_op_eval_xbvs,
444
        gen_op_eval_ba,
445
        gen_op_eval_xbne,
446
        gen_op_eval_xbg,
447
        gen_op_eval_xbge,
448
        gen_op_eval_xbgu,
449
        gen_op_eval_xbcc,
450
        gen_op_eval_xbpos,
451
        gen_op_eval_xbvc,
452
#endif
453
    },
454
};
455

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

    
535
#ifdef TARGET_SPARC64
536
static void gen_cond_reg(int cond)
537
{
538
        switch (cond) {
539
        case 0x1:
540
            gen_op_eval_brz();
541
            break;
542
        case 0x2:
543
            gen_op_eval_brlez();
544
            break;
545
        case 0x3:
546
            gen_op_eval_brlz();
547
            break;
548
        case 0x5:
549
            gen_op_eval_brnz();
550
            break;
551
        case 0x6:
552
            gen_op_eval_brgz();
553
            break;
554
        default:
555
        case 0x7:
556
            gen_op_eval_brgez();
557
            break;
558
        }
559
}
560
#endif
561

    
562
/* XXX: potentially incorrect if dynamic npc */
563
static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
564
{
565
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
566
    target_ulong target = dc->pc + offset;
567

    
568
    if (cond == 0x0) {
569
        /* unconditional not taken */
570
        if (a) {
571
            dc->pc = dc->npc + 4;
572
            dc->npc = dc->pc + 4;
573
        } else {
574
            dc->pc = dc->npc;
575
            dc->npc = dc->pc + 4;
576
        }
577
    } else if (cond == 0x8) {
578
        /* unconditional taken */
579
        if (a) {
580
            dc->pc = target;
581
            dc->npc = dc->pc + 4;
582
        } else {
583
            dc->pc = dc->npc;
584
            dc->npc = target;
585
        }
586
    } else {
587
        flush_T2(dc);
588
        gen_cond[cc][cond]();
589
        if (a) {
590
            gen_branch_a(dc, target, dc->npc);
591
            dc->is_br = 1;
592
        } else {
593
            dc->pc = dc->npc;
594
            dc->jump_pc[0] = target;
595
            dc->jump_pc[1] = dc->npc + 4;
596
            dc->npc = JUMP_PC;
597
        }
598
    }
599
}
600

    
601
/* XXX: potentially incorrect if dynamic npc */
602
static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
603
{
604
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
605
    target_ulong target = dc->pc + offset;
606

    
607
    if (cond == 0x0) {
608
        /* unconditional not taken */
609
        if (a) {
610
            dc->pc = dc->npc + 4;
611
            dc->npc = dc->pc + 4;
612
        } else {
613
            dc->pc = dc->npc;
614
            dc->npc = dc->pc + 4;
615
        }
616
    } else if (cond == 0x8) {
617
        /* unconditional taken */
618
        if (a) {
619
            dc->pc = target;
620
            dc->npc = dc->pc + 4;
621
        } else {
622
            dc->pc = dc->npc;
623
            dc->npc = target;
624
        }
625
    } else {
626
        flush_T2(dc);
627
        gen_fcond[cc][cond]();
628
        if (a) {
629
            gen_branch_a(dc, target, dc->npc);
630
            dc->is_br = 1;
631
        } else {
632
            dc->pc = dc->npc;
633
            dc->jump_pc[0] = target;
634
            dc->jump_pc[1] = dc->npc + 4;
635
            dc->npc = JUMP_PC;
636
        }
637
    }
638
}
639

    
640
#ifdef TARGET_SPARC64
641
/* XXX: potentially incorrect if dynamic npc */
642
static void do_branch_reg(DisasContext * dc, int32_t offset, uint32_t insn)
643
{
644
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
645
    target_ulong target = dc->pc + offset;
646

    
647
    flush_T2(dc);
648
    gen_cond_reg(cond);
649
    if (a) {
650
        gen_branch_a(dc, target, dc->npc);
651
        dc->is_br = 1;
652
    } else {
653
        dc->pc = dc->npc;
654
        dc->jump_pc[0] = target;
655
        dc->jump_pc[1] = dc->npc + 4;
656
        dc->npc = JUMP_PC;
657
    }
658
}
659

    
660
static GenOpFunc * const gen_fcmps[4] = {
661
    gen_op_fcmps,
662
    gen_op_fcmps_fcc1,
663
    gen_op_fcmps_fcc2,
664
    gen_op_fcmps_fcc3,
665
};
666

    
667
static GenOpFunc * const gen_fcmpd[4] = {
668
    gen_op_fcmpd,
669
    gen_op_fcmpd_fcc1,
670
    gen_op_fcmpd_fcc2,
671
    gen_op_fcmpd_fcc3,
672
};
673

    
674
#if defined(CONFIG_USER_ONLY)
675
static GenOpFunc * const gen_fcmpq[4] = {
676
    gen_op_fcmpq,
677
    gen_op_fcmpq_fcc1,
678
    gen_op_fcmpq_fcc2,
679
    gen_op_fcmpq_fcc3,
680
};
681
#endif
682

    
683
static GenOpFunc * const gen_fcmpes[4] = {
684
    gen_op_fcmpes,
685
    gen_op_fcmpes_fcc1,
686
    gen_op_fcmpes_fcc2,
687
    gen_op_fcmpes_fcc3,
688
};
689

    
690
static GenOpFunc * const gen_fcmped[4] = {
691
    gen_op_fcmped,
692
    gen_op_fcmped_fcc1,
693
    gen_op_fcmped_fcc2,
694
    gen_op_fcmped_fcc3,
695
};
696

    
697
#if defined(CONFIG_USER_ONLY)
698
static GenOpFunc * const gen_fcmpeq[4] = {
699
    gen_op_fcmpeq,
700
    gen_op_fcmpeq_fcc1,
701
    gen_op_fcmpeq_fcc2,
702
    gen_op_fcmpeq_fcc3,
703
};
704
#endif
705
#endif
706

    
707
static int gen_trap_ifnofpu(DisasContext * dc)
708
{
709
#if !defined(CONFIG_USER_ONLY)
710
    if (!dc->fpu_enabled) {
711
        save_state(dc);
712
        gen_op_exception(TT_NFPU_INSN);
713
        dc->is_br = 1;
714
        return 1;
715
    }
716
#endif
717
    return 0;
718
}
719

    
720
/* asi moves */
721
#ifdef TARGET_SPARC64
722
static inline void gen_ld_asi(int insn, int size, int sign)
723
{
724
    int asi, offset;
725
    TCGv r_size, r_sign;
726

    
727
    r_size = tcg_temp_new(TCG_TYPE_I32);
728
    r_sign = tcg_temp_new(TCG_TYPE_I32);
729
    tcg_gen_movi_i32(r_size, size);
730
    tcg_gen_movi_i32(r_sign, sign);
731
    if (IS_IMM) {
732
        offset = GET_FIELD(insn, 25, 31);
733
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
734
        tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUSPARCState, asi));
735
    } else {
736
        asi = GET_FIELD(insn, 19, 26);
737
        tcg_gen_movi_i32(cpu_T[1], asi);
738
    }
739
    tcg_gen_helper_1_4(helper_ld_asi, cpu_T[1], cpu_T[0], cpu_T[1], r_size,
740
                       r_sign);
741
}
742

    
743
static inline void gen_st_asi(int insn, int size)
744
{
745
    int asi, offset;
746
    TCGv r_asi, r_size;
747

    
748
    r_asi = tcg_temp_new(TCG_TYPE_I32);
749
    r_size = tcg_temp_new(TCG_TYPE_I32);
750
    tcg_gen_movi_i32(r_size, size);
751
    if (IS_IMM) {
752
        offset = GET_FIELD(insn, 25, 31);
753
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
754
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
755
    } else {
756
        asi = GET_FIELD(insn, 19, 26);
757
        tcg_gen_movi_i32(r_asi, asi);
758
    }
759
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], r_asi, r_size);
760
}
761

    
762
static inline void gen_ldf_asi(int insn, int size, int rd)
763
{
764
    int asi, offset;
765
    TCGv r_asi, r_size, r_rd;
766

    
767
    r_asi = tcg_temp_new(TCG_TYPE_I32);
768
    r_size = tcg_temp_new(TCG_TYPE_I32);
769
    r_rd = tcg_temp_new(TCG_TYPE_I32);
770
    tcg_gen_movi_i32(r_size, size);
771
    tcg_gen_movi_i32(r_rd, rd);
772
    if (IS_IMM) {
773
        offset = GET_FIELD(insn, 25, 31);
774
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
775
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
776
    } else {
777
        asi = GET_FIELD(insn, 19, 26);
778
        tcg_gen_movi_i32(r_asi, asi);
779
    }
780
    tcg_gen_helper_0_4(helper_ldf_asi, cpu_T[0], r_asi, r_size, r_rd);
781
}
782

    
783
static inline void gen_stf_asi(int insn, int size, int rd)
784
{
785
    int asi, offset;
786
    TCGv r_asi, r_size, r_rd;
787

    
788
    r_asi = tcg_temp_new(TCG_TYPE_I32);
789
    r_size = tcg_temp_new(TCG_TYPE_I32);
790
    r_rd = tcg_temp_new(TCG_TYPE_I32);
791
    tcg_gen_movi_i32(r_size, size);
792
    tcg_gen_movi_i32(r_rd, rd);
793
    if (IS_IMM) {
794
        offset = GET_FIELD(insn, 25, 31);
795
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
796
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
797
    } else {
798
        asi = GET_FIELD(insn, 19, 26);
799
        tcg_gen_movi_i32(r_asi, asi);
800
    }
801
    tcg_gen_helper_0_4(helper_stf_asi, cpu_T[0], r_asi, r_size, r_rd);
802
}
803

    
804
static inline void gen_swap_asi(int insn)
805
{
806
    int asi, offset;
807
    TCGv r_size, r_sign, r_temp;
808

    
809
    r_size = tcg_temp_new(TCG_TYPE_I32);
810
    r_sign = tcg_temp_new(TCG_TYPE_I32);
811
    r_temp = tcg_temp_new(TCG_TYPE_I32);
812
    tcg_gen_movi_i32(r_size, 4);
813
    tcg_gen_movi_i32(r_sign, 0);
814
    if (IS_IMM) {
815
        offset = GET_FIELD(insn, 25, 31);
816
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
817
        tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUSPARCState, asi));
818
    } else {
819
        asi = GET_FIELD(insn, 19, 26);
820
        tcg_gen_movi_i32(cpu_T[1], asi);
821
    }
822
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, cpu_T[0], cpu_T[1], r_size,
823
                       r_sign);
824
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], r_size, r_sign);
825
    tcg_gen_mov_i32(cpu_T[1], r_temp);
826
}
827

    
828
static inline void gen_ldda_asi(int insn)
829
{
830
    int asi, offset;
831
    TCGv r_size, r_sign, r_dword;
832

    
833
    r_size = tcg_temp_new(TCG_TYPE_I32);
834
    r_sign = tcg_temp_new(TCG_TYPE_I32);
835
    r_dword = tcg_temp_new(TCG_TYPE_I64);
836
    tcg_gen_movi_i32(r_size, 8);
837
    tcg_gen_movi_i32(r_sign, 0);
838
    if (IS_IMM) {
839
        offset = GET_FIELD(insn, 25, 31);
840
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
841
        tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUSPARCState, asi));
842
    } else {
843
        asi = GET_FIELD(insn, 19, 26);
844
        tcg_gen_movi_i32(cpu_T[1], asi);
845
    }
846
    tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], cpu_T[1], r_size,
847
                       r_sign);
848
    tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
849
    tcg_gen_shri_i64(r_dword, r_dword, 32);
850
    tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
851
}
852

    
853
static inline void gen_cas_asi(int insn, int rd)
854
{
855
    int asi, offset;
856
    TCGv r_val1, r_asi;
857

    
858
    r_val1 = tcg_temp_new(TCG_TYPE_I32);
859
    r_asi = tcg_temp_new(TCG_TYPE_I32);
860
    gen_movl_reg_TN(rd, r_val1);
861
    if (IS_IMM) {
862
        offset = GET_FIELD(insn, 25, 31);
863
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
864
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
865
    } else {
866
        asi = GET_FIELD(insn, 19, 26);
867
        tcg_gen_movi_i32(r_asi, asi);
868
    }
869
    tcg_gen_helper_1_4(helper_cas_asi, cpu_T[1], cpu_T[0], r_val1, cpu_T[1],
870
                       r_asi);
871
}
872

    
873
static inline void gen_casx_asi(int insn, int rd)
874
{
875
    int asi, offset;
876
    TCGv r_val1, r_asi;
877

    
878
    r_val1 = tcg_temp_new(TCG_TYPE_I64);
879
    r_asi = tcg_temp_new(TCG_TYPE_I32);
880
    gen_movl_reg_TN(rd, r_val1);
881
    if (IS_IMM) {
882
        offset = GET_FIELD(insn, 25, 31);
883
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
884
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
885
    } else {
886
        asi = GET_FIELD(insn, 19, 26);
887
        tcg_gen_movi_i32(r_asi, asi);
888
    }
889
    tcg_gen_helper_1_4(helper_casx_asi, cpu_T[1], cpu_T[0], r_val1, cpu_T[1],
890
                       r_asi);
891
}
892

    
893
#elif !defined(CONFIG_USER_ONLY)
894

    
895
static inline void gen_ld_asi(int insn, int size, int sign)
896
{
897
    int asi;
898
    TCGv r_size, r_sign, r_dword;
899

    
900
    r_size = tcg_temp_new(TCG_TYPE_I32);
901
    r_sign = tcg_temp_new(TCG_TYPE_I32);
902
    r_dword = tcg_temp_new(TCG_TYPE_I64);
903
    tcg_gen_movi_i32(r_size, size);
904
    tcg_gen_movi_i32(r_sign, sign);
905
    asi = GET_FIELD(insn, 19, 26);
906
    tcg_gen_movi_i32(cpu_T[1], asi);
907
    tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], cpu_T[1], r_size,
908
                       r_sign);
909
    tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
910
}
911

    
912
static inline void gen_st_asi(int insn, int size)
913
{
914
    int asi;
915
    TCGv r_dword, r_asi, r_size;
916

    
917
    r_dword = tcg_temp_new(TCG_TYPE_I64);
918
    tcg_gen_extu_i32_i64(r_dword, cpu_T[1]);
919
    r_asi = tcg_temp_new(TCG_TYPE_I32);
920
    r_size = tcg_temp_new(TCG_TYPE_I32);
921
    asi = GET_FIELD(insn, 19, 26);
922
    tcg_gen_movi_i32(r_asi, asi);
923
    tcg_gen_movi_i32(r_size, size);
924
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, r_asi, r_size);
925
}
926

    
927
static inline void gen_swap_asi(int insn)
928
{
929
    int asi;
930
    TCGv r_size, r_sign, r_temp;
931

    
932
    r_size = tcg_temp_new(TCG_TYPE_I32);
933
    r_sign = tcg_temp_new(TCG_TYPE_I32);
934
    r_temp = tcg_temp_new(TCG_TYPE_I32);
935
    tcg_gen_movi_i32(r_size, 4);
936
    tcg_gen_movi_i32(r_sign, 0);
937
    asi = GET_FIELD(insn, 19, 26);
938
    tcg_gen_movi_i32(cpu_T[1], asi);
939
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, cpu_T[0], cpu_T[1], r_size,
940
                       r_sign);
941
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], r_size, r_sign);
942
    tcg_gen_mov_i32(cpu_T[1], r_temp);
943
}
944

    
945
static inline void gen_ldda_asi(int insn)
946
{
947
    int asi;
948
    TCGv r_size, r_sign, r_dword;
949

    
950
    r_size = tcg_temp_new(TCG_TYPE_I32);
951
    r_sign = tcg_temp_new(TCG_TYPE_I32);
952
    r_dword = tcg_temp_new(TCG_TYPE_I64);
953
    tcg_gen_movi_i32(r_size, 8);
954
    tcg_gen_movi_i32(r_sign, 0);
955
    asi = GET_FIELD(insn, 19, 26);
956
    tcg_gen_movi_i32(cpu_T[1], asi);
957
    tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], cpu_T[1], r_size,
958
                       r_sign);
959
    tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
960
    tcg_gen_shri_i64(r_dword, r_dword, 32);
961
    tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
962
}
963
#endif
964

    
965
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
966
static inline void gen_ldstub_asi(int insn)
967
{
968
    int asi;
969
    TCGv r_dword, r_asi, r_size;
970

    
971
    gen_ld_asi(insn, 1, 0);
972

    
973
    r_dword = tcg_temp_new(TCG_TYPE_I64);
974
    r_asi = tcg_temp_new(TCG_TYPE_I32);
975
    r_size = tcg_temp_new(TCG_TYPE_I32);
976
    asi = GET_FIELD(insn, 19, 26);
977
    tcg_gen_movi_i32(r_dword, 0xff);
978
    tcg_gen_movi_i32(r_asi, asi);
979
    tcg_gen_movi_i32(r_size, 1);
980
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, r_asi, r_size);
981
}
982
#endif
983

    
984
/* before an instruction, dc->pc must be static */
985
static void disas_sparc_insn(DisasContext * dc)
986
{
987
    unsigned int insn, opc, rs1, rs2, rd;
988

    
989
    insn = ldl_code(dc->pc);
990
    opc = GET_FIELD(insn, 0, 1);
991

    
992
    rd = GET_FIELD(insn, 2, 6);
993
    switch (opc) {
994
    case 0:                     /* branches/sethi */
995
        {
996
            unsigned int xop = GET_FIELD(insn, 7, 9);
997
            int32_t target;
998
            switch (xop) {
999
#ifdef TARGET_SPARC64
1000
            case 0x1:           /* V9 BPcc */
1001
                {
1002
                    int cc;
1003

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

    
1085
            tcg_gen_movi_tl(cpu_T[0], dc->pc);
1086
            gen_movl_T0_reg(15);
1087
            target += dc->pc;
1088
            gen_mov_pc_npc(dc);
1089
            dc->npc = target;
1090
        }
1091
        goto jmp_insn;
1092
    case 2:                     /* FPU & Logical Operations */
1093
        {
1094
            unsigned int xop = GET_FIELD(insn, 7, 12);
1095
            if (xop == 0x3a) {  /* generate trap */
1096
                int cond;
1097

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

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

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

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

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

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

    
3281
                        gen_op_check_align_T0_7();
3282
                        r_dword = tcg_temp_new(TCG_TYPE_I64);
3283
                        r_low = tcg_temp_new(TCG_TYPE_I32);
3284
                        gen_movl_reg_TN(rd + 1, r_low);
3285
                        tcg_gen_helper_1_2(helper_pack64, r_dword, cpu_T[1],
3286
                                           r_low);
3287
                        tcg_gen_qemu_st64(r_dword, cpu_T[0], dc->mem_idx);
3288
                    }
3289
                    break;
3290
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
3291
                case 0x14: /* store word alternate */
3292
#ifndef TARGET_SPARC64
3293
                    if (IS_IMM)
3294
                        goto illegal_insn;
3295
                    if (!supervisor(dc))
3296
                        goto priv_insn;
3297
#endif
3298
                    gen_op_check_align_T0_3();
3299
                    gen_st_asi(insn, 4);
3300
                    break;
3301
                case 0x15: /* store byte alternate */
3302
#ifndef TARGET_SPARC64
3303
                    if (IS_IMM)
3304
                        goto illegal_insn;
3305
                    if (!supervisor(dc))
3306
                        goto priv_insn;
3307
#endif
3308
                    gen_st_asi(insn, 1);
3309
                    break;
3310
                case 0x16: /* store halfword alternate */
3311
#ifndef TARGET_SPARC64
3312
                    if (IS_IMM)
3313
                        goto illegal_insn;
3314
                    if (!supervisor(dc))
3315
                        goto priv_insn;
3316
#endif
3317
                    gen_op_check_align_T0_1();
3318
                    gen_st_asi(insn, 2);
3319
                    break;
3320
                case 0x17: /* store double word alternate */
3321
#ifndef TARGET_SPARC64
3322
                    if (IS_IMM)
3323
                        goto illegal_insn;
3324
                    if (!supervisor(dc))
3325
                        goto priv_insn;
3326
#endif
3327
                    if (rd & 1)
3328
                        goto illegal_insn;
3329
                    else {
3330
                        int asi;
3331
                        TCGv r_dword, r_temp, r_size;
3332

    
3333
                        gen_op_check_align_T0_7();
3334
                        r_dword = tcg_temp_new(TCG_TYPE_I64);
3335
                        r_temp = tcg_temp_new(TCG_TYPE_I32);
3336
                        r_size = tcg_temp_new(TCG_TYPE_I32);
3337
                        gen_movl_reg_TN(rd + 1, r_temp);
3338
                        tcg_gen_helper_1_2(helper_pack64, r_dword, cpu_T[1],
3339
                                           r_temp);
3340
#ifdef TARGET_SPARC64
3341
                        if (IS_IMM) {
3342
                            int offset;
3343

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

    
3515
static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
3516
{
3517
}
3518

    
3519
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
3520
                                                 int spc, CPUSPARCState *env)
3521
{
3522
    target_ulong pc_start, last_pc;
3523
    uint16_t *gen_opc_end;
3524
    DisasContext dc1, *dc = &dc1;
3525
    int j, lj = -1;
3526

    
3527
    memset(dc, 0, sizeof(DisasContext));
3528
    dc->tb = tb;
3529
    pc_start = tb->pc;
3530
    dc->pc = pc_start;
3531
    last_pc = dc->pc;
3532
    dc->npc = (target_ulong) tb->cs_base;
3533
    dc->mem_idx = cpu_mmu_index(env);
3534
    dc->fpu_enabled = cpu_fpu_enabled(env);
3535
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
3536

    
3537
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
3538
    cpu_regwptr = tcg_temp_new(TCG_TYPE_PTR); // XXX
3539

    
3540
    do {
3541
        if (env->nb_breakpoints > 0) {
3542
            for(j = 0; j < env->nb_breakpoints; j++) {
3543
                if (env->breakpoints[j] == dc->pc) {
3544
                    if (dc->pc != pc_start)
3545
                        save_state(dc);
3546
                    tcg_gen_helper_0_0(helper_debug);
3547
                    tcg_gen_exit_tb(0);
3548
                    dc->is_br = 1;
3549
                    goto exit_gen_loop;
3550
                }
3551
            }
3552
        }
3553
        if (spc) {
3554
            if (loglevel > 0)
3555
                fprintf(logfile, "Search PC...\n");
3556
            j = gen_opc_ptr - gen_opc_buf;
3557
            if (lj < j) {
3558
                lj++;
3559
                while (lj < j)
3560
                    gen_opc_instr_start[lj++] = 0;
3561
                gen_opc_pc[lj] = dc->pc;
3562
                gen_opc_npc[lj] = dc->npc;
3563
                gen_opc_instr_start[lj] = 1;
3564
            }
3565
        }
3566
        last_pc = dc->pc;
3567
        disas_sparc_insn(dc);
3568

    
3569
        if (dc->is_br)
3570
            break;
3571
        /* if the next PC is different, we abort now */
3572
        if (dc->pc != (last_pc + 4))
3573
            break;
3574
        /* if we reach a page boundary, we stop generation so that the
3575
           PC of a TT_TFAULT exception is always in the right page */
3576
        if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
3577
            break;
3578
        /* if single step mode, we generate only one instruction and
3579
           generate an exception */
3580
        if (env->singlestep_enabled) {
3581
            gen_jmp_im(dc->pc);
3582
            tcg_gen_exit_tb(0);
3583
            break;
3584
        }
3585
    } while ((gen_opc_ptr < gen_opc_end) &&
3586
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
3587

    
3588
 exit_gen_loop:
3589
    if (!dc->is_br) {
3590
        if (dc->pc != DYNAMIC_PC &&
3591
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
3592
            /* static PC and NPC: we can use direct chaining */
3593
            gen_branch(dc, dc->pc, dc->npc);
3594
        } else {
3595
            if (dc->pc != DYNAMIC_PC)
3596
                gen_jmp_im(dc->pc);
3597
            save_npc(dc);
3598
            tcg_gen_exit_tb(0);
3599
        }
3600
    }
3601
    *gen_opc_ptr = INDEX_op_end;
3602
    if (spc) {
3603
        j = gen_opc_ptr - gen_opc_buf;
3604
        lj++;
3605
        while (lj <= j)
3606
            gen_opc_instr_start[lj++] = 0;
3607
#if 0
3608
        if (loglevel > 0) {
3609
            page_dump(logfile);
3610
        }
3611
#endif
3612
        gen_opc_jump_pc[0] = dc->jump_pc[0];
3613
        gen_opc_jump_pc[1] = dc->jump_pc[1];
3614
    } else {
3615
        tb->size = last_pc + 4 - pc_start;
3616
    }
3617
#ifdef DEBUG_DISAS
3618
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3619
        fprintf(logfile, "--------------\n");
3620
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
3621
        target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
3622
        fprintf(logfile, "\n");
3623
    }
3624
#endif
3625
    return 0;
3626
}
3627

    
3628
int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
3629
{
3630
    return gen_intermediate_code_internal(tb, 0, env);
3631
}
3632

    
3633
int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
3634
{
3635
    return gen_intermediate_code_internal(tb, 1, env);
3636
}
3637

    
3638
void cpu_reset(CPUSPARCState *env)
3639
{
3640
    tlb_flush(env, 1);
3641
    env->cwp = 0;
3642
    env->wim = 1;
3643
    env->regwptr = env->regbase + (env->cwp * 16);
3644
#if defined(CONFIG_USER_ONLY)
3645
    env->user_mode_only = 1;
3646
#ifdef TARGET_SPARC64
3647
    env->cleanwin = NWINDOWS - 2;
3648
    env->cansave = NWINDOWS - 2;
3649
    env->pstate = PS_RMO | PS_PEF | PS_IE;
3650
    env->asi = 0x82; // Primary no-fault
3651
#endif
3652
#else
3653
    env->psret = 0;
3654
    env->psrs = 1;
3655
    env->psrps = 1;
3656
#ifdef TARGET_SPARC64
3657
    env->pstate = PS_PRIV;
3658
    env->hpstate = HS_PRIV;
3659
    env->pc = 0x1fff0000000ULL;
3660
#else
3661
    env->pc = 0;
3662
    env->mmuregs[0] &= ~(MMU_E | MMU_NF);
3663
    env->mmuregs[0] |= env->mmu_bm;
3664
#endif
3665
    env->npc = env->pc + 4;
3666
#endif
3667
}
3668

    
3669
CPUSPARCState *cpu_sparc_init(const char *cpu_model)
3670
{
3671
    CPUSPARCState *env;
3672
    const sparc_def_t *def;
3673
    static int inited;
3674

    
3675
    def = cpu_sparc_find_by_name(cpu_model);
3676
    if (!def)
3677
        return NULL;
3678

    
3679
    env = qemu_mallocz(sizeof(CPUSPARCState));
3680
    if (!env)
3681
        return NULL;
3682
    cpu_exec_init(env);
3683
    env->cpu_model_str = cpu_model;
3684
    env->version = def->iu_version;
3685
    env->fsr = def->fpu_version;
3686
#if !defined(TARGET_SPARC64)
3687
    env->mmu_bm = def->mmu_bm;
3688
    env->mmu_ctpr_mask = def->mmu_ctpr_mask;
3689
    env->mmu_cxr_mask = def->mmu_cxr_mask;
3690
    env->mmu_sfsr_mask = def->mmu_sfsr_mask;
3691
    env->mmu_trcr_mask = def->mmu_trcr_mask;
3692
    env->mmuregs[0] |= def->mmu_version;
3693
    cpu_sparc_set_id(env, 0);
3694
#endif
3695

    
3696
    /* init various static tables */
3697
    if (!inited) {
3698
        inited = 1;
3699

    
3700
        tcg_set_macro_func(&tcg_ctx, tcg_macro_func);
3701
        cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
3702
        //#if TARGET_LONG_BITS > HOST_LONG_BITS
3703
#ifdef TARGET_SPARC64
3704
        cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
3705
                                      TCG_AREG0, offsetof(CPUState, t0), "T0");
3706
        cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
3707
                                      TCG_AREG0, offsetof(CPUState, t1), "T1");
3708
        cpu_T[2] = tcg_global_mem_new(TCG_TYPE_TL,
3709
                                      TCG_AREG0, offsetof(CPUState, t2), "T2");
3710
#else
3711
        cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
3712
        cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
3713
        cpu_T[2] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T2");
3714
#endif
3715
    }
3716

    
3717
    cpu_reset(env);
3718
    
3719
    return env;
3720
}
3721

    
3722
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
3723
{
3724
#if !defined(TARGET_SPARC64)
3725
    env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
3726
#endif
3727
}
3728

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

    
4049
static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name)
4050
{
4051
    unsigned int i;
4052

    
4053
    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
4054
        if (strcasecmp(name, sparc_defs[i].name) == 0) {
4055
            return &sparc_defs[i];
4056
        }
4057
    }
4058
    return NULL;
4059
}
4060

    
4061
void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
4062
{
4063
    unsigned int i;
4064

    
4065
    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
4066
        (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x\n",
4067
                       sparc_defs[i].name,
4068
                       sparc_defs[i].iu_version,
4069
                       sparc_defs[i].fpu_version,
4070
                       sparc_defs[i].mmu_version);
4071
    }
4072
}
4073

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

    
4076
void cpu_dump_state(CPUState *env, FILE *f,
4077
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
4078
                    int flags)
4079
{
4080
    int i, x;
4081

    
4082
    cpu_fprintf(f, "pc: " TARGET_FMT_lx "  npc: " TARGET_FMT_lx "\n", env->pc, env->npc);
4083
    cpu_fprintf(f, "General Registers:\n");
4084
    for (i = 0; i < 4; i++)
4085
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
4086
    cpu_fprintf(f, "\n");
4087
    for (; i < 8; i++)
4088
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
4089
    cpu_fprintf(f, "\nCurrent Register Window:\n");
4090
    for (x = 0; x < 3; x++) {
4091
        for (i = 0; i < 4; i++)
4092
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
4093
                    (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
4094
                    env->regwptr[i + x * 8]);
4095
        cpu_fprintf(f, "\n");
4096
        for (; i < 8; i++)
4097
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
4098
                    (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
4099
                    env->regwptr[i + x * 8]);
4100
        cpu_fprintf(f, "\n");
4101
    }
4102
    cpu_fprintf(f, "\nFloating Point Registers:\n");
4103
    for (i = 0; i < 32; i++) {
4104
        if ((i & 3) == 0)
4105
            cpu_fprintf(f, "%%f%02d:", i);
4106
        cpu_fprintf(f, " %016lf", env->fpr[i]);
4107
        if ((i & 3) == 3)
4108
            cpu_fprintf(f, "\n");
4109
    }
4110
#ifdef TARGET_SPARC64
4111
    cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d fprs: %d\n",
4112
                env->pstate, GET_CCR(env), env->asi, env->tl, env->fprs);
4113
    cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d cleanwin %d cwp %d\n",
4114
                env->cansave, env->canrestore, env->otherwin, env->wstate,
4115
                env->cleanwin, NWINDOWS - 1 - env->cwp);
4116
#else
4117
    cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n", GET_PSR(env),
4118
            GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
4119
            GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
4120
            env->psrs?'S':'-', env->psrps?'P':'-',
4121
            env->psret?'E':'-', env->wim);
4122
#endif
4123
    cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env));
4124
}
4125

    
4126
#if defined(CONFIG_USER_ONLY)
4127
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
4128
{
4129
    return addr;
4130
}
4131

    
4132
#else
4133
extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
4134
                                 int *access_index, target_ulong address, int rw,
4135
                                 int mmu_idx);
4136

    
4137
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
4138
{
4139
    target_phys_addr_t phys_addr;
4140
    int prot, access_index;
4141

    
4142
    if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2,
4143
                             MMU_KERNEL_IDX) != 0)
4144
        if (get_physical_address(env, &phys_addr, &prot, &access_index, addr,
4145
                                 0, MMU_KERNEL_IDX) != 0)
4146
            return -1;
4147
    if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED)
4148
        return -1;
4149
    return phys_addr;
4150
}
4151
#endif
4152

    
4153
void helper_flush(target_ulong addr)
4154
{
4155
    addr &= ~7;
4156
    tb_invalidate_page_range(addr, addr + 8);
4157
}