Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ ce5b3c3d

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

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

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

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

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

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

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

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

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

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

    
223
#ifndef CONFIG_USER_ONLY
224
#ifdef __i386__
225
OP_LD_TABLE(std);
226
#endif /* __i386__ */
227
OP_LD_TABLE(stdf);
228
OP_LD_TABLE(lddf);
229
#endif
230

    
231
#ifdef TARGET_ABI32
232
#define ABI32_MASK(addr) tcg_gen_andi_tl(addr, addr, 0xffffffffULL);
233
#else
234
#define ABI32_MASK(addr)
235
#endif
236

    
237
static inline void gen_movl_reg_TN(int reg, TCGv tn)
238
{
239
    if (reg == 0)
240
        tcg_gen_movi_tl(tn, 0);
241
    else if (reg < 8)
242
        tcg_gen_mov_tl(tn, cpu_gregs[reg]);
243
    else {
244
        tcg_gen_ld_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
245
    }
246
}
247

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

    
259
static inline void gen_goto_tb(DisasContext *s, int tb_num,
260
                               target_ulong pc, target_ulong npc)
261
{
262
    TranslationBlock *tb;
263

    
264
    tb = s->tb;
265
    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
266
        (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK))  {
267
        /* jump to same page: we can use a direct jump */
268
        tcg_gen_goto_tb(tb_num);
269
        tcg_gen_movi_tl(cpu_pc, pc);
270
        tcg_gen_movi_tl(cpu_npc, npc);
271
        tcg_gen_exit_tb((long)tb + tb_num);
272
    } else {
273
        /* jump to another page: currently not optimized */
274
        tcg_gen_movi_tl(cpu_pc, pc);
275
        tcg_gen_movi_tl(cpu_npc, npc);
276
        tcg_gen_exit_tb(0);
277
    }
278
}
279

    
280
// XXX suboptimal
281
static inline void gen_mov_reg_N(TCGv reg, TCGv src)
282
{
283
    tcg_gen_extu_i32_tl(reg, src);
284
    tcg_gen_shri_tl(reg, reg, 23);
285
    tcg_gen_andi_tl(reg, reg, 0x1);
286
}
287

    
288
static inline void gen_mov_reg_Z(TCGv reg, TCGv src)
289
{
290
    tcg_gen_extu_i32_tl(reg, src);
291
    tcg_gen_shri_tl(reg, reg, 22);
292
    tcg_gen_andi_tl(reg, reg, 0x1);
293
}
294

    
295
static inline void gen_mov_reg_V(TCGv reg, TCGv src)
296
{
297
    tcg_gen_extu_i32_tl(reg, src);
298
    tcg_gen_shri_tl(reg, reg, 21);
299
    tcg_gen_andi_tl(reg, reg, 0x1);
300
}
301

    
302
static inline void gen_mov_reg_C(TCGv reg, TCGv src)
303
{
304
    tcg_gen_extu_i32_tl(reg, src);
305
    tcg_gen_shri_tl(reg, reg, 20);
306
    tcg_gen_andi_tl(reg, reg, 0x1);
307
}
308

    
309
static inline void gen_cc_clear_icc(void)
310
{
311
    tcg_gen_movi_i32(cpu_psr, 0);
312
}
313

    
314
#ifdef TARGET_SPARC64
315
static inline void gen_cc_clear_xcc(void)
316
{
317
    tcg_gen_movi_i32(cpu_xcc, 0);
318
}
319
#endif
320

    
321
/* old op:
322
    if (!T0)
323
        env->psr |= PSR_ZERO;
324
    if ((int32_t) T0 < 0)
325
        env->psr |= PSR_NEG;
326
*/
327
static inline void gen_cc_NZ_icc(TCGv dst)
328
{
329
    TCGv r_temp;
330
    int l1, l2;
331

    
332
    l1 = gen_new_label();
333
    l2 = gen_new_label();
334
    r_temp = tcg_temp_new(TCG_TYPE_TL);
335
    tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
336
    tcg_gen_brcond_tl(TCG_COND_NE, r_temp, tcg_const_tl(0), l1);
337
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_ZERO);
338
    gen_set_label(l1);
339
    tcg_gen_ext_i32_tl(r_temp, dst);
340
    tcg_gen_brcond_tl(TCG_COND_GE, r_temp, tcg_const_tl(0), l2);
341
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_NEG);
342
    gen_set_label(l2);
343
}
344

    
345
#ifdef TARGET_SPARC64
346
static inline void gen_cc_NZ_xcc(TCGv dst)
347
{
348
    int l1, l2;
349

    
350
    l1 = gen_new_label();
351
    l2 = gen_new_label();
352
    tcg_gen_brcond_tl(TCG_COND_NE, dst, tcg_const_tl(0), l1);
353
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_ZERO);
354
    gen_set_label(l1);
355
    tcg_gen_brcond_tl(TCG_COND_GE, dst, tcg_const_tl(0), l2);
356
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_NEG);
357
    gen_set_label(l2);
358
}
359
#endif
360

    
361
/* old op:
362
    if (T0 < src1)
363
        env->psr |= PSR_CARRY;
364
*/
365
static inline void gen_cc_C_add_icc(TCGv dst, TCGv src1)
366
{
367
    TCGv r_temp;
368
    int l1;
369

    
370
    l1 = gen_new_label();
371
    r_temp = tcg_temp_new(TCG_TYPE_TL);
372
    tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
373
    tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l1);
374
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
375
    gen_set_label(l1);
376
}
377

    
378
#ifdef TARGET_SPARC64
379
static inline void gen_cc_C_add_xcc(TCGv dst, TCGv src1)
380
{
381
    int l1;
382

    
383
    l1 = gen_new_label();
384
    tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l1);
385
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
386
    gen_set_label(l1);
387
}
388
#endif
389

    
390
/* old op:
391
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
392
        env->psr |= PSR_OVF;
393
*/
394
static inline void gen_cc_V_add_icc(TCGv dst, TCGv src1, TCGv src2)
395
{
396
    TCGv r_temp;
397
    int l1;
398

    
399
    l1 = gen_new_label();
400

    
401
    r_temp = tcg_temp_new(TCG_TYPE_TL);
402
    tcg_gen_xor_tl(r_temp, src1, src2);
403
    tcg_gen_xori_tl(r_temp, r_temp, -1);
404
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
405
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
406
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
407
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
408
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
409
    gen_set_label(l1);
410
}
411

    
412
#ifdef TARGET_SPARC64
413
static inline void gen_cc_V_add_xcc(TCGv dst, TCGv src1, TCGv src2)
414
{
415
    TCGv r_temp;
416
    int l1;
417

    
418
    l1 = gen_new_label();
419

    
420
    r_temp = tcg_temp_new(TCG_TYPE_TL);
421
    tcg_gen_xor_tl(r_temp, src1, src2);
422
    tcg_gen_xori_tl(r_temp, r_temp, -1);
423
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
424
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
425
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
426
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
427
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_OVF);
428
    gen_set_label(l1);
