Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ 56ec06bb

History | View | Annotate | Download (168.6 kB)

1
/*
2
   SPARC translation
3

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

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

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

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

    
22
/*
23
   TODO-list:
24

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

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

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

    
42
#define DEBUG_DISAS
43

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

    
48
/* global register indexes */
49
static TCGv cpu_env, cpu_T[3], cpu_regwptr;
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 FFPREG(r) (r)
95
#define DFPREG(r) (((r & 1) << 5) | (r & 0x1e))
96
#define QFPREG(r) (((r & 1) << 5) | (r & 0x1c))
97
#else
98
#define FFPREG(r) (r)
99
#define DFPREG(r) (r & 0x1e)
100
#define QFPREG(r) (r & 0x1c)
101
#endif
102

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

    
109
#define IS_IMM (insn & (1<<13))
110

    
111
static void disas_sparc_insn(DisasContext * dc);
112

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
361
// 1
362
static inline void gen_op_eval_ba(TCGv dst)
363
{
364
    tcg_gen_movi_tl(dst, 1);
365
}
366

    
367
// Z
368
static inline void gen_op_eval_be(TCGv dst, TCGv src)
369
{
370
    gen_mov_reg_Z(dst, src);
371
}
372

    
373
// Z | (N ^ V)
374
static inline void gen_op_eval_ble(TCGv dst, TCGv src)
375
{
376
    TCGv r_flag;
377

    
378
    r_flag = tcg_temp_new(TCG_TYPE_TL);
379
    gen_mov_reg_N(r_flag, src);
380
    gen_mov_reg_V(dst, src);
381
    tcg_gen_xor_tl(dst, dst, r_flag);
382
    gen_mov_reg_Z(r_flag, src);
383
    tcg_gen_or_tl(dst, dst, r_flag);
384
}
385

    
386
// N ^ V
387
static inline void gen_op_eval_bl(TCGv dst, TCGv src)
388
{
389
    TCGv r_V;
390

    
391
    r_V = tcg_temp_new(TCG_TYPE_TL);
392
    gen_mov_reg_V(r_V, src);
393
    gen_mov_reg_N(dst, src);
394
    tcg_gen_xor_tl(dst, dst, r_V);
395
}
396

    
397
// C | Z
398
static inline void gen_op_eval_bleu(TCGv dst, TCGv src)
399
{
400
    TCGv r_Z;
401

    
402
    r_Z = tcg_temp_new(TCG_TYPE_TL);
403
    gen_mov_reg_Z(r_Z, src);
404
    gen_mov_reg_C(dst, src);
405
    tcg_gen_or_tl(dst, dst, r_Z);
406
}
407

    
408
// C
409
static inline void gen_op_eval_bcs(TCGv dst, TCGv src)
410
{
411
    gen_mov_reg_C(dst, src);
412
}
413

    
414
// V
415
static inline void gen_op_eval_bvs(TCGv dst, TCGv src)
416
{
417
    gen_mov_reg_V(dst, src);
418
}
419

    
420
// 0
421
static inline void gen_op_eval_bn(TCGv dst)
422
{
423
    tcg_gen_movi_tl(dst, 0);
424
}
425

    
426
// N
427
static inline void gen_op_eval_bneg(TCGv dst, TCGv src)
428
{
429
    gen_mov_reg_N(dst, src);
430
}
431

    
432
// !Z
433
static inline void gen_op_eval_bne(TCGv dst, TCGv src)
434
{
435
    gen_mov_reg_Z(dst, src);
436
    tcg_gen_xori_tl(dst, dst, 0x1);
437
}
438

    
439
// !(Z | (N ^ V))
440
static inline void gen_op_eval_bg(TCGv dst, TCGv src)
441
{
442
    TCGv r_flag;
443

    
444
    r_flag = tcg_temp_new(TCG_TYPE_TL);
445
    gen_mov_reg_N(r_flag, src);
446
    gen_mov_reg_V(dst, src);
447
    tcg_gen_xor_tl(dst, dst, r_flag);
448
    gen_mov_reg_Z(r_flag, src);
449
    tcg_gen_or_tl(dst, dst, r_flag);
450
    tcg_gen_xori_tl(dst, dst, 0x1);
451
}
452

    
453
// !(N ^ V)
454
static inline void gen_op_eval_bge(TCGv dst, TCGv src)
455
{
456
    TCGv r_V;
457

    
458
    r_V = tcg_temp_new(TCG_TYPE_TL);
459
    gen_mov_reg_V(r_V, src);
460
    gen_mov_reg_N(dst, src);
461
    tcg_gen_xor_tl(dst, dst, r_V);
462
    tcg_gen_xori_tl(dst, dst, 0x1);
463
}
464

    
465
// !(C | Z)
466
static inline void gen_op_eval_bgu(TCGv dst, TCGv src)
467
{
468
    TCGv r_Z;
469

    
470
    r_Z = tcg_temp_new(TCG_TYPE_TL);
471
    gen_mov_reg_Z(r_Z, src);
472
    gen_mov_reg_C(dst, src);
473
    tcg_gen_or_tl(dst, dst, r_Z);
474
    tcg_gen_xori_tl(dst, dst, 0x1);
475
}
476

    
477
// !C
478
static inline void gen_op_eval_bcc(TCGv dst, TCGv src)
479
{
480
    gen_mov_reg_C(dst, src);
481
    tcg_gen_xori_tl(dst, dst, 0x1);
482
}
483

    
484
// !N
485
static inline void gen_op_eval_bpos(TCGv dst, TCGv src)
486
{
487
    gen_mov_reg_N(dst, src);
488
    tcg_gen_xori_tl(dst, dst, 0x1);
489
}
490

    
491
// !V
492
static inline void gen_op_eval_bvc(TCGv dst, TCGv src)
493
{
494
    gen_mov_reg_V(dst, src);
495
    tcg_gen_xori_tl(dst, dst, 0x1);
496
}
497

    
498
/*
499
  FPSR bit field FCC1 | FCC0:
500
   0 =
501
   1 <
502
   2 >
503
   3 unordered
504
*/
505
static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src,
506
                                    unsigned int fcc_offset)
507
{
508
    tcg_gen_shri_i32(reg, src, 10 + fcc_offset);
509
    tcg_gen_andi_tl(reg, reg, 0x1);
510
}
511

    
512
static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
513
                                    unsigned int fcc_offset)
514
{
515
    tcg_gen_shri_i32(reg, src, 11 + fcc_offset);
516
    tcg_gen_andi_tl(reg, reg, 0x1);
517
}
518

    
519
// !0: FCC0 | FCC1
520
static inline void gen_op_eval_fbne(TCGv dst, TCGv src,
521
                                    unsigned int fcc_offset)
522
{
523
    TCGv r_fcc1;
524

    
525
    r_fcc1 = tcg_temp_new(TCG_TYPE_TL);
526
    gen_mov_reg_FCC0(dst, src, fcc_offset);
527
    gen_mov_reg_FCC1(r_fcc1, src, fcc_offset);
528
    tcg_gen_or_tl(dst, dst, r_fcc1);
529
}
530

    
531
// 1 or 2: FCC0 ^ FCC1
532
static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
533
                                    unsigned int fcc_offset)
534
{
535
    TCGv r_fcc1;
536

    
537
    r_fcc1 = tcg_temp_new(TCG_TYPE_TL);
538
    gen_mov_reg_FCC0(dst, src, fcc_offset);
539
    gen_mov_reg_FCC1(r_fcc1, src, fcc_offset);
540
    tcg_gen_xor_tl(dst, dst, r_fcc1);
541
}
542

    
543
// 1 or 3: FCC0
544
static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
545
                                    unsigned int fcc_offset)
546
{
547
    gen_mov_reg_FCC0(dst, src, fcc_offset);
548
}
549

    
550
// 1: FCC0 & !FCC1
551
static inline void gen_op_eval_fbl(TCGv dst, TCGv src,
552
                                    unsigned int fcc_offset)
553
{
554
    TCGv r_fcc1;
555

    
556
    r_fcc1 = tcg_temp_new(TCG_TYPE_TL);
557
    gen_mov_reg_FCC0(dst, src, fcc_offset);
558
    gen_mov_reg_FCC1(r_fcc1, src, fcc_offset);
559
    tcg_gen_xori_tl(r_fcc1, r_fcc1, 0x1);
560
    tcg_gen_and_tl(dst, dst, r_fcc1);
561
}
562

    
563
// 2 or 3: FCC1
564
static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
565
                                    unsigned int fcc_offset)
566
{
567
    gen_mov_reg_FCC1(dst, src, fcc_offset);
568
}
569

    
570
// 2: !FCC0 & FCC1
571
static inline void gen_op_eval_fbg(TCGv dst, TCGv src,
572
                                    unsigned int fcc_offset)
573
{
574
    TCGv r_fcc1;
575

    
576
    r_fcc1 = tcg_temp_new(TCG_TYPE_TL);
577
    gen_mov_reg_FCC0(dst, src, fcc_offset);
578
    tcg_gen_xori_tl(dst, dst, 0x1);
579
    gen_mov_reg_FCC1(r_fcc1, src, fcc_offset);
580
    tcg_gen_and_tl(dst, dst, r_fcc1);
581
}
582

    
583
// 3: FCC0 & FCC1
584
static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
585
                                    unsigned int fcc_offset)
586
{
587
    TCGv r_fcc1;
588

    
589
    r_fcc1 = tcg_temp_new(TCG_TYPE_TL);
590
    gen_mov_reg_FCC0(dst, src, fcc_offset);
591
    gen_mov_reg_FCC1(r_fcc1, src, fcc_offset);
592
    tcg_gen_and_tl(dst, dst, r_fcc1);
593
}
594

    
595
// 0: !(FCC0 | FCC1)
596
static inline void gen_op_eval_fbe(TCGv dst, TCGv src,
597
                                    unsigned int fcc_offset)
598
{
599
    TCGv r_fcc1;
600

    
601
    r_fcc1 = tcg_temp_new(TCG_TYPE_TL);
602
    gen_mov_reg_FCC0(dst, src, fcc_offset);
603
    gen_mov_reg_FCC1(r_fcc1, src, fcc_offset);
604
    tcg_gen_or_tl(dst, dst, r_fcc1);
605
    tcg_gen_xori_tl(dst, dst, 0x1);
606
}
607

    
608
// 0 or 3: !(FCC0 ^ FCC1)
609
static inline void gen_op_eval_fbue(TCGv dst, TCGv src,
610
                                    unsigned int fcc_offset)
611
{
612
    TCGv r_fcc1;
613

    
614
    r_fcc1 = tcg_temp_new(TCG_TYPE_TL);
615
    gen_mov_reg_FCC0(dst, src, fcc_offset);
616
    gen_mov_reg_FCC1(r_fcc1, src, fcc_offset);
617
    tcg_gen_xor_tl(dst, dst, r_fcc1);
618
    tcg_gen_xori_tl(dst, dst, 0x1);
619
}
620

    
621
// 0 or 2: !FCC0
622
static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
623
                                    unsigned int fcc_offset)
624
{
625
    gen_mov_reg_FCC0(dst, src, fcc_offset);
626
    tcg_gen_xori_tl(dst, dst, 0x1);
627
}
628

    
629
// !1: !(FCC0 & !FCC1)
630
static inline void gen_op_eval_fbuge(TCGv dst, TCGv src,
631
                                    unsigned int fcc_offset)
632
{
633
    TCGv r_fcc1;
634

    
635
    r_fcc1 = tcg_temp_new(TCG_TYPE_TL);
636
    gen_mov_reg_FCC0(dst, src, fcc_offset);
637
    gen_mov_reg_FCC1(r_fcc1, src, fcc_offset);
638
    tcg_gen_xori_tl(r_fcc1, r_fcc1, 0x1);
639
    tcg_gen_and_tl(dst, dst, r_fcc1);
640
    tcg_gen_xori_tl(dst, dst, 0x1);
641
}
642

    
643
// 0 or 1: !FCC1
644
static inline void gen_op_eval_fble(TCGv dst, TCGv src,
645
                                    unsigned int fcc_offset)
646
{
647
    gen_mov_reg_FCC1(dst, src, fcc_offset);
648
    tcg_gen_xori_tl(dst, dst, 0x1);
649
}
650

    
651
// !2: !(!FCC0 & FCC1)
652
static inline void gen_op_eval_fbule(TCGv dst, TCGv src,
653
                                    unsigned int fcc_offset)
654
{
655
    TCGv r_fcc1;
656

    
657
    r_fcc1 = tcg_temp_new(TCG_TYPE_TL);
658
    gen_mov_reg_FCC0(dst, src, fcc_offset);
659
    tcg_gen_xori_tl(dst, dst, 0x1);
660
    gen_mov_reg_FCC1(r_fcc1, src, fcc_offset);
661
    tcg_gen_and_tl(dst, dst, r_fcc1);
662
    tcg_gen_xori_tl(dst, dst, 0x1);
663
}
664

    
665
// !3: !(FCC0 & FCC1)
666
static inline void gen_op_eval_fbo(TCGv dst, TCGv src,
667
                                    unsigned int fcc_offset)
668
{
669
    TCGv r_fcc1;
670

    
671
    r_fcc1 = tcg_temp_new(TCG_TYPE_TL);
672
    gen_mov_reg_FCC0(dst, src, fcc_offset);
673
    gen_mov_reg_FCC1(r_fcc1, src, fcc_offset);
674
    tcg_gen_and_tl(dst, dst, r_fcc1);
675
    tcg_gen_xori_tl(dst, dst, 0x1);
676
}
677

    
678
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
679
                               target_ulong pc2, TCGv r_cond)
680
{
681
    TCGv r_zero;
682
    int l1;
683

    
684
    l1 = gen_new_label();
685
    r_zero = tcg_temp_new(TCG_TYPE_TL);
686
    tcg_gen_movi_tl(r_zero, 0);
687

    
688
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, r_zero, l1);
689

    
690
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
691

    
692
    gen_set_label(l1);
693
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
694
}
695

    
696
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
697
                                target_ulong pc2, TCGv r_cond)
698
{
699
    TCGv r_zero;
700
    int l1;
701

    
702
    l1 = gen_new_label();
703
    r_zero = tcg_temp_new(TCG_TYPE_TL);
704
    tcg_gen_movi_tl(r_zero, 0);
705

    
706
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, r_zero, l1);
707

    
708
    gen_goto_tb(dc, 0, pc2, pc1);
709

    
710
    gen_set_label(l1);
711
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
712
}
713

    
714
static inline void gen_branch(DisasContext *dc, target_ulong pc,
715
                              target_ulong npc)
716
{
717
    gen_goto_tb(dc, 0, pc, npc);
718
}
719

    
720
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
721
                                      TCGv r_cond)
722
{
723
    TCGv r_zero;
724
    int l1, l2;
725

    
726
    l1 = gen_new_label();
727
    l2 = gen_new_label();
728
    r_zero = tcg_temp_new(TCG_TYPE_TL);
729
    tcg_gen_movi_tl(r_zero, 0);
730

    
731
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, r_zero, l1);
732

    
733
    gen_movl_npc_im(npc1);
734
    gen_op_jmp_label(l2);
735

    
736
    gen_set_label(l1);
737
    gen_movl_npc_im(npc2);
738
    gen_set_label(l2);
739
}
740

    
741
/* call this function before using T2 as it may have been set for a jump */
742
static inline void flush_T2(DisasContext * dc)
743
{
744
    if (dc->npc == JUMP_PC) {
745
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
746
        dc->npc = DYNAMIC_PC;
747
    }
748
}
749

    
750
static inline void save_npc(DisasContext * dc)
751
{
752
    if (dc->npc == JUMP_PC) {
753
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
754
        dc->npc = DYNAMIC_PC;
755
    } else if (dc->npc != DYNAMIC_PC) {
756
        gen_movl_npc_im(dc->npc);
757
    }
758
}
759

    
760
static inline void save_state(DisasContext * dc)
761
{
762
    gen_jmp_im(dc->pc);
763
    save_npc(dc);
764
}
765

    
766
static inline void gen_mov_pc_npc(DisasContext * dc)
767
{
768
    if (dc->npc == JUMP_PC) {
769
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
770
        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, npc));
771
        tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, pc));
772
        dc->pc = DYNAMIC_PC;
773
    } else if (dc->npc == DYNAMIC_PC) {
774
        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, npc));
775
        tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, pc));
776
        dc->pc = DYNAMIC_PC;
777
    } else {
778
        dc->pc = dc->npc;
779
    }
780
}
781

    
782
static inline void gen_op_next_insn(void)
783
{
784
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, npc));
785
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, pc));
786
    tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, 4);
787
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, npc));
788
}
789

    
790
static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond)
791
{
792
    TCGv r_src;
793

    
794
    r_src = tcg_temp_new(TCG_TYPE_TL);
795
#ifdef TARGET_SPARC64
796
    if (cc)
797
        tcg_gen_ld_i32(r_src, cpu_env, offsetof(CPUSPARCState, xcc));
798
    else
799
        tcg_gen_ld_i32(r_src, cpu_env, offsetof(CPUSPARCState, psr));
800
#else
801
    tcg_gen_ld_i32(r_src, cpu_env, offsetof(CPUSPARCState, psr));
802
#endif
803
    switch (cond) {
804
    case 0x0:
805
        gen_op_eval_bn(r_dst);
806
        break;
807
    case 0x1:
808
        gen_op_eval_be(r_dst, r_src);
809
        break;
810
    case 0x2:
811
        gen_op_eval_ble(r_dst, r_src);
812
        break;
813
    case 0x3:
814
        gen_op_eval_bl(r_dst, r_src);
815
        break;
816
    case 0x4:
817
        gen_op_eval_bleu(r_dst, r_src);
818
        break;
819
    case 0x5:
820
        gen_op_eval_bcs(r_dst, r_src);
821
        break;
822
    case 0x6:
823
        gen_op_eval_bneg(r_dst, r_src);
824
        break;
825
    case 0x7:
826
        gen_op_eval_bvs(r_dst, r_src);
827
        break;
828
    case 0x8:
829
        gen_op_eval_ba(r_dst);
830
        break;
831
    case 0x9:
832
        gen_op_eval_bne(r_dst, r_src);
833
        break;
834
    case 0xa:
835
        gen_op_eval_bg(r_dst, r_src);
836
        break;
837
    case 0xb:
838
        gen_op_eval_bge(r_dst, r_src);
839
        break;
840
    case 0xc:
841
        gen_op_eval_bgu(r_dst, r_src);
842
        break;
843
    case 0xd:
844
        gen_op_eval_bcc(r_dst, r_src);
845
        break;
846
    case 0xe:
847
        gen_op_eval_bpos(r_dst, r_src);
848
        break;
849
    case 0xf:
850
        gen_op_eval_bvc(r_dst, r_src);
851
        break;
852
    }
853
}
854

    
855
static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
856
{
857
    TCGv r_src;
858
    unsigned int offset;
859

    
860
    r_src = tcg_temp_new(TCG_TYPE_TL);
861
    tcg_gen_ld_tl(r_src, cpu_env, offsetof(CPUSPARCState, fsr));
862

    
863
    switch (cc) {
864
    default:
865
    case 0x0:
866
        offset = 0;
867
        break;
868
    case 0x1:
869
        offset = 32 - 10;
870
        break;
871
    case 0x2:
872
        offset = 34 - 10;
873
        break;
874
    case 0x3:
875
        offset = 36 - 10;
876
        break;
877
    }
878

    
879
    switch (cond) {
880
    case 0x0:
881
        gen_op_eval_bn(r_dst);
882
        break;
883
    case 0x1:
884
        gen_op_eval_fbne(r_dst, r_src, offset);
885
        break;
886
    case 0x2:
887
        gen_op_eval_fblg(r_dst, r_src, offset);
888
        break;
889
    case 0x3:
890
        gen_op_eval_fbul(r_dst, r_src, offset);
891
        break;
892
    case 0x4:
893
        gen_op_eval_fbl(r_dst, r_src, offset);
894
        break;
895
    case 0x5:
896
        gen_op_eval_fbug(r_dst, r_src, offset);
897
        break;
898
    case 0x6:
899
        gen_op_eval_fbg(r_dst, r_src, offset);
900
        break;
901
    case 0x7:
902
        gen_op_eval_fbu(r_dst, r_src, offset);
903
        break;
904
    case 0x8:
905
        gen_op_eval_ba(r_dst);
906
        break;
907
    case 0x9:
908
        gen_op_eval_fbe(r_dst, r_src, offset);
909
        break;
910
    case 0xa:
911
        gen_op_eval_fbue(r_dst, r_src, offset);
912
        break;
913
    case 0xb:
914
        gen_op_eval_fbge(r_dst, r_src, offset);
915
        break;
916
    case 0xc:
917
        gen_op_eval_fbuge(r_dst, r_src, offset);
918
        break;
919
    case 0xd:
920
        gen_op_eval_fble(r_dst, r_src, offset);
921
        break;
922
    case 0xe:
923
        gen_op_eval_fbule(r_dst, r_src, offset);
924
        break;
925
    case 0xf:
926
        gen_op_eval_fbo(r_dst, r_src, offset);
927
        break;
928
    }
929
}
930

    
931
#ifdef TARGET_SPARC64
932
// Inverted logic
933
static const int gen_tcg_cond_reg[8] = {
934
    -1,
935
    TCG_COND_NE,
936
    TCG_COND_GT,
937
    TCG_COND_GE,
938
    -1,
939
    TCG_COND_EQ,
940
    TCG_COND_LE,
941
    TCG_COND_LT,
942
};
943

    
944
static inline void gen_cond_reg(TCGv r_dst, int cond)
945
{
946
    TCGv r_zero;
947
    int l1;
948

    
949
    l1 = gen_new_label();
950
    r_zero = tcg_temp_new(TCG_TYPE_TL);
951
    tcg_gen_movi_tl(r_zero, 0);
952
    tcg_gen_mov_tl(r_dst, r_zero);
953
    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0], r_zero, l1);
