Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ 06b3e1b3

History | View | Annotate | Download (182.2 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
/* floating point registers moves */
118
static void gen_op_load_fpr_FT0(unsigned int src)
119
{
120
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fpr[src]));
121
    tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, ft0));
122
}
123

    
124
static void gen_op_load_fpr_FT1(unsigned int src)
125
{
126
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fpr[src]));
127
    tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, ft1));
128
}
129

    
130
static void gen_op_store_FT0_fpr(unsigned int dst)
131
{
132
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, ft0));
133
    tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fpr[dst]));
134
}
135

    
136
static void gen_op_load_fpr_DT0(unsigned int src)
137
{
138
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fpr[src]));
139
    tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, dt0) + offsetof(CPU_DoubleU, l.upper));
140
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
141
    tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, dt0) + offsetof(CPU_DoubleU, l.lower));
142
}
143

    
144
static void gen_op_load_fpr_DT1(unsigned int src)
145
{
146
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fpr[src]));
147
    tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, dt1) + offsetof(CPU_DoubleU, l.upper));
148
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
149
    tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, dt1) + offsetof(CPU_DoubleU, l.lower));
150
}
151

    
152
static void gen_op_store_DT0_fpr(unsigned int dst)
153
{
154
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, dt0) + offsetof(CPU_DoubleU, l.upper));
155
    tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fpr[dst]));
156
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, dt0) + offsetof(CPU_DoubleU, l.lower));
157
    tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fpr[dst + 1]));
158
}
159

    
160
#ifdef CONFIG_USER_ONLY
161
static void gen_op_load_fpr_QT0(unsigned int src)
162
{
163
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fpr[src]));
164
    tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upmost));
165
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
166
    tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upper));
167
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fpr[src + 2]));
168
    tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lower));
169
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fpr[src + 3]));
170
    tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lowest));
171
}
172

    
173
static void gen_op_load_fpr_QT1(unsigned int src)
174
{
175
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fpr[src]));
176
    tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.upmost));
177
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
178
    tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.upper));
179
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fpr[src + 2]));
180
    tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.lower));
181
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fpr[src + 3]));
182
    tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.lowest));
183
}
184

    
185
static void gen_op_store_QT0_fpr(unsigned int dst)
186
{
187
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upmost));
188
    tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fpr[dst]));
189
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upper));
190
    tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fpr[dst + 1]));
191
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lower));
192
    tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fpr[dst + 2]));
193
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lowest));
194
    tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fpr[dst + 3]));
195
}
196
#endif
197

    
198
/* moves */
199
#ifdef CONFIG_USER_ONLY
200
#define supervisor(dc) 0
201
#ifdef TARGET_SPARC64
202
#define hypervisor(dc) 0
203
#endif
204
#define gen_op_ldst(name)        gen_op_##name##_raw()
205
#else
206
#define supervisor(dc) (dc->mem_idx >= 1)
207
#ifdef TARGET_SPARC64
208
#define hypervisor(dc) (dc->mem_idx == 2)
209
#define OP_LD_TABLE(width)                                              \
210
    static GenOpFunc * const gen_op_##width[] = {                       \
211
        &gen_op_##width##_user,                                         \
212
        &gen_op_##width##_kernel,                                       \
213
        &gen_op_##width##_hypv,                                         \
214
    };
215
#else
216
#define OP_LD_TABLE(width)                                              \
217
    static GenOpFunc * const gen_op_##width[] = {                       \
218
        &gen_op_##width##_user,                                         \
219
        &gen_op_##width##_kernel,                                       \
220
    };
221
#endif
222
#define gen_op_ldst(name)        (*gen_op_##name[dc->mem_idx])()
223
#endif
224

    
225
#ifndef CONFIG_USER_ONLY
226
#ifdef __i386__
227
OP_LD_TABLE(std);
228
#endif /* __i386__ */
229
OP_LD_TABLE(stf);
230
OP_LD_TABLE(stdf);
231
OP_LD_TABLE(ldf);
232
OP_LD_TABLE(lddf);
233
#endif
234

    
235
#ifdef TARGET_ABI32
236
#define ABI32_MASK(addr) tcg_gen_andi_i64(addr, addr, 0xffffffffULL);
237
#else
238
#define ABI32_MASK(addr)
239
#endif
240

    
241
static inline void gen_movl_simm_T1(int32_t val)
242
{
243
    tcg_gen_movi_tl(cpu_T[1], val);
244
}
245

    
246
static inline void gen_movl_reg_TN(int reg, TCGv tn)
247
{
248
    if (reg == 0)
249
        tcg_gen_movi_tl(tn, 0);
250
    else if (reg < 8)
251
        tcg_gen_mov_tl(tn, cpu_gregs[reg]);
252
    else {
253
        tcg_gen_ld_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
254
    }
255
}
256

    
257
static inline void gen_movl_reg_T0(int reg)
258
{
259
    gen_movl_reg_TN(reg, cpu_T[0]);
260
}
261

    
262
static inline void gen_movl_reg_T1(int reg)
263
{
264
    gen_movl_reg_TN(reg, cpu_T[1]);
265
}
266

    
267
#ifdef __i386__
268
static inline void gen_movl_reg_T2(int reg)
269
{
270
    gen_movl_reg_TN(reg, cpu_T[2]);
271
}
272

    
273
#endif /* __i386__ */
274
static inline void gen_movl_TN_reg(int reg, TCGv tn)
275
{
276
    if (reg == 0)
277
        return;
278
    else if (reg < 8)
279
        tcg_gen_mov_tl(cpu_gregs[reg], tn);
280
    else {
281
        tcg_gen_st_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
282
    }
283
}
284

    
285
static inline void gen_movl_T0_reg(int reg)
286
{
287
    gen_movl_TN_reg(reg, cpu_T[0]);
288
}
289

    
290
static inline void gen_movl_T1_reg(int reg)
291
{
292
    gen_movl_TN_reg(reg, cpu_T[1]);
293
}
294

    
295
static inline void gen_op_movl_T0_env(size_t offset)
296
{
297
    tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
298
}
299

    
300
static inline void gen_op_movl_env_T0(size_t offset)
301
{
302
    tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
303
}
304

    
305
static inline void gen_op_movtl_T0_env(size_t offset)
306
{
307
    tcg_gen_ld_tl(cpu_T[0], cpu_env, offset);
308
}
309

    
310
static inline void gen_op_movtl_env_T0(size_t offset)
311
{
312
    tcg_gen_st_tl(cpu_T[0], cpu_env, offset);
313
}
314

    
315
static inline void gen_op_add_T1_T0(void)
316
{
317
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
318
}
319

    
320
static inline void gen_op_or_T1_T0(void)
321
{
322
    tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
323
}
324

    
325
static inline void gen_op_xor_T1_T0(void)
326
{
327
    tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
328
}
329

    
330
static inline void gen_jmp_im(target_ulong pc)
331
{
332
    tcg_gen_movi_tl(cpu_pc, pc);
333
}
334

    
335
static inline void gen_movl_npc_im(target_ulong npc)
336
{
337
    tcg_gen_movi_tl(cpu_npc, npc);
338
}
339

    
340
static inline void gen_goto_tb(DisasContext *s, int tb_num,
341
                               target_ulong pc, target_ulong npc)
342
{
343
    TranslationBlock *tb;
344

    
345
    tb = s->tb;
346
    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
347
        (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK))  {
348
        /* jump to same page: we can use a direct jump */
349
        tcg_gen_goto_tb(tb_num);
350
        gen_jmp_im(pc);
351
        gen_movl_npc_im(npc);
352
        tcg_gen_exit_tb((long)tb + tb_num);
353
    } else {
354
        /* jump to another page: currently not optimized */
355
        gen_jmp_im(pc);
356
        gen_movl_npc_im(npc);
357
        tcg_gen_exit_tb(0);
358
    }
359
}
360

    
361
// XXX suboptimal
362
static inline void gen_mov_reg_N(TCGv reg, TCGv src)
363
{
364
    tcg_gen_shri_i32(reg, src, 23);
365
    tcg_gen_andi_tl(reg, reg, 0x1);
366
}
367

    
368
static inline void gen_mov_reg_Z(TCGv reg, TCGv src)
369
{
370
    tcg_gen_shri_i32(reg, src, 22);
371
    tcg_gen_andi_tl(reg, reg, 0x1);
372
}
373

    
374
static inline void gen_mov_reg_V(TCGv reg, TCGv src)
375
{
376
    tcg_gen_shri_i32(reg, src, 21);
377
    tcg_gen_andi_tl(reg, reg, 0x1);
378
}
379

    
380
static inline void gen_mov_reg_C(TCGv reg, TCGv src)
381
{
382
    tcg_gen_shri_i32(reg, src, 20);
383
    tcg_gen_andi_tl(reg, reg, 0x1);
384
}
385

    
386
static inline void gen_op_exception(int exception)
387
{
388
    tcg_gen_movi_i32(cpu_tmp0, exception);
389
    tcg_gen_helper_0_1(raise_exception, cpu_tmp0);
390
}
391

    
392
static inline void gen_cc_clear(void)
393
{
394
    tcg_gen_movi_i32(cpu_psr, 0);
395
#ifdef TARGET_SPARC64
396
    tcg_gen_movi_i32(cpu_xcc, 0);
397
#endif
398
}
399

    
400
/* old op:
401
    if (!T0)
402
        env->psr |= PSR_ZERO;
403
    if ((int32_t) T0 < 0)
404
        env->psr |= PSR_NEG;
405
*/
406
static inline void gen_cc_NZ(TCGv dst)
407
{
408
    int l1, l2;
409

    
410
    l1 = gen_new_label();
411
    l2 = gen_new_label();
412
    tcg_gen_brcond_i32(TCG_COND_NE, dst, tcg_const_i32(0), l1);
413
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_ZERO);
414
    gen_set_label(l1);
415
    tcg_gen_brcond_i32(TCG_COND_GE, dst, tcg_const_i32(0), l2);
416
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_NEG);
417
    gen_set_label(l2);
418
#ifdef TARGET_SPARC64
419
    {
420
        int l3, l4;
421

    
422
        l3 = gen_new_label();
423
        l4 = gen_new_label();
424
        tcg_gen_brcond_tl(TCG_COND_NE, dst, tcg_const_tl(0), l3);
425
        tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_ZERO);
426
        gen_set_label(l3);
427
        tcg_gen_brcond_tl(TCG_COND_GE, dst, tcg_const_tl(0), l4);
428
        tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_NEG);
429
        gen_set_label(l4);
430
    }
431
#endif
432
}
433

    
434
/* old op:
435
    if (T0 < src1)
436
        env->psr |= PSR_CARRY;
437
*/
438
static inline void gen_cc_C_add(TCGv dst, TCGv src1)
439
{
440
    int l1;
441

    
442
    l1 = gen_new_label();
443
    tcg_gen_brcond_i32(TCG_COND_GEU, dst, src1, l1);
444
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
445
    gen_set_label(l1);
446
#ifdef TARGET_SPARC64
447
    {
448
        int l2;
449

    
450
        l2 = gen_new_label();
451
        tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l2);
452
        tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
453
        gen_set_label(l2);
454
    }
455
#endif
456
}
457

    
458
/* old op:
459
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
460
        env->psr |= PSR_OVF;
461
*/
462
static inline void gen_cc_V_add(TCGv dst, TCGv src1, TCGv src2)
463
{
464
    TCGv r_temp;
465
    int l1;
466

    
467
    l1 = gen_new_label();
468

    
469
    r_temp = tcg_temp_new(TCG_TYPE_TL);
470
    tcg_gen_xor_tl(r_temp, src1, src2);
471
    tcg_gen_xori_tl(r_temp, r_temp, -1);
472
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
473
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
474
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
475
    tcg_gen_brcond_i32(TCG_COND_EQ, r_temp, tcg_const_i32(0), l1);
476
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
477
    gen_set_label(l1);
478
#ifdef TARGET_SPARC64
479
    {
480
        int l2;
481

    
482
        l2 = gen_new_label();
483
        tcg_gen_xor_tl(r_temp, src1, src2);
484
        tcg_gen_xori_tl(r_temp, r_temp, -1);
485
        tcg_gen_xor_tl(cpu_tmp0, src1, dst);
486
        tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
487
        tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
488
        tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l2);
489
        tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_OVF);
490
        gen_set_label(l2);
491
    }
492
#endif
493
    tcg_gen_discard_tl(r_temp);
494
}
495

    
496
static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
497
{
498
    TCGv r_temp;
499
    int l1;
500

    
501
    l1 = gen_new_label();
502

    
503
    r_temp = tcg_temp_new(TCG_TYPE_TL);
504
    tcg_gen_xor_tl(r_temp, src1, src2);
505
    tcg_gen_xori_tl(r_temp, r_temp, -1);
506
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
507
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
508
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
509
    tcg_gen_brcond_i32(TCG_COND_EQ, r_temp, tcg_const_i32(0), l1);
510
    gen_op_exception(TT_TOVF);
511
    gen_set_label(l1);
512
#ifdef TARGET_SPARC64
513
    {
514
        int l2;
515

    
516
        l2 = gen_new_label();
517
        tcg_gen_xor_tl(r_temp, src1, src2);
518
        tcg_gen_xori_tl(r_temp, r_temp, -1);
519
        tcg_gen_xor_tl(cpu_tmp0, src1, dst);
520
        tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
521
        tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
522
        tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l2);
523
        gen_op_exception(TT_TOVF);
524
        gen_set_label(l2);
525
    }
526
#endif
527
    tcg_gen_discard_tl(r_temp);