429
}
430
#endif
431

    
432
static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
433
{
434
    TCGv r_temp;
435
    int l1;
436

    
437
    l1 = gen_new_label();
438

    
439
    r_temp = tcg_temp_new(TCG_TYPE_TL);
440
    tcg_gen_xor_tl(r_temp, src1, src2);
441
    tcg_gen_xori_tl(r_temp, r_temp, -1);
442
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
443
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
444
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
445
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
446
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
447
    gen_set_label(l1);
448
}
449

    
450
static inline void gen_cc_V_tag(TCGv src1, TCGv src2)
451
{
452
    int l1;
453

    
454
    l1 = gen_new_label();
455
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
456
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
457
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
458
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
459
    gen_set_label(l1);
460
}
461

    
462
static inline void gen_tag_tv(TCGv src1, TCGv src2)
463
{
464
    int l1;
465

    
466
    l1 = gen_new_label();
467
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
468
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
469
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
470
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
471
    gen_set_label(l1);
472
}
473

    
474
static inline void gen_op_add_T1_T0_cc(void)
475
{
476
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
477
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
478
    gen_cc_clear_icc();
479
    gen_cc_NZ_icc(cpu_T[0]);
480
    gen_cc_C_add_icc(cpu_T[0], cpu_cc_src);
481
    gen_cc_V_add_icc(cpu_T[0], cpu_cc_src, cpu_T[1]);
482
#ifdef TARGET_SPARC64
483
    gen_cc_clear_xcc();
484
    gen_cc_NZ_xcc(cpu_T[0]);
485
    gen_cc_C_add_xcc(cpu_T[0], cpu_cc_src);
486
    gen_cc_V_add_xcc(cpu_T[0], cpu_cc_src, cpu_T[1]);
487
#endif
488
}
489

    
490
static inline void gen_op_addx_T1_T0_cc(void)
491
{
492
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
493
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
494
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
495
    gen_cc_clear_icc();
496
    gen_cc_C_add_icc(cpu_T[0], cpu_cc_src);
497
#ifdef TARGET_SPARC64
498
    gen_cc_clear_xcc();
499
    gen_cc_C_add_xcc(cpu_T[0], cpu_cc_src);
500
#endif
501
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
502
    gen_cc_NZ_icc(cpu_T[0]);
503
    gen_cc_C_add_icc(cpu_T[0], cpu_cc_src);
504
    gen_cc_V_add_icc(cpu_T[0], cpu_cc_src, cpu_T[1]);
505
#ifdef TARGET_SPARC64
506
    gen_cc_NZ_xcc(cpu_T[0]);
507
    gen_cc_C_add_xcc(cpu_T[0], cpu_cc_src);
508
    gen_cc_V_add_xcc(cpu_T[0], cpu_cc_src, cpu_T[1]);
509
#endif
510
}
511

    
512
static inline void gen_op_tadd_T1_T0_cc(void)
513
{
514
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
515
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
516
    gen_cc_clear_icc();
517
    gen_cc_NZ_icc(cpu_T[0]);
518
    gen_cc_C_add_icc(cpu_T[0], cpu_cc_src);
519
    gen_cc_V_add_icc(cpu_T[0], cpu_cc_src, cpu_T[1]);
520
    gen_cc_V_tag(cpu_cc_src, cpu_T[1]);
521
#ifdef TARGET_SPARC64
522
    gen_cc_clear_xcc();
523
    gen_cc_NZ_xcc(cpu_T[0]);
524
    gen_cc_C_add_xcc(cpu_T[0], cpu_cc_src);
525
    gen_cc_V_add_xcc(cpu_T[0], cpu_cc_src, cpu_T[1]);
526
#endif
527
}
528

    
529
static inline void gen_op_tadd_T1_T0_ccTV(void)
530
{
531
    gen_tag_tv(cpu_T[0], cpu_T[1]);
532
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
533
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
534
    gen_add_tv(cpu_T[0], cpu_cc_src, cpu_T[1]);
535
    gen_cc_clear_icc();
536
    gen_cc_NZ_icc(cpu_T[0]);
537
    gen_cc_C_add_icc(cpu_T[0], cpu_cc_src);
538
#ifdef TARGET_SPARC64
539
    gen_cc_clear_xcc();
540
    gen_cc_NZ_xcc(cpu_T[0]);
541
    gen_cc_C_add_xcc(cpu_T[0], cpu_cc_src);
542
    gen_cc_V_add_xcc(cpu_T[0], cpu_cc_src, cpu_T[1]);
543
#endif
544
}
545

    
546
/* old op:
547
    if (src1 < T1)
548
        env->psr |= PSR_CARRY;
549
*/
550
static inline void gen_cc_C_sub_icc(TCGv src1, TCGv src2)
551
{
552
    TCGv r_temp1, r_temp2;
553
    int l1;
554

    
555
    l1 = gen_new_label();
556
    r_temp1 = tcg_temp_new(TCG_TYPE_TL);
557
    r_temp2 = tcg_temp_new(TCG_TYPE_TL);
558
    tcg_gen_andi_tl(r_temp1, src1, 0xffffffffULL);
559
    tcg_gen_andi_tl(r_temp2, src2, 0xffffffffULL);
560
    tcg_gen_brcond_tl(TCG_COND_GEU, r_temp1, r_temp2, l1);
561
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
562
    gen_set_label(l1);
563
}
564

    
565
#ifdef TARGET_SPARC64
566
static inline void gen_cc_C_sub_xcc(TCGv src1, TCGv src2)
567
{
568
    int l1;
569

    
570
    l1 = gen_new_label();
571
    tcg_gen_brcond_tl(TCG_COND_GEU, src1, src2, l1);
572
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
573
    gen_set_label(l1);
574
}
575
#endif
576

    
577
/* old op:
578
    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
579
        env->psr |= PSR_OVF;
580
*/
581
static inline void gen_cc_V_sub_icc(TCGv dst, TCGv src1, TCGv src2)
582
{
583
    TCGv r_temp;
584
    int l1;
585

    
586
    l1 = gen_new_label();
587

    
588
    r_temp = tcg_temp_new(TCG_TYPE_TL);
589
    tcg_gen_xor_tl(r_temp, src1, src2);
590
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
591
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
592
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
593
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
594
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
595
    gen_set_label(l1);
596
}
597

    
598
#ifdef TARGET_SPARC64
599
static inline void gen_cc_V_sub_xcc(TCGv dst, TCGv src1, TCGv src2)
600
{
601
    TCGv r_temp;
602
    int l1;
603

    
604
    l1 = gen_new_label();
605

    
606
    r_temp = tcg_temp_new(TCG_TYPE_TL);
607
    tcg_gen_xor_tl(r_temp, src1, src2);
608
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
609
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
610
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
611
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
612
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_OVF);
613
    gen_set_label(l1);
614
}
615
#endif
616

    
617
static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
618
{
619
    TCGv r_temp;
620
    int l1;
621

    
622
    l1 = gen_new_label();
623

    
624
    r_temp = tcg_temp_new(TCG_TYPE_TL);
625
    tcg_gen_xor_tl(r_temp, src1, src2);
626
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
627
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
628
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
629
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
630
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
631
    gen_set_label(l1);
632
    tcg_gen_discard_tl(r_temp);
633
}
634

    
635
static inline void gen_op_sub_T1_T0_cc(void)
636
{
637
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
638
    tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
639
    gen_cc_clear_icc();
640
    gen_cc_NZ_icc(cpu_T[0]);
641
    gen_cc_C_sub_icc(cpu_cc_src, cpu_T[1]);
642
    gen_cc_V_sub_icc(cpu_T[0], cpu_cc_src, cpu_T[1]);
643
#ifdef TARGET_SPARC64
644
    gen_cc_clear_xcc();
645
    gen_cc_NZ_xcc(cpu_T[0]);
646
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_T[1]);
647
    gen_cc_V_sub_xcc(cpu_T[0], cpu_cc_src, cpu_T[1]);