954
    tcg_gen_movi_tl(r_dst, 1);
955
    gen_set_label(l1);
956
}
957
#endif
958

    
959
/* XXX: potentially incorrect if dynamic npc */
960
static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
961
{
962
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
963
    target_ulong target = dc->pc + offset;
964

    
965
    if (cond == 0x0) {
966
        /* unconditional not taken */
967
        if (a) {
968
            dc->pc = dc->npc + 4;
969
            dc->npc = dc->pc + 4;
970
        } else {
971
            dc->pc = dc->npc;
972
            dc->npc = dc->pc + 4;
973
        }
974
    } else if (cond == 0x8) {
975
        /* unconditional taken */
976
        if (a) {
977
            dc->pc = target;
978
            dc->npc = dc->pc + 4;
979
        } else {
980
            dc->pc = dc->npc;
981
            dc->npc = target;
982
        }
983
    } else {
984
        flush_T2(dc);
985
        gen_cond(cpu_T[2], cc, cond);
986
        if (a) {
987
            gen_branch_a(dc, target, dc->npc, cpu_T[2]);
988
            dc->is_br = 1;
989
        } else {
990
            dc->pc = dc->npc;
991
            dc->jump_pc[0] = target;
992
            dc->jump_pc[1] = dc->npc + 4;
993
            dc->npc = JUMP_PC;
994
        }
995
    }
996
}
997

    
998
/* XXX: potentially incorrect if dynamic npc */
999
static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
1000
{
1001
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1002
    target_ulong target = dc->pc + offset;
1003

    
1004
    if (cond == 0x0) {
1005
        /* unconditional not taken */
1006
        if (a) {
1007
            dc->pc = dc->npc + 4;
1008
            dc->npc = dc->pc + 4;
1009
        } else {
1010
            dc->pc = dc->npc;
1011
            dc->npc = dc->pc + 4;
1012
        }
1013
    } else if (cond == 0x8) {
1014
        /* unconditional taken */
1015
        if (a) {
1016
            dc->pc = target;
1017
            dc->npc = dc->pc + 4;
1018
        } else {
1019
            dc->pc = dc->npc;
1020
            dc->npc = target;
1021
        }
1022
    } else {
1023
        flush_T2(dc);
1024
        gen_fcond(cpu_T[2], cc, cond);
1025
        if (a) {
1026
            gen_branch_a(dc, target, dc->npc, cpu_T[2]);
1027
            dc->is_br = 1;
1028
        } else {
1029
            dc->pc = dc->npc;
1030
            dc->jump_pc[0] = target;
1031
            dc->jump_pc[1] = dc->npc + 4;
1032
            dc->npc = JUMP_PC;
1033
        }
1034
    }
1035
}
1036

    
1037
#ifdef TARGET_SPARC64
1038
/* XXX: potentially incorrect if dynamic npc */
1039
static void do_branch_reg(DisasContext * dc, int32_t offset, uint32_t insn)
1040
{
1041
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1042
    target_ulong target = dc->pc + offset;
1043

    
1044
    flush_T2(dc);
1045
    gen_cond_reg(cpu_T[2], cond);
1046
    if (a) {
1047
        gen_branch_a(dc, target, dc->npc, cpu_T[2]);
1048
        dc->is_br = 1;
1049
    } else {
1050
        dc->pc = dc->npc;
1051
        dc->jump_pc[0] = target;
1052
        dc->jump_pc[1] = dc->npc + 4;
1053
        dc->npc = JUMP_PC;
1054
    }
1055
}
1056

    
1057
static GenOpFunc * const gen_fcmps[4] = {
1058
    helper_fcmps,
1059
    helper_fcmps_fcc1,
1060
    helper_fcmps_fcc2,
1061
    helper_fcmps_fcc3,
1062
};
1063

    
1064
static GenOpFunc * const gen_fcmpd[4] = {
1065
    helper_fcmpd,
1066
    helper_fcmpd_fcc1,
1067
    helper_fcmpd_fcc2,
1068
    helper_fcmpd_fcc3,
1069
};
1070

    
1071
#if defined(CONFIG_USER_ONLY)
1072
static GenOpFunc * const gen_fcmpq[4] = {
1073
    helper_fcmpq,
1074
    helper_fcmpq_fcc1,
1075
    helper_fcmpq_fcc2,
1076
    helper_fcmpq_fcc3,
1077
};
1078
#endif
1079

    
1080
static GenOpFunc * const gen_fcmpes[4] = {
1081
    helper_fcmpes,
1082
    helper_fcmpes_fcc1,
1083
    helper_fcmpes_fcc2,
1084
    helper_fcmpes_fcc3,
1085
};
1086

    
1087
static GenOpFunc * const gen_fcmped[4] = {
1088
    helper_fcmped,
1089
    helper_fcmped_fcc1,
1090
    helper_fcmped_fcc2,
1091
    helper_fcmped_fcc3,
1092
};
1093

    
1094
#if defined(CONFIG_USER_ONLY)
1095
static GenOpFunc * const gen_fcmpeq[4] = {
1096
    helper_fcmpeq,
1097
    helper_fcmpeq_fcc1,
1098
    helper_fcmpeq_fcc2,
1099
    helper_fcmpeq_fcc3,
1100
};
1101
#endif
1102

    
1103
static inline void gen_op_fcmps(int fccno)
1104
{
1105
    tcg_gen_helper_0_0(gen_fcmps[fccno]);
1106
}
1107

    
1108
static inline void gen_op_fcmpd(int fccno)
1109
{
1110
    tcg_gen_helper_0_0(gen_fcmpd[fccno]);
1111
}
1112

    
1113
#if defined(CONFIG_USER_ONLY)
1114
static inline void gen_op_fcmpq(int fccno)
1115
{
1116
    tcg_gen_helper_0_0(gen_fcmpq[fccno]);
1117
}
1118
#endif
1119

    
1120
static inline void gen_op_fcmpes(int fccno)
1121
{
1122
    tcg_gen_helper_0_0(gen_fcmpes[fccno]);
1123
}
1124

    
1125
static inline void gen_op_fcmped(int fccno)
1126
{
1127
    tcg_gen_helper_0_0(gen_fcmped[fccno]);
1128
}
1129

    
1130
#if defined(CONFIG_USER_ONLY)
1131
static inline void gen_op_fcmpeq(int fccno)
1132
{
1133
    tcg_gen_helper_0_0(gen_fcmpeq[fccno]);
1134
}
1135
#endif
1136

    
1137
#else
1138

    
1139
static inline void gen_op_fcmps(int fccno)
1140
{
1141
    tcg_gen_helper_0_0(helper_fcmps);
1142
}
1143

    
1144
static inline void gen_op_fcmpd(int fccno)
1145
{
1146
    tcg_gen_helper_0_0(helper_fcmpd);
1147
}
1148

    
1149
#if defined(CONFIG_USER_ONLY)
1150
static inline void gen_op_fcmpq(int fccno)
1151
{
1152
    tcg_gen_helper_0_0(helper_fcmpq);
1153
}
1154
#endif
1155

    
1156
static inline void gen_op_fcmpes(int fccno)
1157
{
1158
    tcg_gen_helper_0_0(helper_fcmpes);
1159
}
1160

    
1161
static inline void gen_op_fcmped(int fccno)
1162
{
1163
    tcg_gen_helper_0_0(helper_fcmped);
1164
}
1165

    
1166
#if defined(CONFIG_USER_ONLY)
1167
static inline void gen_op_fcmpeq(int fccno)
1168
{
1169
    tcg_gen_helper_0_0(helper_fcmpeq);
1170
}
1171
#endif
1172

    
1173
#endif
1174

    
1175
static inline void gen_op_exception(int exception)
1176
{
1177
    TCGv r_except;
1178

    
1179
    r_except = tcg_temp_new(TCG_TYPE_I32);
1180
    tcg_gen_movi_i32(r_except, exception);
1181
    tcg_gen_helper_0_1(raise_exception, r_except);
1182
}
1183

    
1184
static inline void gen_op_fpexception_im(int fsr_flags)
1185
{
1186
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fsr));
1187
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, ~FSR_FTT_MASK);
1188
    tcg_gen_ori_tl(cpu_tmp0, cpu_tmp0, fsr_flags);
1189
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fsr));
1190
    gen_op_exception(TT_FP_EXCP);
1191
}
1192

    
1193
static int gen_trap_ifnofpu(DisasContext * dc)
1194
{
1195
#if !defined(CONFIG_USER_ONLY)
1196
    if (!dc->fpu_enabled) {
1197
        save_state(dc);
1198
        gen_op_exception(TT_NFPU_INSN);
1199
        dc->is_br = 1;
1200
        return 1;
1201
    }
1202
#endif
1203
    return 0;
1204
}
1205

    
1206
static inline void gen_op_clear_ieee_excp_and_FTT(void)
1207
{
1208
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fsr));
1209
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, ~(FSR_FTT_MASK | FSR_CEXC_MASK));
1210
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fsr));
1211
}
1212

    
1213
static inline void gen_clear_float_exceptions(void)
1214
{
1215
    tcg_gen_helper_0_0(helper_clear_float_exceptions);
1216
}
1217

    
1218
/* asi moves */
1219
#ifdef TARGET_SPARC64
1220
static inline void gen_ld_asi(int insn, int size, int sign)
1221
{
1222
    int asi, offset;
1223
    TCGv r_size, r_sign;
1224

    
1225
    r_size = tcg_temp_new(TCG_TYPE_I32);
1226
    r_sign = tcg_temp_new(TCG_TYPE_I32);
1227
    tcg_gen_movi_i32(r_size, size);
1228
    tcg_gen_movi_i32(r_sign, sign);
1229
    if (IS_IMM) {
1230
        offset = GET_FIELD(insn, 25, 31);
1231
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
1232
        tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUSPARCState, asi));
1233
    } else {
1234
        asi = GET_FIELD(insn, 19, 26);
1235
        tcg_gen_movi_i32(cpu_T[1], asi);
1236
    }
1237
    tcg_gen_helper_1_4(helper_ld_asi, cpu_T[1], cpu_T[0], cpu_T[1], r_size,
1238
                       r_sign);
1239
}
1240

    
1241
static inline void gen_st_asi(int insn, int size)
1242
{
1243
    int asi, offset;
1244
    TCGv r_asi, r_size;
1245

    
1246
    r_asi = tcg_temp_new(TCG_TYPE_I32);
1247
    r_size = tcg_temp_new(TCG_TYPE_I32);
1248
    tcg_gen_movi_i32(r_size, size);
1249
    if (IS_IMM) {
1250
        offset = GET_FIELD(insn, 25, 31);
1251
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
1252
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
1253
    } else {
1254
        asi = GET_FIELD(insn, 19, 26);
1255
        tcg_gen_movi_i32(r_asi, asi);
1256
    }
1257
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], r_asi, r_size);
1258
}
1259

    
1260
static inline void gen_ldf_asi(int insn, int size, int rd)
1261
{
1262
    int asi, offset;
1263
    TCGv r_asi, r_size, r_rd;
1264

    
1265
    r_asi = tcg_temp_new(TCG_TYPE_I32);
1266
    r_size = tcg_temp_new(TCG_TYPE_I32);
1267
    r_rd = tcg_temp_new(TCG_TYPE_I32);
1268
    tcg_gen_movi_i32(r_size, size);
1269
    tcg_gen_movi_i32(r_rd, rd);
1270
    if (IS_IMM) {
1271
        offset = GET_FIELD(insn, 25, 31);
1272
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
1273
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
1274
    } else {
1275
        asi = GET_FIELD(insn, 19, 26);
1276
        tcg_gen_movi_i32(r_asi, asi);
1277
    }
1278
    tcg_gen_helper_0_4(helper_ldf_asi, cpu_T[0], r_asi, r_size, r_rd);
1279
}
1280

    
1281
static inline void gen_stf_asi(int insn, int size, int rd)
1282
{
1283
    int asi, offset;
1284
    TCGv r_asi, r_size, r_rd;
1285

    
1286
    r_asi = tcg_temp_new(TCG_TYPE_I32);
1287
    r_size = tcg_temp_new(TCG_TYPE_I32);
1288
    r_rd = tcg_temp_new(TCG_TYPE_I32);
1289
    tcg_gen_movi_i32(r_size, size);
1290
    tcg_gen_movi_i32(r_rd, rd);
1291
    if (IS_IMM) {
1292
        offset = GET_FIELD(insn, 25, 31);
1293
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
1294
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
1295
    } else {
1296
        asi = GET_FIELD(insn, 19, 26);
1297
        tcg_gen_movi_i32(r_asi, asi);
1298
    }
1299
    tcg_gen_helper_0_4(helper_stf_asi, cpu_T[0], r_asi, r_size, r_rd);
1300
}
1301

    
1302
static inline void gen_swap_asi(int insn)
1303
{
1304
    int asi, offset;
1305
    TCGv r_size, r_sign, r_temp;
1306

    
1307
    r_size = tcg_temp_new(TCG_TYPE_I32);
1308
    r_sign = tcg_temp_new(TCG_TYPE_I32);
1309
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1310
    tcg_gen_movi_i32(r_size, 4);
1311
    tcg_gen_movi_i32(r_sign, 0);
1312
    if (IS_IMM) {
1313
        offset = GET_FIELD(insn, 25, 31);
1314
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
1315
        tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUSPARCState, asi));
1316
    } else {
1317
        asi = GET_FIELD(insn, 19, 26);
1318
        tcg_gen_movi_i32(cpu_T[1], asi);
1319
    }
1320
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, cpu_T[0], cpu_T[1], r_size,
1321
                       r_sign);
1322
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], r_size, r_sign);
1323
    tcg_gen_mov_i32(cpu_T[1], r_temp);
1324
}
1325

    
1326
static inline void gen_ldda_asi(int insn)
1327
{
1328
    int asi, offset;
1329
    TCGv r_size, r_sign, r_dword;
1330

    
1331
    r_size = tcg_temp_new(TCG_TYPE_I32);
1332
    r_sign = tcg_temp_new(TCG_TYPE_I32);
1333
    r_dword = tcg_temp_new(TCG_TYPE_I64);
1334
    tcg_gen_movi_i32(r_size, 8);
1335
    tcg_gen_movi_i32(r_sign, 0);
1336
    if (IS_IMM) {
1337
        offset = GET_FIELD(insn, 25, 31);
1338
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
1339
        tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUSPARCState, asi));
1340
    } else {
1341
        asi = GET_FIELD(insn, 19, 26);
1342
        tcg_gen_movi_i32(cpu_T[1], asi);
1343
    }
1344
    tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], cpu_T[1], r_size,
1345
                       r_sign);
1346
    tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
1347
    tcg_gen_shri_i64(r_dword, r_dword, 32);
1348
    tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
1349
}
1350

    
1351
static inline void gen_cas_asi(int insn, int rd)
1352
{
1353
    int asi, offset;
1354
    TCGv r_val1, r_asi;
1355

    
1356
    r_val1 = tcg_temp_new(TCG_TYPE_I32);
1357
    r_asi = tcg_temp_new(TCG_TYPE_I32);
1358
    gen_movl_reg_TN(rd, r_val1);
1359
    if (IS_IMM) {
1360
        offset = GET_FIELD(insn, 25, 31);
1361
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
1362
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
1363
    } else {
1364
        asi = GET_FIELD(insn, 19, 26);
1365
        tcg_gen_movi_i32(r_asi, asi);
1366
    }
1367
    tcg_gen_helper_1_4(helper_cas_asi, cpu_T[1], cpu_T[0], r_val1, cpu_T[1],
1368
                       r_asi);
1369
}
1370

    
1371
static inline void gen_casx_asi(int insn, int rd)
1372
{
1373
    int asi, offset;
1374
    TCGv r_val1, r_asi;
1375

    
1376
    r_val1 = tcg_temp_new(TCG_TYPE_I64);
1377
    r_asi = tcg_temp_new(TCG_TYPE_I32);
1378
    gen_movl_reg_TN(rd, r_val1);
1379
    if (IS_IMM) {
1380
        offset = GET_FIELD(insn, 25, 31);
1381
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
1382
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
1383
    } else {
1384
        asi = GET_FIELD(insn, 19, 26);
1385
        tcg_gen_movi_i32(r_asi, asi);
1386
    }
1387
    tcg_gen_helper_1_4(helper_casx_asi, cpu_T[1], cpu_T[0], r_val1, cpu_T[1],
1388
                       r_asi);
1389
}
1390

    
1391
#elif !defined(CONFIG_USER_ONLY)
1392

    
1393
static inline void gen_ld_asi(int insn, int size, int sign)
1394
{
1395
    int asi;
1396
    TCGv r_size, r_sign, r_dword;
1397

    
1398
    r_size = tcg_temp_new(TCG_TYPE_I32);
1399
    r_sign = tcg_temp_new(TCG_TYPE_I32);
1400
    r_dword = tcg_temp_new(TCG_TYPE_I64);
1401
    tcg_gen_movi_i32(r_size, size);
1402
    tcg_gen_movi_i32(r_sign, sign);
1403
    asi = GET_FIELD(insn, 19, 26);
1404
    tcg_gen_movi_i32(cpu_T[1], asi);
1405
    tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], cpu_T[1], r_size,
1406
                       r_sign);
1407
    tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
1408
}
1409

    
1410
static inline void gen_st_asi(int insn, int size)
1411
{
1412
    int asi;
1413
    TCGv r_dword, r_asi, r_size;
1414

    
1415
    r_dword = tcg_temp_new(TCG_TYPE_I64);
1416
    tcg_gen_extu_i32_i64(r_dword, cpu_T[1]);
1417
    r_asi = tcg_temp_new(TCG_TYPE_I32);
1418
    r_size = tcg_temp_new(TCG_TYPE_I32);
1419
    asi = GET_FIELD(insn, 19, 26);
1420
    tcg_gen_movi_i32(r_asi, asi);
1421
    tcg_gen_movi_i32(r_size, size);
1422
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, r_asi, r_size);
1423
}
1424

    
1425
static inline void gen_swap_asi(int insn)
1426
{
1427
    int asi;
1428
    TCGv r_size, r_sign, r_temp;
1429

    
1430
    r_size = tcg_temp_new(TCG_TYPE_I32);
1431
    r_sign = tcg_temp_new(TCG_TYPE_I32);
1432
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1433
    tcg_gen_movi_i32(r_size, 4);
1434
    tcg_gen_movi_i32(r_sign, 0);
1435
    asi = GET_FIELD(insn, 19, 26);
1436
    tcg_gen_movi_i32(cpu_T[1], asi);
1437
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, cpu_T[0], cpu_T[1], r_size,
1438
                       r_sign);
1439
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], r_size, r_sign);
1440
    tcg_gen_mov_i32(cpu_T[1], r_temp);
1441
}
1442

    
1443
static inline void gen_ldda_asi(int insn)
1444
{
1445
    int asi;
1446
    TCGv r_size, r_sign, r_dword;
1447

    
1448
    r_size = tcg_temp_new(TCG_TYPE_I32);
1449
    r_sign = tcg_temp_new(TCG_TYPE_I32);
1450
    r_dword = tcg_temp_new(TCG_TYPE_I64);
1451
    tcg_gen_movi_i32(r_size, 8);
1452
    tcg_gen_movi_i32(r_sign, 0);
1453
    asi = GET_FIELD(insn, 19, 26);
1454
    tcg_gen_movi_i32(cpu_T[1], asi);
1455
    tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], cpu_T[1], r_size,
1456
                       r_sign);
1457
    tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
1458
    tcg_gen_shri_i64(r_dword, r_dword, 32);
1459
    tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
