Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ 3b89f26c

History | View | Annotate | Download (179.7 kB)

1
/*
2
   SPARC translation
3

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

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

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

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

    
22
/*
23
   TODO-list:
24

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

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

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

    
42
#define DEBUG_DISAS
43

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

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

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

    
67
typedef struct sparc_def_t sparc_def_t;
68

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

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

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

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

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

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

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

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

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

    
115
static void disas_sparc_insn(DisasContext * dc);
116

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
442
    l1 = gen_new_label();
443

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

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

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

    
476
    l1 = gen_new_label();
477

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
607
    l1 = gen_new_label();
608

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

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

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

    
639
    l1 = gen_new_label();
640

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

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

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

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

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

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

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

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

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

    
733
    // b2 = T0 & 1;
734
    // env->y = (b2 << 31) | (env->y >> 1);
735
    tcg_gen_shli_i32(r_temp, cpu_T[0], 31);
736
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, y));
737
    tcg_gen_shri_i32(cpu_tmp0, cpu_tmp0, 1);
738
    tcg_gen_or_i32(cpu_tmp0, cpu_tmp0, r_temp);
739
    tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, y));
740

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

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

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

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

    
762
static inline void gen_op_umul_T1_T0(void)
763
{
764
    TCGv r_temp, r_temp2;
765

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

    
769
    tcg_gen_extu_i32_i64(r_temp, cpu_T[1]);
770
    tcg_gen_extu_i32_i64(r_temp2, cpu_T[0]);
771
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
772

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

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

    
786
static inline void gen_op_smul_T1_T0(void)
787
{
788
    TCGv r_temp, r_temp2;
789

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

    
793
    tcg_gen_ext_i32_i64(r_temp, cpu_T[1]);
794
    tcg_gen_ext_i32_i64(r_temp2, cpu_T[0]);
795
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
796

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

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

    
810
static inline void gen_op_udiv_T1_T0(void)
811
{
812
    tcg_gen_helper_1_2(helper_udiv, cpu_T[0], cpu_T[0], cpu_T[1]);
813
}
814

    
815
static inline void gen_op_sdiv_T1_T0(void)
816
{
817
    tcg_gen_helper_1_2(helper_sdiv, cpu_T[0], cpu_T[0], cpu_T[1]);
818
}
819

    
820
#ifdef TARGET_SPARC64
821
static inline void gen_trap_ifdivzero_i64(TCGv divisor)
822
{
823
    int l1;
824

    
825
    l1 = gen_new_label();
826
    tcg_gen_brcond_i64(TCG_COND_NE, divisor, tcg_const_tl(0), l1);
827
    gen_op_exception(TT_DIV_ZERO);
828
    gen_set_label(l1);
829
}
830

    
831
static inline void gen_op_sdivx_T1_T0(void)
832
{
833
    int l1, l2;
834

    
835
    l1 = gen_new_label();
836
    l2 = gen_new_label();
837
    gen_trap_ifdivzero_i64(cpu_T[1]);
838
    tcg_gen_brcond_i64(TCG_COND_NE, cpu_T[0], tcg_const_i64(INT64_MIN), l1);
839
    tcg_gen_brcond_i64(TCG_COND_NE, cpu_T[1], tcg_const_i64(-1), l1);
840
    tcg_gen_movi_i64(cpu_T[0], INT64_MIN);
841
    gen_op_jmp_label(l2);
842
    gen_set_label(l1);
843
    tcg_gen_div_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
844
    gen_set_label(l2);
845
}
846
#endif
847

    
848
static inline void gen_op_div_cc(void)
849
{
850
    int l1;
851

    
852
    gen_cc_clear();
853
    gen_cc_NZ(cpu_T[0]);
854
    l1 = gen_new_label();
855
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, cc_src2));
856
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
857
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
858
    gen_set_label(l1);
859
}
860

    
861
static inline void gen_op_logic_T0_cc(void)
862
{
863
    gen_cc_clear();
864
    gen_cc_NZ(cpu_T[0]);
865
}
866

    
867
// 1
868
static inline void gen_op_eval_ba(TCGv dst)
869
{
870
    tcg_gen_movi_tl(dst, 1);
871
}
872

    
873
// Z
874
static inline void gen_op_eval_be(TCGv dst, TCGv src)
875
{
876
    gen_mov_reg_Z(dst, src);
877
}
878

    
879
// Z | (N ^ V)
880
static inline void gen_op_eval_ble(TCGv dst, TCGv src)
881
{
882
    gen_mov_reg_N(cpu_tmp0, src);
883
    gen_mov_reg_V(dst, src);
884
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
885
    gen_mov_reg_Z(cpu_tmp0, src);
886
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
887
}
888

    
889
// N ^ V
890
static inline void gen_op_eval_bl(TCGv dst, TCGv src)
891
{
892
    gen_mov_reg_V(cpu_tmp0, src);
893
    gen_mov_reg_N(dst, src);
894
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
895
}
896

    
897
// C | Z
898
static inline void gen_op_eval_bleu(TCGv dst, TCGv src)
899
{
900
    gen_mov_reg_Z(cpu_tmp0, src);
901
    gen_mov_reg_C(dst, src);
902
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
903
}
904

    
905
// C
906
static inline void gen_op_eval_bcs(TCGv dst, TCGv src)
907
{
908
    gen_mov_reg_C(dst, src);
909
}
910

    
911
// V
912
static inline void gen_op_eval_bvs(TCGv dst, TCGv src)
913
{
914
    gen_mov_reg_V(dst, src);
915
}
916

    
917
// 0
918
static inline void gen_op_eval_bn(TCGv dst)
919
{
920
    tcg_gen_movi_tl(dst, 0);
921
}
922

    
923
// N
924
static inline void gen_op_eval_bneg(TCGv dst, TCGv src)
925
{
926
    gen_mov_reg_N(dst, src);
927
}
928

    
929
// !Z
930
static inline void gen_op_eval_bne(TCGv dst, TCGv src)
931
{
932
    gen_mov_reg_Z(dst, src);
933
    tcg_gen_xori_tl(dst, dst, 0x1);
934
}
935

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

    
947
// !(N ^ V)
948
static inline void gen_op_eval_bge(TCGv dst, TCGv src)
949
{
950
    gen_mov_reg_V(cpu_tmp0, src);
951
    gen_mov_reg_N(dst, src);
952
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
953
    tcg_gen_xori_tl(dst, dst, 0x1);
954
}
955

    
956
// !(C | Z)
957
static inline void gen_op_eval_bgu(TCGv dst, TCGv src)
958
{
959
    gen_mov_reg_Z(cpu_tmp0, src);
960
    gen_mov_reg_C(dst, src);
961
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
962
    tcg_gen_xori_tl(dst, dst, 0x1);
963
}
964

    
965
// !C
966
static inline void gen_op_eval_bcc(TCGv dst, TCGv src)
967
{
968
    gen_mov_reg_C(dst, src);
969
    tcg_gen_xori_tl(dst, dst, 0x1);
970
}
971

    
972
// !N
973
static inline void gen_op_eval_bpos(TCGv dst, TCGv src)
974
{
975
    gen_mov_reg_N(dst, src);
976
    tcg_gen_xori_tl(dst, dst, 0x1);
977
}
978

    
979
// !V
980
static inline void gen_op_eval_bvc(TCGv dst, TCGv src)
981
{
982
    gen_mov_reg_V(dst, src);
983
    tcg_gen_xori_tl(dst, dst, 0x1);
984
}
985

    
986
/*
987
  FPSR bit field FCC1 | FCC0:
988
   0 =
989
   1 <
990
   2 >
991
   3 unordered
992
*/
993
static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src,
994
                                    unsigned int fcc_offset)