648
#endif
649
}
650

    
651
static inline void gen_op_subx_T1_T0_cc(void)
652
{
653
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
654
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
655
    tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
656
    gen_cc_clear_icc();
657
    gen_cc_C_sub_icc(cpu_T[0], cpu_cc_src);
658
#ifdef TARGET_SPARC64
659
    gen_cc_clear_xcc();
660
    gen_cc_C_sub_xcc(cpu_T[0], cpu_cc_src);
661
#endif
662
    tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
663
    gen_cc_NZ_icc(cpu_T[0]);
664
    gen_cc_C_sub_icc(cpu_T[0], cpu_cc_src);
665
    gen_cc_V_sub_icc(cpu_T[0], cpu_cc_src, cpu_T[1]);
666
#ifdef TARGET_SPARC64
667
    gen_cc_NZ_xcc(cpu_T[0]);
668
    gen_cc_C_sub_xcc(cpu_T[0], cpu_cc_src);
669
    gen_cc_V_sub_xcc(cpu_T[0], cpu_cc_src, cpu_T[1]);
670
#endif
671
}
672

    
673
static inline void gen_op_tsub_T1_T0_cc(void)
674
{
675
    tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
676
    tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
677
    gen_cc_clear_icc();
678
    gen_cc_NZ_icc(cpu_T[0]);
679
    gen_cc_C_sub_icc(cpu_cc_src, cpu_T[1]);
680
    gen_cc_V_sub_icc(cpu_T[0], cpu_cc_src, cpu_T[1]);
681
    gen_cc_V_tag(cpu_cc_src, cpu_T[1]);
682
#ifdef TARGET_SPARC64
683
    gen_cc_clear_xcc();
684
    gen_cc_NZ_xcc(cpu_T[0]);
685
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_T[1]);
686
    gen_cc_V_sub_xcc(cpu_T[0], cpu_cc_src, cpu_T[1]);
687
#endif
688
}
689

    
690
static inline void gen_op_tsub_T1_T0_ccTV(void)
691
{
692
    gen_tag_tv(cpu_T[0], cpu_T[1]);
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_sub_tv(cpu_T[0], cpu_cc_src, cpu_T[1]);
696
    gen_cc_clear_icc();
697
    gen_cc_NZ_icc(cpu_T[0]);
698
    gen_cc_C_sub_icc(cpu_cc_src, cpu_T[1]);
699
#ifdef TARGET_SPARC64
700
    gen_cc_clear_xcc();
701
    gen_cc_NZ_xcc(cpu_T[0]);
702
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_T[1]);
703
    gen_cc_V_sub_xcc(cpu_T[0], cpu_cc_src, cpu_T[1]);
704
#endif
705
}
706

    
707
static inline void gen_op_mulscc_T1_T0(void)
708
{
709
    TCGv r_temp, r_temp2;
710
    int l1, l2;
711

    
712
    l1 = gen_new_label();
713
    l2 = gen_new_label();
714
    r_temp = tcg_temp_new(TCG_TYPE_TL);
715
    r_temp2 = tcg_temp_new(TCG_TYPE_I32);
716

    
717
    /* old op:
718
    if (!(env->y & 1))
719
        T1 = 0;
720
    */
721
    tcg_gen_ld32u_tl(r_temp, cpu_env, offsetof(CPUSPARCState, y));
722
    tcg_gen_trunc_tl_i32(r_temp2, r_temp);
723
    tcg_gen_andi_i32(r_temp2, r_temp2, 0x1);
724
    tcg_gen_brcond_i32(TCG_COND_EQ, r_temp2, tcg_const_i32(0), l1);
725
    tcg_gen_mov_tl(cpu_cc_src2, cpu_T[1]);
726
    tcg_gen_br(l2);
727
    gen_set_label(l1);
728
    tcg_gen_movi_tl(cpu_cc_src2, 0);
729
    gen_set_label(l2);
730

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

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

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

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

    
756
    gen_cc_clear_icc();
757
    gen_cc_NZ_icc(cpu_T[0]);
758
    gen_cc_V_add_icc(cpu_T[0], cpu_cc_src, cpu_cc_src2);
759
    gen_cc_C_add_icc(cpu_T[0], cpu_cc_src);
760
}
761

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

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

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

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

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

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

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

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

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

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

    
810
#ifdef TARGET_SPARC64
811
static inline void gen_trap_ifdivzero_tl(TCGv divisor)
812
{
813
    int l1;
814

    
815
    l1 = gen_new_label();
816
    tcg_gen_brcond_tl(TCG_COND_NE, divisor, tcg_const_tl(0), l1);
817
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_DIV_ZERO));
818
    gen_set_label(l1);
819
}
820

    
821
static inline void gen_op_sdivx_T1_T0(void)
822
{
823
    int l1, l2;
824

    
825
    l1 = gen_new_label();
826
    l2 = gen_new_label();
827
    gen_trap_ifdivzero_tl(cpu_T[1]);
828
    tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[0], tcg_const_tl(INT64_MIN), l1);
829
    tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[1], tcg_const_tl(-1), l1);
830
    tcg_gen_movi_i64(cpu_T[0], INT64_MIN);
831
    tcg_gen_br(l2);
832
    gen_set_label(l1);
833
    tcg_gen_div_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
834
    gen_set_label(l2);
835
}
836
#endif
837

    
838
static inline void gen_op_div_cc(void)
839
{
840
    int l1;
841

    
842
    gen_cc_clear_icc();
843
    gen_cc_NZ_icc(cpu_T[0]);
844
    l1 = gen_new_label();
845
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, cc_src2));
846
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
847
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
848
    gen_set_label(l1);
849
}
850

    
851
static inline void gen_op_logic_T0_cc(void)
852
{
853
    gen_cc_clear_icc();
854
    gen_cc_NZ_icc(cpu_T[0]);
855
#ifdef TARGET_SPARC64
856
    gen_cc_clear_xcc();
857
    gen_cc_NZ_xcc(cpu_T[0]);
858
#endif
859
}
860

    
861
// 1
862
static inline void gen_op_eval_ba(TCGv dst)
863
{
864
    tcg_gen_movi_tl(dst, 1);
865
}
866

    
867
// Z
868
static inline void gen_op_eval_be(TCGv dst, TCGv src)
869
{
870
    gen_mov_reg_Z(dst, src);
871
}
872

    
873
// Z | (N ^ V)
874
static inline void gen_op_eval_ble(TCGv dst, TCGv src)
875
{
876
    gen_mov_reg_N(cpu_tmp0, src);
877
    gen_mov_reg_V(dst, src);
878
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
879
    gen_mov_reg_Z(cpu_tmp0, src);
880
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
881
}
882

    
883
// N ^ V
884
static inline void gen_op_eval_bl(TCGv dst, TCGv src)
885
{
886
    gen_mov_reg_V(cpu_tmp0, src);
887
    gen_mov_reg_N(dst, src);
888
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
889
}
890

    
891
// C | Z
892
static inline void gen_op_eval_bleu(TCGv dst, TCGv src)
893
{
894
    gen_mov_reg_Z(cpu_tmp0, src);
895
    gen_mov_reg_C(dst, src);
896
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
897
}
898

    
899
// C
900
static inline void gen_op_eval_bcs(TCGv dst, TCGv src)
901
{
902
    gen_mov_reg_C(dst, src);
903
}
904

    
905
// V
906
static inline void gen_op_eval_bvs(TCGv dst, TCGv src)
907
{
908
    gen_mov_reg_V(dst, src);
909
}
910

    
911
// 0
912
static inline void gen_op_eval_bn(TCGv dst)
913
{
914
    tcg_gen_movi_tl(dst, 0);
915
}
916

    
917
// N
918
static inline void gen_op_eval_bneg(TCGv dst, TCGv src)
919
{
920
    gen_mov_reg_N(dst, src);
921
}
922

    
923
// !Z
924
static inline void gen_op_eval_bne(TCGv dst, TCGv src)
925
{
926
    gen_mov_reg_Z(dst, src);
927
    tcg_gen_xori_tl(dst, dst, 0x1);
928
}
929

    
930
// !(Z | (N ^ V))
931
static inline void gen_op_eval_bg(TCGv dst, TCGv src)
932
{
933
    gen_mov_reg_N(cpu_tmp0, src);
934
    gen_mov_reg_V(dst, src);
935
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
936
    gen_mov_reg_Z(cpu_tmp0, src);
937
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
938
    tcg_gen_xori_tl(dst, dst, 0x1);
939
}
940

    
941
// !(N ^ V)
942
static inline void gen_op_eval_bge(TCGv dst, TCGv src)
943
{
944
    gen_mov_reg_V(cpu_tmp0, src);
945
    gen_mov_reg_N(dst, src);
946
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
947
    tcg_gen_xori_tl(dst, dst, 0x1);
948
}
949

    
950
// !(C | Z)
951
static inline void gen_op_eval_bgu(TCGv dst, TCGv src)
952
{
953
    gen_mov_reg_Z(cpu_tmp0, src);
954
    gen_mov_reg_C(dst, src);
955
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
956
    tcg_gen_xori_tl(dst, dst, 0x1);
957
}
958

    
959
// !C
960
static inline void gen_op_eval_bcc(TCGv dst, TCGv src)
961
{
962
    gen_mov_reg_C(dst, src);
963
    tcg_gen_xori_tl(dst, dst, 0x1);
964
}
965

    
966
// !N
967
static inline void gen_op_eval_bpos(TCGv dst, TCGv src)
968
{
969
    gen_mov_reg_N(dst, src);
970
    tcg_gen_xori_tl(dst, dst, 0x1);
971
}
972

    
973
// !V
974
static inline void gen_op_eval_bvc(TCGv dst, TCGv src)
975
{
976
    gen_mov_reg_V(dst, src);
977
    tcg_gen_xori_tl(dst, dst, 0x1);
978
}
979

    
980
/*
981
  FPSR bit field FCC1 | FCC0:
982
   0 =
983
   1 <
984
   2 >
985
   3 unordered
986
*/
987
static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src,
988
                                    unsigned int fcc_offset)