528
}
529

    
530
static inline void gen_cc_V_tag(TCGv src1, TCGv src2)
531
{
532
    int l1;
533

    
534
    l1 = gen_new_label();
535
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
536
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
537
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
538
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
539
    gen_set_label(l1);
540
}
541

    
542
static inline void gen_tag_tv(TCGv src1, TCGv src2)
543
{
544
    int l1;
545

    
546
    l1 = gen_new_label();
547
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
548
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
549
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
550
    gen_op_exception(TT_TOVF);
551
    gen_set_label(l1);
552
}
553

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

    
564
static inline void gen_op_addx_T1_T0_cc(void)
565
{
566
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
567
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
568
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
569
    gen_cc_clear();
570
    gen_cc_C_add(cpu_T[0], cpu_cc_src);
571
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
572
    gen_cc_C_add(cpu_T[0], cpu_cc_src);
573
    gen_cc_NZ(cpu_T[0]);
574
    gen_cc_V_add(cpu_T[0], cpu_cc_src, cpu_T[1]);
575
}
576

    
577
static inline void gen_op_tadd_T1_T0_cc(void)
578
{
579
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
580
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
581
    gen_cc_clear();
582
    gen_cc_NZ(cpu_T[0]);
583
    gen_cc_C_add(cpu_T[0], cpu_cc_src);
584
    gen_cc_V_add(cpu_T[0], cpu_cc_src, cpu_T[1]);
585
    gen_cc_V_tag(cpu_cc_src, cpu_T[1]);
586
}
587

    
588
static inline void gen_op_tadd_T1_T0_ccTV(void)
589
{
590
    gen_tag_tv(cpu_T[0], cpu_T[1]);
591
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
592
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
593
    gen_add_tv(cpu_T[0], cpu_cc_src, cpu_T[1]);
594
    gen_cc_clear();
595
    gen_cc_NZ(cpu_T[0]);
596
    gen_cc_C_add(cpu_T[0], cpu_cc_src);
597
}
598

    
599
/* old op:
600
    if (src1 < T1)
601
        env->psr |= PSR_CARRY;
602
*/
603
static inline void gen_cc_C_sub(TCGv src1, TCGv src2)
604
{
605
    int l1;
606

    
607
    l1 = gen_new_label();
608
    tcg_gen_brcond_i32(TCG_COND_GEU, src1, src2, l1);
609
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
610
    gen_set_label(l1);
611
#ifdef TARGET_SPARC64
612
    {
613
        int l2;
614

    
615
        l2 = gen_new_label();
616
        tcg_gen_brcond_tl(TCG_COND_GEU, src1, src2, l2);
617
        tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
618
        gen_set_label(l2);
619
    }
620
#endif
621
}
622

    
623
/* old op:
624
    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
625
        env->psr |= PSR_OVF;
626
*/
627
static inline void gen_cc_V_sub(TCGv dst, TCGv src1, TCGv src2)
628
{
629
    TCGv r_temp;
630
    int l1;
631

    
632
    l1 = gen_new_label();
633

    
634
    r_temp = tcg_temp_new(TCG_TYPE_TL);
635
    tcg_gen_xor_tl(r_temp, src1, src2);
636
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
637
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
638
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
639
    tcg_gen_brcond_i32(TCG_COND_EQ, r_temp, tcg_const_i32(0), l1);
640
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
641
    gen_set_label(l1);
642
#ifdef TARGET_SPARC64
643
    {
644
        int l2;
645

    
646
        l2 = gen_new_label();
647
        tcg_gen_xor_tl(r_temp, src1, src2);
648
        tcg_gen_xor_tl(cpu_tmp0, src1, dst);
649
        tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
650
        tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
651
        tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l2);
652
        tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_OVF);
653
        gen_set_label(l2);
654
    }
655
#endif
656
    tcg_gen_discard_tl(r_temp);
657
}
658

    
659
static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
660
{
661
    TCGv r_temp;
662
    int l1;
663

    
664
    l1 = gen_new_label();
665

    
666
    r_temp = tcg_temp_new(TCG_TYPE_TL);
667
    tcg_gen_xor_tl(r_temp, src1, src2);
668
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
669
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
670
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
671
    tcg_gen_brcond_i32(TCG_COND_EQ, r_temp, tcg_const_i32(0), l1);
672
    gen_op_exception(TT_TOVF);
673
    gen_set_label(l1);
674
#ifdef TARGET_SPARC64
675
    {
676
        int l2;
677

    
678
        l2 = gen_new_label();
679
        tcg_gen_xor_tl(r_temp, src1, src2);
680
        tcg_gen_xor_tl(cpu_tmp0, src1, dst);
681
        tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
682
        tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
683
        tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l2);
684
        gen_op_exception(TT_TOVF);
685
        gen_set_label(l2);
686
    }
687
#endif
688
    tcg_gen_discard_tl(r_temp);
689
}
690

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

    
701
static inline void gen_op_subx_T1_T0_cc(void)
702
{
703
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
704
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
705
    tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
706
    gen_cc_clear();
707
    gen_cc_C_sub(cpu_T[0], cpu_cc_src);
708
    tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
709
    gen_cc_C_sub(cpu_T[0], cpu_cc_src);
710
    gen_cc_NZ(cpu_T[0]);
711
    gen_cc_V_sub(cpu_T[0], cpu_cc_src, cpu_T[1]);
712
}
713

    
714
static inline void gen_op_tsub_T1_T0_cc(void)
715
{
716
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
717
    tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
718
    gen_cc_clear();
719
    gen_cc_NZ(cpu_T[0]);
720
    gen_cc_C_sub(cpu_cc_src, cpu_T[1]);
721
    gen_cc_V_sub(cpu_T[0], cpu_cc_src, cpu_T[1]);
722
    gen_cc_V_tag(cpu_cc_src, cpu_T[1]);
723
}
724

    
725
static inline void gen_op_tsub_T1_T0_ccTV(void)
726
{
727
    gen_tag_tv(cpu_T[0], cpu_T[1]);
728
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
729
    tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
730
    gen_sub_tv(cpu_T[0], cpu_cc_src, cpu_T[1]);
731
    gen_cc_clear();
732
    gen_cc_NZ(cpu_T[0]);
733
    gen_cc_C_sub(cpu_cc_src, cpu_T[1]);
734
}
735

    
736
static inline void gen_op_mulscc_T1_T0(void)
737
{
738
    TCGv r_temp;
739
    int l1, l2;
740

    
741
    l1 = gen_new_label();
742
    l2 = gen_new_label();
743
    r_temp = tcg_temp_new(TCG_TYPE_TL);
744

    
745
    /* old op:
746
    if (!(env->y & 1))
747
        T1 = 0;
748
    */
749
    tcg_gen_ld_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
750
    tcg_gen_andi_i32(r_temp, r_temp, 0x1);
751
    tcg_gen_brcond_i32(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
752
    tcg_gen_mov_tl(cpu_cc_src2, cpu_T[1]);
753
    tcg_gen_br(l2);
754
    gen_set_label(l1);
755
    tcg_gen_movi_tl(cpu_cc_src2, 0);
756
    gen_set_label(l2);
757

    
758
    // b2 = T0 & 1;
759
    // env->y = (b2 << 31) | (env->y >> 1);
760
    tcg_gen_shli_i32(r_temp, cpu_T[0], 31);
761
    tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, y));
762
    tcg_gen_shri_i32(cpu_tmp0, cpu_tmp0, 1);
763
    tcg_gen_or_i32(cpu_tmp0, cpu_tmp0, r_temp);
764
    tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, y));
765

    
766
    // b1 = N ^ V;
767
    gen_mov_reg_N(cpu_tmp0, cpu_psr);
768
    gen_mov_reg_V(r_temp, cpu_psr);
769
    tcg_gen_xor_tl(cpu_tmp0, cpu_tmp0, r_temp);
770

    
771
    // T0 = (b1 << 31) | (T0 >> 1);
772
    // src1 = T0;
773
    tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
774
    tcg_gen_shri_tl(cpu_cc_src, cpu_T[0], 1);
775
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
776

    
777
    /* do addition and update flags */
778
    tcg_gen_add_tl(cpu_T[0], cpu_cc_src, cpu_cc_src2);
779
    tcg_gen_discard_tl(r_temp);
780

    
781
    gen_cc_clear();
782
    gen_cc_NZ(cpu_T[0]);
783
    gen_cc_V_add(cpu_T[0], cpu_cc_src, cpu_cc_src2);
784
    gen_cc_C_add(cpu_T[0], cpu_cc_src);
785
}
786

    
787
static inline void gen_op_umul_T1_T0(void)
788
{
789
    TCGv r_temp, r_temp2;
790

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

    
794
    tcg_gen_extu_i32_i64(r_temp, cpu_T[1]);
795
    tcg_gen_extu_i32_i64(r_temp2, cpu_T[0]);
796
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
797

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

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

    
811
static inline void gen_op_smul_T1_T0(void)
812
{
813
    TCGv r_temp, r_temp2;
814

    
815
    r_temp = tcg_temp_new(TCG_TYPE_I64);
816
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);
817

    
818
    tcg_gen_ext_i32_i64(r_temp, cpu_T[1]);
819
    tcg_gen_ext_i32_i64(r_temp2, cpu_T[0]);
820
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
821

    
822
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
823
    tcg_gen_trunc_i64_i32(r_temp, r_temp);
824
    tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
825
#ifdef TARGET_SPARC64
826
    tcg_gen_mov_i64(cpu_T[0], r_temp2);
827
#else
828
    tcg_gen_trunc_i64_i32(cpu_T[0], r_temp2);
829
#endif
830

    
831
    tcg_gen_discard_i64(r_temp);
832
    tcg_gen_discard_i64(r_temp2);
833
}
834

    
835
static inline void gen_op_udiv_T1_T0(void)
836
{
837
    tcg_gen_helper_1_2(helper_udiv, cpu_T[0], cpu_T[0], cpu_T[1]);
838
}
839

    
840
static inline void gen_op_sdiv_T1_T0(void)
841
{
842
    tcg_gen_helper_1_2(helper_sdiv, cpu_T[0], cpu_T[0], cpu_T[1]);
843
}
844

    
845
#ifdef TARGET_SPARC64
846
static inline void gen_trap_ifdivzero_i64(TCGv divisor)
847
{
848
    int l1;
849

    
850
    l1 = gen_new_label();
851
    tcg_gen_brcond_i64(TCG_COND_NE, divisor, tcg_const_tl(0), l1);
852
    gen_op_exception(TT_DIV_ZERO);
853
    gen_set_label(l1);
854
}
855

    
856
static inline void gen_op_sdivx_T1_T0(void)
857
{
858
    int l1, l2;
859

    
860
    l1 = gen_new_label();
861
    l2 = gen_new_label();
862
    gen_trap_ifdivzero_i64(cpu_T[1]);
863
    tcg_gen_brcond_i64(TCG_COND_NE, cpu_T[0], tcg_const_i64(INT64_MIN), l1);
864
    tcg_gen_brcond_i64(TCG_COND_NE, cpu_T[1], tcg_const_i64(-1), l1);
865
    tcg_gen_movi_i64(cpu_T[0], INT64_MIN);
866
    tcg_gen_br(l2);
867
    gen_set_label(l1);
868
    tcg_gen_div_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
869
    gen_set_label(l2);
870
}
871
#endif
872

    
873
static inline void gen_op_div_cc(void)
874
{
875
    int l1;
876

    
877
    gen_cc_clear();
878
    gen_cc_NZ(cpu_T[0]);
879
    l1 = gen_new_label();
880
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, cc_src2));
881
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
882
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
883
    gen_set_label(l1);