995
{
996
    tcg_gen_shri_i32(reg, src, 10 + fcc_offset);
997
    tcg_gen_andi_tl(reg, reg, 0x1);
998
}
999

    
1000
static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
1001
                                    unsigned int fcc_offset)
1002
{
1003
    tcg_gen_shri_i32(reg, src, 11 + fcc_offset);
1004
    tcg_gen_andi_tl(reg, reg, 0x1);
1005
}
1006

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

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

    
1025
// 1 or 3: FCC0
1026
static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
1027
                                    unsigned int fcc_offset)
1028
{
1029
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1030
}
1031

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

    
1042
// 2 or 3: FCC1
1043
static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
1044
                                    unsigned int fcc_offset)
1045
{
1046
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1047
}
1048

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

    
1059
// 3: FCC0 & FCC1
1060
static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
1061
                                    unsigned int fcc_offset)
1062
{
1063
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1064
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1065
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1066
}
1067

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

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

    
1088
// 0 or 2: !FCC0
1089
static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
1090
                                    unsigned int fcc_offset)
1091
{
1092
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1093
    tcg_gen_xori_tl(dst, dst, 0x1);
1094
}
1095

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

    
1107
// 0 or 1: !FCC1
1108
static inline void gen_op_eval_fble(TCGv dst, TCGv src,
1109
                                    unsigned int fcc_offset)
1110
{
1111
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1112
    tcg_gen_xori_tl(dst, dst, 0x1);
1113
}
1114

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

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

    
1136
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
1137
                               target_ulong pc2, TCGv r_cond)
1138
{
1139
    int l1;
1140

    
1141
    l1 = gen_new_label();
1142

    
1143
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1144

    
1145
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
1146

    
1147
    gen_set_label(l1);
1148
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
1149
}
1150

    
1151
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
1152
                                target_ulong pc2, TCGv r_cond)
1153
{
1154
    int l1;
1155

    
1156
    l1 = gen_new_label();
1157

    
1158
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1159

    
1160
    gen_goto_tb(dc, 0, pc2, pc1);
1161

    
1162
    gen_set_label(l1);
1163
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
1164
}
1165

    
1166
static inline void gen_branch(DisasContext *dc, target_ulong pc,
1167
                              target_ulong npc)
1168
{
1169
    gen_goto_tb(dc, 0, pc, npc);
1170
}
1171

    
1172
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
1173
                                      TCGv r_cond)