989
{
990
    tcg_gen_extu_i32_tl(reg, src);
991
    tcg_gen_shri_tl(reg, reg, 10 + fcc_offset);
992
    tcg_gen_andi_tl(reg, reg, 0x1);
993
}
994

    
995
static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
996
                                    unsigned int fcc_offset)
997
{
998
    tcg_gen_extu_i32_tl(reg, src);
999
    tcg_gen_shri_tl(reg, reg, 11 + fcc_offset);
1000
    tcg_gen_andi_tl(reg, reg, 0x1);
1001
}
1002

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

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

    
1021
// 1 or 3: FCC0
1022
static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
1023
                                    unsigned int fcc_offset)
1024
{
1025
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1026
}
1027

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

    
1038
// 2 or 3: FCC1
1039
static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
1040
                                    unsigned int fcc_offset)
1041
{
1042
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1043
}
1044

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

    
1055
// 3: FCC0 & FCC1
1056
static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
1057
                                    unsigned int fcc_offset)
1058
{
1059
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1060
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1061
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1062
}
1063

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

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

    
1084
// 0 or 2: !FCC0
1085
static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
1086
                                    unsigned int fcc_offset)
1087
{
1088
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1089
    tcg_gen_xori_tl(dst, dst, 0x1);
1090
}
1091

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

    
1103
// 0 or 1: !FCC1
1104
static inline void gen_op_eval_fble(TCGv dst, TCGv src,
1105
                                    unsigned int fcc_offset)
1106
{
1107
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1108
    tcg_gen_xori_tl(dst, dst, 0x1);
1109
}
1110

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

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

    
1132
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
1133
                               target_ulong pc2, TCGv r_cond)
1134
{
1135
    int l1;
1136

    
1137
    l1 = gen_new_label();
1138

    
1139
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1140

    
1141
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
1142

    
1143
    gen_set_label(l1);
1144
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
1145
}
1146

    
1147
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
1148
                                target_ulong pc2, TCGv r_cond)
1149
{
1150
    int l1;
1151

    
1152
    l1 = gen_new_label();
1153

    
1154
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1155

    
1156
    gen_goto_tb(dc, 0, pc2, pc1);
1157

    
1158
    gen_set_label(l1);
1159
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
1160
}
1161

    
1162
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
1163
                                      TCGv r_cond)