884
}
885

    
886
static inline void gen_op_logic_T0_cc(void)
887
{
888
    gen_cc_clear();
889
    gen_cc_NZ(cpu_T[0]);
890
}
891

    
892
// 1
893
static inline void gen_op_eval_ba(TCGv dst)
894
{
895
    tcg_gen_movi_tl(dst, 1);
896
}
897

    
898
// Z
899
static inline void gen_op_eval_be(TCGv dst, TCGv src)
900
{
901
    gen_mov_reg_Z(dst, src);
902
}
903

    
904
// Z | (N ^ V)
905
static inline void gen_op_eval_ble(TCGv dst, TCGv src)
906
{
907
    gen_mov_reg_N(cpu_tmp0, src);
908
    gen_mov_reg_V(dst, src);
909
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
910
    gen_mov_reg_Z(cpu_tmp0, src);
911
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
912
}
913

    
914
// N ^ V
915
static inline void gen_op_eval_bl(TCGv dst, TCGv src)
916
{
917
    gen_mov_reg_V(cpu_tmp0, src);
918
    gen_mov_reg_N(dst, src);
919
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
920
}
921

    
922
// C | Z
923
static inline void gen_op_eval_bleu(TCGv dst, TCGv src)
924
{
925
    gen_mov_reg_Z(cpu_tmp0, src);
926
    gen_mov_reg_C(dst, src);
927
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
928
}
929

    
930
// C
931
static inline void gen_op_eval_bcs(TCGv dst, TCGv src)
932
{
933
    gen_mov_reg_C(dst, src);
934
}
935

    
936
// V
937
static inline void gen_op_eval_bvs(TCGv dst, TCGv src)
938
{
939
    gen_mov_reg_V(dst, src);
940
}
941

    
942
// 0
943
static inline void gen_op_eval_bn(TCGv dst)
944
{
945
    tcg_gen_movi_tl(dst, 0);
946
}
947

    
948
// N
949
static inline void gen_op_eval_bneg(TCGv dst, TCGv src)
950
{
951
    gen_mov_reg_N(dst, src);
952
}
953

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

    
961
// !(Z | (N ^ V))
962
static inline void gen_op_eval_bg(TCGv dst, TCGv src)
963
{
964
    gen_mov_reg_N(cpu_tmp0, src);
965
    gen_mov_reg_V(dst, src);
966
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
967
    gen_mov_reg_Z(cpu_tmp0, src);
968
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
969
    tcg_gen_xori_tl(dst, dst, 0x1);
970
}
971

    
972
// !(N ^ V)
973
static inline void gen_op_eval_bge(TCGv dst, TCGv src)
974
{
975
    gen_mov_reg_V(cpu_tmp0, src);
976
    gen_mov_reg_N(dst, src);
977
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
978
    tcg_gen_xori_tl(dst, dst, 0x1);
979
}
980

    
981
// !(C | Z)
982
static inline void gen_op_eval_bgu(TCGv dst, TCGv src)
983
{
984
    gen_mov_reg_Z(cpu_tmp0, src);
985
    gen_mov_reg_C(dst, src);
986
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
987
    tcg_gen_xori_tl(dst, dst, 0x1);
988
}
989

    
990
// !C
991
static inline void gen_op_eval_bcc(TCGv dst, TCGv src)
992
{
993
    gen_mov_reg_C(dst, src);
994
    tcg_gen_xori_tl(dst, dst, 0x1);
995
}
996

    
997
// !N
998
static inline void gen_op_eval_bpos(TCGv dst, TCGv src)
999
{
1000
    gen_mov_reg_N(dst, src);
1001
    tcg_gen_xori_tl(dst, dst, 0x1);
1002
}
1003

    
1004
// !V
1005
static inline void gen_op_eval_bvc(TCGv dst, TCGv src)
1006
{
1007
    gen_mov_reg_V(dst, src);
1008
    tcg_gen_xori_tl(dst, dst, 0x1);
1009
}
1010

    
1011
/*
1012
  FPSR bit field FCC1 | FCC0:
1013
   0 =
1014
   1 <
1015
   2 >
1016
   3 unordered
1017
*/
1018
static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src,
1019
                                    unsigned int fcc_offset)
1020
{
1021
    tcg_gen_shri_i32(reg, src, 10 + fcc_offset);
1022
    tcg_gen_andi_tl(reg, reg, 0x1);
1023
}
1024

    
1025
static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
1026
                                    unsigned int fcc_offset)
1027
{
1028
    tcg_gen_shri_i32(reg, src, 11 + fcc_offset);
1029
    tcg_gen_andi_tl(reg, reg, 0x1);
1030
}
1031

    
1032
// !0: FCC0 | FCC1
1033
static inline void gen_op_eval_fbne(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_or_tl(dst, dst, cpu_tmp0);
1039
}
1040

    
1041
// 1 or 2: FCC0 ^ FCC1
1042
static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
1043
                                    unsigned int fcc_offset)
1044
{
1045
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1046
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1047
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1048
}
1049

    
1050
// 1 or 3: FCC0
1051
static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
1052
                                    unsigned int fcc_offset)
1053
{
1054
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1055
}
1056

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

    
1067
// 2 or 3: FCC1
1068
static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
1069
                                    unsigned int fcc_offset)
1070
{
1071
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1072
}
1073

    
1074
// 2: !FCC0 & FCC1
1075
static inline void gen_op_eval_fbg(TCGv dst, TCGv src,
1076
                                    unsigned int fcc_offset)
1077
{
1078
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1079
    tcg_gen_xori_tl(dst, dst, 0x1);
1080
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1081
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1082
}
1083

    
1084
// 3: FCC0 & FCC1
1085
static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
1086
                                    unsigned int fcc_offset)
1087
{
1088
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1089
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1090
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1091
}
1092

    
1093
// 0: !(FCC0 | FCC1)
1094
static inline void gen_op_eval_fbe(TCGv dst, TCGv src,
1095
                                    unsigned int fcc_offset)
1096
{
1097
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1098
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1099
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
1100
    tcg_gen_xori_tl(dst, dst, 0x1);
1101
}
1102

    
1103
// 0 or 3: !(FCC0 ^ FCC1)
1104
static inline void gen_op_eval_fbue(TCGv dst, TCGv src,
1105
                                    unsigned int fcc_offset)
1106
{
1107
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1108
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1109
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1110
    tcg_gen_xori_tl(dst, dst, 0x1);
1111
}
1112

    
1113
// 0 or 2: !FCC0
1114
static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
1115
                                    unsigned int fcc_offset)
1116
{
1117
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1118
    tcg_gen_xori_tl(dst, dst, 0x1);
1119
}
1120

    
1121
// !1: !(FCC0 & !FCC1)
1122
static inline void gen_op_eval_fbuge(TCGv dst, TCGv src,
1123
                                    unsigned int fcc_offset)
1124
{
1125
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1126
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1127
    tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
1128
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1129
    tcg_gen_xori_tl(dst, dst, 0x1);
1130
}
1131

    
1132
// 0 or 1: !FCC1
1133
static inline void gen_op_eval_fble(TCGv dst, TCGv src,
1134
                                    unsigned int fcc_offset)
1135
{
1136
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1137
    tcg_gen_xori_tl(dst, dst, 0x1);
1138
}
1139

    
1140
// !2: !(!FCC0 & FCC1)
1141
static inline void gen_op_eval_fbule(TCGv dst, TCGv src,
1142
                                    unsigned int fcc_offset)
1143
{
1144
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1145
    tcg_gen_xori_tl(dst, dst, 0x1);
1146
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1147
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1148
    tcg_gen_xori_tl(dst, dst, 0x1);
1149
}
1150

    
1151
// !3: !(FCC0 & FCC1)
1152
static inline void gen_op_eval_fbo(TCGv dst, TCGv src,
1153
                                    unsigned int fcc_offset)
1154
{
1155
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1156
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1157
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1158
    tcg_gen_xori_tl(dst, dst, 0x1);
1159
}
1160

    
1161
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
1162
                               target_ulong pc2, TCGv r_cond)
1163
{
1164
    int l1;
1165

    
1166
    l1 = gen_new_label();
1167

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

    
1170
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
1171

    
1172
    gen_set_label(l1);
1173
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
1174
}
1175

    
1176
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
1177
                                target_ulong pc2, TCGv r_cond)
1178
{
1179
    int l1;
1180

    
1181
    l1 = gen_new_label();
1182

    
1183
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1184

    
1185
    gen_goto_tb(dc, 0, pc2, pc1);
1186

    
1187
    gen_set_label(l1);
1188
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
1189
}
1190

    
1191
static inline void gen_branch(DisasContext *dc, target_ulong pc,
1192
                              target_ulong npc)
1193
{
1194
    gen_goto_tb(dc, 0, pc, npc);
1195
}
1196

    
1197
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
1198
                                      TCGv r_cond)
1199
{
1200
    int l1, l2;
1201

    
1202
    l1 = gen_new_label();
1203
    l2 = gen_new_label();
1204

    
1205
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1206

    
1207
    gen_movl_npc_im(npc1);
1208
    tcg_gen_br(l2);
1209

    
1210
    gen_set_label(l1);
1211
    gen_movl_npc_im(npc2);
1212
    gen_set_label(l2);
1213
}
1214

    
1215
/* call this function before using T2 as it may have been set for a jump */
1216
static inline void flush_T2(DisasContext * dc)
1217
{
1218
    if (dc->npc == JUMP_PC) {
1219
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
1220
        dc->npc = DYNAMIC_PC;
1221
    }
1222
}
1223

    
1224
static inline void save_npc(DisasContext * dc)
1225
{
1226
    if (dc->npc == JUMP_PC) {
1227
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
1228
        dc->npc = DYNAMIC_PC;
1229
    } else if (dc->npc != DYNAMIC_PC) {
1230
        gen_movl_npc_im(dc->npc);
1231
    }
1232
}
1233

    
1234
static inline void save_state(DisasContext * dc)
1235
{
1236
    gen_jmp_im(dc->pc);
1237
    save_npc(dc);
1238
}
1239

    
1240
static inline void gen_mov_pc_npc(DisasContext * dc)
1241
{
1242
    if (dc->npc == JUMP_PC) {
1243
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
1244
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1245
        dc->pc = DYNAMIC_PC;
1246
    } else if (dc->npc == DYNAMIC_PC) {
1247
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1248
        dc->pc = DYNAMIC_PC;
1249
    } else {
1250
        dc->pc = dc->npc;
1251
    }
1252
}
1253

    
1254
static inline void gen_op_next_insn(void)
1255
{
1256
    tcg_gen_mov_tl(cpu_pc, cpu_npc);
1257
    tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
1258
}
1259

    
1260
static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond)
1261
{
1262
    TCGv r_src;
1263

    
1264
#ifdef TARGET_SPARC64
1265
    if (cc)
1266
        r_src = cpu_xcc;
1267
    else
1268
        r_src = cpu_psr;
1269
#else
1270
    r_src = cpu_psr;
1271
#endif
1272
    switch (cond) {
1273
    case 0x0:
1274
        gen_op_eval_bn(r_dst);
1275
        break;
1276
    case 0x1:
1277
        gen_op_eval_be(r_dst, r_src);
1278
        break;
1279
    case 0x2:
1280
        gen_op_eval_ble(r_dst, r_src);
1281
        break;
1282
    case 0x3:
1283
        gen_op_eval_bl(r_dst, r_src);
1284
        break;
1285
    case 0x4:
1286
        gen_op_eval_bleu(r_dst, r_src);
1287
        break;
1288
    case 0x5:
1289
        gen_op_eval_bcs(r_dst, r_src);
1290
        break;
1291
    case 0x6:
1292
        gen_op_eval_bneg(r_dst, r_src);
1293
        break;
1294
    case 0x7:
1295
        gen_op_eval_bvs(r_dst, r_src);
1296
        break;
1297
    case 0x8:
1298
        gen_op_eval_ba(r_dst);
1299
        break;
1300
    case 0x9:
1301
        gen_op_eval_bne(r_dst, r_src);
1302
        break;
1303
    case 0xa:
1304
        gen_op_eval_bg(r_dst, r_src);
1305
        break;
1306
    case 0xb:
1307
        gen_op_eval_bge(r_dst, r_src);
1308
        break;
1309
    case 0xc:
1310
        gen_op_eval_bgu(r_dst, r_src);
1311
        break;
1312
    case 0xd:
1313
        gen_op_eval_bcc(r_dst, r_src);
1314
        break;
1315
    case 0xe:
1316
        gen_op_eval_bpos(r_dst, r_src);
1317
        break;
1318
    case 0xf:
1319
        gen_op_eval_bvc(r_dst, r_src);
1320
        break;
1321
    }
1322
}
1323

    
1324
static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
1325
{
1326
    unsigned int offset;
1327

    
1328
    switch (cc) {
1329
    default:
1330
    case 0x0:
1331
        offset = 0;
1332
        break;
1333
    case 0x1:
1334
        offset = 32 - 10;
1335
        break;
1336
    case 0x2:
1337
        offset = 34 - 10;
1338
        break;
1339
    case 0x3:
1340
        offset = 36 - 10;
1341
        break;
1342
    }
1343

    
1344
    switch (cond) {
1345
    case 0x0:
1346
        gen_op_eval_bn(r_dst);
1347
        break;
1348
    case 0x1:
1349
        gen_op_eval_fbne(r_dst, cpu_fsr, offset);
1350
        break;
1351
    case 0x2:
1352
        gen_op_eval_fblg(r_dst, cpu_fsr, offset);
1353
        break;
1354
    case 0x3:
1355
        gen_op_eval_fbul(r_dst, cpu_fsr, offset);
1356
        break;
1357
    case 0x4:
1358
        gen_op_eval_fbl(r_dst, cpu_fsr, offset);
1359
        break;
1360
    case 0x5:
1361
        gen_op_eval_fbug(r_dst, cpu_fsr, offset);
1362
        break;
1363
    case 0x6:
1364
        gen_op_eval_fbg(r_dst, cpu_fsr, offset);
1365
        break;
1366
    case 0x7:
1367
        gen_op_eval_fbu(r_dst, cpu_fsr, offset);
1368
        break;
1369
    case 0x8:
1370
        gen_op_eval_ba(r_dst);
1371
        break;
1372
    case 0x9:
1373
        gen_op_eval_fbe(r_dst, cpu_fsr, offset);
1374
        break;
1375
    case 0xa:
1376
        gen_op_eval_fbue(r_dst, cpu_fsr, offset);
1377
        break;
1378
    case 0xb:
1379
        gen_op_eval_fbge(r_dst, cpu_fsr, offset);
1380
        break;
1381
    case 0xc:
1382
        gen_op_eval_fbuge(r_dst, cpu_fsr, offset);
1383
        break;
1384
    case 0xd:
1385
        gen_op_eval_fble(r_dst, cpu_fsr, offset);
1386
        break;
1387
    case 0xe:
1388
        gen_op_eval_fbule(r_dst, cpu_fsr, offset);
1389
        break;
1390
    case 0xf:
1391
        gen_op_eval_fbo(r_dst, cpu_fsr, offset);
1392
        break;
1393
    }
1394
}
1395

    
1396
#ifdef TARGET_SPARC64
1397
// Inverted logic
1398
static const int gen_tcg_cond_reg[8] = {
1399
    -1,
1400
    TCG_COND_NE,
1401
    TCG_COND_GT,
1402
    TCG_COND_GE,
1403
    -1,
1404
    TCG_COND_EQ,
1405
    TCG_COND_LE,
1406
    TCG_COND_LT,
1407
};
1408

    
1409
static inline void gen_cond_reg(TCGv r_dst, int cond)
1410
{
1411
    int l1;
1412

    
1413
    l1 = gen_new_label();
1414
    tcg_gen_movi_tl(r_dst, 0);
1415
    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0], tcg_const_tl(0), l1);