1174
{
1175
    int l1, l2;
1176

    
1177
    l1 = gen_new_label();
1178
    l2 = gen_new_label();
1179

    
1180
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1181

    
1182
    gen_movl_npc_im(npc1);
1183
    gen_op_jmp_label(l2);
1184

    
1185
    gen_set_label(l1);
1186
    gen_movl_npc_im(npc2);
1187
    gen_set_label(l2);
1188
}
1189

    
1190
/* call this function before using T2 as it may have been set for a jump */
1191
static inline void flush_T2(DisasContext * dc)
1192
{
1193
    if (dc->npc == JUMP_PC) {
1194
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
1195
        dc->npc = DYNAMIC_PC;
1196
    }
1197
}
1198

    
1199
static inline void save_npc(DisasContext * dc)
1200
{
1201
    if (dc->npc == JUMP_PC) {
1202
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
1203
        dc->npc = DYNAMIC_PC;
1204
    } else if (dc->npc != DYNAMIC_PC) {
1205
        gen_movl_npc_im(dc->npc);
1206
    }
1207
}
1208

    
1209
static inline void save_state(DisasContext * dc)
1210
{
1211
    gen_jmp_im(dc->pc);
1212
    save_npc(dc);
1213
}
1214

    
1215
static inline void gen_mov_pc_npc(DisasContext * dc)
1216
{
1217
    if (dc->npc == JUMP_PC) {
1218
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
1219
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1220
        dc->pc = DYNAMIC_PC;
1221
    } else if (dc->npc == DYNAMIC_PC) {
1222
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1223
        dc->pc = DYNAMIC_PC;
1224
    } else {
1225
        dc->pc = dc->npc;
1226
    }
1227
}
1228

    
1229
static inline void gen_op_next_insn(void)
1230
{
1231
    tcg_gen_mov_tl(cpu_pc, cpu_npc);
1232
    tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
1233
}
1234

    
1235
static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond)
1236
{
1237
    TCGv r_src;
1238

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

    
1299
static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
1300
{
1301
    unsigned int offset;
1302

    
1303
    switch (cc) {
1304
    default:
1305
    case 0x0:
1306
        offset = 0;
1307
        break;
1308
    case 0x1:
1309
        offset = 32 - 10;
1310
        break;
1311
    case 0x2:
1312
        offset = 34 - 10;
1313
        break;
1314
    case 0x3:
1315
        offset = 36 - 10;
1316
        break;
1317
    }
1318

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

    
1371
#ifdef TARGET_SPARC64
1372
// Inverted logic
1373
static const int gen_tcg_cond_reg[8] = {
1374
    -1,
1375
    TCG_COND_NE,
1376
    TCG_COND_GT,
1377
    TCG_COND_GE,
1378
    -1,
1379
    TCG_COND_EQ,
1380
    TCG_COND_LE,
1381
    TCG_COND_LT,
1382
};
1383

    
1384
static inline void gen_cond_reg(TCGv r_dst, int cond)
1385
{
1386
    int l1;
1387

    
1388
    l1 = gen_new_label();
1389
    tcg_gen_movi_tl(r_dst, 0);
1390
    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0], tcg_const_tl(0), l1);
1391
    tcg_gen_movi_tl(r_dst, 1);
1392
    gen_set_label(l1);
1393
}
1394
#endif
1395

    
1396
/* XXX: potentially incorrect if dynamic npc */
1397
static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
1398
{
1399
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1400
    target_ulong target = dc->pc + offset;
1401

    
1402
    if (cond == 0x0) {
1403
        /* unconditional not taken */
1404
        if (a) {
1405
            dc->pc = dc->npc + 4;
1406
            dc->npc = dc->pc + 4;
1407
        } else {
1408
            dc->pc = dc->npc;
1409
            dc->npc = dc->pc + 4;
1410
        }
1411
    } else if (cond == 0x8) {
1412
        /* unconditional taken */
1413
        if (a) {
1414
            dc->pc = target;
1415
            dc->npc = dc->pc + 4;
1416
        } else {
1417
            dc->pc = dc->npc;
1418
            dc->npc = target;
1419
        }
1420
    } else {
1421
        flush_T2(dc);
1422
        gen_cond(cpu_T[2], cc, cond);
1423
        if (a) {
1424
            gen_branch_a(dc, target, dc->npc, cpu_T[2]);
1425
            dc->is_br = 1;
1426
        } else {
1427
            dc->pc = dc->npc;
1428
            dc->jump_pc[0] = target;
1429
            dc->jump_pc[1] = dc->npc + 4;
1430
            dc->npc = JUMP_PC;
1431
        }
1432
    }
1433
}
1434

    
1435
/* XXX: potentially incorrect if dynamic npc */
1436
static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
1437
{
1438
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1439
    target_ulong target = dc->pc + offset;
1440

    
1441
    if (cond == 0x0) {
1442
        /* unconditional not taken */
1443
        if (a) {
1444
            dc->pc = dc->npc + 4;
1445
            dc->npc = dc->pc + 4;
1446
        } else {
1447
            dc->pc = dc->npc;
1448
            dc->npc = dc->pc + 4;
1449
        }
1450
    } else if (cond == 0x8) {
1451
        /* unconditional taken */
1452
        if (a) {
1453
            dc->pc = target;
1454
            dc->npc = dc->pc + 4;
1455
        } else {
1456
            dc->pc = dc->npc;
1457
            dc->npc = target;
1458
        }
1459
    } else {
1460
        flush_T2(dc);
1461
        gen_fcond(cpu_T[2], cc, cond);
1462
        if (a) {
1463
            gen_branch_a(dc, target, dc->npc, cpu_T[2]);
1464
            dc->is_br = 1;
1465
        } else {
1466
            dc->pc = dc->npc;
1467
            dc->jump_pc[0] = target;
1468
            dc->jump_pc[1] = dc->npc + 4;
1469
            dc->npc = JUMP_PC;
1470
        }
1471
    }
1472
}
1473

    
1474
#ifdef TARGET_SPARC64
1475
/* XXX: potentially incorrect if dynamic npc */
1476
static void do_branch_reg(DisasContext * dc, int32_t offset, uint32_t insn)
1477
{
1478
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1479
    target_ulong target = dc->pc + offset;
1480

    
1481
    flush_T2(dc);
1482
    gen_cond_reg(cpu_T[2], cond);
1483
    if (a) {
1484
        gen_branch_a(dc, target, dc->npc, cpu_T[2]);
1485
        dc->is_br = 1;
1486
    } else {
1487
        dc->pc = dc->npc;
1488
        dc->jump_pc[0] = target;
1489
        dc->jump_pc[1] = dc->npc + 4;
1490
        dc->npc = JUMP_PC;
1491
    }
1492
}
1493

    
1494
static GenOpFunc * const gen_fcmps[4] = {
1495
    helper_fcmps,
1496
    helper_fcmps_fcc1,
1497
    helper_fcmps_fcc2,
1498
    helper_fcmps_fcc3,
1499
};
1500

    
1501
static GenOpFunc * const gen_fcmpd[4] = {
1502
    helper_fcmpd,
1503
    helper_fcmpd_fcc1,
1504
    helper_fcmpd_fcc2,
1505
    helper_fcmpd_fcc3,
1506
};
1507

    
1508
#if defined(CONFIG_USER_ONLY)
1509
static GenOpFunc * const gen_fcmpq[4] = {
1510
    helper_fcmpq,
1511
    helper_fcmpq_fcc1,
1512
    helper_fcmpq_fcc2,
1513
    helper_fcmpq_fcc3,
1514
};
1515
#endif
1516

    
1517
static GenOpFunc * const gen_fcmpes[4] = {
1518
    helper_fcmpes,
1519
    helper_fcmpes_fcc1,
1520
    helper_fcmpes_fcc2,
1521
    helper_fcmpes_fcc3,
1522
};
1523

    
1524
static GenOpFunc * const gen_fcmped[4] = {
1525
    helper_fcmped,
1526
    helper_fcmped_fcc1,
1527
    helper_fcmped_fcc2,
1528
    helper_fcmped_fcc3,
1529
};
1530

    
1531
#if defined(CONFIG_USER_ONLY)
1532
static GenOpFunc * const gen_fcmpeq[4] = {
1533
    helper_fcmpeq,
1534
    helper_fcmpeq_fcc1,
1535
    helper_fcmpeq_fcc2,
1536
    helper_fcmpeq_fcc3,
1537
};
1538
#endif
1539

    
1540
static inline void gen_op_fcmps(int fccno)
1541
{
1542
    tcg_gen_helper_0_0(gen_fcmps[fccno]);
1543
}
1544

    
1545
static inline void gen_op_fcmpd(int fccno)
1546
{
1547
    tcg_gen_helper_0_0(gen_fcmpd[fccno]);
1548
}
1549

    
1550
#if defined(CONFIG_USER_ONLY)
1551
static inline void gen_op_fcmpq(int fccno)
1552
{
1553
    tcg_gen_helper_0_0(gen_fcmpq[fccno]);
1554
}
1555
#endif
1556

    
1557
static inline void gen_op_fcmpes(int fccno)
1558
{
1559
    tcg_gen_helper_0_0(gen_fcmpes[fccno]);
1560
}
1561

    
1562
static inline void gen_op_fcmped(int fccno)
1563
{
1564
    tcg_gen_helper_0_0(gen_fcmped[fccno]);
1565
}
1566

    
1567
#if defined(CONFIG_USER_ONLY)
1568
static inline void gen_op_fcmpeq(int fccno)
1569
{
1570
    tcg_gen_helper_0_0(gen_fcmpeq[fccno]);
1571
}
1572
#endif
1573

    
1574
#else
1575

    
1576
static inline void gen_op_fcmps(int fccno)
1577
{
1578
    tcg_gen_helper_0_0(helper_fcmps);
1579
}
1580

    
1581
static inline void gen_op_fcmpd(int fccno)
1582
{
1583
    tcg_gen_helper_0_0(helper_fcmpd);
1584
}
1585

    
1586
#if defined(CONFIG_USER_ONLY)
1587
static inline void gen_op_fcmpq(int fccno)
1588
{
1589
    tcg_gen_helper_0_0(helper_fcmpq);
1590
}
1591
#endif
1592

    
1593
static inline void gen_op_fcmpes(int fccno)
1594
{
1595
    tcg_gen_helper_0_0(helper_fcmpes);
1596
}
1597

    
1598
static inline void gen_op_fcmped(int fccno)
1599
{
1600
    tcg_gen_helper_0_0(helper_fcmped);
1601
}
1602

    
1603
#if defined(CONFIG_USER_ONLY)
1604
static inline void gen_op_fcmpeq(int fccno)
1605
{
1606
    tcg_gen_helper_0_0(helper_fcmpeq);
1607
}
1608
#endif
1609

    
1610
#endif
1611

    
1612
static inline void gen_op_fpexception_im(int fsr_flags)
1613
{
1614
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~FSR_FTT_MASK);
1615
    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