1164
{
1165
    int l1, l2;
1166

    
1167
    l1 = gen_new_label();
1168
    l2 = gen_new_label();
1169

    
1170
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1171

    
1172
    tcg_gen_movi_tl(cpu_npc, npc1);
1173
    tcg_gen_br(l2);
1174

    
1175
    gen_set_label(l1);
1176
    tcg_gen_movi_tl(cpu_npc, npc2);
1177
    gen_set_label(l2);
1178
}
1179

    
1180
/* call this function before using T2 as it may have been set for a jump */
1181
static inline void flush_T2(DisasContext * dc)
1182
{
1183
    if (dc->npc == JUMP_PC) {
1184
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
1185
        dc->npc = DYNAMIC_PC;
1186
    }
1187
}
1188

    
1189
static inline void save_npc(DisasContext * dc)
1190
{
1191
    if (dc->npc == JUMP_PC) {
1192
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
1193
        dc->npc = DYNAMIC_PC;
1194
    } else if (dc->npc != DYNAMIC_PC) {
1195
        tcg_gen_movi_tl(cpu_npc, dc->npc);
1196
    }
1197
}
1198

    
1199
static inline void save_state(DisasContext * dc)
1200
{
1201
    tcg_gen_movi_tl(cpu_pc, dc->pc);
1202
    save_npc(dc);
1203
}
1204

    
1205
static inline void gen_mov_pc_npc(DisasContext * dc)
1206
{
1207
    if (dc->npc == JUMP_PC) {
1208
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
1209
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1210
        dc->pc = DYNAMIC_PC;
1211
    } else if (dc->npc == DYNAMIC_PC) {
1212
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1213
        dc->pc = DYNAMIC_PC;
1214
    } else {
1215
        dc->pc = dc->npc;
1216
    }
1217
}
1218

    
1219
static inline void gen_op_next_insn(void)
1220
{
1221
    tcg_gen_mov_tl(cpu_pc, cpu_npc);
1222
    tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
1223
}
1224

    
1225
static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond)
1226
{
1227
    TCGv r_src;
1228

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

    
1289
static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
1290
{
1291
    unsigned int offset;
1292

    
1293
    switch (cc) {
1294
    default:
1295
    case 0x0:
1296
        offset = 0;
1297
        break;
1298
    case 0x1:
1299
        offset = 32 - 10;
1300
        break;
1301
    case 0x2:
1302
        offset = 34 - 10;
1303
        break;
1304
    case 0x3:
1305
        offset = 36 - 10;
1306
        break;
1307
    }
1308

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

    
1361
#ifdef TARGET_SPARC64
1362
// Inverted logic
1363
static const int gen_tcg_cond_reg[8] = {
1364
    -1,
1365
    TCG_COND_NE,
1366
    TCG_COND_GT,
1367
    TCG_COND_GE,
1368
    -1,
1369
    TCG_COND_EQ,
1370
    TCG_COND_LE,
1371
    TCG_COND_LT,
1372
};
1373

    
1374
static inline void gen_cond_reg(TCGv r_dst, int cond)
1375
{
1376
    int l1;
1377

    
1378
    l1 = gen_new_label();
1379
    tcg_gen_movi_tl(r_dst, 0);
1380
    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0], tcg_const_tl(0), l1);
1381
    tcg_gen_movi_tl(r_dst, 1);
1382
    gen_set_label(l1);
1383
}
1384
#endif
1385

    
1386
/* XXX: potentially incorrect if dynamic npc */
1387
static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
1388
{
1389
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1390
    target_ulong target = dc->pc + offset;
1391

    
1392
    if (cond == 0x0) {
1393
        /* unconditional not taken */
1394
        if (a) {
1395
            dc->pc = dc->npc + 4;
1396
            dc->npc = dc->pc + 4;
1397
        } else {
1398
            dc->pc = dc->npc;
1399
            dc->npc = dc->pc + 4;
1400
        }
1401
    } else if (cond == 0x8) {
1402
        /* unconditional taken */
1403
        if (a) {
1404
            dc->pc = target;
1405
            dc->npc = dc->pc + 4;
1406
        } else {
1407
            dc->pc = dc->npc;
1408
            dc->npc = target;
1409
        }
1410
    } else {
1411
        flush_T2(dc);
1412
        gen_cond(cpu_T[2], cc, cond);
1413
        if (a) {
1414
            gen_branch_a(dc, target, dc->npc, cpu_T[2]);
1415
            dc->is_br = 1;
1416
        } else {
1417
            dc->pc = dc->npc;
1418
            dc->jump_pc[0] = target;
1419
            dc->jump_pc[1] = dc->npc + 4;
1420
            dc->npc = JUMP_PC;
1421
        }
1422
    }
1423
}
1424

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

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

    
1464
#ifdef TARGET_SPARC64
1465
/* XXX: potentially incorrect if dynamic npc */
1466
static void do_branch_reg(DisasContext * dc, int32_t offset, uint32_t insn)
1467
{
1468
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1469
    target_ulong target = dc->pc + offset;
1470

    
1471
    flush_T2(dc);
1472
    gen_cond_reg(cpu_T[2], cond);
1473
    if (a) {
1474
        gen_branch_a(dc, target, dc->npc, cpu_T[2]);
1475
        dc->is_br = 1;
1476
    } else {
1477
        dc->pc = dc->npc;
1478
        dc->jump_pc[0] = target;
1479
        dc->jump_pc[1] = dc->npc + 4;
1480
        dc->npc = JUMP_PC;
1481
    }
1482
}
1483

    
1484
static GenOpFunc * const gen_fcmps[4] = {
1485
    helper_fcmps,
1486
    helper_fcmps_fcc1,
1487
    helper_fcmps_fcc2,
1488
    helper_fcmps_fcc3,
1489
};
1490

    
1491
static GenOpFunc * const gen_fcmpd[4] = {
1492
    helper_fcmpd,
1493
    helper_fcmpd_fcc1,
1494
    helper_fcmpd_fcc2,
1495
    helper_fcmpd_fcc3,
1496
};
1497

    
1498
#if defined(CONFIG_USER_ONLY)
1499
static GenOpFunc * const gen_fcmpq[4] = {
1500
    helper_fcmpq,
1501
    helper_fcmpq_fcc1,
1502
    helper_fcmpq_fcc2,
1503
    helper_fcmpq_fcc3,
1504
};
1505
#endif
1506

    
1507
static GenOpFunc * const gen_fcmpes[4] = {
1508
    helper_fcmpes,
1509
    helper_fcmpes_fcc1,
1510
    helper_fcmpes_fcc2,
1511
    helper_fcmpes_fcc3,
1512
};
1513

    
1514
static GenOpFunc * const gen_fcmped[4] = {
1515
    helper_fcmped,
1516
    helper_fcmped_fcc1,
1517
    helper_fcmped_fcc2,
1518
    helper_fcmped_fcc3,
1519
};
1520

    
1521
#if defined(CONFIG_USER_ONLY)
1522
static GenOpFunc * const gen_fcmpeq[4] = {
1523
    helper_fcmpeq,
1524
    helper_fcmpeq_fcc1,
1525
    helper_fcmpeq_fcc2,
1526
    helper_fcmpeq_fcc3,
1527
};
1528
#endif
1529

    
1530
static inline void gen_op_fcmps(int fccno)
1531
{
1532
    tcg_gen_helper_0_0(gen_fcmps[fccno]);
1533
}
1534

    
1535
static inline void gen_op_fcmpd(int fccno)
1536
{
1537
    tcg_gen_helper_0_0(gen_fcmpd[fccno]);
1538
}
1539

    
1540
#if defined(CONFIG_USER_ONLY)
1541
static inline void gen_op_fcmpq(int fccno)
1542
{
1543
    tcg_gen_helper_0_0(gen_fcmpq[fccno]);
1544
}
1545
#endif
1546

    
1547
static inline void gen_op_fcmpes(int fccno)
1548
{
1549
    tcg_gen_helper_0_0(gen_fcmpes[fccno]);
1550
}
1551

    
1552
static inline void gen_op_fcmped(int fccno)
1553
{
1554
    tcg_gen_helper_0_0(gen_fcmped[fccno]);
1555
}
1556

    
1557
#if defined(CONFIG_USER_ONLY)
1558
static inline void gen_op_fcmpeq(int fccno)
1559
{
1560
    tcg_gen_helper_0_0(gen_fcmpeq[fccno]);
1561
}
1562
#endif
1563

    
1564
#else
1565

    
1566
static inline void gen_op_fcmps(int fccno)
1567
{
1568
    tcg_gen_helper_0_0(helper_fcmps);
1569
}
1570

    
1571
static inline void gen_op_fcmpd(int fccno)
1572
{
1573
    tcg_gen_helper_0_0(helper_fcmpd);
1574
}
1575

    
1576
#if defined(CONFIG_USER_ONLY)
1577
static inline void gen_op_fcmpq(int fccno)
1578
{
1579
    tcg_gen_helper_0_0(helper_fcmpq);
1580
}
1581
#endif
1582

    
1583
static inline void gen_op_fcmpes(int fccno)
1584
{
1585
    tcg_gen_helper_0_0(helper_fcmpes);
1586
}
1587

    
1588
static inline void gen_op_fcmped(int fccno)
1589
{
1590
    tcg_gen_helper_0_0(helper_fcmped);
1591
}
1592

    
1593
#if defined(CONFIG_USER_ONLY)
1594
static inline void gen_op_fcmpeq(int fccno)
1595
{
1596
    tcg_gen_helper_0_0(helper_fcmpeq);
1597
}
1598
#endif
1599

    
1600
#endif
1601

    
1602
static inline void gen_op_fpexception_im(int fsr_flags)
1603
{
1604
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~FSR_FTT_MASK);
1605
    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
1606
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_FP_EXCP));
1607
}
1608

    
1609
static int gen_trap_ifnofpu(DisasContext * dc)
1610
{
1611
#if !defined(CONFIG_USER_ONLY)
1612
    if (!dc->fpu_enabled) {
1613
        save_state(dc);
1614
        tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_NFPU_INSN));
1615
        dc->is_br = 1;
1616
        return 1;
1617
    }
1618
#endif
1619
    return 0;
1620
}
1621

    
1622
static inline void gen_op_clear_ieee_excp_and_FTT(void)
1623
{
1624
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~(FSR_FTT_MASK | FSR_CEXC_MASK));
1625
}
1626

    
1627
static inline void gen_clear_float_exceptions(void)
1628
{
1629
    tcg_gen_helper_0_0(helper_clear_float_exceptions);
1630
}
1631

    
1632
static inline void gen_check_align(TCGv r_addr, int align)
1633
{
1634
    tcg_gen_helper_0_2(helper_check_align, r_addr, tcg_const_i32(align));
1635
}
1636

    
1637
static inline void gen_op_check_align_T0_1(void)
1638
{
1639
    gen_check_align(cpu_T[0], 1);
1640
}
1641

    
1642
static inline void gen_op_check_align_T0_3(void)
1643
{
1644
    gen_check_align(cpu_T[0], 3);
1645
}
1646

    
1647
static inline void gen_op_check_align_T0_7(void)
1648
{
1649
    gen_check_align(cpu_T[0], 7);
1650
}
1651

    
1652
/* asi moves */
1653
#ifdef TARGET_SPARC64
1654
static inline TCGv gen_get_asi(int insn, TCGv r_addr)
1655
{
1656
    int asi, offset;
1657
    TCGv r_asi;
1658

    
1659
    if (IS_IMM) {
1660
        r_asi = tcg_temp_new(TCG_TYPE_I32);
1661
        offset = GET_FIELD(insn, 25, 31);
1662
        tcg_gen_addi_tl(r_addr, r_addr, offset);
1663
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
1664
    } else {
1665
        asi = GET_FIELD(insn, 19, 26);
1666
        r_asi = tcg_const_i32(asi);
1667
    }
1668
    return r_asi;
1669
}
1670

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

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

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

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

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

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

    
1701
static inline void gen_stf_asi(int insn, int size, int rd)
1702
{
1703
    TCGv r_asi;
1704

    
1705
    r_asi = gen_get_asi(insn, cpu_T[0]);
1706
    tcg_gen_helper_0_4(helper_stf_asi, cpu_T[0], r_asi, tcg_const_i32(size),
1707
                       tcg_const_i32(rd));
1708
    tcg_gen_discard_i32(r_asi);
1709
}
1710

    
1711
static inline void gen_swap_asi(int insn)
1712
{
1713
    TCGv r_temp, r_asi;
1714

    
1715
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1716
    r_asi = gen_get_asi(insn, cpu_T[0]);
1717
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, cpu_T[0], r_asi,
1718
                       tcg_const_i32(4), tcg_const_i32(0));