1416
    tcg_gen_movi_tl(r_dst, 1);
1417
    gen_set_label(l1);
1418
}
1419
#endif
1420

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

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

    
1460
/* XXX: potentially incorrect if dynamic npc */
1461
static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
1462
{
1463
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1464
    target_ulong target = dc->pc + offset;
1465

    
1466
    if (cond == 0x0) {
1467
        /* unconditional not taken */
1468
        if (a) {
1469
            dc->pc = dc->npc + 4;
1470
            dc->npc = dc->pc + 4;
1471
        } else {
1472
            dc->pc = dc->npc;
1473
            dc->npc = dc->pc + 4;
1474
        }
1475
    } else if (cond == 0x8) {
1476
        /* unconditional taken */
1477
        if (a) {
1478
            dc->pc = target;
1479
            dc->npc = dc->pc + 4;
1480
        } else {
1481
            dc->pc = dc->npc;
1482
            dc->npc = target;
1483
        }
1484
    } else {
1485
        flush_T2(dc);
1486
        gen_fcond(cpu_T[2], cc, cond);
1487
        if (a) {
1488
            gen_branch_a(dc, target, dc->npc, cpu_T[2]);
1489
            dc->is_br = 1;
1490
        } else {
1491
            dc->pc = dc->npc;
1492
            dc->jump_pc[0] = target;
1493
            dc->jump_pc[1] = dc->npc + 4;
1494
            dc->npc = JUMP_PC;
1495
        }
1496
    }
1497
}
1498

    
1499
#ifdef TARGET_SPARC64
1500
/* XXX: potentially incorrect if dynamic npc */
1501
static void do_branch_reg(DisasContext * dc, int32_t offset, uint32_t insn)
1502
{
1503
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1504
    target_ulong target = dc->pc + offset;
1505

    
1506
    flush_T2(dc);
1507
    gen_cond_reg(cpu_T[2], cond);
1508
    if (a) {
1509
        gen_branch_a(dc, target, dc->npc, cpu_T[2]);
1510
        dc->is_br = 1;
1511
    } else {
1512
        dc->pc = dc->npc;
1513
        dc->jump_pc[0] = target;
1514
        dc->jump_pc[1] = dc->npc + 4;
1515
        dc->npc = JUMP_PC;
1516
    }
1517
}
1518

    
1519
static GenOpFunc * const gen_fcmps[4] = {
1520
    helper_fcmps,
1521
    helper_fcmps_fcc1,
1522
    helper_fcmps_fcc2,
1523
    helper_fcmps_fcc3,
1524
};
1525

    
1526
static GenOpFunc * const gen_fcmpd[4] = {
1527
    helper_fcmpd,
1528
    helper_fcmpd_fcc1,
1529
    helper_fcmpd_fcc2,
1530
    helper_fcmpd_fcc3,
1531
};
1532

    
1533
#if defined(CONFIG_USER_ONLY)
1534
static GenOpFunc * const gen_fcmpq[4] = {
1535
    helper_fcmpq,
1536
    helper_fcmpq_fcc1,
1537
    helper_fcmpq_fcc2,
1538
    helper_fcmpq_fcc3,
1539
};
1540
#endif
1541

    
1542
static GenOpFunc * const gen_fcmpes[4] = {
1543
    helper_fcmpes,
1544
    helper_fcmpes_fcc1,
1545
    helper_fcmpes_fcc2,
1546
    helper_fcmpes_fcc3,
1547
};
1548

    
1549
static GenOpFunc * const gen_fcmped[4] = {
1550
    helper_fcmped,
1551
    helper_fcmped_fcc1,
1552
    helper_fcmped_fcc2,
1553
    helper_fcmped_fcc3,
1554
};
1555

    
1556
#if defined(CONFIG_USER_ONLY)
1557
static GenOpFunc * const gen_fcmpeq[4] = {
1558
    helper_fcmpeq,
1559
    helper_fcmpeq_fcc1,
1560
    helper_fcmpeq_fcc2,
1561
    helper_fcmpeq_fcc3,
1562
};
1563
#endif
1564

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

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

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

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

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

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

    
1599
#else
1600

    
1601
static inline void gen_op_fcmps(int fccno)
1602
{
1603
    tcg_gen_helper_0_0(helper_fcmps);
1604
}
1605

    
1606
static inline void gen_op_fcmpd(int fccno)
1607
{
1608
    tcg_gen_helper_0_0(helper_fcmpd);
1609
}
1610

    
1611
#if defined(CONFIG_USER_ONLY)
1612
static inline void gen_op_fcmpq(int fccno)
1613
{
1614
    tcg_gen_helper_0_0(helper_fcmpq);
1615
}
1616
#endif
1617

    
1618
static inline void gen_op_fcmpes(int fccno)
1619
{
1620
    tcg_gen_helper_0_0(helper_fcmpes);
1621
}
1622

    
1623
static inline void gen_op_fcmped(int fccno)
1624
{
1625
    tcg_gen_helper_0_0(helper_fcmped);
1626
}
1627

    
1628
#if defined(CONFIG_USER_ONLY)
1629
static inline void gen_op_fcmpeq(int fccno)
1630
{
1631
    tcg_gen_helper_0_0(helper_fcmpeq);
1632
}
1633
#endif
1634

    
1635
#endif
1636

    
1637
static inline void gen_op_fpexception_im(int fsr_flags)
1638
{
1639
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~FSR_FTT_MASK);
1640
    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
1641
    gen_op_exception(TT_FP_EXCP);
1642
}
1643

    
1644
static int gen_trap_ifnofpu(DisasContext * dc)
1645
{
1646
#if !defined(CONFIG_USER_ONLY)
1647
    if (!dc->fpu_enabled) {
1648
        save_state(dc);
1649
        gen_op_exception(TT_NFPU_INSN);
1650
        dc->is_br = 1;
1651
        return 1;
1652
    }
1653
#endif
1654
    return 0;
1655
}
1656

    
1657
static inline void gen_op_clear_ieee_excp_and_FTT(void)
1658
{
1659
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~(FSR_FTT_MASK | FSR_CEXC_MASK));
1660
}
1661

    
1662
static inline void gen_clear_float_exceptions(void)
1663
{
1664
    tcg_gen_helper_0_0(helper_clear_float_exceptions);
1665
}
1666

    
1667
/* asi moves */
1668
#ifdef TARGET_SPARC64
1669
static inline TCGv gen_get_asi(int insn, TCGv r_addr)
1670
{
1671
    int asi, offset;
1672
    TCGv r_asi;
1673

    
1674
    if (IS_IMM) {
1675
        r_asi = tcg_temp_new(TCG_TYPE_I32);
1676
        offset = GET_FIELD(insn, 25, 31);
1677
        tcg_gen_addi_tl(r_addr, r_addr, offset);
1678
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
1679
    } else {
1680
        asi = GET_FIELD(insn, 19, 26);
1681
        r_asi = tcg_const_i32(asi);
1682
    }
1683
    return r_asi;
1684
}
1685

    
1686
static inline void gen_ld_asi(int insn, int size, int sign)
1687
{
1688
    TCGv r_asi;
1689

    
1690
    r_asi = gen_get_asi(insn, cpu_T[0]);
1691
    tcg_gen_helper_1_4(helper_ld_asi, cpu_T[1], cpu_T[0], r_asi,
1692
                       tcg_const_i32(size), tcg_const_i32(sign));
1693
    tcg_gen_discard_i32(r_asi);
1694
}
1695

    
1696
static inline void gen_st_asi(int insn, int size)
1697
{
1698
    TCGv r_asi;
1699

    
1700
    r_asi = gen_get_asi(insn, cpu_T[0]);
1701
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], r_asi,
1702
                       tcg_const_i32(size));
1703
    tcg_gen_discard_i32(r_asi);
1704
}
1705

    
1706
static inline void gen_ldf_asi(int insn, int size, int rd)
1707
{
1708
    TCGv r_asi;
1709

    
1710
    r_asi = gen_get_asi(insn, cpu_T[0]);
1711
    tcg_gen_helper_0_4(helper_ldf_asi, cpu_T[0], r_asi, tcg_const_i32(size),
1712
                       tcg_const_i32(rd));
1713
    tcg_gen_discard_i32(r_asi);
1714
}
1715

    
1716
static inline void gen_stf_asi(int insn, int size, int rd)
1717
{
1718
    TCGv r_asi;
1719

    
1720
    r_asi = gen_get_asi(insn, cpu_T[0]);
1721
    tcg_gen_helper_0_4(helper_stf_asi, cpu_T[0], r_asi, tcg_const_i32(size),
1722
                       tcg_const_i32(rd));
1723
    tcg_gen_discard_i32(r_asi);
1724
}
1725

    
1726
static inline void gen_swap_asi(int insn)
1727
{
1728
    TCGv r_temp, r_asi;
1729

    
1730
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1731
    r_asi = gen_get_asi(insn, cpu_T[0]);
1732
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, cpu_T[0], r_asi,
1733
                       tcg_const_i32(4), tcg_const_i32(0));
1734
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_temp, r_asi,
1735
                       tcg_const_i32(4));
1736
    tcg_gen_mov_i32(cpu_T[1], r_temp);
1737
    tcg_gen_discard_i32(r_asi);
1738
    tcg_gen_discard_i32(r_temp);
1739
}
1740

    
1741
static inline void gen_ldda_asi(int insn)
1742
{
1743
    TCGv r_dword, r_asi;
1744

    
1745
    r_dword = tcg_temp_new(TCG_TYPE_I64);
1746
    r_asi = gen_get_asi(insn, cpu_T[0]);
1747
    tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], r_asi,
1748
                       tcg_const_i32(8), tcg_const_i32(0));
1749
    tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
1750
    tcg_gen_shri_i64(r_dword, r_dword, 32);
1751
    tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
1752
    tcg_gen_discard_i32(r_asi);
1753
    tcg_gen_discard_i64(r_dword);
1754
}
1755

    
1756
static inline void gen_stda_asi(int insn, int rd)
1757
{
1758
    TCGv r_dword, r_temp, r_asi;
1759

    
1760
    r_dword = tcg_temp_new(TCG_TYPE_I64);
1761
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1762
    gen_movl_reg_TN(rd + 1, r_temp);
1763
    tcg_gen_helper_1_2(helper_pack64, r_dword, cpu_T[1],
1764
                       r_temp);
1765
    r_asi = gen_get_asi(insn, cpu_T[0]);
1766
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, r_asi,
1767
                       tcg_const_i32(8));
1768
    tcg_gen_discard_i32(r_asi);
1769
    tcg_gen_discard_i32(r_temp);
1770
    tcg_gen_discard_i64(r_dword);
1771
}
1772

    
1773
static inline void gen_cas_asi(int insn, int rd)
1774
{
1775
    TCGv r_val1, r_asi;
1776

    
1777
    r_val1 = tcg_temp_new(TCG_TYPE_I32);
1778
    gen_movl_reg_TN(rd, r_val1);
1779
    r_asi = gen_get_asi(insn, cpu_T[0]);
1780
    tcg_gen_helper_1_4(helper_cas_asi, cpu_T[1], cpu_T[0], r_val1, cpu_T[1],
1781
                       r_asi);
1782
    tcg_gen_discard_i32(r_asi);
1783
    tcg_gen_discard_i32(r_val1);
1784
}
1785

    
1786
static inline void gen_casx_asi(int insn, int rd)
1787
{
1788
    TCGv r_val1, r_asi;
1789

    
1790
    r_val1 = tcg_temp_new(TCG_TYPE_I64);
1791
    gen_movl_reg_TN(rd, r_val1);
1792
    r_asi = gen_get_asi(insn, cpu_T[0]);
1793
    tcg_gen_helper_1_4(helper_casx_asi, cpu_T[1], cpu_T[0], r_val1, cpu_T[1],
1794
                       r_asi);
1795
    tcg_gen_discard_i32(r_asi);
1796
    tcg_gen_discard_i32(r_val1);
1797
}
1798

    
1799
#elif !defined(CONFIG_USER_ONLY)
1800

    
1801
static inline void gen_ld_asi(int insn, int size, int sign)
1802
{
1803
    int asi;
1804
    TCGv r_dword;
1805

    
1806
    r_dword = tcg_temp_new(TCG_TYPE_I64);
1807
    asi = GET_FIELD(insn, 19, 26);
1808
    tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], tcg_const_i32(asi),
1809
                       tcg_const_i32(size), tcg_const_i32(sign));
1810
    tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
1811
    tcg_gen_discard_i64(r_dword);
1812
}
1813

    
1814
static inline void gen_st_asi(int insn, int size)
1815
{
1816
    int asi;
1817
    TCGv r_dword;
1818

    
1819
    r_dword = tcg_temp_new(TCG_TYPE_I64);
1820
    tcg_gen_extu_i32_i64(r_dword, cpu_T[1]);
1821
    asi = GET_FIELD(insn, 19, 26);
1822
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, tcg_const_i32(asi),
1823
                       tcg_const_i32(size));
1824
    tcg_gen_discard_i64(r_dword);
1825
}
1826

    
1827
static inline void gen_swap_asi(int insn)
1828
{
1829
    int asi;
1830
    TCGv r_temp;
1831

    
1832
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1833
    asi = GET_FIELD(insn, 19, 26);
1834
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, cpu_T[0], tcg_const_i32(asi),
1835
                       tcg_const_i32(4), tcg_const_i32(0));