1616
    gen_op_exception(TT_FP_EXCP);
1617
}
1618

    
1619
static int gen_trap_ifnofpu(DisasContext * dc)
1620
{
1621
#if !defined(CONFIG_USER_ONLY)
1622
    if (!dc->fpu_enabled) {
1623
        save_state(dc);
1624
        gen_op_exception(TT_NFPU_INSN);
1625
        dc->is_br = 1;
1626
        return 1;
1627
    }
1628
#endif
1629
    return 0;
1630
}
1631

    
1632
static inline void gen_op_clear_ieee_excp_and_FTT(void)
1633
{
1634
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~(FSR_FTT_MASK | FSR_CEXC_MASK));
1635
}
1636

    
1637
static inline void gen_clear_float_exceptions(void)
1638
{
1639
    tcg_gen_helper_0_0(helper_clear_float_exceptions);
1640
}
1641

    
1642
/* asi moves */
1643
#ifdef TARGET_SPARC64
1644
static inline TCGv gen_get_asi(int insn, TCGv r_addr)
1645
{
1646
    int asi, offset;
1647
    TCGv r_asi;
1648

    
1649
    if (IS_IMM) {
1650
        r_asi = tcg_temp_new(TCG_TYPE_I32);
1651
        offset = GET_FIELD(insn, 25, 31);
1652
        tcg_gen_addi_tl(r_addr, r_addr, offset);
1653
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
1654
    } else {
1655
        asi = GET_FIELD(insn, 19, 26);
1656
        r_asi = tcg_const_i32(asi);
1657
    }
1658
    return r_asi;
1659
}
1660

    
1661
static inline void gen_ld_asi(int insn, int size, int sign)
1662
{
1663
    TCGv r_asi;
1664

    
1665
    r_asi = gen_get_asi(insn, cpu_T[0]);
1666
    tcg_gen_helper_1_4(helper_ld_asi, cpu_T[1], cpu_T[0], r_asi,
1667
                       tcg_const_i32(size), tcg_const_i32(sign));
1668
    tcg_gen_discard_i32(r_asi);
1669
}
1670

    
1671
static inline void gen_st_asi(int insn, int size)
1672
{
1673
    TCGv r_asi;
1674

    
1675
    r_asi = gen_get_asi(insn, cpu_T[0]);
1676
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], r_asi,
1677
                       tcg_const_i32(size));
1678
    tcg_gen_discard_i32(r_asi);