1719
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_temp, r_asi,
1720
                       tcg_const_i32(4));
1721
    tcg_gen_extu_i32_tl(cpu_T[1], r_temp);
1722
    tcg_gen_discard_i32(r_asi);
1723
    tcg_gen_discard_i32(r_temp);
1724
}
1725

    
1726
static inline void gen_ldda_asi(int insn)
1727
{
1728
    TCGv r_asi;
1729

    
1730
    r_asi = gen_get_asi(insn, cpu_T[0]);
1731
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, cpu_T[0], r_asi,
1732
                       tcg_const_i32(8), tcg_const_i32(0));
1733
    tcg_gen_andi_i64(cpu_T[0], cpu_tmp64, 0xffffffffULL);
1734
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1735
    tcg_gen_andi_i64(cpu_T[1], cpu_tmp64, 0xffffffffULL);
1736
    tcg_gen_discard_i32(r_asi);
1737
}
1738

    
1739
static inline void gen_stda_asi(int insn, int rd)
1740
{
1741
    TCGv r_temp, r_asi;
1742

    
1743
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1744
    gen_movl_reg_TN(rd + 1, r_temp);
1745
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, cpu_T[1],
1746
                       r_temp);
1747
    r_asi = gen_get_asi(insn, cpu_T[0]);
1748
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_tmp64, r_asi,
1749
                       tcg_const_i32(8));
1750
    tcg_gen_discard_i32(r_asi);
1751
    tcg_gen_discard_i32(r_temp);
1752
}
1753

    
1754
static inline void gen_cas_asi(int insn, int rd)
1755
{
1756
    TCGv r_val1, r_asi;
1757

    
1758
    r_val1 = tcg_temp_new(TCG_TYPE_I32);
1759
    gen_movl_reg_TN(rd, r_val1);
1760
    r_asi = gen_get_asi(insn, cpu_T[0]);
1761
    tcg_gen_helper_1_4(helper_cas_asi, cpu_T[1], cpu_T[0], r_val1, cpu_T[1],
1762
                       r_asi);
1763
    tcg_gen_discard_i32(r_asi);
1764
    tcg_gen_discard_i32(r_val1);
1765
}
1766

    
1767
static inline void gen_casx_asi(int insn, int rd)
1768
{
1769
    TCGv r_asi;
1770

    
1771
    gen_movl_reg_TN(rd, cpu_tmp64);
1772
    r_asi = gen_get_asi(insn, cpu_T[0]);
1773
    tcg_gen_helper_1_4(helper_casx_asi, cpu_T[1], cpu_T[0], cpu_tmp64, cpu_T[1],
1774
                       r_asi);
1775
    tcg_gen_discard_i32(r_asi);
1776
}
1777

    
1778
#elif !defined(CONFIG_USER_ONLY)
1779

    
1780
static inline void gen_ld_asi(int insn, int size, int sign)
1781
{
1782
    int asi;
1783

    
1784
    asi = GET_FIELD(insn, 19, 26);
1785
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, cpu_T[0], tcg_const_i32(asi),
1786
                       tcg_const_i32(size), tcg_const_i32(sign));
1787
    tcg_gen_trunc_i64_tl(cpu_T[1], cpu_tmp64);
1788
}
1789

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

    
1794
    tcg_gen_extu_tl_i64(cpu_tmp64, cpu_T[1]);
1795
    asi = GET_FIELD(insn, 19, 26);
1796
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_tmp64, tcg_const_i32(asi),
1797
                       tcg_const_i32(size));
1798
}
1799

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

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

    
1815
static inline void gen_ldda_asi(int insn)
1816
{
1817
    int asi;
1818

    
1819
    asi = GET_FIELD(insn, 19, 26);
1820
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, cpu_T[0], tcg_const_i32(asi),
1821
                       tcg_const_i32(8), tcg_const_i32(0));
1822
    tcg_gen_trunc_i64_tl(cpu_T[0], cpu_tmp64);
1823
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1824
    tcg_gen_trunc_i64_tl(cpu_T[1], cpu_tmp64);
1825
}
1826

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

    
1832
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1833
    gen_movl_reg_TN(rd + 1, r_temp);
1834
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, cpu_T[1], r_temp);
1835
    asi = GET_FIELD(insn, 19, 26);
1836
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_tmp64, tcg_const_i32(asi),
1837
                       tcg_const_i32(8));
1838
}
1839
#endif
1840

    
1841
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1842
static inline void gen_ldstub_asi(int insn)
1843
{
1844
    int asi;
1845

    
1846
    gen_ld_asi(insn, 1, 0);
1847

    
1848
    asi = GET_FIELD(insn, 19, 26);
1849
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], tcg_const_i64(0xffULL),
1850
                       tcg_const_i32(asi), tcg_const_i32(1));