1460
}
1461
#endif
1462

    
1463
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1464
static inline void gen_ldstub_asi(int insn)
1465
{
1466
    int asi;
1467
    TCGv r_dword, r_asi, r_size;
1468

    
1469
    gen_ld_asi(insn, 1, 0);
1470

    
1471
    r_dword = tcg_temp_new(TCG_TYPE_I64);
1472
    r_asi = tcg_temp_new(TCG_TYPE_I32);
1473
    r_size = tcg_temp_new(TCG_TYPE_I32);
1474
    asi = GET_FIELD(insn, 19, 26);
1475
    tcg_gen_movi_i32(r_dword, 0xff);
1476
    tcg_gen_movi_i32(r_asi, asi);
1477
    tcg_gen_movi_i32(r_size, 1);
1478
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, r_asi, r_size);
1479
}
1480
#endif
1481

    
1482
/* before an instruction, dc->pc must be static */
1483
static void disas_sparc_insn(DisasContext * dc)
1484
{
1485
    unsigned int insn, opc, rs1, rs2, rd;
1486

    
1487
    insn = ldl_code(dc->pc);
1488
    opc = GET_FIELD(insn, 0, 1);
1489

    
1490
    rd = GET_FIELD(insn, 2, 6);
1491
    switch (opc) {
1492
    case 0:                     /* branches/sethi */
1493
        {
1494
            unsigned int xop = GET_FIELD(insn, 7, 9);
1495
            int32_t target;
1496
            switch (xop) {
1497
#ifdef TARGET_SPARC64
1498
            case 0x1:           /* V9 BPcc */
1499
                {
1500
                    int cc;
1501

    
1502
                    target = GET_FIELD_SP(insn, 0, 18);
1503
                    target = sign_extend(target, 18);
1504
                    target <<= 2;
1505
                    cc = GET_FIELD_SP(insn, 20, 21);
1506
                    if (cc == 0)
1507
                        do_branch(dc, target, insn, 0);
1508
                    else if (cc == 2)
1509
                        do_branch(dc, target, insn, 1);
1510
                    else
1511
                        goto illegal_insn;
1512
                    goto jmp_insn;
1513
                }
1514
            case 0x3:           /* V9 BPr */
1515
                {
1516
                    target = GET_FIELD_SP(insn, 0, 13) |
1517
                        (GET_FIELD_SP(insn, 20, 21) << 14);
1518
                    target = sign_extend(target, 16);
1519
                    target <<= 2;
1520
                    rs1 = GET_FIELD(insn, 13, 17);
1521
                    gen_movl_reg_T0(rs1);
1522
                    do_branch_reg(dc, target, insn);
1523
                    goto jmp_insn;
1524
                }
1525
            case 0x5:           /* V9 FBPcc */
1526
                {
1527
                    int cc = GET_FIELD_SP(insn, 20, 21);
1528
                    if (gen_trap_ifnofpu(dc))
1529
                        goto jmp_insn;
1530
                    target = GET_FIELD_SP(insn, 0, 18);
1531
                    target = sign_extend(target, 19);
1532
                    target <<= 2;
1533
                    do_fbranch(dc, target, insn, cc);
1534
                    goto jmp_insn;
1535
                }
1536
#else
1537
            case 0x7:           /* CBN+x */
1538
                {
1539
                    goto ncp_insn;
1540
                }
1541
#endif
1542
            case 0x2:           /* BN+x */
1543
                {
1544
                    target = GET_FIELD(insn, 10, 31);
1545
                    target = sign_extend(target, 22);
1546
                    target <<= 2;
1547
                    do_branch(dc, target, insn, 0);
1548
                    goto jmp_insn;
1549
                }
1550
            case 0x6:           /* FBN+x */
1551
                {
1552
                    if (gen_trap_ifnofpu(dc))
1553
                        goto jmp_insn;
1554
                    target = GET_FIELD(insn, 10, 31);
1555
                    target = sign_extend(target, 22);
1556
                    target <<= 2;
1557
                    do_fbranch(dc, target, insn, 0);
1558
                    goto jmp_insn;
1559
                }
1560
            case 0x4:           /* SETHI */
1561
#define OPTIM
1562
#if defined(OPTIM)
1563
                if (rd) { // nop
1564
#endif
1565
                    uint32_t value = GET_FIELD(insn, 10, 31);
1566
                    tcg_gen_movi_tl(cpu_T[0], value << 10);
1567
                    gen_movl_T0_reg(rd);
1568
#if defined(OPTIM)
1569
                }
1570
#endif
1571
                break;
1572
            case 0x0:           /* UNIMPL */
1573
            default:
1574
                goto illegal_insn;
1575
            }
1576
            break;
1577
        }
1578
        break;
1579
    case 1:
1580
        /*CALL*/ {
1581
            target_long target = GET_FIELDs(insn, 2, 31) << 2;
1582

    
1583
            tcg_gen_movi_tl(cpu_T[0], dc->pc);
1584
            gen_movl_T0_reg(15);
1585
            target += dc->pc;
1586
            gen_mov_pc_npc(dc);
1587
            dc->npc = target;
1588
        }
1589
        goto jmp_insn;
1590
    case 2:                     /* FPU & Logical Operations */
1591
        {
1592
            unsigned int xop = GET_FIELD(insn, 7, 12);
1593
            if (xop == 0x3a) {  /* generate trap */
1594
                int cond;
1595

    
1596
                rs1 = GET_FIELD(insn, 13, 17);
1597
                gen_movl_reg_T0(rs1);
1598
                if (IS_IMM) {
1599
                    rs2 = GET_FIELD(insn, 25, 31);
1600
                    tcg_gen_addi_tl(cpu_T[0], cpu_T[0], rs2);
1601
                } else {
1602
                    rs2 = GET_FIELD(insn, 27, 31);
1603
#if defined(OPTIM)
1604
                    if (rs2 != 0) {
1605
#endif
1606
                        gen_movl_reg_T1(rs2);
1607
                        gen_op_add_T1_T0();
1608
#if defined(OPTIM)
1609
                    }
1610
#endif
1611
                }
1612
                cond = GET_FIELD(insn, 3, 6);
1613
                if (cond == 0x8) {
1614
                    save_state(dc);
1615
                    tcg_gen_helper_0_1(helper_trap, cpu_T[0]);
1616
                } else if (cond != 0) {
1617
#ifdef TARGET_SPARC64
1618
                    /* V9 icc/xcc */
1619
                    int cc = GET_FIELD_SP(insn, 11, 12);
1620
                    flush_T2(dc);
1621
                    save_state(dc);
1622
                    if (cc == 0)
1623
                        gen_cond(cpu_T[2], 0, cond);
1624
                    else if (cc == 2)
1625
                        gen_cond(cpu_T[2], 1, cond);
1626
                    else
1627
                        goto illegal_insn;
1628
#else
1629
                    flush_T2(dc);
1630
                    save_state(dc);
1631
                    gen_cond(cpu_T[2], 0, cond);
1632
#endif
1633
                    tcg_gen_helper_0_2(helper_trapcc, cpu_T[0], cpu_T[2]);
1634
                }
1635
                gen_op_next_insn();
1636
                tcg_gen_exit_tb(0);
1637
                dc->is_br = 1;
1638
                goto jmp_insn;
1639
            } else if (xop == 0x28) {
1640
                rs1 = GET_FIELD(insn, 13, 17);
1641
                switch(rs1) {
1642
                case 0: /* rdy */
1643
#ifndef TARGET_SPARC64
1644
                case 0x01 ... 0x0e: /* undefined in the SPARCv8
1645
                                       manual, rdy on the microSPARC
1646
                                       II */
1647
                case 0x0f:          /* stbar in the SPARCv8 manual,
1648
                                       rdy on the microSPARC II */
1649
                case 0x10 ... 0x1f: /* implementation-dependent in the
1650
                                       SPARCv8 manual, rdy on the
1651
                                       microSPARC II */
1652
#endif
1653
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, y));
1654
                    gen_movl_T0_reg(rd);
1655
                    break;
1656
#ifdef TARGET_SPARC64
1657
                case 0x2: /* V9 rdccr */
1658
                    gen_op_rdccr();
1659
                    gen_movl_T0_reg(rd);
1660
                    break;
1661
                case 0x3: /* V9 rdasi */
1662
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, asi));
1663
                    gen_movl_T0_reg(rd);
1664
                    break;
1665
                case 0x4: /* V9 rdtick */
1666
                    {
1667
                        TCGv r_tickptr;
1668

    
1669
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
1670
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
1671
                                       offsetof(CPUState, tick));
1672
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_T[0],
1673
                                           r_tickptr);
1674
                        gen_movl_T0_reg(rd);
1675
                    }
1676
                    break;
1677
                case 0x5: /* V9 rdpc */
1678
                    tcg_gen_movi_tl(cpu_T[0], dc->pc);
1679
                    gen_movl_T0_reg(rd);
1680
                    break;
1681
                case 0x6: /* V9 rdfprs */
1682
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, fprs));
1683
                    gen_movl_T0_reg(rd);
1684
                    break;
1685
                case 0xf: /* V9 membar */
1686
                    break; /* no effect */
1687
                case 0x13: /* Graphics Status */
1688
                    if (gen_trap_ifnofpu(dc))
1689
                        goto jmp_insn;
1690
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, gsr));
1691
                    gen_movl_T0_reg(rd);
1692
                    break;
1693
                case 0x17: /* Tick compare */
1694
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, tick_cmpr));
1695
                    gen_movl_T0_reg(rd);
1696
                    break;
1697
                case 0x18: /* System tick */
1698
                    {
1699
                        TCGv r_tickptr;
1700

    
1701
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
1702
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
1703
                                       offsetof(CPUState, stick));
1704
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_T[0],
1705
                                           r_tickptr);
1706
                        gen_movl_T0_reg(rd);
1707
                    }
1708
                    break;
1709
                case 0x19: /* System tick compare */
1710
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, stick_cmpr));
1711
                    gen_movl_T0_reg(rd);
1712
                    break;
1713
                case 0x10: /* Performance Control */
1714
                case 0x11: /* Performance Instrumentation Counter */
1715
                case 0x12: /* Dispatch Control */
1716
                case 0x14: /* Softint set, WO */
1717
                case 0x15: /* Softint clear, WO */
1718
                case 0x16: /* Softint write */
1719
#endif
1720
                default:
1721
                    goto illegal_insn;
1722
                }
1723
#if !defined(CONFIG_USER_ONLY)
1724
            } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
1725
#ifndef TARGET_SPARC64
1726
                if (!supervisor(dc))
1727
                    goto priv_insn;
1728
                tcg_gen_helper_1_0(helper_rdpsr, cpu_T[0]);
1729
#else
1730
                if (!hypervisor(dc))
1731
                    goto priv_insn;
1732
                rs1 = GET_FIELD(insn, 13, 17);
1733
                switch (rs1) {
1734
                case 0: // hpstate
1735
                    // gen_op_rdhpstate();
1736
                    break;
1737
                case 1: // htstate
1738
                    // gen_op_rdhtstate();
1739
                    break;
1740
                case 3: // hintp
1741
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, hintp));
1742
                    break;
1743
                case 5: // htba
1744
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, htba));
1745
                    break;
1746
                case 6: // hver
1747
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, hver));
1748
                    break;
1749
                case 31: // hstick_cmpr
1750
                    gen_op_movl_env_T0(offsetof(CPUSPARCState, hstick_cmpr));
1751
                    break;
1752
                default:
1753
                    goto illegal_insn;
1754
                }
1755
#endif
1756
                gen_movl_T0_reg(rd);
1757
                break;
1758
            } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
1759
                if (!supervisor(dc))
1760
                    goto priv_insn;
1761
#ifdef TARGET_SPARC64
1762
                rs1 = GET_FIELD(insn, 13, 17);
1763
                switch (rs1) {
1764
                case 0: // tpc
1765
                    {
1766
                        TCGv r_tsptr;
1767

    
1768
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
1769
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
1770
                                       offsetof(CPUState, tsptr));
1771
                        tcg_gen_ld_tl(cpu_T[0], r_tsptr,
1772
                                      offsetof(trap_state, tpc));
1773
                    }
1774
                    break;
1775
                case 1: // tnpc
1776
                    {
1777
                        TCGv r_tsptr;
1778

    
1779
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
1780
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
1781
                                       offsetof(CPUState, tsptr));
1782
                        tcg_gen_ld_tl(cpu_T[0], r_tsptr,
1783
                                      offsetof(trap_state, tnpc));
1784
                    }
1785
                    break;
1786
                case 2: // tstate
1787
                    {
1788
                        TCGv r_tsptr;
1789

    
1790
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
1791
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
1792
                                       offsetof(CPUState, tsptr));
1793
                        tcg_gen_ld_tl(cpu_T[0], r_tsptr,
1794
                                      offsetof(trap_state, tstate));
1795
                    }
1796
                    break;
1797
                case 3: // tt
1798
                    {
1799
                        TCGv r_tsptr;
1800

    
1801
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
1802
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
1803
                                       offsetof(CPUState, tsptr));
1804
                        tcg_gen_ld_i32(cpu_T[0], r_tsptr,
1805
                                       offsetof(trap_state, tt));
1806
                    }
1807
                    break;
1808
                case 4: // tick
1809
                    {
1810
                        TCGv r_tickptr;
1811

    
1812
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
1813
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
1814
                                       offsetof(CPUState, tick));
1815
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_T[0],
1816
                                           r_tickptr);
1817
                        gen_movl_T0_reg(rd);
1818
                    }
1819
                    break;
1820
                case 5: // tba
1821
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
1822
                    break;
1823
                case 6: // pstate
1824
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, pstate));
1825
                    break;
1826
                case 7: // tl
1827
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, tl));
1828
                    break;
1829
                case 8: // pil
1830
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, psrpil));
1831
                    break;
1832
                case 9: // cwp
1833
                    gen_op_rdcwp();
1834
                    break;
1835
                case 10: // cansave
1836
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, cansave));
1837
                    break;
1838
                case 11: // canrestore
1839
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, canrestore));
1840
                    break;
1841
                case 12: // cleanwin
1842
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, cleanwin));
1843
                    break;
1844
                case 13: // otherwin
1845
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, otherwin));
1846
                    break;
1847
                case 14: // wstate
1848
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, wstate));
1849
                    break;
1850
                case 16: // UA2005 gl
1851
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, gl));
1852
                    break;
1853
                case 26: // UA2005 strand status
1854
                    if (!hypervisor(dc))
1855
                        goto priv_insn;
1856
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, ssr));
1857
                    break;
1858
                case 31: // ver
1859
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, version));
1860
                    break;
1861
                case 15: // fq
1862
                default:
1863
                    goto illegal_insn;
1864
                }
1865
#else
1866
                gen_op_movl_T0_env(offsetof(CPUSPARCState, wim));
1867
#endif
1868
                gen_movl_T0_reg(rd);
1869
                break;
1870
            } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
1871
#ifdef TARGET_SPARC64
1872
                gen_op_flushw();
1873
#else
1874
                if (!supervisor(dc))
1875
                    goto priv_insn;
1876
                gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
1877
                gen_movl_T0_reg(rd);
1878
#endif
1879
                break;
1880
#endif
1881
            } else if (xop == 0x34) {   /* FPU Operations */
1882
                if (gen_trap_ifnofpu(dc))
1883
                    goto jmp_insn;
1884
                gen_op_clear_ieee_excp_and_FTT();
1885
                rs1 = GET_FIELD(insn, 13, 17);
1886
                rs2 = GET_FIELD(insn, 27, 31);
1887
                xop = GET_FIELD(insn, 18, 26);
1888
                switch (xop) {
1889
                    case 0x1: /* fmovs */
1890
                        gen_op_load_fpr_FT0(rs2);
1891
                        gen_op_store_FT0_fpr(rd);
1892
                        break;
1893
                    case 0x5: /* fnegs */
1894
                        gen_op_load_fpr_FT1(rs2);
1895
                        gen_op_fnegs();
1896
                        gen_op_store_FT0_fpr(rd);
1897
                        break;
1898
                    case 0x9: /* fabss */
1899
                        gen_op_load_fpr_FT1(rs2);
1900
                        tcg_gen_helper_0_0(helper_fabss);
1901
                        gen_op_store_FT0_fpr(rd);
1902
                        break;
1903
                    case 0x29: /* fsqrts */
1904
                        gen_op_load_fpr_FT1(rs2);
1905
                        gen_clear_float_exceptions();
1906
                        tcg_gen_helper_0_0(helper_fsqrts);
1907
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1908
                        gen_op_store_FT0_fpr(rd);
1909
                        break;
1910
                    case 0x2a: /* fsqrtd */
1911
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1912
                        gen_clear_float_exceptions();
1913
                        tcg_gen_helper_0_0(helper_fsqrtd);
1914
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1915
                        gen_op_store_DT0_fpr(DFPREG(rd));
1916
                        break;
1917
                    case 0x2b: /* fsqrtq */
1918
#if defined(CONFIG_USER_ONLY)
1919
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1920
                        gen_clear_float_exceptions();
1921
                        tcg_gen_helper_0_0(helper_fsqrtq);
1922
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1923
                        gen_op_store_QT0_fpr(QFPREG(rd));
1924
                        break;
1925
#else
1926
                        goto nfpu_insn;
1927
#endif
1928
                    case 0x41:
1929
                        gen_op_load_fpr_FT0(rs1);
1930
                        gen_op_load_fpr_FT1(rs2);
1931
                        gen_clear_float_exceptions();
1932
                        gen_op_fadds();
1933
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1934
                        gen_op_store_FT0_fpr(rd);
1935
                        break;
1936
                    case 0x42:
1937
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1938
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1939
                        gen_clear_float_exceptions();
1940
                        gen_op_faddd();
1941
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1942
                        gen_op_store_DT0_fpr(DFPREG(rd));
1943
                        break;
1944
                    case 0x43: /* faddq */
1945
#if defined(CONFIG_USER_ONLY)
1946
                        gen_op_load_fpr_QT0(QFPREG(rs1));
1947
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1948
                        gen_clear_float_exceptions();
1949
                        gen_op_faddq();
1950
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1951
                        gen_op_store_QT0_fpr(QFPREG(rd));
1952
                        break;
1953
#else
1954
                        goto nfpu_insn;
1955
#endif
1956
                    case 0x45:
1957
                        gen_op_load_fpr_FT0(rs1);
1958
                        gen_op_load_fpr_FT1(rs2);
1959
                        gen_clear_float_exceptions();
1960
                        gen_op_fsubs();
1961
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1962
                        gen_op_store_FT0_fpr(rd);
1963
                        break;
1964
                    case 0x46:
1965
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1966
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1967
                        gen_clear_float_exceptions();
1968
                        gen_op_fsubd();
1969
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1970
                        gen_op_store_DT0_fpr(DFPREG(rd));
1971
                        break;
1972
                    case 0x47: /* fsubq */
1973
#if defined(CONFIG_USER_ONLY)
1974
                        gen_op_load_fpr_QT0(QFPREG(rs1));
1975
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1976
                        gen_clear_float_exceptions();
1977
                        gen_op_fsubq();
1978
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1979
                        gen_op_store_QT0_fpr(QFPREG(rd));
1980
                        break;
1981
#else
1982
                        goto nfpu_insn;
1983
#endif
1984
                    case 0x49:
1985
                        gen_op_load_fpr_FT0(rs1);
1986
                        gen_op_load_fpr_FT1(rs2);
1987
                        gen_clear_float_exceptions();
1988
                        gen_op_fmuls();
1989
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1990
                        gen_op_store_FT0_fpr(rd);
1991
                        break;
1992
                    case 0x4a:
1993
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1994
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1995
                        gen_clear_float_exceptions();
1996
                        gen_op_fmuld();
1997
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1998
                        gen_op_store_DT0_fpr(DFPREG(rd));
1999
                        break;
2000
                    case 0x4b: /* fmulq */
2001
#if defined(CONFIG_USER_ONLY)
2002
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2003
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2004
                        gen_clear_float_exceptions();
2005
                        gen_op_fmulq();
2006
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2007
                        gen_op_store_QT0_fpr(QFPREG(rd));
2008
                        break;
2009
#else
2010
                        goto nfpu_insn;
2011
#endif
2012
                    case 0x4d:
2013
                        gen_op_load_fpr_FT0(rs1);
2014
                        gen_op_load_fpr_FT1(rs2);
2015
                        gen_clear_float_exceptions();
2016
                        gen_op_fdivs();
2017
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2018
                        gen_op_store_FT0_fpr(rd);
2019
                        break;
2020
                    case 0x4e:
2021
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2022
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2023
                        gen_clear_float_exceptions();
2024
                        gen_op_fdivd();
2025
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2026
                        gen_op_store_DT0_fpr(DFPREG(rd));
2027
                        break;
2028
                    case 0x4f: /* fdivq */
2029
#if defined(CONFIG_USER_ONLY)
2030
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2031
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2032
                        gen_clear_float_exceptions();
2033
                        gen_op_fdivq();
2034
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2035
                        gen_op_store_QT0_fpr(QFPREG(rd));
2036
                        break;
2037
#else
2038
                        goto nfpu_insn;
2039
#endif
2040
                    case 0x69:
2041
                        gen_op_load_fpr_FT0(rs1);
2042
                        gen_op_load_fpr_FT1(rs2);
2043
                        gen_clear_float_exceptions();
2044
                        gen_op_fsmuld();
2045
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2046
                        gen_op_store_DT0_fpr(DFPREG(rd));
2047
                        break;
2048
                    case 0x6e: /* fdmulq */
2049
#if defined(CONFIG_USER_ONLY)
2050
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2051
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2052
                        gen_clear_float_exceptions();
2053
                        gen_op_fdmulq();
2054
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2055
                        gen_op_store_QT0_fpr(QFPREG(rd));
2056
                        break;
2057
#else
2058
                        goto nfpu_insn;
2059
#endif
2060
                    case 0xc4:
2061
                        gen_op_load_fpr_FT1(rs2);
2062
                        gen_clear_float_exceptions();
2063
                        gen_op_fitos();
2064
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2065
                        gen_op_store_FT0_fpr(rd);
2066
                        break;
2067
                    case 0xc6:
2068
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2069
                        gen_clear_float_exceptions();
2070
                        gen_op_fdtos();
2071
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2072
                        gen_op_store_FT0_fpr(rd);
2073
                        break;
2074
                    case 0xc7: /* fqtos */
2075
#if defined(CONFIG_USER_ONLY)
2076
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2077
                        gen_clear_float_exceptions();
2078
                        gen_op_fqtos();
2079
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2080
                        gen_op_store_FT0_fpr(rd);
2081
                        break;
2082
#else
2083
                        goto nfpu_insn;
2084
#endif
2085
                    case 0xc8:
2086
                        gen_op_load_fpr_FT1(rs2);
2087
                        gen_op_fitod();
2088
                        gen_op_store_DT0_fpr(DFPREG(rd));
2089
                        break;
2090
                    case 0xc9:
2091
                        gen_op_load_fpr_FT1(rs2);
2092
                        gen_op_fstod();
2093
                        gen_op_store_DT0_fpr(DFPREG(rd));
2094
                        break;
2095
                    case 0xcb: /* fqtod */
2096
#if defined(CONFIG_USER_ONLY)
2097
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2098
                        gen_clear_float_exceptions();
2099
                        gen_op_fqtod();
2100
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2101
                        gen_op_store_DT0_fpr(DFPREG(rd));
2102
                        break;
2103
#else
2104
                        goto nfpu_insn;
2105
#endif
2106
                    case 0xcc: /* fitoq */
2107
#if defined(CONFIG_USER_ONLY)
2108
                        gen_op_load_fpr_FT1(rs2);
2109
                        gen_op_fitoq();
2110
                        gen_op_store_QT0_fpr(QFPREG(rd));
2111
                        break;
2112
#else
2113
                        goto nfpu_insn;
2114
#endif
2115
                    case 0xcd: /* fstoq */
2116
#if defined(CONFIG_USER_ONLY)
2117
                        gen_op_load_fpr_FT1(rs2);
2118
                        gen_op_fstoq();
2119
                        gen_op_store_QT0_fpr(QFPREG(rd));
2120
                        break;
2121
#else
2122
                        goto nfpu_insn;
2123
#endif
2124
                    case 0xce: /* fdtoq */
2125
#if defined(CONFIG_USER_ONLY)
2126
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2127
                        gen_op_fdtoq();
2128
                        gen_op_store_QT0_fpr(QFPREG(rd));
2129
                        break;
2130
#else
2131
                        goto nfpu_insn;
2132
#endif
2133
                    case 0xd1:
2134
                        gen_op_load_fpr_FT1(rs2);
2135
                        gen_clear_float_exceptions();
2136
                        gen_op_fstoi();
2137
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2138
                        gen_op_store_FT0_fpr(rd);
2139
                        break;
2140
                    case 0xd2:
2141
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2142
                        gen_clear_float_exceptions();
2143
                        gen_op_fdtoi();
2144
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2145
                        gen_op_store_FT0_fpr(rd);
2146
                        break;
2147
                    case 0xd3: /* fqtoi */
2148
#if defined(CONFIG_USER_ONLY)
2149
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2150
                        gen_clear_float_exceptions();
2151
                        gen_op_fqtoi();
2152
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2153
                        gen_op_store_FT0_fpr(rd);
2154
                        break;
2155
#else
2156
                        goto nfpu_insn;
2157
#endif
2158
#ifdef TARGET_SPARC64
2159
                    case 0x2: /* V9 fmovd */
2160
                        gen_op_load_fpr_DT0(DFPREG(rs2));
2161
                        gen_op_store_DT0_fpr(DFPREG(rd));
2162
                        break;
2163
                    case 0x3: /* V9 fmovq */
2164
#if defined(CONFIG_USER_ONLY)
2165
                        gen_op_load_fpr_QT0(QFPREG(rs2));
2166
                        gen_op_store_QT0_fpr(QFPREG(rd));
2167
                        break;
2168
#else
2169
                        goto nfpu_insn;
2170
#endif
2171
                    case 0x6: /* V9 fnegd */
2172
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2173
                        gen_op_fnegd();
2174
                        gen_op_store_DT0_fpr(DFPREG(rd));
2175
                        break;
2176
                    case 0x7: /* V9 fnegq */
2177
#if defined(CONFIG_USER_ONLY)
2178
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2179
                        gen_op_fnegq();
2180
                        gen_op_store_QT0_fpr(QFPREG(rd));
2181
                        break;
2182
#else
2183
                        goto nfpu_insn;
2184
#endif
2185
                    case 0xa: /* V9 fabsd */
2186
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2187
                        tcg_gen_helper_0_0(helper_fabsd);
2188
                        gen_op_store_DT0_fpr(DFPREG(rd));
2189
                        break;
2190
                    case 0xb: /* V9 fabsq */
2191
#if defined(CONFIG_USER_ONLY)
2192
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2193
                        tcg_gen_helper_0_0(helper_fabsq);
2194
                        gen_op_store_QT0_fpr(QFPREG(rd));
2195
                        break;
2196
#else
2197
                        goto nfpu_insn;
2198
#endif
2199
                    case 0x81: /* V9 fstox */
2200
                        gen_op_load_fpr_FT1(rs2);
2201
                        gen_clear_float_exceptions();
2202
                        gen_op_fstox();
2203
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2204
                        gen_op_store_DT0_fpr(DFPREG(rd));
2205
                        break;
2206
                    case 0x82: /* V9 fdtox */
2207
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2208
                        gen_clear_float_exceptions();
2209
                        gen_op_fdtox();
2210
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2211
                        gen_op_store_DT0_fpr(DFPREG(rd));
2212
                        break;
2213
                    case 0x83: /* V9 fqtox */
2214
#if defined(CONFIG_USER_ONLY)
2215
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2216
                        gen_clear_float_exceptions();
2217
                        gen_op_fqtox();
2218
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2219
                        gen_op_store_DT0_fpr(DFPREG(rd));
2220
                        break;
2221
#else
2222
                        goto nfpu_insn;
2223
#endif
2224
                    case 0x84: /* V9 fxtos */
2225
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2226
                        gen_clear_float_exceptions();
2227
                        gen_op_fxtos();
2228
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2229
                        gen_op_store_FT0_fpr(rd);
2230
                        break;
2231
                    case 0x88: /* V9 fxtod */
2232
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2233
                        gen_clear_float_exceptions();
2234
                        gen_op_fxtod();
2235
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2236
                        gen_op_store_DT0_fpr(DFPREG(rd));
2237
                        break;
2238
                    case 0x8c: /* V9 fxtoq */
2239
#if defined(CONFIG_USER_ONLY)
2240
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2241
                        gen_clear_float_exceptions();
2242
                        gen_op_fxtoq();
2243
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2244
                        gen_op_store_QT0_fpr(QFPREG(rd));
2245
                        break;
2246
#else
2247
                        goto nfpu_insn;
2248
#endif
2249
#endif
2250
                    default:
2251
                        goto illegal_insn;
2252
                }
2253
            } else if (xop == 0x35) {   /* FPU Operations */
2254
#ifdef TARGET_SPARC64
2255
                int cond;
2256
#endif
2257
                if (gen_trap_ifnofpu(dc))
2258
                    goto jmp_insn;
2259
                gen_op_clear_ieee_excp_and_FTT();
2260
                rs1 = GET_FIELD(insn, 13, 17);
2261
                rs2 = GET_FIELD(insn, 27, 31);
2262
                xop = GET_FIELD(insn, 18, 26);
2263
#ifdef TARGET_SPARC64
2264
                if ((xop & 0x11f) == 0x005) { // V9 fmovsr
2265
                    TCGv r_zero;
2266
                    int l1;
2267

    
2268
                    l1 = gen_new_label();
2269
                    r_zero = tcg_temp_new(TCG_TYPE_TL);
2270
                    cond = GET_FIELD_SP(insn, 14, 17);
2271
                    rs1 = GET_FIELD(insn, 13, 17);
2272
                    gen_movl_reg_T0(rs1);
2273
                    tcg_gen_movi_tl(r_zero, 0);
2274
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0], r_zero, l1);
2275
                    gen_op_load_fpr_FT0(rs2);