1679
}
1680

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

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

    
1691
static inline void gen_stf_asi(int insn, int size, int rd)
1692
{
1693
    TCGv r_asi;
1694

    
1695
    r_asi = gen_get_asi(insn, cpu_T[0]);
1696
    tcg_gen_helper_0_4(helper_stf_asi, cpu_T[0], r_asi, tcg_const_i32(size),
1697
                       tcg_const_i32(rd));
1698
    tcg_gen_discard_i32(r_asi);
1699
}
1700

    
1701
static inline void gen_swap_asi(int insn)
1702
{
1703
    TCGv r_temp, r_asi;
1704

    
1705
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1706
    r_asi = gen_get_asi(insn, cpu_T[0]);
1707
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, cpu_T[0], r_asi,
1708
                       tcg_const_i32(4), tcg_const_i32(0));
1709
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_temp, r_asi,
1710
                       tcg_const_i32(4));
1711
    tcg_gen_mov_i32(cpu_T[1], r_temp);
1712
    tcg_gen_discard_i32(r_asi);
1713
    tcg_gen_discard_i32(r_temp);
1714
}
1715

    
1716
static inline void gen_ldda_asi(int insn)
1717
{
1718
    TCGv r_dword, r_asi;
1719

    
1720
    r_dword = tcg_temp_new(TCG_TYPE_I64);
1721
    r_asi = gen_get_asi(insn, cpu_T[0]);
1722
    tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], r_asi,
1723
                       tcg_const_i32(8), tcg_const_i32(0));
1724
    tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
1725
    tcg_gen_shri_i64(r_dword, r_dword, 32);
1726
    tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
1727
    tcg_gen_discard_i32(r_asi);
1728
    tcg_gen_discard_i64(r_dword);
1729
}
1730

    
1731
static inline void gen_stda_asi(int insn, int rd)
1732
{
1733
    TCGv r_dword, r_temp, r_asi;
1734

    
1735
    r_dword = tcg_temp_new(TCG_TYPE_I64);
1736
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1737
    gen_movl_reg_TN(rd + 1, r_temp);
1738
    tcg_gen_helper_1_2(helper_pack64, r_dword, cpu_T[1],
1739
                       r_temp);
1740
    r_asi = gen_get_asi(insn, cpu_T[0]);
1741
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, r_asi,
1742
                       tcg_const_i32(8));
1743
    tcg_gen_discard_i32(r_asi);
1744
    tcg_gen_discard_i32(r_temp);
1745
    tcg_gen_discard_i64(r_dword);
1746
}
1747

    
1748
static inline void gen_cas_asi(int insn, int rd)
1749
{
1750
    TCGv r_val1, r_asi;
1751

    
1752
    r_val1 = tcg_temp_new(TCG_TYPE_I32);
1753
    gen_movl_reg_TN(rd, r_val1);
1754
    r_asi = gen_get_asi(insn, cpu_T[0]);
1755
    tcg_gen_helper_1_4(helper_cas_asi, cpu_T[1], cpu_T[0], r_val1, cpu_T[1],
1756
                       r_asi);
1757
    tcg_gen_discard_i32(r_asi);
1758
    tcg_gen_discard_i32(r_val1);
1759
}
1760

    
1761
static inline void gen_casx_asi(int insn, int rd)
1762
{
1763
    TCGv r_val1, r_asi;
1764

    
1765
    r_val1 = tcg_temp_new(TCG_TYPE_I64);
1766
    gen_movl_reg_TN(rd, r_val1);
1767
    r_asi = gen_get_asi(insn, cpu_T[0]);
1768
    tcg_gen_helper_1_4(helper_casx_asi, cpu_T[1], cpu_T[0], r_val1, cpu_T[1],
1769
                       r_asi);
1770
    tcg_gen_discard_i32(r_asi);
1771
    tcg_gen_discard_i32(r_val1);
1772
}
1773

    
1774
#elif !defined(CONFIG_USER_ONLY)
1775

    
1776
static inline void gen_ld_asi(int insn, int size, int sign)
1777
{
1778
    int asi;
1779
    TCGv r_dword;
1780

    
1781
    r_dword = tcg_temp_new(TCG_TYPE_I64);
1782
    asi = GET_FIELD(insn, 19, 26);
1783
    tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], tcg_const_i32(asi),
1784
                       tcg_const_i32(size), tcg_const_i32(sign));
1785
    tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
1786
    tcg_gen_discard_i64(r_dword);
1787
}
1788

    
1789
static inline void gen_st_asi(int insn, int size)
1790
{
1791
    int asi;
1792
    TCGv r_dword;
1793

    
1794
    r_dword = tcg_temp_new(TCG_TYPE_I64);
1795
    tcg_gen_extu_i32_i64(r_dword, cpu_T[1]);
1796
    asi = GET_FIELD(insn, 19, 26);
1797
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, tcg_const_i32(asi),
1798
                       tcg_const_i32(size));
1799
    tcg_gen_discard_i64(r_dword);
1800
}
1801

    
1802
static inline void gen_swap_asi(int insn)
1803
{
1804
    int asi;
1805
    TCGv r_temp;
1806

    
1807
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1808
    asi = GET_FIELD(insn, 19, 26);
1809
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, cpu_T[0], tcg_const_i32(asi),
1810
                       tcg_const_i32(4), tcg_const_i32(0));
1811
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], tcg_const_i32(asi),
1812
                       tcg_const_i32(4));
1813
    tcg_gen_mov_i32(cpu_T[1], r_temp);
1814
    tcg_gen_discard_i32(r_temp);
1815
}
1816

    
1817
static inline void gen_ldda_asi(int insn)
1818
{
1819
    int asi;
1820
    TCGv r_dword;
1821

    
1822
    r_dword = tcg_temp_new(TCG_TYPE_I64);
1823
    asi = GET_FIELD(insn, 19, 26);
1824
    tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], tcg_const_i32(asi),
1825
                       tcg_const_i32(8), tcg_const_i32(0));
1826
    tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
1827
    tcg_gen_shri_i64(r_dword, r_dword, 32);
1828
    tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
1829
    tcg_gen_discard_i64(r_dword);