1836
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], tcg_const_i32(asi),
1837
                       tcg_const_i32(4));
1838
    tcg_gen_mov_i32(cpu_T[1], r_temp);
1839
    tcg_gen_discard_i32(r_temp);
1840
}
1841

    
1842
static inline void gen_ldda_asi(int insn)
1843
{
1844
    int asi;
1845
    TCGv r_dword;
1846

    
1847
    r_dword = tcg_temp_new(TCG_TYPE_I64);
1848
    asi = GET_FIELD(insn, 19, 26);
1849
    tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], tcg_const_i32(asi),
1850
                       tcg_const_i32(8), tcg_const_i32(0));
1851
    tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
1852
    tcg_gen_shri_i64(r_dword, r_dword, 32);
1853
    tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
1854
    tcg_gen_discard_i64(r_dword);
1855
}
1856

    
1857
static inline void gen_stda_asi(int insn, int rd)
1858
{
1859
    int asi;
1860
    TCGv r_dword, r_temp;
1861

    
1862
    r_dword = tcg_temp_new(TCG_TYPE_I64);
1863
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1864
    gen_movl_reg_TN(rd + 1, r_temp);
1865
    tcg_gen_helper_1_2(helper_pack64, r_dword, cpu_T[1], r_temp);
1866
    asi = GET_FIELD(insn, 19, 26);
1867
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, tcg_const_i32(asi),
1868
                       tcg_const_i32(8));
1869
    tcg_gen_discard_i64(r_dword);
1870
}
1871
#endif
1872

    
1873
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1874
static inline void gen_ldstub_asi(int insn)
1875
{
1876
    int asi;
1877

    
1878
    gen_ld_asi(insn, 1, 0);
1879

    
1880
    asi = GET_FIELD(insn, 19, 26);
1881
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], tcg_const_i64(0xff),
1882
                       tcg_const_i32(asi), tcg_const_i32(1));
1883
}
1884
#endif
1885

    
1886
/* before an instruction, dc->pc must be static */
1887
static void disas_sparc_insn(DisasContext * dc)
1888
{
1889
    unsigned int insn, opc, rs1, rs2, rd;
1890

    
1891
    insn = ldl_code(dc->pc);
1892
    opc = GET_FIELD(insn, 0, 1);
1893

    
1894
    rd = GET_FIELD(insn, 2, 6);
1895
    switch (opc) {
1896
    case 0:                     /* branches/sethi */
1897
        {
1898
            unsigned int xop = GET_FIELD(insn, 7, 9);
1899
            int32_t target;
1900
            switch (xop) {
1901
#ifdef TARGET_SPARC64
1902
            case 0x1:           /* V9 BPcc */
1903
                {
1904
                    int cc;
1905

    
1906
                    target = GET_FIELD_SP(insn, 0, 18);
1907
                    target = sign_extend(target, 18);
1908
                    target <<= 2;
1909
                    cc = GET_FIELD_SP(insn, 20, 21);
1910
                    if (cc == 0)
1911
                        do_branch(dc, target, insn, 0);
1912
                    else if (cc == 2)
1913
                        do_branch(dc, target, insn, 1);
1914
                    else
1915
                        goto illegal_insn;
1916
                    goto jmp_insn;
1917
                }
1918
            case 0x3:           /* V9 BPr */
1919
                {
1920
                    target = GET_FIELD_SP(insn, 0, 13) |
1921
                        (GET_FIELD_SP(insn, 20, 21) << 14);
1922
                    target = sign_extend(target, 16);
1923
                    target <<= 2;
1924
                    rs1 = GET_FIELD(insn, 13, 17);
1925
                    gen_movl_reg_T0(rs1);
1926
                    do_branch_reg(dc, target, insn);
1927
                    goto jmp_insn;
1928
                }
1929
            case 0x5:           /* V9 FBPcc */
1930
                {
1931
                    int cc = GET_FIELD_SP(insn, 20, 21);
1932
                    if (gen_trap_ifnofpu(dc))
1933
                        goto jmp_insn;
1934
                    target = GET_FIELD_SP(insn, 0, 18);
1935
                    target = sign_extend(target, 19);
1936
                    target <<= 2;
1937
                    do_fbranch(dc, target, insn, cc);
1938
                    goto jmp_insn;
1939
                }
1940
#else
1941
            case 0x7:           /* CBN+x */
1942
                {
1943
                    goto ncp_insn;
1944
                }
1945
#endif
1946
            case 0x2:           /* BN+x */
1947
                {
1948
                    target = GET_FIELD(insn, 10, 31);
1949
                    target = sign_extend(target, 22);
1950
                    target <<= 2;
1951
                    do_branch(dc, target, insn, 0);
1952
                    goto jmp_insn;
1953
                }
1954
            case 0x6:           /* FBN+x */
1955
                {
1956
                    if (gen_trap_ifnofpu(dc))
1957
                        goto jmp_insn;
1958
                    target = GET_FIELD(insn, 10, 31);
1959
                    target = sign_extend(target, 22);
1960
                    target <<= 2;
1961
                    do_fbranch(dc, target, insn, 0);
1962
                    goto jmp_insn;
1963
                }
1964
            case 0x4:           /* SETHI */
1965
#define OPTIM
1966
#if defined(OPTIM)
1967
                if (rd) { // nop
1968
#endif
1969
                    uint32_t value = GET_FIELD(insn, 10, 31);
1970
                    tcg_gen_movi_tl(cpu_T[0], value << 10);
1971
                    gen_movl_T0_reg(rd);
1972
#if defined(OPTIM)
1973
                }
1974
#endif
1975
                break;
1976
            case 0x0:           /* UNIMPL */
1977
            default:
1978
                goto illegal_insn;
1979
            }
1980
            break;
1981
        }
1982
        break;
1983
    case 1:
1984
        /*CALL*/ {
1985
            target_long target = GET_FIELDs(insn, 2, 31) << 2;
1986

    
1987
            gen_movl_TN_reg(15, tcg_const_tl(dc->pc));
1988
            target += dc->pc;
1989
            gen_mov_pc_npc(dc);
1990
            dc->npc = target;
1991
        }
1992
        goto jmp_insn;
1993
    case 2:                     /* FPU & Logical Operations */
1994
        {
1995
            unsigned int xop = GET_FIELD(insn, 7, 12);
1996
            if (xop == 0x3a) {  /* generate trap */
1997
                int cond;
1998

    
1999
                rs1 = GET_FIELD(insn, 13, 17);
2000
                gen_movl_reg_T0(rs1);
2001
                if (IS_IMM) {
2002
                    rs2 = GET_FIELD(insn, 25, 31);
2003
                    tcg_gen_addi_tl(cpu_T[0], cpu_T[0], rs2);
2004
                } else {
2005
                    rs2 = GET_FIELD(insn, 27, 31);
2006
#if defined(OPTIM)
2007
                    if (rs2 != 0) {
2008
#endif
2009
                        gen_movl_reg_T1(rs2);
2010
                        gen_op_add_T1_T0();
2011
#if defined(OPTIM)
2012
                    }
2013
#endif
2014
                }
2015
                cond = GET_FIELD(insn, 3, 6);
2016
                if (cond == 0x8) {
2017
                    save_state(dc);
2018
                    tcg_gen_helper_0_1(helper_trap, cpu_T[0]);
2019
                } else if (cond != 0) {
2020
                    TCGv r_cond = tcg_temp_new(TCG_TYPE_TL);
2021
#ifdef TARGET_SPARC64
2022
                    /* V9 icc/xcc */
2023
                    int cc = GET_FIELD_SP(insn, 11, 12);
2024

    
2025
                    save_state(dc);
2026
                    if (cc == 0)
2027
                        gen_cond(r_cond, 0, cond);
2028
                    else if (cc == 2)
2029
                        gen_cond(r_cond, 1, cond);
2030
                    else
2031
                        goto illegal_insn;
2032
#else
2033
                    save_state(dc);
2034
                    gen_cond(r_cond, 0, cond);
2035
#endif
2036
                    tcg_gen_helper_0_2(helper_trapcc, cpu_T[0], r_cond);
2037
                    tcg_gen_discard_tl(r_cond);
2038
                }
2039
                gen_op_next_insn();
2040
                tcg_gen_exit_tb(0);
2041
                dc->is_br = 1;
2042
                goto jmp_insn;
2043
            } else if (xop == 0x28) {
2044
                rs1 = GET_FIELD(insn, 13, 17);
2045
                switch(rs1) {
2046
                case 0: /* rdy */
2047
#ifndef TARGET_SPARC64
2048
                case 0x01 ... 0x0e: /* undefined in the SPARCv8
2049
                                       manual, rdy on the microSPARC
2050
                                       II */
2051
                case 0x0f:          /* stbar in the SPARCv8 manual,
2052
                                       rdy on the microSPARC II */
2053
                case 0x10 ... 0x1f: /* implementation-dependent in the
2054
                                       SPARCv8 manual, rdy on the
2055
                                       microSPARC II */
2056
#endif
2057
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, y));
2058
                    gen_movl_T0_reg(rd);
2059
                    break;
2060
#ifdef TARGET_SPARC64
2061
                case 0x2: /* V9 rdccr */
2062
                    tcg_gen_helper_1_0(helper_rdccr, cpu_T[0]);
2063
                    gen_movl_T0_reg(rd);
2064
                    break;
2065
                case 0x3: /* V9 rdasi */
2066
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, asi));
2067
                    gen_movl_T0_reg(rd);
2068
                    break;
2069
                case 0x4: /* V9 rdtick */
2070
                    {
2071
                        TCGv r_tickptr;
2072

    
2073
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2074
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2075
                                       offsetof(CPUState, tick));
2076
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_T[0],
2077
                                           r_tickptr);
2078
                        gen_movl_T0_reg(rd);
2079
                        tcg_gen_discard_ptr(r_tickptr);
2080
                    }
2081
                    break;
2082
                case 0x5: /* V9 rdpc */
2083
                    tcg_gen_movi_tl(cpu_T[0], dc->pc);
2084
                    gen_movl_T0_reg(rd);
2085
                    break;
2086
                case 0x6: /* V9 rdfprs */
2087
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, fprs));
2088
                    gen_movl_T0_reg(rd);
2089
                    break;
2090
                case 0xf: /* V9 membar */
2091
                    break; /* no effect */
2092
                case 0x13: /* Graphics Status */
2093
                    if (gen_trap_ifnofpu(dc))
2094
                        goto jmp_insn;
2095
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, gsr));
2096
                    gen_movl_T0_reg(rd);
2097
                    break;
2098
                case 0x17: /* Tick compare */
2099
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, tick_cmpr));
2100
                    gen_movl_T0_reg(rd);
2101
                    break;
2102
                case 0x18: /* System tick */
2103
                    {
2104
                        TCGv r_tickptr;
2105

    
2106
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2107
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2108
                                       offsetof(CPUState, stick));
2109
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_T[0],
2110
                                           r_tickptr);
2111
                        gen_movl_T0_reg(rd);
2112
                        tcg_gen_discard_ptr(r_tickptr);
2113
                    }
2114
                    break;
2115
                case 0x19: /* System tick compare */
2116
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, stick_cmpr));
2117
                    gen_movl_T0_reg(rd);
2118
                    break;
2119
                case 0x10: /* Performance Control */
2120
                case 0x11: /* Performance Instrumentation Counter */
2121
                case 0x12: /* Dispatch Control */
2122
                case 0x14: /* Softint set, WO */
2123
                case 0x15: /* Softint clear, WO */
2124
                case 0x16: /* Softint write */
2125
#endif
2126
                default:
2127
                    goto illegal_insn;
2128
                }
2129
#if !defined(CONFIG_USER_ONLY)
2130
            } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
2131
#ifndef TARGET_SPARC64
2132
                if (!supervisor(dc))
2133
                    goto priv_insn;
2134
                tcg_gen_helper_1_0(helper_rdpsr, cpu_T[0]);
2135
#else
2136
                if (!hypervisor(dc))
2137
                    goto priv_insn;
2138
                rs1 = GET_FIELD(insn, 13, 17);
2139
                switch (rs1) {
2140
                case 0: // hpstate
2141
                    // gen_op_rdhpstate();
2142
                    break;
2143
                case 1: // htstate
2144
                    // gen_op_rdhtstate();
2145
                    break;
2146
                case 3: // hintp
2147
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, hintp));
2148
                    break;
2149
                case 5: // htba
2150
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, htba));
2151
                    break;
2152
                case 6: // hver
2153
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, hver));
2154
                    break;
2155
                case 31: // hstick_cmpr
2156
                    gen_op_movl_env_T0(offsetof(CPUSPARCState, hstick_cmpr));
2157
                    break;
2158
                default:
2159
                    goto illegal_insn;
2160
                }
2161
#endif
2162
                gen_movl_T0_reg(rd);
2163
                break;
2164
            } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
2165
                if (!supervisor(dc))
2166
                    goto priv_insn;
2167
#ifdef TARGET_SPARC64
2168
                rs1 = GET_FIELD(insn, 13, 17);
2169
                switch (rs1) {
2170
                case 0: // tpc
2171
                    {
2172
                        TCGv r_tsptr;
2173

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

    
2186
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2187
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2188
                                       offsetof(CPUState, tsptr));
2189
                        tcg_gen_ld_tl(cpu_T[0], r_tsptr,
2190
                                      offsetof(trap_state, tnpc));
2191
                        tcg_gen_discard_ptr(r_tsptr);
2192
                    }
2193
                    break;
2194
                case 2: // tstate