2276
                    gen_op_store_FT0_fpr(rd);
2277
                    gen_set_label(l1);
2278
                    break;
2279
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
2280
                    TCGv r_zero;
2281
                    int l1;
2282

    
2283
                    l1 = gen_new_label();
2284
                    r_zero = tcg_temp_new(TCG_TYPE_TL);
2285
                    cond = GET_FIELD_SP(insn, 14, 17);
2286
                    rs1 = GET_FIELD(insn, 13, 17);
2287
                    gen_movl_reg_T0(rs1);
2288
                    tcg_gen_movi_tl(r_zero, 0);
2289
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0], r_zero, l1);
2290
                    gen_op_load_fpr_DT0(DFPREG(rs2));
2291
                    gen_op_store_DT0_fpr(DFPREG(rd));
2292
                    gen_set_label(l1);
2293
                    break;
2294
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
2295
#if defined(CONFIG_USER_ONLY)
2296
                    TCGv r_zero;
2297
                    int l1;
2298

    
2299
                    l1 = gen_new_label();
2300
                    r_zero = tcg_temp_new(TCG_TYPE_TL);
2301
                    cond = GET_FIELD_SP(insn, 14, 17);
2302
                    rs1 = GET_FIELD(insn, 13, 17);
2303
                    gen_movl_reg_T0(rs1);
2304
                    tcg_gen_movi_tl(r_zero, 0);
2305
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0], r_zero, l1);
2306
                    gen_op_load_fpr_QT0(QFPREG(rs2));
2307
                    gen_op_store_QT0_fpr(QFPREG(rd));
2308
                    gen_set_label(l1);
2309
                    break;
2310
#else
2311
                    goto nfpu_insn;
2312
#endif
2313
                }
2314
#endif
2315
                switch (xop) {
2316
#ifdef TARGET_SPARC64
2317
#define FMOVCC(size_FDQ, fcc)                                           \
2318
                    {                                                   \
2319
                        TCGv r_zero, r_cond;                            \
2320
                        int l1;                                         \
2321
                                                                        \
2322
                        l1 = gen_new_label();                           \
2323
                        r_zero = tcg_temp_new(TCG_TYPE_TL);             \
2324
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2325
                        tcg_gen_movi_tl(r_zero, 0);                     \
2326
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2327
                        gen_fcond(r_cond, fcc, cond);                   \
2328
                        tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, r_zero, l1); \
2329
                        glue(glue(gen_op_load_fpr_, size_FDQ), T0)(glue(size_FDQ, FPREG(rs2))); \
2330
                        glue(glue(gen_op_store_, size_FDQ), T0_fpr)(glue(size_FDQ, FPREG(rd))); \
2331
                        gen_set_label(l1);                              \
2332
                    }
2333
                    case 0x001: /* V9 fmovscc %fcc0 */
2334
                        FMOVCC(F, 0);
2335
                        break;
2336
                    case 0x002: /* V9 fmovdcc %fcc0 */
2337
                        FMOVCC(D, 0);
2338
                        break;
2339
                    case 0x003: /* V9 fmovqcc %fcc0 */
2340
#if defined(CONFIG_USER_ONLY)
2341
                        FMOVCC(Q, 0);
2342
                        break;
2343
#else
2344
                        goto nfpu_insn;
2345
#endif
2346
                    case 0x041: /* V9 fmovscc %fcc1 */
2347
                        FMOVCC(F, 1);
2348
                        break;
2349
                    case 0x042: /* V9 fmovdcc %fcc1 */
2350
                        FMOVCC(D, 1);
2351
                        break;
2352
                    case 0x043: /* V9 fmovqcc %fcc1 */
2353
#if defined(CONFIG_USER_ONLY)
2354
                        FMOVCC(Q, 1);
2355
                        break;
2356
#else
2357
                        goto nfpu_insn;
2358
#endif
2359
                    case 0x081: /* V9 fmovscc %fcc2 */
2360
                        FMOVCC(F, 2);
2361
                        break;
2362
                    case 0x082: /* V9 fmovdcc %fcc2 */
2363
                        FMOVCC(D, 2);
2364
                        break;
2365
                    case 0x083: /* V9 fmovqcc %fcc2 */
2366
#if defined(CONFIG_USER_ONLY)
2367
                        FMOVCC(Q, 2);
2368
                        break;
2369
#else
2370
                        goto nfpu_insn;
2371
#endif
2372
                    case 0x0c1: /* V9 fmovscc %fcc3 */
2373
                        FMOVCC(F, 3);
2374
                        break;
2375
                    case 0x0c2: /* V9 fmovdcc %fcc3 */
2376
                        FMOVCC(D, 3);
2377
                        break;
2378
                    case 0x0c3: /* V9 fmovqcc %fcc3 */
2379
#if defined(CONFIG_USER_ONLY)
2380
                        FMOVCC(Q, 3);
2381
                        break;
2382
#else
2383
                        goto nfpu_insn;
2384
#endif
2385
#undef FMOVCC
2386
#define FMOVCC(size_FDQ, icc)                                           \
2387
                    {                                                   \
2388
                        TCGv r_zero, r_cond;                            \
2389
                        int l1;                                         \
2390
                                                                        \
2391
                        l1 = gen_new_label();                           \
2392
                        r_zero = tcg_temp_new(TCG_TYPE_TL);             \
2393
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2394
                        tcg_gen_movi_tl(r_zero, 0);                     \
2395
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2396
                        gen_cond(r_cond, icc, cond);                    \
2397
                        tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, r_zero, l1); \
2398
                        glue(glue(gen_op_load_fpr_, size_FDQ), T0)(glue(size_FDQ, FPREG(rs2))); \
2399
                        glue(glue(gen_op_store_, size_FDQ), T0_fpr)(glue(size_FDQ, FPREG(rd))); \
2400
                        gen_set_label(l1);                              \
2401
                    }
2402

    
2403
                    case 0x101: /* V9 fmovscc %icc */
2404
                        FMOVCC(F, 0);
2405
                        break;
2406
                    case 0x102: /* V9 fmovdcc %icc */
2407
                        FMOVCC(D, 0);
2408
                    case 0x103: /* V9 fmovqcc %icc */
2409
#if defined(CONFIG_USER_ONLY)
2410
                        FMOVCC(D, 0);
2411
                        break;
2412
#else
2413
                        goto nfpu_insn;
2414
#endif
2415
                    case 0x181: /* V9 fmovscc %xcc */
2416
                        FMOVCC(F, 1);
2417
                        break;
2418
                    case 0x182: /* V9 fmovdcc %xcc */
2419
                        FMOVCC(D, 1);
2420
                        break;
2421
                    case 0x183: /* V9 fmovqcc %xcc */
2422
#if defined(CONFIG_USER_ONLY)
2423
                        FMOVCC(Q, 1);
2424
                        break;
2425
#else
2426
                        goto nfpu_insn;
2427
#endif
2428
#undef FMOVCC
2429
#endif
2430
                    case 0x51: /* fcmps, V9 %fcc */
2431
                        gen_op_load_fpr_FT0(rs1);
2432
                        gen_op_load_fpr_FT1(rs2);
2433
                        gen_op_fcmps(rd & 3);
2434
                        break;
2435
                    case 0x52: /* fcmpd, V9 %fcc */
2436
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2437
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2438
                        gen_op_fcmpd(rd & 3);
2439
                        break;
2440
                    case 0x53: /* fcmpq, V9 %fcc */
2441
#if defined(CONFIG_USER_ONLY)
2442
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2443
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2444
                        gen_op_fcmpq(rd & 3);
2445
                        break;
2446
#else /* !defined(CONFIG_USER_ONLY) */
2447
                        goto nfpu_insn;
2448
#endif
2449
                    case 0x55: /* fcmpes, V9 %fcc */
2450
                        gen_op_load_fpr_FT0(rs1);
2451
                        gen_op_load_fpr_FT1(rs2);
2452
                        gen_op_fcmpes(rd & 3);
2453
                        break;
2454
                    case 0x56: /* fcmped, V9 %fcc */
2455
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2456
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2457
                        gen_op_fcmped(rd & 3);
2458
                        break;
2459
                    case 0x57: /* fcmpeq, V9 %fcc */
2460
#if defined(CONFIG_USER_ONLY)
2461
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2462
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2463
                        gen_op_fcmpeq(rd & 3);
2464
                        break;
2465
#else/* !defined(CONFIG_USER_ONLY) */
2466
                        goto nfpu_insn;
2467
#endif
2468
                    default:
2469
                        goto illegal_insn;
2470
                }
2471
#if defined(OPTIM)
2472
            } else if (xop == 0x2) {
2473
                // clr/mov shortcut
2474

    
2475
                rs1 = GET_FIELD(insn, 13, 17);
2476
                if (rs1 == 0) {
2477
                    // or %g0, x, y -> mov T0, x; mov y, T0
2478
                    if (IS_IMM) {       /* immediate */
2479
                        rs2 = GET_FIELDs(insn, 19, 31);
2480
                        tcg_gen_movi_tl(cpu_T[0], (int)rs2);
2481
                    } else {            /* register */
2482
                        rs2 = GET_FIELD(insn, 27, 31);
2483
                        gen_movl_reg_T0(rs2);
2484
                    }
2485
                } else {
2486
                    gen_movl_reg_T0(rs1);
2487
                    if (IS_IMM) {       /* immediate */
2488
                        rs2 = GET_FIELDs(insn, 19, 31);
2489
                        tcg_gen_ori_tl(cpu_T[0], cpu_T[0], (int)rs2);
2490
                    } else {            /* register */
2491
                        // or x, %g0, y -> mov T1, x; mov y, T1
2492
                        rs2 = GET_FIELD(insn, 27, 31);
2493
                        if (rs2 != 0) {
2494
                            gen_movl_reg_T1(rs2);
2495
                            gen_op_or_T1_T0();
2496
                        }
2497
                    }
2498
                }
2499
                gen_movl_T0_reg(rd);
2500
#endif
2501
#ifdef TARGET_SPARC64
2502
            } else if (xop == 0x25) { /* sll, V9 sllx */
2503
                rs1 = GET_FIELD(insn, 13, 17);
2504
                gen_movl_reg_T0(rs1);
2505
                if (IS_IMM) {   /* immediate */
2506
                    rs2 = GET_FIELDs(insn, 20, 31);
2507
                    if (insn & (1 << 12)) {
2508
                        tcg_gen_shli_i64(cpu_T[0], cpu_T[0], rs2 & 0x3f);
2509
                    } else {
2510
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
2511
                        tcg_gen_shli_i64(cpu_T[0], cpu_T[0], rs2 & 0x1f);
2512
                    }
2513
                } else {                /* register */
2514
                    rs2 = GET_FIELD(insn, 27, 31);
2515
                    gen_movl_reg_T1(rs2);
2516
                    if (insn & (1 << 12)) {
2517
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x3f);
2518
                        tcg_gen_shl_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2519
                    } else {
2520
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x1f);
2521
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
2522
                        tcg_gen_shl_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2523
                    }
2524
                }
2525
                gen_movl_T0_reg(rd);
2526
            } else if (xop == 0x26) { /* srl, V9 srlx */
2527
                rs1 = GET_FIELD(insn, 13, 17);
2528
                gen_movl_reg_T0(rs1);
2529
                if (IS_IMM) {   /* immediate */
2530
                    rs2 = GET_FIELDs(insn, 20, 31);
2531
                    if (insn & (1 << 12)) {
2532
                        tcg_gen_shri_i64(cpu_T[0], cpu_T[0], rs2 & 0x3f);
2533
                    } else {
2534
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
2535
                        tcg_gen_shri_i64(cpu_T[0], cpu_T[0], rs2 & 0x1f);
2536
                    }
2537
                } else {                /* register */
2538
                    rs2 = GET_FIELD(insn, 27, 31);
2539
                    gen_movl_reg_T1(rs2);
2540
                    if (insn & (1 << 12)) {
2541
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x3f);
2542
                        tcg_gen_shr_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2543
                    } else {
2544
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x1f);
2545
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
2546
                        tcg_gen_shr_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2547
                    }
2548
                }
2549
                gen_movl_T0_reg(rd);
2550
            } else if (xop == 0x27) { /* sra, V9 srax */
2551
                rs1 = GET_FIELD(insn, 13, 17);
2552
                gen_movl_reg_T0(rs1);
2553
                if (IS_IMM) {   /* immediate */
2554
                    rs2 = GET_FIELDs(insn, 20, 31);
2555
                    if (insn & (1 << 12)) {
2556
                        tcg_gen_sari_i64(cpu_T[0], cpu_T[0], rs2 & 0x3f);
2557
                    } else {
2558
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
2559
                        tcg_gen_ext_i32_i64(cpu_T[0], cpu_T[0]);
2560
                        tcg_gen_sari_i64(cpu_T[0], cpu_T[0], rs2 & 0x1f);
2561
                    }
2562
                } else {                /* register */
2563
                    rs2 = GET_FIELD(insn, 27, 31);
2564
                    gen_movl_reg_T1(rs2);
2565
                    if (insn & (1 << 12)) {
2566
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x3f);
2567
                        tcg_gen_sar_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2568
                    } else {
2569
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x1f);
2570
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
2571
                        tcg_gen_sar_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2572
                    }
2573
                }
2574
                gen_movl_T0_reg(rd);