1830
}
1831

    
1832
static inline void gen_stda_asi(int insn, int rd)
1833
{
1834
    int asi;
1835
    TCGv r_dword, r_temp;
1836

    
1837
    r_dword = tcg_temp_new(TCG_TYPE_I64);
1838
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1839
    gen_movl_reg_TN(rd + 1, r_temp);
1840
    tcg_gen_helper_1_2(helper_pack64, r_dword, cpu_T[1], r_temp);
1841
    asi = GET_FIELD(insn, 19, 26);
1842
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, tcg_const_i32(asi),
1843
                       tcg_const_i32(8));
1844
    tcg_gen_discard_i64(r_dword);
1845
}
1846
#endif
1847

    
1848
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1849
static inline void gen_ldstub_asi(int insn)
1850
{
1851
    int asi;
1852

    
1853
    gen_ld_asi(insn, 1, 0);
1854

    
1855
    asi = GET_FIELD(insn, 19, 26);
1856
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], tcg_const_i64(0xff),
1857
                       tcg_const_i32(asi), tcg_const_i32(1));
1858
}
1859
#endif
1860

    
1861
/* before an instruction, dc->pc must be static */
1862
static void disas_sparc_insn(DisasContext * dc)
1863
{
1864
    unsigned int insn, opc, rs1, rs2, rd;
1865

    
1866
    insn = ldl_code(dc->pc);
1867
    opc = GET_FIELD(insn, 0, 1);
1868

    
1869
    rd = GET_FIELD(insn, 2, 6);
1870
    switch (opc) {
1871
    case 0:                     /* branches/sethi */
1872
        {
1873
            unsigned int xop = GET_FIELD(insn, 7, 9);
1874
            int32_t target;
1875
            switch (xop) {
1876
#ifdef TARGET_SPARC64
1877
            case 0x1:           /* V9 BPcc */
1878
                {
1879
                    int cc;
1880

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

    
1962
            gen_movl_TN_reg(15, tcg_const_tl(dc->pc));
1963
            target += dc->pc;
1964
            gen_mov_pc_npc(dc);
1965
            dc->npc = target;
1966
        }
1967
        goto jmp_insn;
1968
    case 2:                     /* FPU & Logical Operations */
1969
        {
1970
            unsigned int xop = GET_FIELD(insn, 7, 12);
1971
            if (xop == 0x3a) {  /* generate trap */
1972
                int cond;
1973

    
1974
                rs1 = GET_FIELD(insn, 13, 17);
1975
                gen_movl_reg_T0(rs1);
1976
                if (IS_IMM) {
1977
                    rs2 = GET_FIELD(insn, 25, 31);
1978
                    tcg_gen_addi_tl(cpu_T[0], cpu_T[0], rs2);
1979
                } else {
1980
                    rs2 = GET_FIELD(insn, 27, 31);
1981
#if defined(OPTIM)
1982
                    if (rs2 != 0) {
1983
#endif
1984
                        gen_movl_reg_T1(rs2);
1985
                        gen_op_add_T1_T0();
1986
#if defined(OPTIM)
1987
                    }
1988
#endif
1989
                }
1990
                cond = GET_FIELD(insn, 3, 6);
1991
                if (cond == 0x8) {
1992
                    save_state(dc);
1993
                    tcg_gen_helper_0_1(helper_trap, cpu_T[0]);
1994
                } else if (cond != 0) {
1995
                    TCGv r_cond = tcg_temp_new(TCG_TYPE_TL);
1996
#ifdef TARGET_SPARC64
1997
                    /* V9 icc/xcc */
1998
                    int cc = GET_FIELD_SP(insn, 11, 12);
1999

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

    
2048
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2049
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2050
                                       offsetof(CPUState, tick));
2051
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_T[0],
2052
                                           r_tickptr);
2053
                        gen_movl_T0_reg(rd);
2054
                        tcg_gen_discard_ptr(r_tickptr);
2055
                    }
2056
                    break;
2057
                case 0x5: /* V9 rdpc */
2058
                    tcg_gen_movi_tl(cpu_T[0], dc->pc);
2059
                    gen_movl_T0_reg(rd);
2060
                    break;
2061
                case 0x6: /* V9 rdfprs */
2062
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, fprs));
2063
                    gen_movl_T0_reg(rd);
2064
                    break;
2065
                case 0xf: /* V9 membar */
2066
                    break; /* no effect */
2067
                case 0x13: /* Graphics Status */
2068
                    if (gen_trap_ifnofpu(dc))
2069
                        goto jmp_insn;
2070
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, gsr));
2071
                    gen_movl_T0_reg(rd);
2072
                    break;
2073
                case 0x17: /* Tick compare */
2074
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, tick_cmpr));
2075
                    gen_movl_T0_reg(rd);
2076
                    break;
2077
                case 0x18: /* System tick */
2078
                    {
2079
                        TCGv r_tickptr;
2080

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

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

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

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

    
2185
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2186
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2187
                                       offsetof(CPUState, tsptr));
2188
                        tcg_gen_ld_i32(cpu_T[0], r_tsptr,
2189
                                       offsetof(trap_state, tt));
2190
                        tcg_gen_discard_ptr(r_tsptr);
2191
                    }
2192
                    break;
2193
                case 4: // tick
2194
                    {
2195
                        TCGv r_tickptr;
2196

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

    
2653
                    l1 = gen_new_label();
2654
                    cond = GET_FIELD_SP(insn, 14, 17);
2655
                    rs1 = GET_FIELD(insn, 13, 17);
2656
                    gen_movl_reg_T0(rs1);
2657
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0],
2658
                                      tcg_const_tl(0), l1);
2659
                    gen_op_load_fpr_FT0(rs2);
2660
                    gen_op_store_FT0_fpr(rd);
2661
                    gen_set_label(l1);
2662
                    break;
2663
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
2664
                    int l1;
2665

    
2666
                    l1 = gen_new_label();
2667
                    cond = GET_FIELD_SP(insn, 14, 17);
2668
                    rs1 = GET_FIELD(insn, 13, 17);
2669
                    gen_movl_reg_T0(rs1);
2670
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0],
2671
                                      tcg_const_tl(0), l1);