1851
}
1852
#endif
1853

    
1854
/* before an instruction, dc->pc must be static */
1855
static void disas_sparc_insn(DisasContext * dc)
1856
{
1857
    unsigned int insn, opc, rs1, rs2, rd;
1858

    
1859
    insn = ldl_code(dc->pc);
1860
    opc = GET_FIELD(insn, 0, 1);
1861

    
1862
    rd = GET_FIELD(insn, 2, 6);
1863
    switch (opc) {
1864
    case 0:                     /* branches/sethi */
1865
        {
1866
            unsigned int xop = GET_FIELD(insn, 7, 9);
1867
            int32_t target;
1868
            switch (xop) {
1869
#ifdef TARGET_SPARC64
1870
            case 0x1:           /* V9 BPcc */
1871
                {
1872
                    int cc;
1873

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

    
1955
            gen_movl_TN_reg(15, tcg_const_tl(dc->pc));
1956
            target += dc->pc;
1957
            gen_mov_pc_npc(dc);
1958
            dc->npc = target;
1959
        }
1960
        goto jmp_insn;
1961
    case 2:                     /* FPU & Logical Operations */
1962
        {
1963
            unsigned int xop = GET_FIELD(insn, 7, 12);
1964
            if (xop == 0x3a) {  /* generate trap */
1965
                int cond;
1966

    
1967
                rs1 = GET_FIELD(insn, 13, 17);
1968
                gen_movl_reg_TN(rs1, cpu_T[0]);
1969
                if (IS_IMM) {
1970
                    rs2 = GET_FIELD(insn, 25, 31);
1971
                    tcg_gen_addi_tl(cpu_T[0], cpu_T[0], rs2);
1972
                } else {
1973
                    rs2 = GET_FIELD(insn, 27, 31);
1974
#if defined(OPTIM)
1975
                    if (rs2 != 0) {
1976
#endif
1977
                        gen_movl_reg_TN(rs2, cpu_T[1]);
1978
                        tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
1979
#if defined(OPTIM)
1980
                    }
1981
#endif
1982
                }
1983
                cond = GET_FIELD(insn, 3, 6);
1984
                if (cond == 0x8) {
1985
                    save_state(dc);
1986
                    tcg_gen_helper_0_1(helper_trap, cpu_T[0]);
1987
                } else if (cond != 0) {
1988
                    TCGv r_cond = tcg_temp_new(TCG_TYPE_TL);
1989
#ifdef TARGET_SPARC64
1990
                    /* V9 icc/xcc */
1991
                    int cc = GET_FIELD_SP(insn, 11, 12);
1992

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

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

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

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

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

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

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

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

    
2663
                    l1 = gen_new_label();
2664
                    cond = GET_FIELD_SP(insn, 14, 17);
2665
                    rs1 = GET_FIELD(insn, 13, 17);
2666
                    gen_movl_reg_TN(rs1, cpu_T[0]);
2667
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0],
2668
                                      tcg_const_tl(0), l1);
2669
                    gen_op_load_fpr_FT0(rs2);
2670
                    gen_op_store_FT0_fpr(rd);
2671
                    gen_set_label(l1);
2672
                    break;
2673
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
2674
                    int l1;
2675

    
2676
                    l1 = gen_new_label();
2677
                    cond = GET_FIELD_SP(insn, 14, 17);
2678
                    rs1 = GET_FIELD(insn, 13, 17);
2679
                    gen_movl_reg_TN(rs1, cpu_T[0]);
2680
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0],
2681
                                      tcg_const_tl(0), l1);
2682
                    gen_op_load_fpr_DT0(DFPREG(rs2));
2683
                    gen_op_store_DT0_fpr(DFPREG(rd));
2684
                    gen_set_label(l1);
2685
                    break;
2686
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
2687
#if defined(CONFIG_USER_ONLY)
2688
                    int l1;
2689

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

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

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

    
3173
                                    tcg_gen_xor_tl(cpu_T[0], cpu_T[0],
3174
                                                   cpu_T[1]);
3175
                                    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState,
3176
                                                                 tick_cmpr));
3177
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3178
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3179
                                                   offsetof(CPUState, tick));
3180
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3181
                                                       r_tickptr, cpu_T[0]);
3182
                                    tcg_gen_discard_ptr(r_tickptr);
3183
                                }
3184
                                break;
3185
                            case 0x18: /* System tick */
3186
#if !defined(CONFIG_USER_ONLY)
3187
                                if (!supervisor(dc))
3188
                                    goto illegal_insn;
3189
#endif
3190
                                {
3191
                                    TCGv r_tickptr;
3192

    
3193
                                    tcg_gen_xor_tl(cpu_T[0], cpu_T[0],
3194
                                                   cpu_T[1]);
3195
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3196
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3197
                                                   offsetof(CPUState, stick));
3198
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3199
                                                       r_tickptr, cpu_T[0]);
3200
                                    tcg_gen_discard_ptr(r_tickptr);
3201
                                }
3202
                                break;
3203
                            case 0x19: /* System tick compare */
3204
#if !defined(CONFIG_USER_ONLY)
3205
                                if (!supervisor(dc))
3206
                                    goto illegal_insn;
3207
#endif
3208
                                {
3209
                                    TCGv r_tickptr;
3210

    
3211
                                    tcg_gen_xor_tl(cpu_T[0], cpu_T[0],
3212
                                                   cpu_T[1]);
3213
                                    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState,
3214
                                                                 stick_cmpr));
3215
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3216
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3217
                                                   offsetof(CPUState, stick));
3218
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3219
                                                       r_tickptr, cpu_T[0]);
3220
                                    tcg_gen_discard_ptr(r_tickptr);
3221
                                }
3222
                                break;
3223

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

    
3278
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3279
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3280
                                                   offsetof(CPUState, tsptr));
3281
                                    tcg_gen_st_tl(cpu_T[0], r_tsptr,
3282
                                                  offsetof(trap_state, tpc));
3283
                                    tcg_gen_discard_ptr(r_tsptr);
3284
                                }
3285
                                break;
3286
                            case 1: // tnpc
3287
                                {
3288
                                    TCGv r_tsptr;
3289

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

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

    
3314
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3315
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3316
                                                   offsetof(CPUState, tsptr));
3317
                                    tcg_gen_st_i32(cpu_T[0], r_tsptr,
3318
                                                   offsetof(trap_state, tt));
3319
                                    tcg_gen_discard_ptr(r_tsptr);
3320
                                }
3321
                                break;
3322
                            case 4: // tick
3323
                                {
3324
                                    TCGv r_tickptr;
3325

    
3326
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3327
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3328
                                                   offsetof(CPUState, tick));
3329
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3330
                                                       r_tickptr, cpu_T[0]);
3331
                                    tcg_gen_discard_ptr(r_tickptr);
3332
                                }
3333
                                break;
3334
                            case 5: // tba
3335
                                tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, tbr));
3336
                                break;
3337
                            case 6: // pstate
3338
                                save_state(dc);
3339
                                tcg_gen_helper_0_1(helper_wrpstate, cpu_T[0]);
3340
                                gen_op_next_insn();
3341
                                tcg_gen_exit_tb(0);
3342
                                dc->is_br = 1;
3343
                                break;
3344
                            case 7: // tl
3345
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3346
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, tl));
3347
                                break;
3348
                            case 8: // pil
3349
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3350
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, psrpil));
3351
                                break;
3352
                            case 9: // cwp
3353
                                tcg_gen_helper_0_1(helper_wrcwp, cpu_T[0]);
3354
                                break;
3355
                            case 10: // cansave
3356
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3357
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, cansave));
3358
                                break;
3359
                            case 11: // canrestore
3360
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3361
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, canrestore));
3362
                                break;
3363
                            case 12: // cleanwin
3364
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3365
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, cleanwin));
3366
                                break;
3367
                            case 13: // otherwin
3368
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3369
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, otherwin));
3370
                                break;
3371
                            case 14: // wstate
3372
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3373
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, wstate));
3374
                                break;
3375
                            case 16: // UA2005 gl
3376
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3377
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, gl));
3378
                                break;
3379
                            case 26: // UA2005 strand status
3380
                                if (!hypervisor(dc))
3381
                                    goto priv_insn;
3382
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3383
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ssr));
3384
                                break;
3385
                            default:
3386
                                goto illegal_insn;
3387
                            }
3388
#else
3389
                            tcg_gen_andi_tl(cpu_T[0], cpu_T[0], ((1 << NWINDOWS) - 1));
3390
                            tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3391
                            tcg_gen_st_i32(cpu_tmp32, cpu_env, 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
                            tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3401
                            tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, tbr));
3402
#else
3403
                            if (!hypervisor(dc))
3404
                                goto priv_insn;
3405
                            tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
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
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3419
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, hintp));
3420
                                break;
3421
                            case 5: // htba
3422
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_T[0]);
3423
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, htba));
3424
                                break;
3425
                            case 31: // hstick_cmpr
3426
                                {
3427
                                    TCGv r_tickptr;
3428

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

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

    
3467
                            l1 = gen_new_label();
3468

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

    
3507
                            rs1 = GET_FIELD(insn, 13, 17);
3508
                            gen_movl_reg_TN(rs1, cpu_T[0]);
3509

    
3510
                            l1 = gen_new_label();
3511

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

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

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

    
4329
                        gen_op_check_align_T0_7();
4330
                        r_low = tcg_temp_new(TCG_TYPE_I32);
4331
                        gen_movl_reg_TN(rd + 1, r_low);
4332
                        tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, cpu_T[1],
4333
                                           r_low);
4334
                        tcg_gen_qemu_st64(cpu_tmp64, cpu_T[0], dc->mem_idx);
4335
                    }
4336
#else /* __i386__ */
4337
                    gen_op_check_align_T0_7();
4338
                    flush_T2(dc);