2575
#endif
2576
            } else if (xop < 0x36) {
2577
                rs1 = GET_FIELD(insn, 13, 17);
2578
                gen_movl_reg_T0(rs1);
2579
                if (IS_IMM) {   /* immediate */
2580
                    rs2 = GET_FIELDs(insn, 19, 31);
2581
                    gen_movl_simm_T1(rs2);
2582
                } else {                /* register */
2583
                    rs2 = GET_FIELD(insn, 27, 31);
2584
                    gen_movl_reg_T1(rs2);
2585
                }
2586
                if (xop < 0x20) {
2587
                    switch (xop & ~0x10) {
2588
                    case 0x0:
2589
                        if (xop & 0x10)
2590
                            gen_op_add_T1_T0_cc();
2591
                        else
2592
                            gen_op_add_T1_T0();
2593
                        break;
2594
                    case 0x1:
2595
                        tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2596
                        if (xop & 0x10)
2597
                            gen_op_logic_T0_cc();
2598
                        break;
2599
                    case 0x2:
2600
                        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2601
                        if (xop & 0x10)
2602
                            gen_op_logic_T0_cc();
2603
                        break;
2604
                    case 0x3:
2605
                        tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2606
                        if (xop & 0x10)
2607
                            gen_op_logic_T0_cc();
2608
                        break;
2609
                    case 0x4:
2610
                        if (xop & 0x10)
2611
                            gen_op_sub_T1_T0_cc();
2612
                        else
2613
                            tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2614
                        break;
2615
                    case 0x5:
2616
                        tcg_gen_xori_tl(cpu_T[1], cpu_T[1], -1);
2617
                        tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2618
                        if (xop & 0x10)
2619
                            gen_op_logic_T0_cc();
2620
                        break;
2621
                    case 0x6:
2622
                        tcg_gen_xori_tl(cpu_T[1], cpu_T[1], -1);
2623
                        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2624
                        if (xop & 0x10)
2625
                            gen_op_logic_T0_cc();
2626
                        break;
2627
                    case 0x7:
2628
                        tcg_gen_xori_tl(cpu_T[1], cpu_T[1], -1);
2629
                        tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2630
                        if (xop & 0x10)
2631
                            gen_op_logic_T0_cc();
2632
                        break;
2633
                    case 0x8:
2634
                        if (xop & 0x10)
2635
                            gen_op_addx_T1_T0_cc();
2636
                        else {
2637
                            tcg_gen_ld_i32(cpu_tmp0, cpu_env,
2638
                                           offsetof(CPUSPARCState, psr));
2639
                            gen_mov_reg_C(cpu_tmp0, cpu_tmp0);
2640
                            tcg_gen_add_tl(cpu_T[1], cpu_T[1], cpu_tmp0);
2641
                            tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2642
                        }
2643
                        break;
2644
#ifdef TARGET_SPARC64
2645
                    case 0x9: /* V9 mulx */
2646
                        tcg_gen_mul_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2647
                        break;
2648
#endif
2649
                    case 0xa:
2650
                        gen_op_umul_T1_T0();
2651
                        if (xop & 0x10)
2652
                            gen_op_logic_T0_cc();
2653
                        break;
2654
                    case 0xb:
2655
                        gen_op_smul_T1_T0();
2656
                        if (xop & 0x10)
2657
                            gen_op_logic_T0_cc();
2658
                        break;
2659
                    case 0xc:
2660
                        if (xop & 0x10)
2661
                            gen_op_subx_T1_T0_cc();
2662
                        else {
2663
                            tcg_gen_ld_i32(cpu_tmp0, cpu_env,
2664
                                           offsetof(CPUSPARCState, psr));
2665
                            gen_mov_reg_C(cpu_tmp0, cpu_tmp0);
2666
                            tcg_gen_add_tl(cpu_T[1], cpu_T[1], cpu_tmp0);
2667
                            tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2668
                        }
2669
                        break;
2670
#ifdef TARGET_SPARC64
2671
                    case 0xd: /* V9 udivx */
2672
                        gen_op_udivx_T1_T0();
2673
                        break;
2674
#endif
2675
                    case 0xe:
2676
                        gen_op_udiv_T1_T0();
2677
                        if (xop & 0x10)
2678
                            gen_op_div_cc();
2679
                        break;
2680
                    case 0xf:
2681
                        gen_op_sdiv_T1_T0();
2682
                        if (xop & 0x10)
2683
                            gen_op_div_cc();
2684
                        break;
2685
                    default:
2686
                        goto illegal_insn;
2687
                    }
2688
                    gen_movl_T0_reg(rd);
2689
                } else {
2690
                    switch (xop) {
2691
                    case 0x20: /* taddcc */
2692
                        gen_op_tadd_T1_T0_cc();
2693
                        gen_movl_T0_reg(rd);
2694
                        break;
2695
                    case 0x21: /* tsubcc */
2696
                        gen_op_tsub_T1_T0_cc();
2697
                        gen_movl_T0_reg(rd);
2698
                        break;
2699
                    case 0x22: /* taddcctv */
2700
                        save_state(dc);
2701
                        gen_op_tadd_T1_T0_ccTV();
2702
                        gen_movl_T0_reg(rd);
2703
                        break;
2704
                    case 0x23: /* tsubcctv */
2705
                        save_state(dc);
2706
                        gen_op_tsub_T1_T0_ccTV();
2707
                        gen_movl_T0_reg(rd);
2708
                        break;
2709
                    case 0x24: /* mulscc */
2710
                        gen_op_mulscc_T1_T0();
2711
                        gen_movl_T0_reg(rd);
2712
                        break;
2713
#ifndef TARGET_SPARC64
2714
                    case 0x25:  /* sll */
2715
                        tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0x1f);
2716
                        tcg_gen_shl_i32(cpu_T[0], cpu_T[0], cpu_T[1]);
2717
                        gen_movl_T0_reg(rd);
2718
                        break;
2719
                    case 0x26:  /* srl */
2720
                        tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0x1f);
2721
                        tcg_gen_shr_i32(cpu_T[0], cpu_T[0], cpu_T[1]);
2722
                        gen_movl_T0_reg(rd);
2723
                        break;
2724
                    case 0x27:  /* sra */
2725
                        tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0x1f);
2726
                        tcg_gen_sar_i32(cpu_T[0], cpu_T[0], cpu_T[1]);
2727
                        gen_movl_T0_reg(rd);
2728
                        break;
2729
#endif
2730
                    case 0x30:
2731
                        {
2732
                            switch(rd) {
2733
                            case 0: /* wry */
2734
                                gen_op_xor_T1_T0();
2735
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, y));
2736
                                break;
2737
#ifndef TARGET_SPARC64
2738
                            case 0x01 ... 0x0f: /* undefined in the
2739
                                                   SPARCv8 manual, nop
2740
                                                   on the microSPARC
2741
                                                   II */
2742
                            case 0x10 ... 0x1f: /* implementation-dependent
2743
                                                   in the SPARCv8
2744
                                                   manual, nop on the
2745
                                                   microSPARC II */
2746
                                break;
2747
#else
2748
                            case 0x2: /* V9 wrccr */
2749
                                gen_op_xor_T1_T0();
2750
                                gen_op_wrccr();
2751
                                break;
2752
                            case 0x3: /* V9 wrasi */
2753
                                gen_op_xor_T1_T0();
2754
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, asi));
2755
                                break;
2756
                            case 0x6: /* V9 wrfprs */
2757
                                gen_op_xor_T1_T0();
2758
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, fprs));
2759
                                save_state(dc);
2760
                                gen_op_next_insn();
2761
                                tcg_gen_exit_tb(0);
2762
                                dc->is_br = 1;
2763
                                break;
2764
                            case 0xf: /* V9 sir, nop if user */
2765
#if !defined(CONFIG_USER_ONLY)
2766
                                if (supervisor(dc))
2767
                                    ; // XXX
2768
#endif
2769
                                break;
2770
                            case 0x13: /* Graphics Status */
2771
                                if (gen_trap_ifnofpu(dc))
2772
                                    goto jmp_insn;
2773
                                gen_op_xor_T1_T0();
2774
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, gsr));
2775
                                break;
2776
                            case 0x17: /* Tick compare */
2777
#if !defined(CONFIG_USER_ONLY)
2778
                                if (!supervisor(dc))
2779
                                    goto illegal_insn;
2780
#endif
2781
                                {
2782
                                    TCGv r_tickptr;
2783

    
2784
                                    gen_op_xor_T1_T0();
2785
                                    gen_op_movtl_env_T0(offsetof(CPUSPARCState,
2786
                                                                 tick_cmpr));
2787
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2788
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
2789
                                                   offsetof(CPUState, tick));
2790
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
2791
                                                       r_tickptr, cpu_T[0]);
2792
                                }
2793
                                break;
2794
                            case 0x18: /* System tick */
2795
#if !defined(CONFIG_USER_ONLY)
2796
                                if (!supervisor(dc))
2797
                                    goto illegal_insn;
2798
#endif
2799
                                {
2800
                                    TCGv r_tickptr;
2801

    
2802
                                    gen_op_xor_T1_T0();
2803
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2804
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
2805
                                                   offsetof(CPUState, stick));
2806
                                    tcg_gen_helper_0_2(helper_tick_set_count,
2807
                                                       r_tickptr, cpu_T[0]);
2808
                                }
2809
                                break;
2810
                            case 0x19: /* System tick compare */
2811
#if !defined(CONFIG_USER_ONLY)
2812
                                if (!supervisor(dc))
2813
                                    goto illegal_insn;
2814
#endif
2815
                                {
2816
                                    TCGv r_tickptr;
2817

    
2818
                                    gen_op_xor_T1_T0();
2819
                                    gen_op_movtl_env_T0(offsetof(CPUSPARCState,
2820
                                                                 stick_cmpr));
2821
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2822
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
2823
                                                   offsetof(CPUState, stick));
2824
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
2825
                                                       r_tickptr, cpu_T[0]);
2826
                                }
2827
                                break;
2828

    
2829
                            case 0x10: /* Performance Control */
2830
                            case 0x11: /* Performance Instrumentation Counter */
2831
                            case 0x12: /* Dispatch Control */
2832
                            case 0x14: /* Softint set */
2833
                            case 0x15: /* Softint clear */
2834
                            case 0x16: /* Softint write */
2835
#endif
2836
                            default:
2837
                                goto illegal_insn;
2838
                            }
2839
                        }
2840
                        break;
2841
#if !defined(CONFIG_USER_ONLY)
2842
                    case 0x31: /* wrpsr, V9 saved, restored */
2843
                        {
2844
                            if (!supervisor(dc))
2845
                                goto priv_insn;
2846
#ifdef TARGET_SPARC64
2847
                            switch (rd) {
2848
                            case 0:
2849
                                gen_op_saved();
2850
                                break;
2851
                            case 1:
2852
                                gen_op_restored();
2853
                                break;
2854
                            case 2: /* UA2005 allclean */
2855
                            case 3: /* UA2005 otherw */
2856
                            case 4: /* UA2005 normalw */
2857
                            case 5: /* UA2005 invalw */
2858
                                // XXX
2859
                            default:
2860
                                goto illegal_insn;
2861
                            }
2862
#else
2863
                            gen_op_xor_T1_T0();
2864
                            tcg_gen_helper_0_1(helper_wrpsr, cpu_T[0]);
2865
                            save_state(dc);
2866
                            gen_op_next_insn();
2867
                            tcg_gen_exit_tb(0);
2868
                            dc->is_br = 1;
2869
#endif
2870
                        }
2871
                        break;
2872
                    case 0x32: /* wrwim, V9 wrpr */
2873
                        {
2874
                            if (!supervisor(dc))
2875
                                goto priv_insn;
2876
                            gen_op_xor_T1_T0();
2877
#ifdef TARGET_SPARC64
2878
                            switch (rd) {
2879
                            case 0: // tpc
2880
                                {
2881
                                    TCGv r_tsptr;
2882

    
2883
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2884
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
2885
                                                   offsetof(CPUState, tsptr));
2886
                                    tcg_gen_st_tl(cpu_T[0], r_tsptr,
2887
                                                  offsetof(trap_state, tpc));
2888
                                }
2889
                                break;
2890
                            case 1: // tnpc
2891
                                {
2892
                                    TCGv r_tsptr;
2893

    
2894
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2895
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
2896
                                                   offsetof(CPUState, tsptr));
2897
                                    tcg_gen_st_tl(cpu_T[0], r_tsptr,
2898
                                                  offsetof(trap_state, tnpc));
2899
                                }
2900
                                break;
2901
                            case 2: // tstate
2902
                                {
2903
                                    TCGv r_tsptr;
2904

    
2905
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2906
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
2907
                                                   offsetof(CPUState, tsptr));
2908
                                    tcg_gen_st_tl(cpu_T[0], r_tsptr,
2909
                                                  offsetof(trap_state, tstate));
2910
                                }
2911
                                break;
2912
                            case 3: // tt
2913
                                {
2914
                                    TCGv r_tsptr;
2915

    
2916
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2917
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
2918
                                                   offsetof(CPUState, tsptr));
2919
                                    tcg_gen_st_i32(cpu_T[0], r_tsptr,
2920
                                                   offsetof(trap_state, tt));
2921
                                }
2922
                                break;
2923
                            case 4: // tick
2924
                                {
2925
                                    TCGv r_tickptr;
2926

    
2927
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2928
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
2929
                                                   offsetof(CPUState, tick));
2930
                                    tcg_gen_helper_0_2(helper_tick_set_count,
2931
                                                       r_tickptr, cpu_T[0]);
2932
                                }
2933
                                break;
2934
                            case 5: // tba
2935
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
2936
                                break;
2937
                            case 6: // pstate
2938
                                save_state(dc);
2939
                                tcg_gen_helper_0_1(helper_wrpstate, cpu_T[0]);
2940
                                gen_op_next_insn();
2941
                                tcg_gen_exit_tb(0);
2942
                                dc->is_br = 1;
2943
                                break;
2944
                            case 7: // tl
2945
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, tl));
2946
                                break;
2947
                            case 8: // pil
2948
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, psrpil));
2949
                                break;
2950
                            case 9: // cwp
2951
                                gen_op_wrcwp();
2952
                                break;
2953
                            case 10: // cansave
2954
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, cansave));
2955
                                break;
2956
                            case 11: // canrestore
2957
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, canrestore));
2958
                                break;
2959
                            case 12: // cleanwin
2960
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, cleanwin));
2961
                                break;
2962
                            case 13: // otherwin
2963
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, otherwin));
2964
                                break;
2965
                            case 14: // wstate
2966
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, wstate));
2967
                                break;
2968
                            case 16: // UA2005 gl
2969
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, gl));
2970
                                break;
2971
                            case 26: // UA2005 strand status
2972
                                if (!hypervisor(dc))
2973
                                    goto priv_insn;
2974
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, ssr));
2975
                                break;
2976
                            default:
2977
                                goto illegal_insn;
2978
                            }
2979
#else
2980
                            tcg_gen_andi_i32(cpu_T[0], cpu_T[0], ((1 << NWINDOWS) - 1));
2981
                            gen_op_movl_env_T0(offsetof(CPUSPARCState, wim));
2982
#endif
2983
                        }
2984
                        break;
2985
                    case 0x33: /* wrtbr, UA2005 wrhpr */
2986
                        {
2987
#ifndef TARGET_SPARC64
2988
                            if (!supervisor(dc))
2989
                                goto priv_insn;
2990
                            gen_op_xor_T1_T0();
2991
                            gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
2992
#else
2993
                            if (!hypervisor(dc))
2994
                                goto priv_insn;
2995
                            gen_op_xor_T1_T0();
2996
                            switch (rd) {
2997
                            case 0: // hpstate
2998
                                // XXX gen_op_wrhpstate();
2999
                                save_state(dc);
3000
                                gen_op_next_insn();
3001
                                tcg_gen_exit_tb(0);
3002
                                dc->is_br = 1;
3003
                                break;
3004
                            case 1: // htstate
3005
                                // XXX gen_op_wrhtstate();
3006
                                break;
3007
                            case 3: // hintp
3008
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, hintp));
3009
                                break;
3010
                            case 5: // htba
3011
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, htba));
3012
                                break;
3013
                            case 31: // hstick_cmpr
3014
                                {
3015
                                    TCGv r_tickptr;
3016

    
3017
                                    gen_op_movtl_env_T0(offsetof(CPUSPARCState,
3018
                                                                 hstick_cmpr));
3019
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3020
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3021
                                                   offsetof(CPUState, hstick));
3022
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3023
                                                       r_tickptr, cpu_T[0]);
3024
                                }
3025
                                break;
3026
                            case 6: // hver readonly
3027
                            default:
3028
                                goto illegal_insn;
3029
                            }
3030
#endif
3031
                        }
3032
                        break;
3033
#endif
3034
#ifdef TARGET_SPARC64
3035
                    case 0x2c: /* V9 movcc */
3036
                        {
3037
                            int cc = GET_FIELD_SP(insn, 11, 12);
3038
                            int cond = GET_FIELD_SP(insn, 14, 17);
3039
                            TCGv r_zero;
3040
                            int l1;
3041

    
3042
                            flush_T2(dc);
3043
                            if (insn & (1 << 18)) {
3044
                                if (cc == 0)
3045
                                    gen_cond(cpu_T[2], 0, cond);
3046
                                else if (cc == 2)
3047
                                    gen_cond(cpu_T[2], 1, cond);
3048
                                else
3049
                                    goto illegal_insn;
3050
                            } else {
3051
                                gen_fcond(cpu_T[2], cc, cond);
3052
                            }
3053

    
3054
                            l1 = gen_new_label();
3055

    
3056
                            r_zero = tcg_temp_new(TCG_TYPE_TL);
3057
                            tcg_gen_movi_tl(r_zero, 0);
3058
                            tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[2], r_zero, l1);
3059
                            if (IS_IMM) {       /* immediate */
3060
                                rs2 = GET_FIELD_SPs(insn, 0, 10);
3061
                                gen_movl_simm_T1(rs2);
3062
                            } else {
3063
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3064
                                gen_movl_reg_T1(rs2);
3065
                            }
3066
                            gen_movl_T1_reg(rd);
3067
                            gen_set_label(l1);
3068
                            break;
3069
                        }
3070
                    case 0x2d: /* V9 sdivx */
3071
                        gen_op_sdivx_T1_T0();
3072
                        gen_movl_T0_reg(rd);
3073
                        break;
3074
                    case 0x2e: /* V9 popc */
3075
                        {
3076
                            if (IS_IMM) {       /* immediate */
3077
                                rs2 = GET_FIELD_SPs(insn, 0, 12);
3078
                                gen_movl_simm_T1(rs2);
3079
                                // XXX optimize: popc(constant)
3080
                            }
3081
                            else {
3082
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3083
                                gen_movl_reg_T1(rs2);
3084
                            }
3085
                            tcg_gen_helper_1_1(helper_popc, cpu_T[0],
3086
                                               cpu_T[1]);
3087
                            gen_movl_T0_reg(rd);
3088
                        }
3089
                    case 0x2f: /* V9 movr */
3090
                        {
3091
                            int cond = GET_FIELD_SP(insn, 10, 12);
3092
                            TCGv r_zero;
3093
                            int l1;
3094

    
3095
                            rs1 = GET_FIELD(insn, 13, 17);
3096
                            gen_movl_reg_T0(rs1);
3097

    
3098
                            l1 = gen_new_label();
3099

    
3100
                            r_zero = tcg_temp_new(TCG_TYPE_TL);
3101
                            tcg_gen_movi_tl(r_zero, 0);
3102
                            tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0], r_zero, l1);
3103
                            if (IS_IMM) {       /* immediate */
3104
                                rs2 = GET_FIELD_SPs(insn, 0, 9);
3105
                                gen_movl_simm_T1(rs2);
3106
                            } else {
3107
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3108
                                gen_movl_reg_T1(rs2);
3109
                            }
3110
                            gen_movl_T1_reg(rd);
3111
                            gen_set_label(l1);
3112
                            break;
3113
                        }
3114
#endif
3115
                    default:
3116
                        goto illegal_insn;
3117
                    }
3118
                }
3119
            } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
3120
#ifdef TARGET_SPARC64
3121
                int opf = GET_FIELD_SP(insn, 5, 13);
3122
                rs1 = GET_FIELD(insn, 13, 17);
3123
                rs2 = GET_FIELD(insn, 27, 31);
3124
                if (gen_trap_ifnofpu(dc))
3125
                    goto jmp_insn;