2672
                    gen_op_load_fpr_DT0(DFPREG(rs2));
2673
                    gen_op_store_DT0_fpr(DFPREG(rd));
2674
                    gen_set_label(l1);
2675
                    break;
2676
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
2677
#if defined(CONFIG_USER_ONLY)
2678
                    int l1;
2679

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

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

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

    
3161
                                    gen_op_xor_T1_T0();
3162
                                    gen_op_movtl_env_T0(offsetof(CPUSPARCState,
3163
                                                                 tick_cmpr));
3164
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3165
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3166
                                                   offsetof(CPUState, tick));
3167
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3168
                                                       r_tickptr, cpu_T[0]);
3169
                                    tcg_gen_discard_ptr(r_tickptr);
3170
                                }
3171
                                break;
3172
                            case 0x18: /* System tick */
3173
#if !defined(CONFIG_USER_ONLY)
3174
                                if (!supervisor(dc))
3175
                                    goto illegal_insn;
3176
#endif
3177
                                {
3178
                                    TCGv r_tickptr;
3179

    
3180
                                    gen_op_xor_T1_T0();
3181
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3182
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3183
                                                   offsetof(CPUState, stick));
3184
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3185
                                                       r_tickptr, cpu_T[0]);
3186
                                    tcg_gen_discard_ptr(r_tickptr);
3187
                                }
3188
                                break;
3189
                            case 0x19: /* System tick compare */
3190
#if !defined(CONFIG_USER_ONLY)
3191
                                if (!supervisor(dc))
3192
                                    goto illegal_insn;
3193
#endif
3194
                                {
3195
                                    TCGv r_tickptr;
3196

    
3197
                                    gen_op_xor_T1_T0();
3198
                                    gen_op_movtl_env_T0(offsetof(CPUSPARCState,
3199
                                                                 stick_cmpr));
3200
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3201
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3202
                                                   offsetof(CPUState, stick));
3203
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3204
                                                       r_tickptr, cpu_T[0]);
3205
                                    tcg_gen_discard_ptr(r_tickptr);
3206
                                }
3207
                                break;
3208

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

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

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

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

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

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

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

    
3428
                            r_cond = tcg_temp_new(TCG_TYPE_TL);
3429
                            if (insn & (1 << 18)) {
3430
                                if (cc == 0)
3431
                                    gen_cond(r_cond, 0, cond);
3432
                                else if (cc == 2)
3433
                                    gen_cond(r_cond, 1, cond);
3434
                                else
3435
                                    goto illegal_insn;
3436
                            } else {
3437
                                gen_fcond(r_cond, cc, cond);
3438
                            }
3439

    
3440
                            l1 = gen_new_label();
3441

    
3442
                            tcg_gen_brcond_tl(TCG_COND_EQ, r_cond,
3443
                                              tcg_const_tl(0), l1);
3444
                            if (IS_IMM) {       /* immediate */
3445
                                rs2 = GET_FIELD_SPs(insn, 0, 10);
3446
                                gen_movl_simm_T1(rs2);
3447
                            } else {
3448
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3449
                                gen_movl_reg_T1(rs2);
3450
                            }
3451
                            gen_movl_T1_reg(rd);
3452
                            gen_set_label(l1);
3453
                            tcg_gen_discard_tl(r_cond);
3454
                            break;
3455
                        }
3456
                    case 0x2d: /* V9 sdivx */
3457
                        gen_op_sdivx_T1_T0();
3458
                        gen_movl_T0_reg(rd);
3459
                        break;
3460
                    case 0x2e: /* V9 popc */
3461
                        {
3462
                            if (IS_IMM) {       /* immediate */
3463
                                rs2 = GET_FIELD_SPs(insn, 0, 12);
3464
                                gen_movl_simm_T1(rs2);
3465
                                // XXX optimize: popc(constant)
3466
                            }
3467
                            else {
3468
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3469
                                gen_movl_reg_T1(rs2);
3470
                            }
3471
                            tcg_gen_helper_1_1(helper_popc, cpu_T[0],
3472
                                               cpu_T[1]);
3473
                            gen_movl_T0_reg(rd);
3474
                        }
3475
                    case 0x2f: /* V9 movr */
3476
                        {
3477
                            int cond = GET_FIELD_SP(insn, 10, 12);
3478
                            int l1;
3479

    
3480
                            rs1 = GET_FIELD(insn, 13, 17);
3481
                            gen_movl_reg_T0(rs1);
3482

    
3483
                            l1 = gen_new_label();
3484

    
3485
                            tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0],
3486
                                              tcg_const_tl(0), l1);
3487
                            if (IS_IMM) {       /* immediate */
3488
                                rs2 = GET_FIELD_SPs(insn, 0, 9);
3489
                                gen_movl_simm_T1(rs2);
3490
                            } else {
3491
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3492
                                gen_movl_reg_T1(rs2);
3493
                            }
3494
                            gen_movl_T1_reg(rd);
3495
                            gen_set_label(l1);
3496
                            break;
3497
                        }
3498
#endif
3499
                    default:
3500
                        goto illegal_insn;
3501
                    }
3502
                }
3503
            } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
3504
#ifdef TARGET_SPARC64
3505
                int opf = GET_FIELD_SP(insn, 5, 13);
3506
                rs1 = GET_FIELD(insn, 13, 17);
3507
                rs2 = GET_FIELD(insn, 27, 31);
3508
                if (gen_trap_ifnofpu(dc))
3509
                    goto jmp_insn;
3510

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

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

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

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

    
4519
static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
4520
{
4521
}
4522

    
4523
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
4524
                                                 int spc, CPUSPARCState *env)