4339
                    gen_movl_reg_TN(rd + 1, cpu_T[2]);
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: /* store fpreg */
4407
                    gen_op_check_align_T0_3();
4408
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
4409
                                   offsetof(CPUState, fpr[rd]));
4410
                    tcg_gen_qemu_st32(cpu_tmp32, cpu_T[0], dc->mem_idx);
4411
                    break;
4412
                case 0x25: /* stfsr, V9 stxfsr */
4413
#ifdef CONFIG_USER_ONLY
4414
                    gen_op_check_align_T0_3();
4415
#endif
4416
                    tcg_gen_helper_0_0(helper_stfsr);
4417
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
4418
                                   offsetof(CPUState, ft0));
4419
                    tcg_gen_qemu_st32(cpu_tmp32, cpu_T[0], dc->mem_idx);
4420
                    break;
4421
                case 0x26:
4422
#ifdef TARGET_SPARC64
4423
#if defined(CONFIG_USER_ONLY)
4424
                    /* V9 stqf, store quad fpreg */
4425
                    gen_op_check_align_T0_7();
4426
                    gen_op_load_fpr_QT0(QFPREG(rd));
4427
                    gen_op_ldst(stqf);
4428
                    break;
4429
#else
4430
                    goto nfpu_insn;
4431
#endif
4432
#else /* !TARGET_SPARC64 */
4433
                    /* stdfq, store floating point queue */
4434
#if defined(CONFIG_USER_ONLY)
4435
                    goto illegal_insn;
4436
#else
4437
                    if (!supervisor(dc))
4438
                        goto priv_insn;
4439
                    if (gen_trap_ifnofpu(dc))
4440
                        goto jmp_insn;
4441
                    goto nfq_insn;
4442
#endif
4443
#endif
4444
                case 0x27:
4445
                    gen_op_check_align_T0_7();
4446
                    gen_op_load_fpr_DT0(DFPREG(rd));
4447
                    gen_op_ldst(stdf);
4448
                    break;
4449
                default:
4450
                    goto illegal_insn;
4451
                }
4452
            } else if (xop > 0x33 && xop < 0x3f) {
4453
                switch (xop) {
4454
#ifdef TARGET_SPARC64
4455
                case 0x34: /* V9 stfa */
4456
                    gen_op_check_align_T0_3();
4457
                    gen_op_load_fpr_FT0(rd);
4458
                    gen_stf_asi(insn, 4, rd);
4459
                    break;
4460
                case 0x36: /* V9 stqfa */
4461
#if defined(CONFIG_USER_ONLY)
4462
                    gen_op_check_align_T0_7();
4463
                    gen_op_load_fpr_QT0(QFPREG(rd));
4464
                    gen_stf_asi(insn, 16, QFPREG(rd));
4465
                    break;
4466
#else
4467
                    goto nfpu_insn;
4468
#endif
4469
                case 0x37: /* V9 stdfa */
4470
                    gen_op_check_align_T0_3();
4471
                    gen_op_load_fpr_DT0(DFPREG(rd));
4472
                    gen_stf_asi(insn, 8, DFPREG(rd));
4473
                    break;
4474
                case 0x3c: /* V9 casa */
4475
                    gen_op_check_align_T0_3();
4476
                    gen_cas_asi(insn, rd);
4477
                    gen_movl_TN_reg(rd, cpu_T[1]);
4478
                    break;
4479
                case 0x3e: /* V9 casxa */
4480
                    gen_op_check_align_T0_7();
4481
                    gen_casx_asi(insn, rd);
4482
                    gen_movl_TN_reg(rd, cpu_T[1]);
4483
                    break;
4484
#else
4485
                case 0x34: /* stc */
4486
                case 0x35: /* stcsr */
4487
                case 0x36: /* stdcq */
4488
                case 0x37: /* stdc */
4489
                    goto ncp_insn;
4490
#endif
4491
                default:
4492
                    goto illegal_insn;
4493
                }
4494
            }
4495
            else
4496
                goto illegal_insn;
4497
        }
4498
        break;
4499
    }
4500
    /* default case for non jump instructions */
4501
    if (dc->npc == DYNAMIC_PC) {
4502
        dc->pc = DYNAMIC_PC;
4503
        gen_op_next_insn();
4504
    } else if (dc->npc == JUMP_PC) {
4505
        /* we can do a static jump */
4506
        gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
4507
        dc->is_br = 1;
4508
    } else {
4509
        dc->pc = dc->npc;
4510
        dc->npc = dc->npc + 4;
4511
    }
4512
 jmp_insn:
4513
    return;
4514
 illegal_insn:
4515
    save_state(dc);
4516
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_ILL_INSN));
4517
    dc->is_br = 1;
4518
    return;
4519
#if !defined(CONFIG_USER_ONLY)
4520
 priv_insn:
4521
    save_state(dc);
4522
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_PRIV_INSN));
4523
    dc->is_br = 1;
4524
    return;
4525
 nfpu_insn:
4526
    save_state(dc);
4527
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
4528
    dc->is_br = 1;
4529
    return;
4530
#ifndef TARGET_SPARC64
4531
 nfq_insn:
4532
    save_state(dc);
4533
    gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
4534
    dc->is_br = 1;
4535
    return;
4536
#endif
4537
#endif
4538
#ifndef TARGET_SPARC64
4539
 ncp_insn:
4540
    save_state(dc);
4541
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_NCP_INSN));
4542
    dc->is_br = 1;
4543
    return;
4544
#endif
4545
}
4546

    
4547
static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
4548
{
4549
}
4550

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

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

    
4569
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
4570
    cpu_tmp32 = tcg_temp_new(TCG_TYPE_I32);
4571
    cpu_tmp64 = tcg_temp_new(TCG_TYPE_I64);
4572

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

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

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

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

    
4666
int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
4667
{
4668
    return gen_intermediate_code_internal(tb, 1, env);
4669
}
4670

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

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

    
4720
    def = cpu_sparc_find_by_name(cpu_model);
4721
    if (!def)
4722
        return NULL;
4723

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

    
4741
    /* init various static tables */
4742
    if (!inited) {
4743
        inited = 1;
4744

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

    
4793
    cpu_reset(env);
4794
    
4795
    return env;
4796
}
4797

    
4798
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
4799
{
4800
#if !defined(TARGET_SPARC64)
4801
    env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
4802
#endif
4803
}
4804

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

    
5125
static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name)
5126
{
5127
    unsigned int i;
5128

    
5129
    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
5130
        if (strcasecmp(name, sparc_defs[i].name) == 0) {
5131
            return &sparc_defs[i];
5132
        }
5133
    }
5134
    return NULL;
5135
}
5136

    
5137
void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
5138
{
5139
    unsigned int i;
5140

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

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

    
5152
void cpu_dump_state(CPUState *env, FILE *f,
5153
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5154
                    int flags)
5155
{
5156
    int i, x;
5157

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

    
5202
#if defined(CONFIG_USER_ONLY)
5203
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
5204
{
5205
    return addr;
5206
}
5207

    
5208
#else
5209
extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
5210
                                 int *access_index, target_ulong address, int rw,
5211
                                 int mmu_idx);
5212

    
5213
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
5214
{
5215
    target_phys_addr_t phys_addr;
5216
    int prot, access_index;
5217

    
5218
    if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2,
5219
                             MMU_KERNEL_IDX) != 0)
5220
        if (get_physical_address(env, &phys_addr, &prot, &access_index, addr,
5221
                                 0, MMU_KERNEL_IDX) != 0)
5222
            return -1;
5223
    if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED)
5224
        return -1;
5225
    return phys_addr;
5226
}
5227
#endif
5228

    
5229
void helper_flush(target_ulong addr)
5230
{
5231
    addr &= ~7;
5232
    tb_invalidate_page_range(addr, addr + 8);
5233
}