3126

    
3127
                switch (opf) {
3128
                case 0x000: /* VIS I edge8cc */
3129
                case 0x001: /* VIS II edge8n */
3130
                case 0x002: /* VIS I edge8lcc */
3131
                case 0x003: /* VIS II edge8ln */
3132
                case 0x004: /* VIS I edge16cc */
3133
                case 0x005: /* VIS II edge16n */
3134
                case 0x006: /* VIS I edge16lcc */
3135
                case 0x007: /* VIS II edge16ln */
3136
                case 0x008: /* VIS I edge32cc */
3137
                case 0x009: /* VIS II edge32n */
3138
                case 0x00a: /* VIS I edge32lcc */
3139
                case 0x00b: /* VIS II edge32ln */
3140
                    // XXX
3141
                    goto illegal_insn;
3142
                case 0x010: /* VIS I array8 */
3143
                    gen_movl_reg_T0(rs1);
3144
                    gen_movl_reg_T1(rs2);
3145
                    gen_op_array8();
3146
                    gen_movl_T0_reg(rd);
3147
                    break;
3148
                case 0x012: /* VIS I array16 */
3149
                    gen_movl_reg_T0(rs1);
3150
                    gen_movl_reg_T1(rs2);
3151
                    gen_op_array16();
3152
                    gen_movl_T0_reg(rd);
3153
                    break;
3154
                case 0x014: /* VIS I array32 */
3155
                    gen_movl_reg_T0(rs1);
3156
                    gen_movl_reg_T1(rs2);
3157
                    gen_op_array32();
3158
                    gen_movl_T0_reg(rd);
3159
                    break;
3160
                case 0x018: /* VIS I alignaddr */
3161
                    gen_movl_reg_T0(rs1);
3162
                    gen_movl_reg_T1(rs2);
3163
                    gen_op_alignaddr();
3164
                    gen_movl_T0_reg(rd);
3165
                    break;
3166
                case 0x019: /* VIS II bmask */
3167
                case 0x01a: /* VIS I alignaddrl */
3168
                    // XXX
3169
                    goto illegal_insn;
3170
                case 0x020: /* VIS I fcmple16 */
3171
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3172
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3173
                    gen_op_fcmple16();
3174
                    gen_op_store_DT0_fpr(DFPREG(rd));
3175
                    break;
3176
                case 0x022: /* VIS I fcmpne16 */
3177
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3178
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3179
                    gen_op_fcmpne16();
3180
                    gen_op_store_DT0_fpr(DFPREG(rd));
3181
                    break;
3182
                case 0x024: /* VIS I fcmple32 */
3183
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3184
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3185
                    gen_op_fcmple32();
3186
                    gen_op_store_DT0_fpr(DFPREG(rd));
3187
                    break;
3188
                case 0x026: /* VIS I fcmpne32 */
3189
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3190
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3191
                    gen_op_fcmpne32();
3192
                    gen_op_store_DT0_fpr(DFPREG(rd));
3193
                    break;
3194
                case 0x028: /* VIS I fcmpgt16 */
3195
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3196
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3197
                    gen_op_fcmpgt16();
3198
                    gen_op_store_DT0_fpr(DFPREG(rd));
3199
                    break;
3200
                case 0x02a: /* VIS I fcmpeq16 */
3201
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3202
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3203
                    gen_op_fcmpeq16();
3204
                    gen_op_store_DT0_fpr(DFPREG(rd));
3205
                    break;
3206
                case 0x02c: /* VIS I fcmpgt32 */
3207
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3208
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3209
                    gen_op_fcmpgt32();
3210
                    gen_op_store_DT0_fpr(DFPREG(rd));
3211
                    break;
3212
                case 0x02e: /* VIS I fcmpeq32 */
3213
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3214
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3215
                    gen_op_fcmpeq32();
3216
                    gen_op_store_DT0_fpr(DFPREG(rd));
3217
                    break;
3218
                case 0x031: /* VIS I fmul8x16 */
3219
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3220
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3221
                    gen_op_fmul8x16();
3222
                    gen_op_store_DT0_fpr(DFPREG(rd));
3223
                    break;
3224
                case 0x033: /* VIS I fmul8x16au */
3225
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3226
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3227
                    gen_op_fmul8x16au();
3228
                    gen_op_store_DT0_fpr(DFPREG(rd));
3229
                    break;
3230
                case 0x035: /* VIS I fmul8x16al */
3231
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3232
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3233
                    gen_op_fmul8x16al();
3234
                    gen_op_store_DT0_fpr(DFPREG(rd));
3235
                    break;
3236
                case 0x036: /* VIS I fmul8sux16 */
3237
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3238
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3239
                    gen_op_fmul8sux16();
3240
                    gen_op_store_DT0_fpr(DFPREG(rd));
3241
                    break;
3242
                case 0x037: /* VIS I fmul8ulx16 */
3243
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3244
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3245
                    gen_op_fmul8ulx16();
3246
                    gen_op_store_DT0_fpr(DFPREG(rd));
3247
                    break;
3248
                case 0x038: /* VIS I fmuld8sux16 */
3249
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3250
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3251
                    gen_op_fmuld8sux16();
3252
                    gen_op_store_DT0_fpr(DFPREG(rd));
3253
                    break;
3254
                case 0x039: /* VIS I fmuld8ulx16 */
3255
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3256
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3257
                    gen_op_fmuld8ulx16();
3258
                    gen_op_store_DT0_fpr(DFPREG(rd));
3259
                    break;
3260
                case 0x03a: /* VIS I fpack32 */
3261
                case 0x03b: /* VIS I fpack16 */
3262
                case 0x03d: /* VIS I fpackfix */
3263
                case 0x03e: /* VIS I pdist */
3264
                    // XXX
3265
                    goto illegal_insn;
3266
                case 0x048: /* VIS I faligndata */
3267
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3268
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3269
                    gen_op_faligndata();
3270
                    gen_op_store_DT0_fpr(DFPREG(rd));
3271
                    break;
3272
                case 0x04b: /* VIS I fpmerge */
3273
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3274
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3275
                    gen_op_fpmerge();
3276
                    gen_op_store_DT0_fpr(DFPREG(rd));
3277
                    break;
3278
                case 0x04c: /* VIS II bshuffle */
3279
                    // XXX
3280
                    goto illegal_insn;
3281
                case 0x04d: /* VIS I fexpand */
3282
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3283
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3284
                    gen_op_fexpand();
3285
                    gen_op_store_DT0_fpr(DFPREG(rd));
3286
                    break;
3287
                case 0x050: /* VIS I fpadd16 */
3288
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3289
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3290
                    gen_op_fpadd16();
3291
                    gen_op_store_DT0_fpr(DFPREG(rd));
3292
                    break;
3293
                case 0x051: /* VIS I fpadd16s */
3294
                    gen_op_load_fpr_FT0(rs1);
3295
                    gen_op_load_fpr_FT1(rs2);
3296
                    gen_op_fpadd16s();
3297
                    gen_op_store_FT0_fpr(rd);
3298
                    break;
3299
                case 0x052: /* VIS I fpadd32 */
3300
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3301
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3302
                    gen_op_fpadd32();
3303
                    gen_op_store_DT0_fpr(DFPREG(rd));
3304
                    break;
3305
                case 0x053: /* VIS I fpadd32s */
3306
                    gen_op_load_fpr_FT0(rs1);
3307
                    gen_op_load_fpr_FT1(rs2);
3308
                    gen_op_fpadd32s();
3309
                    gen_op_store_FT0_fpr(rd);
3310
                    break;
3311
                case 0x054: /* VIS I fpsub16 */
3312
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3313
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3314
                    gen_op_fpsub16();
3315
                    gen_op_store_DT0_fpr(DFPREG(rd));
3316
                    break;
3317
                case 0x055: /* VIS I fpsub16s */
3318
                    gen_op_load_fpr_FT0(rs1);
3319
                    gen_op_load_fpr_FT1(rs2);
3320
                    gen_op_fpsub16s();
3321
                    gen_op_store_FT0_fpr(rd);
3322
                    break;
3323
                case 0x056: /* VIS I fpsub32 */
3324
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3325
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3326
                    gen_op_fpadd32();
3327
                    gen_op_store_DT0_fpr(DFPREG(rd));
3328
                    break;
3329
                case 0x057: /* VIS I fpsub32s */
3330
                    gen_op_load_fpr_FT0(rs1);
3331
                    gen_op_load_fpr_FT1(rs2);
3332
                    gen_op_fpsub32s();
3333
                    gen_op_store_FT0_fpr(rd);
3334
                    break;
3335
                case 0x060: /* VIS I fzero */
3336
                    gen_op_movl_DT0_0();
3337
                    gen_op_store_DT0_fpr(DFPREG(rd));
3338
                    break;
3339
                case 0x061: /* VIS I fzeros */
3340
                    gen_op_movl_FT0_0();
3341
                    gen_op_store_FT0_fpr(rd);
3342
                    break;
3343
                case 0x062: /* VIS I fnor */
3344
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3345
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3346
                    gen_op_fnor();
3347
                    gen_op_store_DT0_fpr(DFPREG(rd));
3348
                    break;
3349
                case 0x063: /* VIS I fnors */
3350
                    gen_op_load_fpr_FT0(rs1);
3351
                    gen_op_load_fpr_FT1(rs2);
3352
                    gen_op_fnors();
3353
                    gen_op_store_FT0_fpr(rd);
3354
                    break;
3355
                case 0x064: /* VIS I fandnot2 */
3356
                    gen_op_load_fpr_DT1(DFPREG(rs1));
3357
                    gen_op_load_fpr_DT0(DFPREG(rs2));
3358
                    gen_op_fandnot();
3359
                    gen_op_store_DT0_fpr(DFPREG(rd));
3360
                    break;
3361
                case 0x065: /* VIS I fandnot2s */
3362
                    gen_op_load_fpr_FT1(rs1);
3363
                    gen_op_load_fpr_FT0(rs2);
3364
                    gen_op_fandnots();
3365
                    gen_op_store_FT0_fpr(rd);
3366
                    break;
3367
                case 0x066: /* VIS I fnot2 */
3368
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3369
                    gen_op_fnot();
3370
                    gen_op_store_DT0_fpr(DFPREG(rd));
3371
                    break;
3372
                case 0x067: /* VIS I fnot2s */
3373
                    gen_op_load_fpr_FT1(rs2);
3374
                    gen_op_fnot();
3375
                    gen_op_store_FT0_fpr(rd);
3376
                    break;
3377
                case 0x068: /* VIS I fandnot1 */
3378
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3379
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3380
                    gen_op_fandnot();
3381
                    gen_op_store_DT0_fpr(DFPREG(rd));
3382
                    break;
3383
                case 0x069: /* VIS I fandnot1s */
3384
                    gen_op_load_fpr_FT0(rs1);
3385
                    gen_op_load_fpr_FT1(rs2);
3386
                    gen_op_fandnots();
3387
                    gen_op_store_FT0_fpr(rd);
3388
                    break;
3389
                case 0x06a: /* VIS I fnot1 */
3390
                    gen_op_load_fpr_DT1(DFPREG(rs1));
3391
                    gen_op_fnot();
3392
                    gen_op_store_DT0_fpr(DFPREG(rd));
3393
                    break;
3394
                case 0x06b: /* VIS I fnot1s */
3395
                    gen_op_load_fpr_FT1(rs1);
3396
                    gen_op_fnot();
3397
                    gen_op_store_FT0_fpr(rd);
3398
                    break;
3399
                case 0x06c: /* VIS I fxor */
3400
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3401
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3402
                    gen_op_fxor();
3403
                    gen_op_store_DT0_fpr(DFPREG(rd));
3404
                    break;
3405
                case 0x06d: /* VIS I fxors */
3406
                    gen_op_load_fpr_FT0(rs1);
3407
                    gen_op_load_fpr_FT1(rs2);
3408
                    gen_op_fxors();
3409
                    gen_op_store_FT0_fpr(rd);
3410
                    break;
3411
                case 0x06e: /* VIS I fnand */
3412
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3413
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3414
                    gen_op_fnand();
3415
                    gen_op_store_DT0_fpr(DFPREG(rd));
3416
                    break;
3417
                case 0x06f: /* VIS I fnands */
3418
                    gen_op_load_fpr_FT0(rs1);
3419
                    gen_op_load_fpr_FT1(rs2);
3420
                    gen_op_fnands();
3421
                    gen_op_store_FT0_fpr(rd);
3422
                    break;
3423
                case 0x070: /* VIS I fand */
3424
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3425
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3426
                    gen_op_fand();
3427
                    gen_op_store_DT0_fpr(DFPREG(rd));
3428
                    break;
3429
                case 0x071: /* VIS I fands */
3430
                    gen_op_load_fpr_FT0(rs1);
3431
                    gen_op_load_fpr_FT1(rs2);
3432
                    gen_op_fands();
3433
                    gen_op_store_FT0_fpr(rd);
3434
                    break;
3435
                case 0x072: /* VIS I fxnor */
3436
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3437
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3438
                    gen_op_fxnor();
3439
                    gen_op_store_DT0_fpr(DFPREG(rd));
3440
                    break;
3441
                case 0x073: /* VIS I fxnors */
3442
                    gen_op_load_fpr_FT0(rs1);
3443
                    gen_op_load_fpr_FT1(rs2);
3444
                    gen_op_fxnors();
3445
                    gen_op_store_FT0_fpr(rd);
3446
                    break;
3447
                case 0x074: /* VIS I fsrc1 */
3448
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3449
                    gen_op_store_DT0_fpr(DFPREG(rd));
3450
                    break;
3451
                case 0x075: /* VIS I fsrc1s */
3452
                    gen_op_load_fpr_FT0(rs1);
3453
                    gen_op_store_FT0_fpr(rd);
3454
                    break;
3455
                case 0x076: /* VIS I fornot2 */
3456
                    gen_op_load_fpr_DT1(DFPREG(rs1));
3457
                    gen_op_load_fpr_DT0(DFPREG(rs2));
3458
                    gen_op_fornot();
3459
                    gen_op_store_DT0_fpr(DFPREG(rd));
3460
                    break;
3461
                case 0x077: /* VIS I fornot2s */
3462
                    gen_op_load_fpr_FT1(rs1);
3463
                    gen_op_load_fpr_FT0(rs2);
3464
                    gen_op_fornots();
3465
                    gen_op_store_FT0_fpr(rd);
3466
                    break;
3467
                case 0x078: /* VIS I fsrc2 */
3468
                    gen_op_load_fpr_DT0(DFPREG(rs2));
3469
                    gen_op_store_DT0_fpr(DFPREG(rd));
3470
                    break;
3471
                case 0x079: /* VIS I fsrc2s */
3472
                    gen_op_load_fpr_FT0(rs2);
3473
                    gen_op_store_FT0_fpr(rd);
3474
                    break;
3475
                case 0x07a: /* VIS I fornot1 */
3476
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3477
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3478
                    gen_op_fornot();
3479
                    gen_op_store_DT0_fpr(DFPREG(rd));
3480
                    break;
3481
                case 0x07b: /* VIS I fornot1s */
3482
                    gen_op_load_fpr_FT0(rs1);
3483
                    gen_op_load_fpr_FT1(rs2);
3484
                    gen_op_fornots();
3485
                    gen_op_store_FT0_fpr(rd);
3486
                    break;
3487
                case 0x07c: /* VIS I for */
3488
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3489
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3490
                    gen_op_for();
3491
                    gen_op_store_DT0_fpr(DFPREG(rd));
3492
                    break;
3493
                case 0x07d: /* VIS I fors */
3494
                    gen_op_load_fpr_FT0(rs1);
3495
                    gen_op_load_fpr_FT1(rs2);
3496
                    gen_op_fors();
3497
                    gen_op_store_FT0_fpr(rd);
3498
                    break;
3499
                case 0x07e: /* VIS I fone */
3500
                    gen_op_movl_DT0_1();
3501
                    gen_op_store_DT0_fpr(DFPREG(rd));
3502
                    break;
3503
                case 0x07f: /* VIS I fones */
3504
                    gen_op_movl_FT0_1();
3505
                    gen_op_store_FT0_fpr(rd);
3506
                    break;
3507
                case 0x080: /* VIS I shutdown */
3508
                case 0x081: /* VIS II siam */
3509
                    // XXX
3510
                    goto illegal_insn;
3511
                default:
3512
                    goto illegal_insn;
3513
                }
3514
#else
3515
                goto ncp_insn;
3516
#endif
3517
            } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
3518
#ifdef TARGET_SPARC64
3519
                goto illegal_insn;
3520
#else
3521
                goto ncp_insn;
3522
#endif
3523
#ifdef TARGET_SPARC64
3524
            } else if (xop == 0x39) { /* V9 return */
3525
                rs1 = GET_FIELD(insn, 13, 17);
3526
                save_state(dc);
3527
                gen_movl_reg_T0(rs1);
3528
                if (IS_IMM) {   /* immediate */
3529
                    rs2 = GET_FIELDs(insn, 19, 31);
3530
                    tcg_gen_addi_tl(cpu_T[0], cpu_T[0], (int)rs2);
3531
                } else {                /* register */
3532
                    rs2 = GET_FIELD(insn, 27, 31);
3533
#if defined(OPTIM)
3534
                    if (rs2) {
3535
#endif
3536
                        gen_movl_reg_T1(rs2);
3537
                        gen_op_add_T1_T0();
3538
#if defined(OPTIM)
3539
                    }
3540
#endif
3541
                }
3542
                gen_op_restore();
3543
                gen_mov_pc_npc(dc);
3544
                gen_op_check_align_T0_3();
3545
                tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, npc));
3546
                dc->npc = DYNAMIC_PC;
3547
                goto jmp_insn;
3548
#endif
3549
            } else {
3550
                rs1 = GET_FIELD(insn, 13, 17);
3551
                gen_movl_reg_T0(rs1);
3552
                if (IS_IMM) {   /* immediate */
3553
                    rs2 = GET_FIELDs(insn, 19, 31);
3554
                    tcg_gen_addi_tl(cpu_T[0], cpu_T[0], (int)rs2);
3555
                } else {                /* register */
3556
                    rs2 = GET_FIELD(insn, 27, 31);
3557
#if defined(OPTIM)
3558
                    if (rs2) {
3559
#endif
3560
                        gen_movl_reg_T1(rs2);
3561
                        gen_op_add_T1_T0();
3562
#if defined(OPTIM)
3563
                    }
3564
#endif
3565
                }
3566
                switch (xop) {
3567
                case 0x38:      /* jmpl */
3568
                    {
3569
                        if (rd != 0) {
3570
                            tcg_gen_movi_tl(cpu_T[1], dc->pc);
3571
                            gen_movl_T1_reg(rd);
3572
                        }
3573
                        gen_mov_pc_npc(dc);
3574
                        gen_op_check_align_T0_3();
3575
                        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, npc));
3576
                        dc->npc = DYNAMIC_PC;
3577
                    }
3578
                    goto jmp_insn;
3579
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
3580
                case 0x39:      /* rett, V9 return */
3581
                    {
3582
                        if (!supervisor(dc))
3583
                            goto priv_insn;
3584
                        gen_mov_pc_npc(dc);
3585
                        gen_op_check_align_T0_3();
3586
                        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, npc));
3587
                        dc->npc = DYNAMIC_PC;
3588
                        tcg_gen_helper_0_0(helper_rett);
3589
                    }
3590
                    goto jmp_insn;
3591
#endif
3592
                case 0x3b: /* flush */
3593
                    tcg_gen_helper_0_1(helper_flush, cpu_T[0]);
3594
                    break;
3595
                case 0x3c:      /* save */
3596
                    save_state(dc);
3597
                    gen_op_save();
3598
                    gen_movl_T0_reg(rd);
3599
                    break;
3600
                case 0x3d:      /* restore */
3601
                    save_state(dc);
3602
                    gen_op_restore();
3603
                    gen_movl_T0_reg(rd);
3604
                    break;
3605
#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
3606
                case 0x3e:      /* V9 done/retry */
3607
                    {
3608
                        switch (rd) {
3609
                        case 0:
3610
                            if (!supervisor(dc))
3611
                                goto priv_insn;
3612
                            dc->npc = DYNAMIC_PC;
3613
                            dc->pc = DYNAMIC_PC;
3614
                            tcg_gen_helper_0_0(helper_done);
3615
                            goto jmp_insn;
3616
                        case 1:
3617
                            if (!supervisor(dc))
3618
                                goto priv_insn;
3619
                            dc->npc = DYNAMIC_PC;
3620
                            dc->pc = DYNAMIC_PC;
3621
                            tcg_gen_helper_0_0(helper_retry);
3622
                            goto jmp_insn;
3623
                        default:
3624
                            goto illegal_insn;
3625
                        }
3626
                    }
3627
                    break;
3628
#endif
3629
                default:
3630
                    goto illegal_insn;
3631
                }
3632
            }
3633
            break;
3634
        }
3635
        break;
3636
    case 3:                     /* load/store instructions */