4525
{
4526
    target_ulong pc_start, last_pc;
4527
    uint16_t *gen_opc_end;
4528
    DisasContext dc1, *dc = &dc1;
4529
    int j, lj = -1;
4530

    
4531
    memset(dc, 0, sizeof(DisasContext));
4532
    dc->tb = tb;
4533
    pc_start = tb->pc;
4534
    dc->pc = pc_start;
4535
    last_pc = dc->pc;
4536
    dc->npc = (target_ulong) tb->cs_base;
4537
    dc->mem_idx = cpu_mmu_index(env);
4538
    dc->fpu_enabled = cpu_fpu_enabled(env);
4539
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4540

    
4541
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
4542

    
4543
    do {
4544
        if (env->nb_breakpoints > 0) {
4545
            for(j = 0; j < env->nb_breakpoints; j++) {
4546
                if (env->breakpoints[j] == dc->pc) {
4547
                    if (dc->pc != pc_start)
4548
                        save_state(dc);
4549
                    tcg_gen_helper_0_0(helper_debug);
4550
                    tcg_gen_exit_tb(0);
4551
                    dc->is_br = 1;
4552
                    goto exit_gen_loop;
4553
                }
4554
            }
4555
        }
4556
        if (spc) {
4557
            if (loglevel > 0)
4558
                fprintf(logfile, "Search PC...\n");
4559
            j = gen_opc_ptr - gen_opc_buf;
4560
            if (lj < j) {
4561
                lj++;
4562
                while (lj < j)
4563
                    gen_opc_instr_start[lj++] = 0;
4564
                gen_opc_pc[lj] = dc->pc;
4565
                gen_opc_npc[lj] = dc->npc;
4566
                gen_opc_instr_start[lj] = 1;
4567
            }
4568
        }
4569
        last_pc = dc->pc;
4570
        disas_sparc_insn(dc);
4571

    
4572
        if (dc->is_br)
4573
            break;
4574
        /* if the next PC is different, we abort now */
4575
        if (dc->pc != (last_pc + 4))
4576
            break;
4577
        /* if we reach a page boundary, we stop generation so that the
4578
           PC of a TT_TFAULT exception is always in the right page */
4579
        if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
4580
            break;
4581
        /* if single step mode, we generate only one instruction and
4582
           generate an exception */
4583
        if (env->singlestep_enabled) {
4584
            gen_jmp_im(dc->pc);
4585
            tcg_gen_exit_tb(0);
4586
            break;
4587
        }
4588
    } while ((gen_opc_ptr < gen_opc_end) &&
4589
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
4590

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

    
4631
int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
4632
{
4633
    return gen_intermediate_code_internal(tb, 0, env);
4634
}
4635

    
4636
int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
4637
{
4638
    return gen_intermediate_code_internal(tb, 1, env);
4639
}
4640

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

    
4673
CPUSPARCState *cpu_sparc_init(const char *cpu_model)
4674
{
4675
    CPUSPARCState *env;
4676
    const sparc_def_t *def;
4677
    static int inited;
4678
    unsigned int i;
4679
    static const char * const gregnames[8] = {
4680
        NULL, // g0 not used
4681
        "g1",
4682
        "g2",
4683
        "g3",
4684
        "g4",
4685
        "g5",
4686
        "g6",
4687
        "g7",
4688
    };
4689

    
4690
    def = cpu_sparc_find_by_name(cpu_model);
4691
    if (!def)
4692
        return NULL;
4693

    
4694
    env = qemu_mallocz(sizeof(CPUSPARCState));
4695
    if (!env)
4696
        return NULL;
4697
    cpu_exec_init(env);
4698
    env->cpu_model_str = cpu_model;
4699
    env->version = def->iu_version;
4700
    env->fsr = def->fpu_version;
4701
#if !defined(TARGET_SPARC64)
4702
    env->mmu_bm = def->mmu_bm;
4703
    env->mmu_ctpr_mask = def->mmu_ctpr_mask;
4704
    env->mmu_cxr_mask = def->mmu_cxr_mask;
4705
    env->mmu_sfsr_mask = def->mmu_sfsr_mask;
4706
    env->mmu_trcr_mask = def->mmu_trcr_mask;
4707
    env->mmuregs[0] |= def->mmu_version;
4708
    cpu_sparc_set_id(env, 0);
4709
#endif
4710

    
4711
    /* init various static tables */
4712
    if (!inited) {
4713
        inited = 1;
4714

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

    
4763
    cpu_reset(env);
4764
    
4765
    return env;
4766
}
4767

    
4768
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
4769
{
4770
#if !defined(TARGET_SPARC64)
4771
    env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
4772
#endif
4773
}
4774

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

    
5095
static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name)
5096
{
5097
    unsigned int i;
5098

    
5099
    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
5100
        if (strcasecmp(name, sparc_defs[i].name) == 0) {
5101
            return &sparc_defs[i];
5102
        }
5103
    }
5104
    return NULL;
5105
}
5106

    
5107
void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
5108
{
5109
    unsigned int i;
5110

    
5111
    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
5112
        (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x\n",
5113
                       sparc_defs[i].name,
5114
                       sparc_defs[i].iu_version,
5115
                       sparc_defs[i].fpu_version,
5116
                       sparc_defs[i].mmu_version);
5117
    }
5118
}
5119

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

    
5122
void cpu_dump_state(CPUState *env, FILE *f,
5123
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5124
                    int flags)
5125
{
5126
    int i, x;
5127

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

    
5172
#if defined(CONFIG_USER_ONLY)
5173
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
5174
{
5175
    return addr;
5176
}
5177

    
5178
#else
5179
extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
5180
                                 int *access_index, target_ulong address, int rw,
5181
                                 int mmu_idx);
5182

    
5183
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
5184
{
5185
    target_phys_addr_t phys_addr;
5186
    int prot, access_index;
5187

    
5188
    if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2,
5189
                             MMU_KERNEL_IDX) != 0)
5190
        if (get_physical_address(env, &phys_addr, &prot, &access_index, addr,
5191
                                 0, MMU_KERNEL_IDX) != 0)
5192
            return -1;
5193
    if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED)
5194
        return -1;
5195
    return phys_addr;
5196
}
5197
#endif
5198

    
5199
void helper_flush(target_ulong addr)
5200
{
5201
    addr &= ~7;
5202
    tb_invalidate_page_range(addr, addr + 8);
5203
}