2195
                    {
2196
                        TCGv r_tsptr;
2197

    
2198
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2199
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2200
                                       offsetof(CPUState, tsptr));
2201
                        tcg_gen_ld_tl(cpu_T[0], r_tsptr,
2202
                                      offsetof(trap_state, tstate));
2203
                        tcg_gen_discard_ptr(r_tsptr);
2204
                    }
2205
                    break;
2206
                case 3: // tt
2207
                    {
2208
                        TCGv r_tsptr;
2209

    
2210
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2211
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2212
                                       offsetof(CPUState, tsptr));
2213
                        tcg_gen_ld_i32(cpu_T[0], r_tsptr,
2214
                                       offsetof(trap_state, tt));
2215
                        tcg_gen_discard_ptr(r_tsptr);
2216
                    }
2217
                    break;
2218
                case 4: // tick
2219
                    {
2220
                        TCGv r_tickptr;
2221

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

    
2678
                    l1 = gen_new_label();
2679
                    cond = GET_FIELD_SP(insn, 14, 17);
2680
                    rs1 = GET_FIELD(insn, 13, 17);
2681
                    gen_movl_reg_T0(rs1);
2682
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0],
2683
                                      tcg_const_tl(0), l1);
2684
                    gen_op_load_fpr_FT0(rs2);
2685
                    gen_op_store_FT0_fpr(rd);
2686
                    gen_set_label(l1);
2687
                    break;
2688
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
2689
                    int l1;
2690

    
2691
                    l1 = gen_new_label();
2692
                    cond = GET_FIELD_SP(insn, 14, 17);
2693
                    rs1 = GET_FIELD(insn, 13, 17);
2694
                    gen_movl_reg_T0(rs1);
2695
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0],
2696
                                      tcg_const_tl(0), l1);
2697
                    gen_op_load_fpr_DT0(DFPREG(rs2));
2698
                    gen_op_store_DT0_fpr(DFPREG(rd));
2699
                    gen_set_label(l1);
2700
                    break;
2701
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
2702
#if defined(CONFIG_USER_ONLY)
2703
                    int l1;
2704

    
2705
                    l1 = gen_new_label();
2706
                    cond = GET_FIELD_SP(insn, 14, 17);
2707
                    rs1 = GET_FIELD(insn, 13, 17);
2708
                    gen_movl_reg_T0(rs1);
2709
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0],
2710
                                      tcg_const_tl(0), l1);
2711
                    gen_op_load_fpr_QT0(QFPREG(rs2));
2712
                    gen_op_store_QT0_fpr(QFPREG(rd));
2713
                    gen_set_label(l1);
2714
                    break;
2715
#else
2716
                    goto nfpu_insn;
2717
#endif
2718
                }
2719
#endif
2720
                switch (xop) {
2721
#ifdef TARGET_SPARC64
2722
#define FMOVCC(size_FDQ, fcc)                                           \
2723
                    {                                                   \
2724
                        TCGv r_cond;                                    \
2725
                        int l1;                                         \
2726
                                                                        \
2727
                        l1 = gen_new_label();                           \
2728
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2729
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2730
                        gen_fcond(r_cond, fcc, cond);                   \
2731
                        tcg_gen_brcond_tl(TCG_COND_EQ, r_cond,          \
2732
                                          tcg_const_tl(0), l1);         \
2733
                        glue(glue(gen_op_load_fpr_, size_FDQ), T0)(glue(size_FDQ, FPREG(rs2))); \
2734
                        glue(glue(gen_op_store_, size_FDQ), T0_fpr)(glue(size_FDQ, FPREG(rd))); \
2735
                        gen_set_label(l1);                              \
2736
                        tcg_gen_discard_tl(r_cond);                     \
2737
                    }
2738
                    case 0x001: /* V9 fmovscc %fcc0 */
2739
                        FMOVCC(F, 0);
2740
                        break;
2741
                    case 0x002: /* V9 fmovdcc %fcc0 */
2742
                        FMOVCC(D, 0);
2743
                        break;
2744
                    case 0x003: /* V9 fmovqcc %fcc0 */
2745
#if defined(CONFIG_USER_ONLY)
2746
                        FMOVCC(Q, 0);
2747
                        break;
2748
#else
2749
                        goto nfpu_insn;
2750
#endif
2751
                    case 0x041: /* V9 fmovscc %fcc1 */
2752
                        FMOVCC(F, 1);
2753
                        break;
2754
                    case 0x042: /* V9 fmovdcc %fcc1 */
2755
                        FMOVCC(D, 1);
2756
                        break;
2757
                    case 0x043: /* V9 fmovqcc %fcc1 */
2758
#if defined(CONFIG_USER_ONLY)
2759
                        FMOVCC(Q, 1);
2760
                        break;
2761
#else
2762
                        goto nfpu_insn;
2763
#endif
2764
                    case 0x081: /* V9 fmovscc %fcc2 */
2765
                        FMOVCC(F, 2);
2766
                        break;
2767
                    case 0x082: /* V9 fmovdcc %fcc2 */
2768
                        FMOVCC(D, 2);
2769
                        break;
2770
                    case 0x083: /* V9 fmovqcc %fcc2 */
2771
#if defined(CONFIG_USER_ONLY)
2772
                        FMOVCC(Q, 2);
2773
                        break;
2774
#else
2775
                        goto nfpu_insn;
2776
#endif
2777
                    case 0x0c1: /* V9 fmovscc %fcc3 */
2778
                        FMOVCC(F, 3);
2779
                        break;
2780
                    case 0x0c2: /* V9 fmovdcc %fcc3 */
2781
                        FMOVCC(D, 3);
2782
                        break;
2783
                    case 0x0c3: /* V9 fmovqcc %fcc3 */
2784
#if defined(CONFIG_USER_ONLY)
2785
                        FMOVCC(Q, 3);
2786
                        break;
2787
#else
2788
                        goto nfpu_insn;
2789
#endif
2790
#undef FMOVCC
2791
#define FMOVCC(size_FDQ, icc)                                           \
2792
                    {                                                   \
2793
                        TCGv r_cond;                                    \
2794
                        int l1;                                         \
2795
                                                                        \
2796
                        l1 = gen_new_label();                           \
2797
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2798
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2799
                        gen_cond(r_cond, icc, cond);                    \
2800
                        tcg_gen_brcond_tl(TCG_COND_EQ, r_cond,          \
2801
                                          tcg_const_tl(0), l1);         \
2802
                        glue(glue(gen_op_load_fpr_, size_FDQ), T0)(glue(size_FDQ, FPREG(rs2))); \
2803
                        glue(glue(gen_op_store_, size_FDQ), T0_fpr)(glue(size_FDQ, FPREG(rd))); \
2804
                        gen_set_label(l1);                              \
2805
                        tcg_gen_discard_tl(r_cond);                     \
2806
                    }
2807

    
2808
                    case 0x101: /* V9 fmovscc %icc */
2809
                        FMOVCC(F, 0);
2810
                        break;
2811
                    case 0x102: /* V9 fmovdcc %icc */
2812
                        FMOVCC(D, 0);
2813
                    case 0x103: /* V9 fmovqcc %icc */
2814
#if defined(CONFIG_USER_ONLY)
2815
                        FMOVCC(D, 0);
2816
                        break;
2817
#else
2818
                        goto nfpu_insn;
2819
#endif
2820
                    case 0x181: /* V9 fmovscc %xcc */
2821
                        FMOVCC(F, 1);
2822
                        break;
2823
                    case 0x182: /* V9 fmovdcc %xcc */
2824
                        FMOVCC(D, 1);
2825
                        break;
2826
                    case 0x183: /* V9 fmovqcc %xcc */
2827
#if defined(CONFIG_USER_ONLY)
2828
                        FMOVCC(Q, 1);
2829
                        break;
2830
#else
2831
                        goto nfpu_insn;
2832
#endif
2833
#undef FMOVCC
2834
#endif
2835
                    case 0x51: /* fcmps, V9 %fcc */
2836
                        gen_op_load_fpr_FT0(rs1);
2837
                        gen_op_load_fpr_FT1(rs2);
2838
                        gen_op_fcmps(rd & 3);
2839
                        break;
2840
                    case 0x52: /* fcmpd, V9 %fcc */
2841
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2842
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2843
                        gen_op_fcmpd(rd & 3);
2844
                        break;
2845
                    case 0x53: /* fcmpq, V9 %fcc */
2846
#if defined(CONFIG_USER_ONLY)
2847
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2848
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2849
                        gen_op_fcmpq(rd & 3);
2850
                        break;
2851
#else /* !defined(CONFIG_USER_ONLY) */
2852
                        goto nfpu_insn;
2853
#endif
2854
                    case 0x55: /* fcmpes, V9 %fcc */
2855
                        gen_op_load_fpr_FT0(rs1);
2856
                        gen_op_load_fpr_FT1(rs2);
2857
                        gen_op_fcmpes(rd & 3);
2858
                        break;
2859
                    case 0x56: /* fcmped, V9 %fcc */
2860
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2861
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2862
                        gen_op_fcmped(rd & 3);
2863
                        break;
2864
                    case 0x57: /* fcmpeq, V9 %fcc */
2865
#if defined(CONFIG_USER_ONLY)
2866
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2867
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2868
                        gen_op_fcmpeq(rd & 3);
2869
                        break;
2870
#else/* !defined(CONFIG_USER_ONLY) */
2871
                        goto nfpu_insn;
2872
#endif
2873
                    default:
2874
                        goto illegal_insn;
2875
                }
2876
#if defined(OPTIM)
2877
            } else if (xop == 0x2) {
2878
                // clr/mov shortcut
2879

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

    
3186
                                    gen_op_xor_T1_T0();
3187
                                    gen_op_movtl_env_T0(offsetof(CPUSPARCState,
3188
                                                                 tick_cmpr));
3189
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3190
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3191
                                                   offsetof(CPUState, tick));
3192
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3193
                                                       r_tickptr, cpu_T[0]);
3194
                                    tcg_gen_discard_ptr(r_tickptr);
3195
                                }
3196
                                break;
3197
                            case 0x18: /* System tick */
3198
#if !defined(CONFIG_USER_ONLY)
3199
                                if (!supervisor(dc))
3200
                                    goto illegal_insn;
3201
#endif
3202
                                {
3203
                                    TCGv r_tickptr;
3204

    
3205
                                    gen_op_xor_T1_T0();
3206
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3207
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3208
                                                   offsetof(CPUState, stick));
3209
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3210
                                                       r_tickptr, cpu_T[0]);
3211
                                    tcg_gen_discard_ptr(r_tickptr);
3212
                                }
3213
                                break;
3214
                            case 0x19: /* System tick compare */
3215
#if !defined(CONFIG_USER_ONLY)
3216
                                if (!supervisor(dc))
3217
                                    goto illegal_insn;
3218
#endif
3219
                                {
3220
                                    TCGv r_tickptr;
3221

    
3222
                                    gen_op_xor_T1_T0();
3223
                                    gen_op_movtl_env_T0(offsetof(CPUSPARCState,
3224
                                                                 stick_cmpr));
3225
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3226
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3227
                                                   offsetof(CPUState, stick));
3228
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3229
                                                       r_tickptr, cpu_T[0]);
3230
                                    tcg_gen_discard_ptr(r_tickptr);
3231
                                }
3232
                                break;
3233

    
3234
                            case 0x10: /* Performance Control */
3235
                            case 0x11: /* Performance Instrumentation Counter */
3236
                            case 0x12: /* Dispatch Control */
3237
                            case 0x14: /* Softint set */
3238
                            case 0x15: /* Softint clear */
3239
                            case 0x16: /* Softint write */
3240
#endif
3241
                            default:
3242
                                goto illegal_insn;
3243
                            }
3244
                        }
3245
                        break;
3246
#if !defined(CONFIG_USER_ONLY)
3247
                    case 0x31: /* wrpsr, V9 saved, restored */
3248
                        {
3249
                            if (!supervisor(dc))
3250
                                goto priv_insn;
3251
#ifdef TARGET_SPARC64
3252
                            switch (rd) {
3253
                            case 0:
3254
                                tcg_gen_helper_0_0(helper_saved);
3255
                                break;
3256
                            case 1:
3257
                                tcg_gen_helper_0_0(helper_restored);
3258
                                break;
3259
                            case 2: /* UA2005 allclean */
3260
                            case 3: /* UA2005 otherw */
3261
                            case 4: /* UA2005 normalw */
3262
                            case 5: /* UA2005 invalw */
3263
                                // XXX
3264
                            default:
3265
                                goto illegal_insn;
3266
                            }
3267
#else
3268
                            gen_op_xor_T1_T0();
3269
                            tcg_gen_helper_0_1(helper_wrpsr, cpu_T[0]);
3270
                            save_state(dc);
3271
                            gen_op_next_insn();
3272
                            tcg_gen_exit_tb(0);
3273
                            dc->is_br = 1;
3274
#endif
3275
                        }
3276
                        break;
3277
                    case 0x32: /* wrwim, V9 wrpr */
3278
                        {
3279
                            if (!supervisor(dc))
3280
                                goto priv_insn;
3281
                            gen_op_xor_T1_T0();
3282
#ifdef TARGET_SPARC64
3283
                            switch (rd) {
3284
                            case 0: // tpc
3285
                                {
3286
                                    TCGv r_tsptr;
3287

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

    
3300
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3301
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3302
                                                   offsetof(CPUState, tsptr));
3303
                                    tcg_gen_st_tl(cpu_T[0], r_tsptr,
3304
                                                  offsetof(trap_state, tnpc));
3305
                                    tcg_gen_discard_ptr(r_tsptr);
3306
                                }
3307
                                break;
3308
                            case 2: // tstate
3309
                                {
3310
                                    TCGv r_tsptr;
3311

    
3312
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3313
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3314
                                                   offsetof(CPUState, tsptr));
3315
                                    tcg_gen_st_tl(cpu_T[0], r_tsptr,
3316
                                                  offsetof(trap_state, tstate));
3317
                                    tcg_gen_discard_ptr(r_tsptr);
3318
                                }