3637
        {
3638
            unsigned int xop = GET_FIELD(insn, 7, 12);
3639
            rs1 = GET_FIELD(insn, 13, 17);
3640
            save_state(dc);
3641
            gen_movl_reg_T0(rs1);
3642
            if (xop == 0x3c || xop == 0x3e)
3643
            {
3644
                rs2 = GET_FIELD(insn, 27, 31);
3645
                gen_movl_reg_T1(rs2);
3646
            }
3647
            else if (IS_IMM) {       /* immediate */
3648
                rs2 = GET_FIELDs(insn, 19, 31);
3649
                tcg_gen_addi_tl(cpu_T[0], cpu_T[0], (int)rs2);
3650
            } else {            /* register */
3651
                rs2 = GET_FIELD(insn, 27, 31);
3652
#if defined(OPTIM)
3653
                if (rs2 != 0) {
3654
#endif
3655
                    gen_movl_reg_T1(rs2);
3656
                    gen_op_add_T1_T0();
3657
#if defined(OPTIM)
3658
                }
3659
#endif
3660
            }
3661
            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
3662
                (xop > 0x17 && xop <= 0x1d ) ||
3663
                (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
3664
                switch (xop) {
3665
                case 0x0:       /* load unsigned word */
3666
                    gen_op_check_align_T0_3();
3667
                    ABI32_MASK(cpu_T[0]);
3668
                    tcg_gen_qemu_ld32u(cpu_T[1], cpu_T[0], dc->mem_idx);
3669
                    break;
3670
                case 0x1:       /* load unsigned byte */
3671
                    ABI32_MASK(cpu_T[0]);
3672
                    tcg_gen_qemu_ld8u(cpu_T[1], cpu_T[0], dc->mem_idx);
3673
                    break;
3674
                case 0x2:       /* load unsigned halfword */
3675
                    gen_op_check_align_T0_1();
3676
                    ABI32_MASK(cpu_T[0]);
3677
                    tcg_gen_qemu_ld16u(cpu_T[1], cpu_T[0], dc->mem_idx);
3678
                    break;
3679
                case 0x3:       /* load double word */
3680
                    if (rd & 1)
3681
                        goto illegal_insn;
3682
                    else {
3683
                        TCGv r_dword;
3684

    
3685
                        r_dword = tcg_temp_new(TCG_TYPE_I64);
3686
                        gen_op_check_align_T0_7();
3687
                        ABI32_MASK(cpu_T[0]);
3688
                        tcg_gen_qemu_ld64(r_dword, cpu_T[0], dc->mem_idx);
3689
                        tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
3690
                        gen_movl_T0_reg(rd + 1);
3691
                        tcg_gen_shri_i64(r_dword, r_dword, 32);
3692
                        tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
3693
                    }
3694
                    break;
3695
                case 0x9:       /* load signed byte */
3696
                    ABI32_MASK(cpu_T[0]);
3697
                    tcg_gen_qemu_ld8s(cpu_T[1], cpu_T[0], dc->mem_idx);
3698
                    break;
3699
                case 0xa:       /* load signed halfword */
3700
                    gen_op_check_align_T0_1();
3701
                    ABI32_MASK(cpu_T[0]);
3702
                    tcg_gen_qemu_ld16s(cpu_T[1], cpu_T[0], dc->mem_idx);
3703
                    break;
3704
                case 0xd:       /* ldstub -- XXX: should be atomically */
3705
                    tcg_gen_movi_i32(cpu_tmp0, 0xff);
3706
                    ABI32_MASK(cpu_T[0]);
3707
                    tcg_gen_qemu_ld8s(cpu_T[1], cpu_T[0], dc->mem_idx);
3708
                    tcg_gen_qemu_st8(cpu_tmp0, cpu_T[0], dc->mem_idx);
3709
                    break;
3710
                case 0x0f:      /* swap register with memory. Also atomically */
3711
                    gen_op_check_align_T0_3();
3712
                    gen_movl_reg_T1(rd);
3713
                    ABI32_MASK(cpu_T[0]);
3714
                    tcg_gen_qemu_ld32u(cpu_tmp0, cpu_T[0], dc->mem_idx);
3715
                    tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], dc->mem_idx);
3716
                    tcg_gen_mov_i32(cpu_T[1], cpu_tmp0);
3717
                    break;
3718
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
3719
                case 0x10:      /* load word alternate */
3720
#ifndef TARGET_SPARC64
3721
                    if (IS_IMM)
3722
                        goto illegal_insn;
3723
                    if (!supervisor(dc))
3724
                        goto priv_insn;
3725
#endif
3726
                    gen_op_check_align_T0_3();
3727
                    gen_ld_asi(insn, 4, 0);
3728
                    break;
3729
                case 0x11:      /* load unsigned byte alternate */
3730
#ifndef TARGET_SPARC64
3731
                    if (IS_IMM)
3732
                        goto illegal_insn;
3733
                    if (!supervisor(dc))
3734
                        goto priv_insn;
3735
#endif
3736
                    gen_ld_asi(insn, 1, 0);
3737
                    break;
3738
                case 0x12:      /* load unsigned halfword alternate */
3739
#ifndef TARGET_SPARC64
3740
                    if (IS_IMM)
3741
                        goto illegal_insn;
3742
                    if (!supervisor(dc))
3743
                        goto priv_insn;
3744
#endif
3745
                    gen_op_check_align_T0_1();
3746
                    gen_ld_asi(insn, 2, 0);
3747
                    break;
3748
                case 0x13:      /* load double word alternate */
3749
#ifndef TARGET_SPARC64
3750
                    if (IS_IMM)
3751
                        goto illegal_insn;
3752
                    if (!supervisor(dc))
3753
                        goto priv_insn;
3754
#endif
3755
                    if (rd & 1)
3756
                        goto illegal_insn;
3757
                    gen_op_check_align_T0_7();
3758
                    gen_ldda_asi(insn);
3759
                    gen_movl_T0_reg(rd + 1);
3760
                    break;
3761
                case 0x19:      /* load signed byte alternate */
3762
#ifndef TARGET_SPARC64
3763
                    if (IS_IMM)
3764
                        goto illegal_insn;
3765
                    if (!supervisor(dc))
3766
                        goto priv_insn;
3767
#endif
3768
                    gen_ld_asi(insn, 1, 1);
3769
                    break;
3770
                case 0x1a:      /* load signed halfword alternate */
3771
#ifndef TARGET_SPARC64
3772
                    if (IS_IMM)
3773
                        goto illegal_insn;
3774
                    if (!supervisor(dc))
3775
                        goto priv_insn;
3776
#endif
3777
                    gen_op_check_align_T0_1();
3778
                    gen_ld_asi(insn, 2, 1);
3779
                    break;
3780
                case 0x1d:      /* ldstuba -- XXX: should be atomically */
3781
#ifndef TARGET_SPARC64
3782
                    if (IS_IMM)
3783
                        goto illegal_insn;
3784
                    if (!supervisor(dc))
3785
                        goto priv_insn;
3786
#endif
3787
                    gen_ldstub_asi(insn);
3788
                    break;
3789
                case 0x1f:      /* swap reg with alt. memory. Also atomically */
3790
#ifndef TARGET_SPARC64
3791
                    if (IS_IMM)
3792
                        goto illegal_insn;
3793
                    if (!supervisor(dc))
3794
                        goto priv_insn;
3795
#endif
3796
                    gen_op_check_align_T0_3();
3797
                    gen_movl_reg_T1(rd);
3798
                    gen_swap_asi(insn);
3799
                    break;
3800

    
3801
#ifndef TARGET_SPARC64
3802
                case 0x30: /* ldc */
3803
                case 0x31: /* ldcsr */
3804
                case 0x33: /* lddc */
3805
                    goto ncp_insn;
3806
#endif
3807
#endif
3808
#ifdef TARGET_SPARC64
3809
                case 0x08: /* V9 ldsw */
3810
                    gen_op_check_align_T0_3();
3811
                    ABI32_MASK(cpu_T[0]);
3812
                    tcg_gen_qemu_ld32s(cpu_T[1], cpu_T[0], dc->mem_idx);
3813
                    break;
3814
                case 0x0b: /* V9 ldx */
3815
                    gen_op_check_align_T0_7();
3816
                    ABI32_MASK(cpu_T[0]);
3817
                    tcg_gen_qemu_ld64(cpu_T[1], cpu_T[0], dc->mem_idx);
3818
                    break;
3819
                case 0x18: /* V9 ldswa */
3820
                    gen_op_check_align_T0_3();
3821
                    gen_ld_asi(insn, 4, 1);
3822
                    break;
3823
                case 0x1b: /* V9 ldxa */
3824
                    gen_op_check_align_T0_7();
3825
                    gen_ld_asi(insn, 8, 0);
3826
                    break;
3827
                case 0x2d: /* V9 prefetch, no effect */
3828
                    goto skip_move;
3829
                case 0x30: /* V9 ldfa */
3830
                    gen_op_check_align_T0_3();
3831
                    gen_ldf_asi(insn, 4, rd);
3832
                    goto skip_move;
3833
                case 0x33: /* V9 lddfa */
3834
                    gen_op_check_align_T0_3();
3835
                    gen_ldf_asi(insn, 8, DFPREG(rd));
3836
                    goto skip_move;
3837
                case 0x3d: /* V9 prefetcha, no effect */
3838
                    goto skip_move;
3839
                case 0x32: /* V9 ldqfa */
3840
#if defined(CONFIG_USER_ONLY)
3841
                    gen_op_check_align_T0_3();
3842
                    gen_ldf_asi(insn, 16, QFPREG(rd));
3843
                    goto skip_move;
3844
#else
3845
                    goto nfpu_insn;
3846
#endif
3847
#endif
3848
                default:
3849
                    goto illegal_insn;
3850
                }
3851
                gen_movl_T1_reg(rd);
3852
#ifdef TARGET_SPARC64
3853
            skip_move: ;
3854
#endif
3855
            } else if (xop >= 0x20 && xop < 0x24) {
3856
                if (gen_trap_ifnofpu(dc))
3857
                    goto jmp_insn;
3858
                switch (xop) {
3859
                case 0x20:      /* load fpreg */
3860
                    gen_op_check_align_T0_3();
3861
                    gen_op_ldst(ldf);
3862
                    gen_op_store_FT0_fpr(rd);
3863
                    break;
3864
                case 0x21:      /* load fsr */
3865
                    gen_op_check_align_T0_3();
3866
                    gen_op_ldst(ldf);
3867
                    gen_op_ldfsr();
3868
                    tcg_gen_helper_0_0(helper_ldfsr);
3869
                    break;
3870
                case 0x22:      /* load quad fpreg */
3871
#if defined(CONFIG_USER_ONLY)
3872
                    gen_op_check_align_T0_7();
3873
                    gen_op_ldst(ldqf);
3874
                    gen_op_store_QT0_fpr(QFPREG(rd));
3875
                    break;
3876
#else
3877
                    goto nfpu_insn;
3878
#endif
3879
                case 0x23:      /* load double fpreg */
3880
                    gen_op_check_align_T0_7();
3881
                    gen_op_ldst(lddf);
3882
                    gen_op_store_DT0_fpr(DFPREG(rd));
3883
                    break;
3884
                default:
3885
                    goto illegal_insn;
3886
                }
3887
            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) || \
3888
                       xop == 0xe || xop == 0x1e) {
3889
                gen_movl_reg_T1(rd);
3890
                switch (xop) {
3891
                case 0x4: /* store word */
3892
                    gen_op_check_align_T0_3();
3893
                    ABI32_MASK(cpu_T[0]);
3894
                    tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], dc->mem_idx);
3895
                    break;
3896
                case 0x5: /* store byte */
3897
                    ABI32_MASK(cpu_T[0]);
3898
                    tcg_gen_qemu_st8(cpu_T[1], cpu_T[0], dc->mem_idx);
3899
                    break;
3900
                case 0x6: /* store halfword */
3901
                    gen_op_check_align_T0_1();
3902
                    ABI32_MASK(cpu_T[0]);
3903
                    tcg_gen_qemu_st16(cpu_T[1], cpu_T[0], dc->mem_idx);
3904
                    break;
3905
                case 0x7: /* store double word */
3906
                    if (rd & 1)
3907
                        goto illegal_insn;
3908
#ifndef __i386__
3909
                    else {
3910
                        TCGv r_dword, r_low;
3911

    
3912
                        gen_op_check_align_T0_7();
3913
                        r_dword = tcg_temp_new(TCG_TYPE_I64);
3914
                        r_low = tcg_temp_new(TCG_TYPE_I32);
3915
                        gen_movl_reg_TN(rd + 1, r_low);
3916
                        tcg_gen_helper_1_2(helper_pack64, r_dword, cpu_T[1],
3917
                                           r_low);
3918
                        tcg_gen_qemu_st64(r_dword, cpu_T[0], dc->mem_idx);
3919
                    }
3920
#else /* __i386__ */
3921
                    gen_op_check_align_T0_7();
3922
                    flush_T2(dc);
3923
                    gen_movl_reg_T2(rd + 1);
3924
                    gen_op_ldst(std);
3925
#endif /* __i386__ */
3926
                    break;
3927
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
3928
                case 0x14: /* store word alternate */
3929
#ifndef TARGET_SPARC64
3930
                    if (IS_IMM)
3931
                        goto illegal_insn;
3932
                    if (!supervisor(dc))
3933
                        goto priv_insn;
3934
#endif
3935
                    gen_op_check_align_T0_3();
3936
                    gen_st_asi(insn, 4);
3937
                    break;
3938
                case 0x15: /* store byte alternate */
3939
#ifndef TARGET_SPARC64
3940
                    if (IS_IMM)
3941
                        goto illegal_insn;
3942
                    if (!supervisor(dc))
3943
                        goto priv_insn;
3944
#endif
3945
                    gen_st_asi(insn, 1);
3946
                    break;
3947
                case 0x16: /* store halfword alternate */
3948
#ifndef TARGET_SPARC64
3949
                    if (IS_IMM)
3950
                        goto illegal_insn;
3951
                    if (!supervisor(dc))
3952
                        goto priv_insn;
3953
#endif
3954
                    gen_op_check_align_T0_1();
3955
                    gen_st_asi(insn, 2);
3956
                    break;
3957
                case 0x17: /* store double word alternate */
3958
#ifndef TARGET_SPARC64
3959
                    if (IS_IMM)
3960
                        goto illegal_insn;
3961
                    if (!supervisor(dc))
3962
                        goto priv_insn;
3963
#endif
3964
                    if (rd & 1)
3965
                        goto illegal_insn;
3966
                    else {
3967
                        int asi;
3968
                        TCGv r_dword, r_temp, r_size;
3969

    
3970
                        gen_op_check_align_T0_7();
3971
                        r_dword = tcg_temp_new(TCG_TYPE_I64);
3972
                        r_temp = tcg_temp_new(TCG_TYPE_I32);
3973
                        r_size = tcg_temp_new(TCG_TYPE_I32);
3974
                        gen_movl_reg_TN(rd + 1, r_temp);
3975
                        tcg_gen_helper_1_2(helper_pack64, r_dword, cpu_T[1],
3976
                                           r_temp);
3977
#ifdef TARGET_SPARC64
3978
                        if (IS_IMM) {
3979
                            int offset;
3980

    
3981
                            offset = GET_FIELD(insn, 25, 31);
3982
                            tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
3983
                            tcg_gen_ld_i32(r_dword, cpu_env, offsetof(CPUSPARCState, asi));
3984
                        } else {
3985
#endif
3986
                            asi = GET_FIELD(insn, 19, 26);
3987
                            tcg_gen_movi_i32(r_temp, asi);
3988
#ifdef TARGET_SPARC64
3989
                        }
3990
#endif
3991
                        tcg_gen_movi_i32(r_size, 8);
3992
                        tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, r_temp, r_size);
3993
                    }
3994
                    break;
3995
#endif
3996
#ifdef TARGET_SPARC64
3997
                case 0x0e: /* V9 stx */
3998
                    gen_op_check_align_T0_7();
3999
                    ABI32_MASK(cpu_T[0]);
4000
                    tcg_gen_qemu_st64(cpu_T[1], cpu_T[0], dc->mem_idx);
4001
                    break;
4002
                case 0x1e: /* V9 stxa */
4003
                    gen_op_check_align_T0_7();
4004
                    gen_st_asi(insn, 8);
4005
                    break;
4006
#endif
4007
                default:
4008
                    goto illegal_insn;
4009
                }
4010
            } else if (xop > 0x23 && xop < 0x28) {
4011
                if (gen_trap_ifnofpu(dc))
4012
                    goto jmp_insn;
4013
                switch (xop) {
4014
                case 0x24:
4015
                    gen_op_check_align_T0_3();
4016
                    gen_op_load_fpr_FT0(rd);
4017
                    gen_op_ldst(stf);
4018
                    break;
4019
                case 0x25: /* stfsr, V9 stxfsr */
4020
#ifdef CONFIG_USER_ONLY
4021
                    gen_op_check_align_T0_3();
4022
#endif
4023
                    gen_op_stfsr();
4024
                    gen_op_ldst(stf);
4025
                    break;
4026
                case 0x26:
4027
#ifdef TARGET_SPARC64
4028
#if defined(CONFIG_USER_ONLY)
4029
                    /* V9 stqf, store quad fpreg */
4030
                    gen_op_check_align_T0_7();
4031
                    gen_op_load_fpr_QT0(QFPREG(rd));
4032
                    gen_op_ldst(stqf);
4033
                    break;
4034
#else
4035
                    goto nfpu_insn;
4036
#endif
4037
#else /* !TARGET_SPARC64 */
4038
                    /* stdfq, store floating point queue */
4039
#if defined(CONFIG_USER_ONLY)
4040
                    goto illegal_insn;
4041
#else
4042
                    if (!supervisor(dc))
4043
                        goto priv_insn;
4044
                    if (gen_trap_ifnofpu(dc))
4045
                        goto jmp_insn;
4046
                    goto nfq_insn;
4047
#endif
4048
#endif
4049
                case 0x27:
4050
                    gen_op_check_align_T0_7();
4051
                    gen_op_load_fpr_DT0(DFPREG(rd));
4052
                    gen_op_ldst(stdf);
4053
                    break;
4054
                default:
4055
                    goto illegal_insn;
4056
                }
4057
            } else if (xop > 0x33 && xop < 0x3f) {
4058
                switch (xop) {
4059
#ifdef TARGET_SPARC64
4060
                case 0x34: /* V9 stfa */
4061
                    gen_op_check_align_T0_3();
4062
                    gen_op_load_fpr_FT0(rd);
4063
                    gen_stf_asi(insn, 4, rd);
4064
                    break;
4065
                case 0x36: /* V9 stqfa */
4066
#if defined(CONFIG_USER_ONLY)
4067
                    gen_op_check_align_T0_7();
4068
                    gen_op_load_fpr_QT0(QFPREG(rd));
4069
                    gen_stf_asi(insn, 16, QFPREG(rd));
4070
                    break;
4071
#else
4072
                    goto nfpu_insn;
4073
#endif
4074
                case 0x37: /* V9 stdfa */
4075
                    gen_op_check_align_T0_3();
4076
                    gen_op_load_fpr_DT0(DFPREG(rd));
4077
                    gen_stf_asi(insn, 8, DFPREG(rd));
4078
                    break;
4079
                case 0x3c: /* V9 casa */
4080
                    gen_op_check_align_T0_3();
4081
                    gen_cas_asi(insn, rd);
4082
                    gen_movl_T1_reg(rd);
4083
                    break;
4084
                case 0x3e: /* V9 casxa */
4085
                    gen_op_check_align_T0_7();
4086
                    gen_casx_asi(insn, rd);
4087
                    gen_movl_T1_reg(rd);
4088
                    break;
4089
#else
4090
                case 0x34: /* stc */
4091
                case 0x35: /* stcsr */
4092
                case 0x36: /* stdcq */
4093
                case 0x37: /* stdc */
4094
                    goto ncp_insn;
4095
#endif
4096
                default:
4097
                    goto illegal_insn;
4098
                }
4099
            }
4100
            else
4101
                goto illegal_insn;
4102
        }
4103
        break;
4104
    }
4105
    /* default case for non jump instructions */
4106
    if (dc->npc == DYNAMIC_PC) {
4107
        dc->pc = DYNAMIC_PC;
4108
        gen_op_next_insn();
4109
    } else if (dc->npc == JUMP_PC) {
4110
        /* we can do a static jump */
4111
        gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
4112
        dc->is_br = 1;
4113
    } else {
4114
        dc->pc = dc->npc;
4115
        dc->npc = dc->npc + 4;
4116
    }
4117
 jmp_insn:
4118
    return;
4119
 illegal_insn:
4120
    save_state(dc);
4121
    gen_op_exception(TT_ILL_INSN);
4122
    dc->is_br = 1;
4123
    return;
4124
#if !defined(CONFIG_USER_ONLY)
4125
 priv_insn:
4126
    save_state(dc);
4127
    gen_op_exception(TT_PRIV_INSN);
4128
    dc->is_br = 1;
4129
    return;
4130
 nfpu_insn:
4131
    save_state(dc);
4132
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
4133
    dc->is_br = 1;
4134
    return;
4135
#ifndef TARGET_SPARC64
4136
 nfq_insn:
4137
    save_state(dc);
4138
    gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
4139
    dc->is_br = 1;
4140
    return;
4141
#endif
4142
#endif
4143
#ifndef TARGET_SPARC64
4144
 ncp_insn:
4145
    save_state(dc);
4146
    gen_op_exception(TT_NCP_INSN);
4147
    dc->is_br = 1;
4148
    return;
4149
#endif
4150
}
4151

    
4152
static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
4153
{
4154
}
4155

    
4156
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
4157
                                                 int spc, CPUSPARCState *env)
4158
{
4159
    target_ulong pc_start, last_pc;
4160
    uint16_t *gen_opc_end;
4161
    DisasContext dc1, *dc = &dc1;
4162
    int j, lj = -1;
4163

    
4164
    memset(dc, 0, sizeof(DisasContext));
4165
    dc->tb = tb;
4166
    pc_start = tb->pc;
4167
    dc->pc = pc_start;
4168
    last_pc = dc->pc;
4169
    dc->npc = (target_ulong) tb->cs_base;
4170
    dc->mem_idx = cpu_mmu_index(env);
4171
    dc->fpu_enabled = cpu_fpu_enabled(env);
4172
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4173

    
4174
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
4175
    cpu_regwptr = tcg_temp_new(TCG_TYPE_PTR); // XXX
4176

    
4177
    do {
4178
        if (env->nb_breakpoints > 0) {
4179
            for(j = 0; j < env->nb_breakpoints; j++) {
4180
                if (env->breakpoints[j] == dc->pc) {
4181
                    if (dc->pc != pc_start)
4182
                        save_state(dc);
4183
                    tcg_gen_helper_0_0(helper_debug);
4184
                    tcg_gen_exit_tb(0);
4185
                    dc->is_br = 1;
4186
                    goto exit_gen_loop;
4187
                }
4188
            }
4189
        }
4190
        if (spc) {
4191
            if (loglevel > 0)
4192
                fprintf(logfile, "Search PC...\n");
4193
            j = gen_opc_ptr - gen_opc_buf;
4194
            if (lj < j) {
4195
                lj++;
4196
                while (lj < j)
4197
                    gen_opc_instr_start[lj++] = 0;
4198
                gen_opc_pc[lj] = dc->pc;
4199
                gen_opc_npc[lj] = dc->npc;
4200
                gen_opc_instr_start[lj] = 1;
4201
            }
4202
        }
4203
        last_pc = dc->pc;
4204
        disas_sparc_insn(dc);
4205

    
4206
        if (dc->is_br)
4207
            break;
4208
        /* if the next PC is different, we abort now */
4209
        if (dc->pc != (last_pc + 4))
4210
            break;
4211
        /* if we reach a page boundary, we stop generation so that the
4212
           PC of a TT_TFAULT exception is always in the right page */
4213
        if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
4214
            break;
4215
        /* if single step mode, we generate only one instruction and
4216
           generate an exception */
4217
        if (env->singlestep_enabled) {
4218
            gen_jmp_im(dc->pc);
4219
            tcg_gen_exit_tb(0);
4220
            break;
4221
        }
4222
    } while ((gen_opc_ptr < gen_opc_end) &&
4223
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
4224

    
4225
 exit_gen_loop:
4226
    if (!dc->is_br) {
4227
        if (dc->pc != DYNAMIC_PC &&
4228
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
4229
            /* static PC and NPC: we can use direct chaining */
4230
            gen_branch(dc, dc->pc, dc->npc);
4231
        } else {
4232
            if (dc->pc != DYNAMIC_PC)
4233
                gen_jmp_im(dc->pc);
4234
            save_npc(dc);
4235
            tcg_gen_exit_tb(0);
4236
        }
4237
    }
4238
    *gen_opc_ptr = INDEX_op_end;
4239
    if (spc) {
4240
        j = gen_opc_ptr - gen_opc_buf;
4241
        lj++;
4242
        while (lj <= j)
4243
            gen_opc_instr_start[lj++] = 0;
4244
#if 0
4245
        if (loglevel > 0) {
4246
            page_dump(logfile);
4247
        }
4248
#endif
4249
        gen_opc_jump_pc[0] = dc->jump_pc[0];
4250
        gen_opc_jump_pc[1] = dc->jump_pc[1];
4251
    } else {
4252
        tb->size = last_pc + 4 - pc_start;
4253
    }
4254
#ifdef DEBUG_DISAS
4255
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4256
        fprintf(logfile, "--------------\n");
4257
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
4258
        target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
4259
        fprintf(logfile, "\n");
4260
    }
4261
#endif
4262
    return 0;
4263
}
4264

    
4265
int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
4266
{
4267
    return gen_intermediate_code_internal(tb, 0, env);
4268
}
4269

    
4270
int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
4271
{
4272
    return gen_intermediate_code_internal(tb, 1, env);
4273
}
4274

    
4275
void cpu_reset(CPUSPARCState *env)
4276
{
4277
    tlb_flush(env, 1);
4278
    env->cwp = 0;
4279
    env->wim = 1;
4280
    env->regwptr = env->regbase + (env->cwp * 16);
4281
#if defined(CONFIG_USER_ONLY)
4282
    env->user_mode_only = 1;
4283
#ifdef TARGET_SPARC64
4284
    env->cleanwin = NWINDOWS - 2;
4285
    env->cansave = NWINDOWS - 2;
4286
    env->pstate = PS_RMO | PS_PEF | PS_IE;
4287
    env->asi = 0x82; // Primary no-fault
4288
#endif
4289
#else
4290
    env->psret = 0;
4291
    env->psrs = 1;
4292
    env->psrps = 1;
4293
#ifdef TARGET_SPARC64
4294
    env->pstate = PS_PRIV;
4295
    env->hpstate = HS_PRIV;
4296
    env->pc = 0x1fff0000000ULL;
4297
    env->tsptr = &env->ts[env->tl];
4298
#else
4299
    env->pc = 0;
4300
    env->mmuregs[0] &= ~(MMU_E | MMU_NF);
4301
    env->mmuregs[0] |= env->mmu_bm;
4302
#endif
4303
    env->npc = env->pc + 4;
4304
#endif
4305
}
4306

    
4307
CPUSPARCState *cpu_sparc_init(const char *cpu_model)
4308
{
4309
    CPUSPARCState *env;
4310
    const sparc_def_t *def;
4311
    static int inited;
4312

    
4313
    def = cpu_sparc_find_by_name(cpu_model);
4314
    if (!def)
4315
        return NULL;
4316

    
4317
    env = qemu_mallocz(sizeof(CPUSPARCState));
4318
    if (!env)
4319
        return NULL;
4320
    cpu_exec_init(env);
4321
    env->cpu_model_str = cpu_model;
4322
    env->version = def->iu_version;
4323
    env->fsr = def->fpu_version;
4324
#if !defined(TARGET_SPARC64)
4325
    env->mmu_bm = def->mmu_bm;
4326
    env->mmu_ctpr_mask = def->mmu_ctpr_mask;
4327
    env->mmu_cxr_mask = def->mmu_cxr_mask;
4328
    env->mmu_sfsr_mask = def->mmu_sfsr_mask;
4329
    env->mmu_trcr_mask = def->mmu_trcr_mask;
4330
    env->mmuregs[0] |= def->mmu_version;
4331
    cpu_sparc_set_id(env, 0);
4332
#endif
4333

    
4334
    /* init various static tables */
4335
    if (!inited) {
4336
        inited = 1;
4337

    
4338
        tcg_set_macro_func(&tcg_ctx, tcg_macro_func);
4339
        cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
4340
        //#if TARGET_LONG_BITS > HOST_LONG_BITS
4341
#ifdef TARGET_SPARC64
4342
        cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
4343
                                      TCG_AREG0, offsetof(CPUState, t0), "T0");
4344
        cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
4345
                                      TCG_AREG0, offsetof(CPUState, t1), "T1");
4346
        cpu_T[2] = tcg_global_mem_new(TCG_TYPE_TL,
4347
                                      TCG_AREG0, offsetof(CPUState, t2), "T2");
4348
#else
4349
        cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
4350
        cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
4351
        cpu_T[2] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T2");
4352
#endif
4353
    }
4354

    
4355
    cpu_reset(env);
4356
    
4357
    return env;
4358
}
4359

    
4360
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
4361
{
4362
#if !defined(TARGET_SPARC64)
4363
    env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
4364
#endif
4365
}
4366

    
4367
static const sparc_def_t sparc_defs[] = {
4368
#ifdef TARGET_SPARC64
4369
    {
4370
        .name = "Fujitsu Sparc64",
4371
        .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)
4372
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4373
        .fpu_version = 0x00000000,
4374
        .mmu_version = 0,
4375
    },
4376
    {
4377
        .name = "Fujitsu Sparc64 III",
4378
        .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)
4379
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4380
        .fpu_version = 0x00000000,
4381
        .mmu_version = 0,
4382
    },
4383
    {
4384
        .name = "Fujitsu Sparc64 IV",
4385
        .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)
4386
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4387
        .fpu_version = 0x00000000,
4388
        .mmu_version = 0,
4389
    },
4390
    {
4391
        .name = "Fujitsu Sparc64 V",
4392
        .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)
4393
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4394
        .fpu_version = 0x00000000,
4395
        .mmu_version = 0,
4396
    },
4397
    {
4398
        .name = "TI UltraSparc I",
4399
        .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)
4400
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4401
        .fpu_version = 0x00000000,
4402
        .mmu_version = 0,
4403
    },
4404
    {
4405
        .name = "TI UltraSparc II",
4406
        .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)
4407
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4408
        .fpu_version = 0x00000000,
4409
        .mmu_version = 0,
4410
    },
4411
    {
4412
        .name = "TI UltraSparc IIi",
4413
        .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)
4414
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4415
        .fpu_version = 0x00000000,
4416
        .mmu_version = 0,
4417
    },
4418
    {
4419
        .name = "TI UltraSparc IIe",
4420
        .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)
4421
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4422
        .fpu_version = 0x00000000,
4423
        .mmu_version = 0,
4424
    },
4425
    {
4426
        .name = "Sun UltraSparc III",
4427
        .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)
4428
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4429
        .fpu_version = 0x00000000,
4430
        .mmu_version = 0,
4431
    },
4432
    {
4433
        .name = "Sun UltraSparc III Cu",
4434
        .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)
4435
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4436
        .fpu_version = 0x00000000,
4437
        .mmu_version = 0,
4438
    },
4439
    {
4440
        .name = "Sun UltraSparc IIIi",
4441
        .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)
4442
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4443
        .fpu_version = 0x00000000,
4444
        .mmu_version = 0,
4445
    },
4446
    {
4447
        .name = "Sun UltraSparc IV",
4448
        .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)
4449
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4450
        .fpu_version = 0x00000000,
4451
        .mmu_version = 0,
4452
    },
4453
    {
4454
        .name = "Sun UltraSparc IV+",
4455
        .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)
4456
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4457
        .fpu_version = 0x00000000,
4458
        .mmu_version = 0,
4459
    },
4460
    {
4461
        .name = "Sun UltraSparc IIIi+",
4462
        .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)
4463
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4464
        .fpu_version = 0x00000000,
4465
        .mmu_version = 0,
4466
    },
4467
    {
4468
        .name = "NEC UltraSparc I",
4469
        .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)
4470
                       | (MAXTL << 8) | (NWINDOWS - 1)),
4471
        .fpu_version = 0x00000000,
4472
        .mmu_version = 0,
4473
    },
4474
#else
4475
    {
4476
        .name = "Fujitsu MB86900",
4477
        .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
4478
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
4479
        .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
4480
        .mmu_bm = 0x00004000,
4481
        .mmu_ctpr_mask = 0x007ffff0,
4482
        .mmu_cxr_mask = 0x0000003f,
4483
        .mmu_sfsr_mask = 0xffffffff,
4484
        .mmu_trcr_mask = 0xffffffff,
4485
    },
4486
    {
4487
        .name = "Fujitsu MB86904",
4488
        .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
4489
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
4490
        .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
4491
        .mmu_bm = 0x00004000,
4492
        .mmu_ctpr_mask = 0x00ffffc0,
4493
        .mmu_cxr_mask = 0x000000ff,
4494
        .mmu_sfsr_mask = 0x00016fff,
4495
        .mmu_trcr_mask = 0x00ffffff,
4496
    },
4497
    {
4498
        .name = "Fujitsu MB86907",
4499
        .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
4500
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
4501
        .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
4502
        .mmu_bm = 0x00004000,
4503
        .mmu_ctpr_mask = 0xffffffc0,
4504
        .mmu_cxr_mask = 0x000000ff,
4505
        .mmu_sfsr_mask = 0x00016fff,
4506
        .mmu_trcr_mask = 0xffffffff,
4507
    },
4508
    {
4509
        .name = "LSI L64811",
4510
        .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
4511
        .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
4512
        .mmu_version = 0x10 << 24,
4513
        .mmu_bm = 0x00004000,
4514
        .mmu_ctpr_mask = 0x007ffff0,
4515
        .mmu_cxr_mask = 0x0000003f,
4516
        .mmu_sfsr_mask = 0xffffffff,
4517
        .mmu_trcr_mask = 0xffffffff,
4518
    },
4519
    {
4520
        .name = "Cypress CY7C601",
4521
        .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
4522
        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
4523
        .mmu_version = 0x10 << 24,
4524
        .mmu_bm = 0x00004000,
4525
        .mmu_ctpr_mask = 0x007ffff0,
4526
        .mmu_cxr_mask = 0x0000003f,
4527
        .mmu_sfsr_mask = 0xffffffff,
4528
        .mmu_trcr_mask = 0xffffffff,
4529
    },
4530
    {
4531
        .name = "Cypress CY7C611",
4532
        .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
4533
        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
4534
        .mmu_version = 0x10 << 24,
4535
        .mmu_bm = 0x00004000,
4536
        .mmu_ctpr_mask = 0x007ffff0,
4537
        .mmu_cxr_mask = 0x0000003f,
4538
        .mmu_sfsr_mask = 0xffffffff,
4539
        .mmu_trcr_mask = 0xffffffff,
4540
    },
4541
    {
4542
        .name = "TI SuperSparc II",
4543
        .iu_version = 0x40000000,
4544
        .fpu_version = 0 << 17,
4545
        .mmu_version = 0x04000000,
4546
        .mmu_bm = 0x00002000,
4547
        .mmu_ctpr_mask = 0xffffffc0,
4548
        .mmu_cxr_mask = 0x0000ffff,
4549
        .mmu_sfsr_mask = 0xffffffff,
4550
        .mmu_trcr_mask = 0xffffffff,
4551
    },
4552
    {
4553
        .name = "TI MicroSparc I",
4554
        .iu_version = 0x41000000,
4555
        .fpu_version = 4 << 17,
4556
        .mmu_version = 0x41000000,
4557
        .mmu_bm = 0x00004000,
4558
        .mmu_ctpr_mask = 0x007ffff0,
4559
        .mmu_cxr_mask = 0x0000003f,
4560
        .mmu_sfsr_mask = 0x00016fff,
4561
        .mmu_trcr_mask = 0x0000003f,
4562
    },
4563
    {
4564
        .name = "TI MicroSparc II",
4565
        .iu_version = 0x42000000,
4566
        .fpu_version = 4 << 17,
4567
        .mmu_version = 0x02000000,
4568
        .mmu_bm = 0x00004000,
4569
        .mmu_ctpr_mask = 0x00ffffc0,
4570
        .mmu_cxr_mask = 0x000000ff,
4571
        .mmu_sfsr_mask = 0x00016fff,
4572
        .mmu_trcr_mask = 0x00ffffff,
4573
    },
4574
    {
4575
        .name = "TI MicroSparc IIep",
4576
        .iu_version = 0x42000000,
4577
        .fpu_version = 4 << 17,
4578
        .mmu_version = 0x04000000,
4579
        .mmu_bm = 0x00004000,
4580
        .mmu_ctpr_mask = 0x00ffffc0,
4581
        .mmu_cxr_mask = 0x000000ff,
4582
        .mmu_sfsr_mask = 0x00016bff,
4583
        .mmu_trcr_mask = 0x00ffffff,
4584
    },
4585
    {
4586
        .name = "TI SuperSparc 51",
4587
        .iu_version = 0x43000000,
4588
        .fpu_version = 0 << 17,
4589
        .mmu_version = 0x04000000,
4590
        .mmu_bm = 0x00002000,
4591
        .mmu_ctpr_mask = 0xffffffc0,
4592
        .mmu_cxr_mask = 0x0000ffff,
4593
        .mmu_sfsr_mask = 0xffffffff,
4594
        .mmu_trcr_mask = 0xffffffff,
4595
    },
4596
    {
4597
        .name = "TI SuperSparc 61",
4598
        .iu_version = 0x44000000,
4599
        .fpu_version = 0 << 17,
4600
        .mmu_version = 0x04000000,
4601
        .mmu_bm = 0x00002000,
4602
        .mmu_ctpr_mask = 0xffffffc0,
4603
        .mmu_cxr_mask = 0x0000ffff,
4604
        .mmu_sfsr_mask = 0xffffffff,
4605
        .mmu_trcr_mask = 0xffffffff,
4606
    },
4607
    {
4608
        .name = "Ross RT625",
4609
        .iu_version = 0x1e000000,
4610
        .fpu_version = 1 << 17,
4611
        .mmu_version = 0x1e000000,
4612
        .mmu_bm = 0x00004000,
4613
        .mmu_ctpr_mask = 0x007ffff0,
4614
        .mmu_cxr_mask = 0x0000003f,
4615
        .mmu_sfsr_mask = 0xffffffff,
4616
        .mmu_trcr_mask = 0xffffffff,
4617
    },
4618
    {
4619
        .name = "Ross RT620",
4620
        .iu_version = 0x1f000000,
4621
        .fpu_version = 1 << 17,
4622
        .mmu_version = 0x1f000000,
4623
        .mmu_bm = 0x00004000,
4624
        .mmu_ctpr_mask = 0x007ffff0,
4625
        .mmu_cxr_mask = 0x0000003f,
4626
        .mmu_sfsr_mask = 0xffffffff,
4627
        .mmu_trcr_mask = 0xffffffff,
4628
    },
4629
    {
4630
        .name = "BIT B5010",
4631
        .iu_version = 0x20000000,
4632
        .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
4633
        .mmu_version = 0x20000000,
4634
        .mmu_bm = 0x00004000,
4635
        .mmu_ctpr_mask = 0x007ffff0,
4636
        .mmu_cxr_mask = 0x0000003f,
4637
        .mmu_sfsr_mask = 0xffffffff,
4638
        .mmu_trcr_mask = 0xffffffff,
4639
    },
4640
    {
4641
        .name = "Matsushita MN10501",
4642
        .iu_version = 0x50000000,
4643
        .fpu_version = 0 << 17,
4644
        .mmu_version = 0x50000000,
4645
        .mmu_bm = 0x00004000,
4646
        .mmu_ctpr_mask = 0x007ffff0,
4647
        .mmu_cxr_mask = 0x0000003f,
4648
        .mmu_sfsr_mask = 0xffffffff,
4649
        .mmu_trcr_mask = 0xffffffff,
4650
    },
4651
    {
4652
        .name = "Weitek W8601",
4653
        .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
4654
        .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
4655
        .mmu_version = 0x10 << 24,
4656
        .mmu_bm = 0x00004000,
4657
        .mmu_ctpr_mask = 0x007ffff0,
4658
        .mmu_cxr_mask = 0x0000003f,
4659
        .mmu_sfsr_mask = 0xffffffff,
4660
        .mmu_trcr_mask = 0xffffffff,
4661
    },
4662
    {
4663
        .name = "LEON2",
4664
        .iu_version = 0xf2000000,
4665
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
4666
        .mmu_version = 0xf2000000,
4667
        .mmu_bm = 0x00004000,
4668
        .mmu_ctpr_mask = 0x007ffff0,
4669
        .mmu_cxr_mask = 0x0000003f,
4670
        .mmu_sfsr_mask = 0xffffffff,
4671
        .mmu_trcr_mask = 0xffffffff,
4672
    },
4673
    {
4674
        .name = "LEON3",
4675
        .iu_version = 0xf3000000,
4676
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
4677
        .mmu_version = 0xf3000000,
4678
        .mmu_bm = 0x00004000,
4679
        .mmu_ctpr_mask = 0x007ffff0,
4680
        .mmu_cxr_mask = 0x0000003f,
4681
        .mmu_sfsr_mask = 0xffffffff,
4682
        .mmu_trcr_mask = 0xffffffff,
4683
    },
4684
#endif
4685
};
4686

    
4687
static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name)
4688
{
4689
    unsigned int i;
4690

    
4691
    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
4692
        if (strcasecmp(name, sparc_defs[i].name) == 0) {
4693
            return &sparc_defs[i];
4694
        }
4695
    }
4696
    return NULL;
4697
}
4698

    
4699
void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
4700
{
4701
    unsigned int i;
4702

    
4703
    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
4704
        (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x\n",
4705
                       sparc_defs[i].name,
4706
                       sparc_defs[i].iu_version,
4707
                       sparc_defs[i].fpu_version,
4708
                       sparc_defs[i].mmu_version);
4709
    }
4710
}
4711

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

    
4714
void cpu_dump_state(CPUState *env, FILE *f,
4715
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
4716
                    int flags)
4717
{
4718
    int i, x;
4719

    
4720
    cpu_fprintf(f, "pc: " TARGET_FMT_lx "  npc: " TARGET_FMT_lx "\n", env->pc, env->npc);
4721
    cpu_fprintf(f, "General Registers:\n");
4722
    for (i = 0; i < 4; i++)
4723
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
4724
    cpu_fprintf(f, "\n");
4725
    for (; i < 8; i++)
4726
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
4727
    cpu_fprintf(f, "\nCurrent Register Window:\n");
4728
    for (x = 0; x < 3; x++) {
4729
        for (i = 0; i < 4; i++)
4730
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
4731
                    (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
4732
                    env->regwptr[i + x * 8]);
4733
        cpu_fprintf(f, "\n");
4734
        for (; i < 8; i++)
4735
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
4736
                    (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
4737
                    env->regwptr[i + x * 8]);
4738
        cpu_fprintf(f, "\n");
4739
    }
4740
    cpu_fprintf(f, "\nFloating Point Registers:\n");
4741
    for (i = 0; i < 32; i++) {
4742
        if ((i & 3) == 0)
4743
            cpu_fprintf(f, "%%f%02d:", i);
4744
        cpu_fprintf(f, " %016lf", env->fpr[i]);
4745
        if ((i & 3) == 3)
4746
            cpu_fprintf(f, "\n");
4747
    }
4748
#ifdef TARGET_SPARC64
4749
    cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d fprs: %d\n",
4750
                env->pstate, GET_CCR(env), env->asi, env->tl, env->fprs);
4751
    cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d cleanwin %d cwp %d\n",
4752
                env->cansave, env->canrestore, env->otherwin, env->wstate,
4753
                env->cleanwin, NWINDOWS - 1 - env->cwp);
4754
#else
4755
    cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n", GET_PSR(env),
4756
            GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
4757
            GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
4758
            env->psrs?'S':'-', env->psrps?'P':'-',
4759
            env->psret?'E':'-', env->wim);
4760
#endif
4761
    cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env));
4762
}
4763

    
4764
#if defined(CONFIG_USER_ONLY)
4765
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
4766
{
4767
    return addr;
4768
}
4769

    
4770
#else
4771
extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
4772
                                 int *access_index, target_ulong address, int rw,
4773
                                 int mmu_idx);
4774

    
4775
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
4776
{
4777
    target_phys_addr_t phys_addr;
4778
    int prot, access_index;
4779

    
4780
    if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2,
4781
                             MMU_KERNEL_IDX) != 0)
4782
        if (get_physical_address(env, &phys_addr, &prot, &access_index, addr,
4783
                                 0, MMU_KERNEL_IDX) != 0)
4784
            return -1;
4785
    if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED)
4786
        return -1;
4787
    return phys_addr;
4788
}
4789
#endif
4790

    
4791
void helper_flush(target_ulong addr)
4792
{
4793
    addr &= ~7;
4794
    tb_invalidate_page_range(addr, addr + 8);
4795
}