3319
                                break;
3320
                            case 3: // tt
3321
                                {
3322
                                    TCGv r_tsptr;
3323

    
3324
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3325
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3326
                                                   offsetof(CPUState, tsptr));
3327
                                    tcg_gen_st_i32(cpu_T[0], r_tsptr,
3328
                                                   offsetof(trap_state, tt));
3329
                                    tcg_gen_discard_ptr(r_tsptr);
3330
                                }
3331
                                break;
3332
                            case 4: // tick
3333
                                {
3334
                                    TCGv r_tickptr;
3335

    
3336
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3337
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3338
                                                   offsetof(CPUState, tick));
3339
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3340
                                                       r_tickptr, cpu_T[0]);
3341
                                    tcg_gen_discard_ptr(r_tickptr);
3342
                                }
3343
                                break;
3344
                            case 5: // tba
3345
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
3346
                                break;
3347
                            case 6: // pstate
3348
                                save_state(dc);
3349
                                tcg_gen_helper_0_1(helper_wrpstate, cpu_T[0]);
3350
                                gen_op_next_insn();
3351
                                tcg_gen_exit_tb(0);
3352
                                dc->is_br = 1;
3353
                                break;
3354
                            case 7: // tl
3355
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, tl));
3356
                                break;
3357
                            case 8: // pil
3358
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, psrpil));
3359
                                break;
3360
                            case 9: // cwp
3361
                                tcg_gen_helper_0_1(helper_wrcwp, cpu_T[0]);
3362
                                break;
3363
                            case 10: // cansave
3364
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, cansave));
3365
                                break;
3366
                            case 11: // canrestore
3367
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, canrestore));
3368
                                break;
3369
                            case 12: // cleanwin
3370
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, cleanwin));
3371
                                break;
3372
                            case 13: // otherwin
3373
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, otherwin));
3374
                                break;
3375
                            case 14: // wstate
3376
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, wstate));
3377
                                break;
3378
                            case 16: // UA2005 gl
3379
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, gl));
3380
                                break;
3381
                            case 26: // UA2005 strand status
3382
                                if (!hypervisor(dc))
3383
                                    goto priv_insn;
3384
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, ssr));
3385
                                break;
3386
                            default:
3387
                                goto illegal_insn;
3388
                            }
3389
#else
3390
                            tcg_gen_andi_i32(cpu_T[0], cpu_T[0], ((1 << NWINDOWS) - 1));
3391
                            gen_op_movl_env_T0(offsetof(CPUSPARCState, wim));
3392
#endif
3393
                        }
3394
                        break;
3395
                    case 0x33: /* wrtbr, UA2005 wrhpr */
3396
                        {
3397
#ifndef TARGET_SPARC64
3398
                            if (!supervisor(dc))
3399
                                goto priv_insn;
3400
                            gen_op_xor_T1_T0();
3401
                            gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
3402
#else
3403
                            if (!hypervisor(dc))
3404
                                goto priv_insn;
3405
                            gen_op_xor_T1_T0();
3406
                            switch (rd) {
3407
                            case 0: // hpstate
3408
                                // XXX gen_op_wrhpstate();
3409
                                save_state(dc);
3410
                                gen_op_next_insn();
3411
                                tcg_gen_exit_tb(0);
3412
                                dc->is_br = 1;
3413
                                break;
3414
                            case 1: // htstate
3415
                                // XXX gen_op_wrhtstate();
3416
                                break;
3417
                            case 3: // hintp
3418
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, hintp));
3419
                                break;
3420
                            case 5: // htba
3421
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, htba));
3422
                                break;
3423
                            case 31: // hstick_cmpr
3424
                                {
3425
                                    TCGv r_tickptr;
3426

    
3427
                                    gen_op_movtl_env_T0(offsetof(CPUSPARCState,
3428
                                                                 hstick_cmpr));
3429
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3430
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3431
                                                   offsetof(CPUState, hstick));
3432
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3433
                                                       r_tickptr, cpu_T[0]);
3434
                                    tcg_gen_discard_ptr(r_tickptr);
3435
                                }
3436
                                break;
3437
                            case 6: // hver readonly
3438
                            default:
3439
                                goto illegal_insn;
3440
                            }
3441
#endif
3442
                        }
3443
                        break;
3444
#endif
3445
#ifdef TARGET_SPARC64
3446
                    case 0x2c: /* V9 movcc */
3447
                        {
3448
                            int cc = GET_FIELD_SP(insn, 11, 12);
3449
                            int cond = GET_FIELD_SP(insn, 14, 17);
3450
                            TCGv r_cond;
3451
                            int l1;
3452

    
3453
                            r_cond = tcg_temp_new(TCG_TYPE_TL);
3454
                            if (insn & (1 << 18)) {
3455
                                if (cc == 0)
3456
                                    gen_cond(r_cond, 0, cond);
3457
                                else if (cc == 2)
3458
                                    gen_cond(r_cond, 1, cond);
3459
                                else
3460
                                    goto illegal_insn;
3461
                            } else {
3462
                                gen_fcond(r_cond, cc, cond);
3463
                            }
3464

    
3465
                            l1 = gen_new_label();
3466

    
3467
                            tcg_gen_brcond_tl(TCG_COND_EQ, r_cond,
3468
                                              tcg_const_tl(0), l1);
3469
                            if (IS_IMM) {       /* immediate */
3470
                                rs2 = GET_FIELD_SPs(insn, 0, 10);
3471
                                gen_movl_simm_T1(rs2);
3472
                            } else {
3473
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3474
                                gen_movl_reg_T1(rs2);
3475
                            }
3476
                            gen_movl_T1_reg(rd);
3477
                            gen_set_label(l1);
3478
                            tcg_gen_discard_tl(r_cond);
3479
                            break;
3480
                        }
3481
                    case 0x2d: /* V9 sdivx */
3482
                        gen_op_sdivx_T1_T0();
3483
                        gen_movl_T0_reg(rd);
3484
                        break;
3485
                    case 0x2e: /* V9 popc */
3486
                        {
3487
                            if (IS_IMM) {       /* immediate */
3488
                                rs2 = GET_FIELD_SPs(insn, 0, 12);
3489
                                gen_movl_simm_T1(rs2);
3490
                                // XXX optimize: popc(constant)
3491
                            }
3492
                            else {
3493
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3494
                                gen_movl_reg_T1(rs2);
3495
                            }
3496
                            tcg_gen_helper_1_1(helper_popc, cpu_T[0],
3497
                                               cpu_T[1]);
3498
                            gen_movl_T0_reg(rd);
3499
                        }
3500
                    case 0x2f: /* V9 movr */
3501
                        {
3502
                            int cond = GET_FIELD_SP(insn, 10, 12);
3503
                            int l1;
3504

    
3505
                            rs1 = GET_FIELD(insn, 13, 17);
3506
                            gen_movl_reg_T0(rs1);
3507

    
3508
                            l1 = gen_new_label();
3509

    
3510
                            tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0],
3511
                                              tcg_const_tl(0), l1);
3512
                            if (IS_IMM) {       /* immediate */
3513
                                rs2 = GET_FIELD_SPs(insn, 0, 9);
3514
                                gen_movl_simm_T1(rs2);
3515
                            } else {
3516
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3517
                                gen_movl_reg_T1(rs2);
3518
                            }
3519
                            gen_movl_T1_reg(rd);
3520
                            gen_set_label(l1);
3521
                            break;
3522
                        }
3523
#endif
3524
                    default:
3525
                        goto illegal_insn;
3526
                    }
3527
                }
3528
            } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
3529
#ifdef TARGET_SPARC64
3530
                int opf = GET_FIELD_SP(insn, 5, 13);
3531
                rs1 = GET_FIELD(insn, 13, 17);
3532
                rs2 = GET_FIELD(insn, 27, 31);
3533
                if (gen_trap_ifnofpu(dc))
3534
                    goto jmp_insn;
3535

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

    
4100
                        r_dword = tcg_temp_new(TCG_TYPE_I64);
4101
                        gen_op_check_align_T0_7();
4102
                        ABI32_MASK(cpu_T[0]);
4103
                        tcg_gen_qemu_ld64(r_dword, cpu_T[0], dc->mem_idx);
4104
                        tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
4105
                        gen_movl_T0_reg(rd + 1);
4106
                        tcg_gen_shri_i64(r_dword, r_dword, 32);
4107
                        tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
4108
                        tcg_gen_discard_i64(r_dword);
4109
                    }
4110
                    break;
4111
                case 0x9:       /* load signed byte */
4112
                    ABI32_MASK(cpu_T[0]);
4113
                    tcg_gen_qemu_ld8s(cpu_T[1], cpu_T[0], dc->mem_idx);
4114
                    break;
4115
                case 0xa:       /* load signed halfword */
4116
                    gen_op_check_align_T0_1();
4117
                    ABI32_MASK(cpu_T[0]);
4118
                    tcg_gen_qemu_ld16s(cpu_T[1], cpu_T[0], dc->mem_idx);
4119
                    break;
4120
                case 0xd:       /* ldstub -- XXX: should be atomically */
4121
                    tcg_gen_movi_i32(cpu_tmp0, 0xff);
4122
                    ABI32_MASK(cpu_T[0]);
4123
                    tcg_gen_qemu_ld8s(cpu_T[1], cpu_T[0], dc->mem_idx);
4124
                    tcg_gen_qemu_st8(cpu_tmp0, cpu_T[0], dc->mem_idx);
4125
                    break;
4126
                case 0x0f:      /* swap register with memory. Also atomically */
4127
                    gen_op_check_align_T0_3();
4128
                    gen_movl_reg_T1(rd);
4129
                    ABI32_MASK(cpu_T[0]);
4130
                    tcg_gen_qemu_ld32u(cpu_tmp0, cpu_T[0], dc->mem_idx);
4131
                    tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], dc->mem_idx);
4132
                    tcg_gen_mov_i32(cpu_T[1], cpu_tmp0);
4133
                    break;
4134
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4135
                case 0x10:      /* load word alternate */
4136
#ifndef TARGET_SPARC64
4137
                    if (IS_IMM)
4138
                        goto illegal_insn;
4139
                    if (!supervisor(dc))
4140
                        goto priv_insn;
4141
#endif
4142
                    gen_op_check_align_T0_3();
4143
                    gen_ld_asi(insn, 4, 0);
4144
                    break;
4145
                case 0x11:      /* load unsigned byte alternate */
4146
#ifndef TARGET_SPARC64
4147
                    if (IS_IMM)
4148
                        goto illegal_insn;
4149
                    if (!supervisor(dc))
4150
                        goto priv_insn;
4151
#endif
4152
                    gen_ld_asi(insn, 1, 0);
4153
                    break;
4154
                case 0x12:      /* load unsigned halfword alternate */
4155
#ifndef TARGET_SPARC64
4156
                    if (IS_IMM)
4157
                        goto illegal_insn;
4158
                    if (!supervisor(dc))
4159
                        goto priv_insn;
4160
#endif
4161
                    gen_op_check_align_T0_1();
4162
                    gen_ld_asi(insn, 2, 0);
4163
                    break;
4164
                case 0x13:      /* load double word alternate */
4165
#ifndef TARGET_SPARC64
4166
                    if (IS_IMM)
4167
                        goto illegal_insn;
4168
                    if (!supervisor(dc))
4169
                        goto priv_insn;
4170
#endif
4171
                    if (rd & 1)
4172
                        goto illegal_insn;
4173
                    gen_op_check_align_T0_7();
4174
                    gen_ldda_asi(insn);
4175
                    gen_movl_T0_reg(rd + 1);
4176
                    break;
4177
                case 0x19:      /* load signed byte alternate */
4178
#ifndef TARGET_SPARC64
4179
                    if (IS_IMM)
4180
                        goto illegal_insn;
4181
                    if (!supervisor(dc))
4182
                        goto priv_insn;
4183
#endif
4184
                    gen_ld_asi(insn, 1, 1);
4185
                    break;
4186
                case 0x1a:      /* load signed halfword alternate */
4187
#ifndef TARGET_SPARC64
4188
                    if (IS_IMM)
4189
                        goto illegal_insn;
4190
                    if (!supervisor(dc))
4191
                        goto priv_insn;
4192
#endif
4193
                    gen_op_check_align_T0_1();
4194
                    gen_ld_asi(insn, 2, 1);
4195
                    break;
4196
                case 0x1d:      /* ldstuba -- XXX: should be atomically */
4197
#ifndef TARGET_SPARC64
4198
                    if (IS_IMM)
4199
                        goto illegal_insn;
4200
                    if (!supervisor(dc))
4201
                        goto priv_insn;
4202
#endif
4203
                    gen_ldstub_asi(insn);
4204
                    break;
4205
                case 0x1f:      /* swap reg with alt. memory. Also atomically */
4206
#ifndef TARGET_SPARC64
4207
                    if (IS_IMM)
4208
                        goto illegal_insn;
4209
                    if (!supervisor(dc))
4210
                        goto priv_insn;
4211
#endif
4212
                    gen_op_check_align_T0_3();
4213
                    gen_movl_reg_T1(rd);
4214
                    gen_swap_asi(insn);
4215
                    break;
4216

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

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

    
4544
static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
4545
{
4546
}
4547

    
4548
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
4549
                                                 int spc, CPUSPARCState *env)
4550
{
4551
    target_ulong pc_start, last_pc;
4552
    uint16_t *gen_opc_end;
4553
    DisasContext dc1, *dc = &dc1;
4554
    int j, lj = -1;
4555

    
4556
    memset(dc, 0, sizeof(DisasContext));
4557
    dc->tb = tb;
4558
    pc_start = tb->pc;
4559
    dc->pc = pc_start;
4560
    last_pc = dc->pc;
4561
    dc->npc = (target_ulong) tb->cs_base;
4562
    dc->mem_idx = cpu_mmu_index(env);
4563
    dc->fpu_enabled = cpu_fpu_enabled(env);
4564
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4565

    
4566
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
4567

    
4568
    do {
4569
        if (env->nb_breakpoints > 0) {
4570
            for(j = 0; j < env->nb_breakpoints; j++) {
4571
                if (env->breakpoints[j] == dc->pc) {
4572
                    if (dc->pc != pc_start)
4573
                        save_state(dc);
4574
                    tcg_gen_helper_0_0(helper_debug);
4575
                    tcg_gen_exit_tb(0);
4576
                    dc->is_br = 1;
4577
                    goto exit_gen_loop;
4578
                }
4579
            }
4580
        }
4581
        if (spc) {
4582
            if (loglevel > 0)
4583
                fprintf(logfile, "Search PC...\n");
4584
            j = gen_opc_ptr - gen_opc_buf;
4585
            if (lj < j) {
4586
                lj++;
4587
                while (lj < j)
4588
                    gen_opc_instr_start[lj++] = 0;
4589
                gen_opc_pc[lj] = dc->pc;
4590
                gen_opc_npc[lj] = dc->npc;
4591
                gen_opc_instr_start[lj] = 1;
4592
            }
4593
        }
4594
        last_pc = dc->pc;
4595
        disas_sparc_insn(dc);
4596

    
4597
        if (dc->is_br)
4598
            break;
4599
        /* if the next PC is different, we abort now */
4600
        if (dc->pc != (last_pc + 4))
4601
            break;
4602
        /* if we reach a page boundary, we stop generation so that the
4603
           PC of a TT_TFAULT exception is always in the right page */
4604
        if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
4605
            break;
4606
        /* if single step mode, we generate only one instruction and
4607
           generate an exception */
4608
        if (env->singlestep_enabled) {
4609
            gen_jmp_im(dc->pc);
4610
            tcg_gen_exit_tb(0);
4611
            break;
4612
        }
4613
    } while ((gen_opc_ptr < gen_opc_end) &&
4614
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
4615

    
4616
 exit_gen_loop:
4617
    if (!dc->is_br) {
4618
        if (dc->pc != DYNAMIC_PC &&
4619
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
4620
            /* static PC and NPC: we can use direct chaining */
4621
            gen_branch(dc, dc->pc, dc->npc);
4622
        } else {
4623
            if (dc->pc != DYNAMIC_PC)
4624
                gen_jmp_im(dc->pc);
4625
            save_npc(dc);
4626
            tcg_gen_exit_tb(0);
4627
        }
4628
    }
4629
    *gen_opc_ptr = INDEX_op_end;
4630
    if (spc) {
4631
        j = gen_opc_ptr - gen_opc_buf;
4632
        lj++;
4633
        while (lj <= j)
4634
            gen_opc_instr_start[lj++] = 0;
4635
#if 0
4636
        if (loglevel > 0) {
4637
            page_dump(logfile);
4638
        }
4639
#endif
4640
        gen_opc_jump_pc[0] = dc->jump_pc[0];
4641
        gen_opc_jump_pc[1] = dc->jump_pc[1];
4642
    } else {
4643
        tb->size = last_pc + 4 - pc_start;
4644
    }
4645
#ifdef DEBUG_DISAS
4646
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4647
        fprintf(logfile, "--------------\n");
4648
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
4649
        target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
4650
        fprintf(logfile, "\n");
4651
    }
4652
#endif
4653
    return 0;
4654
}
4655

    
4656
int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
4657
{
4658
    return gen_intermediate_code_internal(tb, 0, env);
4659
}
4660

    
4661
int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
4662
{
4663
    return gen_intermediate_code_internal(tb, 1, env);
4664
}
4665

    
4666
void cpu_reset(CPUSPARCState *env)
4667
{
4668
    tlb_flush(env, 1);
4669
    env->cwp = 0;
4670
    env->wim = 1;
4671
    env->regwptr = env->regbase + (env->cwp * 16);
4672
#if defined(CONFIG_USER_ONLY)
4673
    env->user_mode_only = 1;
4674
#ifdef TARGET_SPARC64
4675
    env->cleanwin = NWINDOWS - 2;
4676
    env->cansave = NWINDOWS - 2;
4677
    env->pstate = PS_RMO | PS_PEF | PS_IE;
4678
    env->asi = 0x82; // Primary no-fault
4679
#endif
4680
#else
4681
    env->psret = 0;
4682
    env->psrs = 1;
4683
    env->psrps = 1;
4684
#ifdef TARGET_SPARC64
4685
    env->pstate = PS_PRIV;
4686
    env->hpstate = HS_PRIV;
4687
    env->pc = 0x1fff0000000ULL;
4688
    env->tsptr = &env->ts[env->tl];
4689
#else
4690
    env->pc = 0;
4691
    env->mmuregs[0] &= ~(MMU_E | MMU_NF);
4692
    env->mmuregs[0] |= env->mmu_bm;
4693
#endif
4694
    env->npc = env->pc + 4;
4695
#endif
4696
}
4697

    
4698
CPUSPARCState *cpu_sparc_init(const char *cpu_model)
4699
{
4700
    CPUSPARCState *env;
4701
    const sparc_def_t *def;
4702
    static int inited;
4703
    unsigned int i;
4704
    static const char * const gregnames[8] = {
4705
        NULL, // g0 not used
4706
        "g1",
4707
        "g2",
4708
        "g3",
4709
        "g4",
4710
        "g5",
4711
        "g6",
4712
        "g7",
4713
    };
4714

    
4715
    def = cpu_sparc_find_by_name(cpu_model);
4716
    if (!def)
4717
        return NULL;
4718

    
4719
    env = qemu_mallocz(sizeof(CPUSPARCState));
4720
    if (!env)
4721
        return NULL;
4722
    cpu_exec_init(env);
4723
    env->cpu_model_str = cpu_model;
4724
    env->version = def->iu_version;
4725
    env->fsr = def->fpu_version;
4726
#if !defined(TARGET_SPARC64)
4727
    env->mmu_bm = def->mmu_bm;
4728
    env->mmu_ctpr_mask = def->mmu_ctpr_mask;
4729
    env->mmu_cxr_mask = def->mmu_cxr_mask;
4730
    env->mmu_sfsr_mask = def->mmu_sfsr_mask;
4731
    env->mmu_trcr_mask = def->mmu_trcr_mask;
4732
    env->mmuregs[0] |= def->mmu_version;
4733
    cpu_sparc_set_id(env, 0);
4734
#endif
4735

    
4736
    /* init various static tables */
4737
    if (!inited) {
4738
        inited = 1;
4739

    
4740
        tcg_set_macro_func(&tcg_ctx, tcg_macro_func);
4741
        cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
4742
        cpu_regwptr = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
4743
                                         offsetof(CPUState, regwptr),
4744
                                         "regwptr");
4745
        //#if TARGET_LONG_BITS > HOST_LONG_BITS
4746
#ifdef TARGET_SPARC64
4747
        cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
4748
                                      TCG_AREG0, offsetof(CPUState, t0), "T0");
4749
        cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
4750
                                      TCG_AREG0, offsetof(CPUState, t1), "T1");
4751
        cpu_T[2] = tcg_global_mem_new(TCG_TYPE_TL,
4752
                                      TCG_AREG0, offsetof(CPUState, t2), "T2");
4753
        cpu_xcc = tcg_global_mem_new(TCG_TYPE_I32,
4754
                                     TCG_AREG0, offsetof(CPUState, xcc),
4755
                                     "xcc");
4756
#else
4757
        cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
4758
        cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
4759
        cpu_T[2] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T2");
4760
#endif
4761
        cpu_cc_src = tcg_global_mem_new(TCG_TYPE_TL,
4762
                                        TCG_AREG0, offsetof(CPUState, cc_src),
4763
                                        "cc_src");
4764
        cpu_cc_src2 = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4765
                                         offsetof(CPUState, cc_src2),
4766
                                         "cc_src2");
4767
        cpu_cc_dst = tcg_global_mem_new(TCG_TYPE_TL,
4768
                                        TCG_AREG0, offsetof(CPUState, cc_dst),
4769
                                        "cc_dst");
4770
        cpu_psr = tcg_global_mem_new(TCG_TYPE_I32,
4771
                                     TCG_AREG0, offsetof(CPUState, psr),
4772
                                     "psr");
4773
        cpu_fsr = tcg_global_mem_new(TCG_TYPE_TL,
4774
                                     TCG_AREG0, offsetof(CPUState, fsr),
4775
                                     "fsr");
4776
        cpu_pc = tcg_global_mem_new(TCG_TYPE_TL,
4777
                                    TCG_AREG0, offsetof(CPUState, pc),
4778
                                    "pc");
4779
        cpu_npc = tcg_global_mem_new(TCG_TYPE_TL,
4780
                                    TCG_AREG0, offsetof(CPUState, npc),
4781
                                    "npc");
4782
        for (i = 1; i < 8; i++)
4783
            cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4784
                                              offsetof(CPUState, gregs[i]),
4785
                                              gregnames[i]);
4786
    }
4787

    
4788
    cpu_reset(env);
4789
    
4790
    return env;
4791
}
4792

    
4793
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
4794
{
4795
#if !defined(TARGET_SPARC64)
4796
    env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
4797
#endif
4798
}
4799

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

    
5120
static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name)
5121
{
5122
    unsigned int i;
5123

    
5124
    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
5125
        if (strcasecmp(name, sparc_defs[i].name) == 0) {
5126
            return &sparc_defs[i];
5127
        }
5128
    }
5129
    return NULL;
5130
}
5131

    
5132
void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
5133
{
5134
    unsigned int i;
5135

    
5136
    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
5137
        (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x\n",
5138
                       sparc_defs[i].name,
5139
                       sparc_defs[i].iu_version,
5140
                       sparc_defs[i].fpu_version,
5141
                       sparc_defs[i].mmu_version);
5142
    }
5143
}
5144

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

    
5147
void cpu_dump_state(CPUState *env, FILE *f,
5148
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5149
                    int flags)
5150
{
5151
    int i, x;
5152

    
5153
    cpu_fprintf(f, "pc: " TARGET_FMT_lx "  npc: " TARGET_FMT_lx "\n", env->pc, env->npc);
5154
    cpu_fprintf(f, "General Registers:\n");
5155
    for (i = 0; i < 4; i++)
5156
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
5157
    cpu_fprintf(f, "\n");
5158
    for (; i < 8; i++)
5159
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
5160
    cpu_fprintf(f, "\nCurrent Register Window:\n");
5161
    for (x = 0; x < 3; x++) {
5162
        for (i = 0; i < 4; i++)
5163
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
5164
                    (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
5165
                    env->regwptr[i + x * 8]);
5166
        cpu_fprintf(f, "\n");
5167
        for (; i < 8; i++)
5168
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
5169
                    (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
5170
                    env->regwptr[i + x * 8]);
5171
        cpu_fprintf(f, "\n");
5172
    }
5173
    cpu_fprintf(f, "\nFloating Point Registers:\n");
5174
    for (i = 0; i < 32; i++) {
5175
        if ((i & 3) == 0)
5176
            cpu_fprintf(f, "%%f%02d:", i);
5177
        cpu_fprintf(f, " %016lf", env->fpr[i]);
5178
        if ((i & 3) == 3)
5179
            cpu_fprintf(f, "\n");
5180
    }
5181
#ifdef TARGET_SPARC64
5182
    cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d fprs: %d\n",
5183
                env->pstate, GET_CCR(env), env->asi, env->tl, env->fprs);
5184
    cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d cleanwin %d cwp %d\n",
5185
                env->cansave, env->canrestore, env->otherwin, env->wstate,
5186
                env->cleanwin, NWINDOWS - 1 - env->cwp);
5187
#else
5188
    cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n", GET_PSR(env),
5189
            GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
5190
            GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
5191
            env->psrs?'S':'-', env->psrps?'P':'-',
5192
            env->psret?'E':'-', env->wim);
5193
#endif
5194
    cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env));
5195
}
5196

    
5197
#if defined(CONFIG_USER_ONLY)
5198
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
5199
{
5200
    return addr;
5201
}
5202

    
5203
#else
5204
extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
5205
                                 int *access_index, target_ulong address, int rw,
5206
                                 int mmu_idx);
5207

    
5208
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
5209
{
5210
    target_phys_addr_t phys_addr;
5211
    int prot, access_index;
5212

    
5213
    if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2,
5214
                             MMU_KERNEL_IDX) != 0)
5215
        if (get_physical_address(env, &phys_addr, &prot, &access_index, addr,
5216
                                 0, MMU_KERNEL_IDX) != 0)
5217
            return -1;
5218
    if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED)
5219
        return -1;
5220
    return phys_addr;
5221
}
5222
#endif
5223

    
5224
void helper_flush(target_ulong addr)
5225
{
5226
    addr &= ~7;
5227
    tb_invalidate_page_range(addr, addr + 8);
5228
}