Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ 6ae20372

History | View | Annotate | Download (189.6 kB)

1
/*
2
   SPARC translation
3

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

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

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

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

    
22
/*
23
   TODO-list:
24

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

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

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

    
42
#define DEBUG_DISAS
43

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

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

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

    
68
typedef struct sparc_def_t sparc_def_t;
69

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

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

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

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

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

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

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

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

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

    
116
/* floating point registers moves */
117
static void gen_op_load_fpr_FT0(unsigned int src)
118
{
119
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
120
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft0));
121
}
122

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
400
    l1 = gen_new_label();
401

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

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

    
419
    l1 = gen_new_label();
420

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

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

    
438
    l1 = gen_new_label();
439

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

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

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

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

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

    
475
static inline void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2)
476
{
477
    tcg_gen_mov_tl(cpu_cc_src, src1);
478
    tcg_gen_add_tl(dst, src1, src2);
479
    gen_cc_clear_icc();
480
    gen_cc_NZ_icc(dst);
481
    gen_cc_C_add_icc(dst, cpu_cc_src);
482
    gen_cc_V_add_icc(dst, cpu_cc_src, src2);
483
#ifdef TARGET_SPARC64
484
    gen_cc_clear_xcc();
485
    gen_cc_NZ_xcc(dst);
486
    gen_cc_C_add_xcc(dst, cpu_cc_src);
487
    gen_cc_V_add_xcc(dst, cpu_cc_src, src2);
488
#endif
489
}
490

    
491
static inline void gen_op_addx_cc(TCGv dst, TCGv src1, TCGv src2)
492
{
493
    tcg_gen_mov_tl(cpu_cc_src, src1);
494
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
495
    tcg_gen_add_tl(dst, src1, cpu_tmp0);
496
    gen_cc_clear_icc();
497
    gen_cc_C_add_icc(dst, cpu_cc_src);
498
#ifdef TARGET_SPARC64
499
    gen_cc_clear_xcc();
500
    gen_cc_C_add_xcc(dst, cpu_cc_src);
501
#endif
502
    tcg_gen_add_tl(dst, dst, src2);
503
    gen_cc_NZ_icc(dst);
504
    gen_cc_C_add_icc(dst, cpu_cc_src);
505
    gen_cc_V_add_icc(dst, cpu_cc_src, src2);
506
#ifdef TARGET_SPARC64
507
    gen_cc_NZ_xcc(dst);
508
    gen_cc_C_add_xcc(dst, cpu_cc_src);
509
    gen_cc_V_add_xcc(dst, cpu_cc_src, src2);
510
#endif
511
}
512

    
513
static inline void gen_op_tadd_cc(TCGv dst, TCGv src1, TCGv src2)
514
{
515
    tcg_gen_mov_tl(cpu_cc_src, src1);
516
    tcg_gen_add_tl(dst, src1, src2);
517
    gen_cc_clear_icc();
518
    gen_cc_NZ_icc(dst);
519
    gen_cc_C_add_icc(dst, cpu_cc_src);
520
    gen_cc_V_add_icc(dst, cpu_cc_src, src2);
521
    gen_cc_V_tag(cpu_cc_src, src2);
522
#ifdef TARGET_SPARC64
523
    gen_cc_clear_xcc();
524
    gen_cc_NZ_xcc(dst);
525
    gen_cc_C_add_xcc(dst, cpu_cc_src);
526
    gen_cc_V_add_xcc(dst, cpu_cc_src, src2);
527
#endif
528
}
529

    
530
static inline void gen_op_tadd_ccTV(TCGv dst, TCGv src1, TCGv src2)
531
{
532
    gen_tag_tv(src1, src2);
533
    tcg_gen_mov_tl(cpu_cc_src, src1);
534
    tcg_gen_add_tl(dst, src1, src2);
535
    gen_add_tv(dst, cpu_cc_src, src2);
536
    gen_cc_clear_icc();
537
    gen_cc_NZ_icc(dst);
538
    gen_cc_C_add_icc(dst, cpu_cc_src);
539
#ifdef TARGET_SPARC64
540
    gen_cc_clear_xcc();
541
    gen_cc_NZ_xcc(dst);
542
    gen_cc_C_add_xcc(dst, cpu_cc_src);
543
    gen_cc_V_add_xcc(dst, cpu_cc_src, src2);
544
#endif
545
}
546

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

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

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

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

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

    
587
    l1 = gen_new_label();
588

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

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

    
605
    l1 = gen_new_label();
606

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

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

    
623
    l1 = gen_new_label();
624

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

    
636
static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2)
637
{
638
    tcg_gen_mov_tl(cpu_cc_src, src1);
639
    tcg_gen_sub_tl(dst, src1, src2);
640
    gen_cc_clear_icc();
641
    gen_cc_NZ_icc(dst);
642
    gen_cc_C_sub_icc(cpu_cc_src, src2);
643
    gen_cc_V_sub_icc(dst, cpu_cc_src, src2);
644
#ifdef TARGET_SPARC64
645
    gen_cc_clear_xcc();
646
    gen_cc_NZ_xcc(dst);
647
    gen_cc_C_sub_xcc(cpu_cc_src, src2);
648
    gen_cc_V_sub_xcc(dst, cpu_cc_src, src2);
649
#endif
650
}
651

    
652
static inline void gen_op_subx_cc(TCGv dst, TCGv src1, TCGv src2)
653
{
654
    tcg_gen_mov_tl(cpu_cc_src, src1);
655
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
656
    tcg_gen_sub_tl(dst, src1, cpu_tmp0);
657
    gen_cc_clear_icc();
658
    gen_cc_C_sub_icc(dst, cpu_cc_src);
659
#ifdef TARGET_SPARC64
660
    gen_cc_clear_xcc();
661
    gen_cc_C_sub_xcc(dst, cpu_cc_src);
662
#endif
663
    tcg_gen_sub_tl(dst, dst, src2);
664
    gen_cc_NZ_icc(dst);
665
    gen_cc_C_sub_icc(dst, cpu_cc_src);
666
    gen_cc_V_sub_icc(dst, cpu_cc_src, src2);
667
#ifdef TARGET_SPARC64
668
    gen_cc_NZ_xcc(dst);
669
    gen_cc_C_sub_xcc(dst, cpu_cc_src);
670
    gen_cc_V_sub_xcc(dst, cpu_cc_src, src2);
671
#endif
672
}
673

    
674
static inline void gen_op_tsub_cc(TCGv dst, TCGv src1, TCGv src2)
675
{
676
    tcg_gen_mov_tl(cpu_cc_src, src1);
677
    tcg_gen_sub_tl(dst, src1, src2);
678
    gen_cc_clear_icc();
679
    gen_cc_NZ_icc(dst);
680
    gen_cc_C_sub_icc(cpu_cc_src, src2);
681
    gen_cc_V_sub_icc(dst, cpu_cc_src, src2);
682
    gen_cc_V_tag(cpu_cc_src, src2);
683
#ifdef TARGET_SPARC64
684
    gen_cc_clear_xcc();
685
    gen_cc_NZ_xcc(dst);
686
    gen_cc_C_sub_xcc(cpu_cc_src, src2);
687
    gen_cc_V_sub_xcc(dst, cpu_cc_src, src2);
688
#endif
689
}
690

    
691
static inline void gen_op_tsub_ccTV(TCGv dst, TCGv src1, TCGv src2)
692
{
693
    gen_tag_tv(src1, src2);
694
    tcg_gen_mov_tl(cpu_cc_src, src1);
695
    tcg_gen_sub_tl(dst, src1, src2);
696
    gen_sub_tv(dst, cpu_cc_src, src2);
697
    gen_cc_clear_icc();
698
    gen_cc_NZ_icc(dst);
699
    gen_cc_C_sub_icc(cpu_cc_src, src2);
700
#ifdef TARGET_SPARC64
701
    gen_cc_clear_xcc();
702
    gen_cc_NZ_xcc(dst);
703
    gen_cc_C_sub_xcc(cpu_cc_src, src2);
704
    gen_cc_V_sub_xcc(dst, cpu_cc_src, src2);
705
#endif
706
}
707

    
708
static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
709
{
710
    TCGv r_temp, r_temp2;
711
    int l1, l2;
712

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

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

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

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

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

    
753
    /* do addition and update flags */
754
    tcg_gen_add_tl(dst, cpu_cc_src, cpu_cc_src2);
755
    tcg_gen_discard_tl(r_temp);
756

    
757
    gen_cc_clear_icc();
758
    gen_cc_NZ_icc(dst);
759
    gen_cc_V_add_icc(dst, cpu_cc_src, cpu_cc_src2);
760
    gen_cc_C_add_icc(dst, cpu_cc_src);
761
}
762

    
763
static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
764
{
765
    TCGv r_temp, r_temp2;
766

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

    
770
    tcg_gen_extu_tl_i64(r_temp, src2);
771
    tcg_gen_extu_tl_i64(r_temp2, src1);
772
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
773

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

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

    
787
static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
788
{
789
    TCGv r_temp, r_temp2;
790

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

    
794
    tcg_gen_ext_tl_i64(r_temp, src2);
795
    tcg_gen_ext_tl_i64(r_temp2, src1);
796
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
797

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

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

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

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

    
822
static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
823
{
824
    int l1, l2;
825

    
826
    l1 = gen_new_label();
827
    l2 = gen_new_label();
828
    gen_trap_ifdivzero_tl(src2);
829
    tcg_gen_brcond_tl(TCG_COND_NE, src1, tcg_const_tl(INT64_MIN), l1);
830
    tcg_gen_brcond_tl(TCG_COND_NE, src2, tcg_const_tl(-1), l1);
831
    tcg_gen_movi_i64(dst, INT64_MIN);
832
    tcg_gen_br(l2);
833
    gen_set_label(l1);
834
    tcg_gen_div_i64(dst, src1, src2);
835
    gen_set_label(l2);
836
}
837
#endif
838

    
839
static inline void gen_op_div_cc(TCGv dst)
840
{
841
    int l1;
842

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

    
852
static inline void gen_op_logic_cc(TCGv dst)
853
{
854
    gen_cc_clear_icc();
855
    gen_cc_NZ_icc(dst);
856
#ifdef TARGET_SPARC64
857
    gen_cc_clear_xcc();
858
    gen_cc_NZ_xcc(dst);
859
#endif
860
}
861

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1138
    l1 = gen_new_label();
1139

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

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

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

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

    
1153
    l1 = gen_new_label();
1154

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

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

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

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

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

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

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

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

    
1181
/* call this function before using the condition register as it may
1182
   have been set for a jump */
1183
static inline void flush_cond(DisasContext *dc, TCGv cond)
1184
{
1185
    if (dc->npc == JUMP_PC) {
1186
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1187
        dc->npc = DYNAMIC_PC;
1188
    }
1189
}
1190

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

    
1201
static inline void save_state(DisasContext *dc, TCGv cond)
1202
{
1203
    tcg_gen_movi_tl(cpu_pc, dc->pc);
1204
    save_npc(dc, cond);
1205
}
1206

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

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

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

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

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

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

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

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

    
1376
static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
1377
{
1378
    int l1;
1379

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

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

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

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

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

    
1468
#ifdef TARGET_SPARC64
1469
/* XXX: potentially incorrect if dynamic npc */
1470
static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
1471
                          TCGv r_cond, TCGv r_reg)
1472
{
1473
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1474
    target_ulong target = dc->pc + offset;
1475

    
1476
    flush_cond(dc, r_cond);
1477
    gen_cond_reg(r_cond, cond, r_reg);
1478
    if (a) {
1479
        gen_branch_a(dc, target, dc->npc, r_cond);
1480
        dc->is_br = 1;
1481
    } else {
1482
        dc->pc = dc->npc;
1483
        dc->jump_pc[0] = target;
1484
        dc->jump_pc[1] = dc->npc + 4;
1485
        dc->npc = JUMP_PC;
1486
    }
1487
}
1488

    
1489
static GenOpFunc * const gen_fcmps[4] = {
1490
    helper_fcmps,
1491
    helper_fcmps_fcc1,
1492
    helper_fcmps_fcc2,
1493
    helper_fcmps_fcc3,
1494
};
1495

    
1496
static GenOpFunc * const gen_fcmpd[4] = {
1497
    helper_fcmpd,
1498
    helper_fcmpd_fcc1,
1499
    helper_fcmpd_fcc2,
1500
    helper_fcmpd_fcc3,
1501
};
1502

    
1503
#if defined(CONFIG_USER_ONLY)
1504
static GenOpFunc * const gen_fcmpq[4] = {
1505
    helper_fcmpq,
1506
    helper_fcmpq_fcc1,
1507
    helper_fcmpq_fcc2,
1508
    helper_fcmpq_fcc3,
1509
};
1510
#endif
1511

    
1512
static GenOpFunc * const gen_fcmpes[4] = {
1513
    helper_fcmpes,
1514
    helper_fcmpes_fcc1,
1515
    helper_fcmpes_fcc2,
1516
    helper_fcmpes_fcc3,
1517
};
1518

    
1519
static GenOpFunc * const gen_fcmped[4] = {
1520
    helper_fcmped,
1521
    helper_fcmped_fcc1,
1522
    helper_fcmped_fcc2,
1523
    helper_fcmped_fcc3,
1524
};
1525

    
1526
#if defined(CONFIG_USER_ONLY)
1527
static GenOpFunc * const gen_fcmpeq[4] = {
1528
    helper_fcmpeq,
1529
    helper_fcmpeq_fcc1,
1530
    helper_fcmpeq_fcc2,
1531
    helper_fcmpeq_fcc3,
1532
};
1533
#endif
1534

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

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

    
1545
#if defined(CONFIG_USER_ONLY)
1546
static inline void gen_op_fcmpq(int fccno)
1547
{
1548
    tcg_gen_helper_0_0(gen_fcmpq[fccno]);
1549
}
1550
#endif
1551

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

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

    
1562
#if defined(CONFIG_USER_ONLY)
1563
static inline void gen_op_fcmpeq(int fccno)
1564
{
1565
    tcg_gen_helper_0_0(gen_fcmpeq[fccno]);
1566
}
1567
#endif
1568

    
1569
#else
1570

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

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

    
1581
#if defined(CONFIG_USER_ONLY)
1582
static inline void gen_op_fcmpq(int fccno)
1583
{
1584
    tcg_gen_helper_0_0(helper_fcmpq);
1585
}
1586
#endif
1587

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

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

    
1598
#if defined(CONFIG_USER_ONLY)
1599
static inline void gen_op_fcmpeq(int fccno)
1600
{
1601
    tcg_gen_helper_0_0(helper_fcmpeq);
1602
}
1603
#endif
1604

    
1605
#endif
1606

    
1607
static inline void gen_op_fpexception_im(int fsr_flags)
1608
{
1609
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~FSR_FTT_MASK);
1610
    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
1611
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_FP_EXCP));
1612
}
1613

    
1614
static int gen_trap_ifnofpu(DisasContext *dc, TCGv r_cond)
1615
{
1616
#if !defined(CONFIG_USER_ONLY)
1617
    if (!dc->fpu_enabled) {
1618
        save_state(dc, r_cond);
1619
        tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_NFPU_INSN));
1620
        dc->is_br = 1;
1621
        return 1;
1622
    }
1623
#endif
1624
    return 0;
1625
}
1626

    
1627
static inline void gen_op_clear_ieee_excp_and_FTT(void)
1628
{
1629
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~(FSR_FTT_MASK | FSR_CEXC_MASK));
1630
}
1631

    
1632
static inline void gen_clear_float_exceptions(void)
1633
{
1634
    tcg_gen_helper_0_0(helper_clear_float_exceptions);
1635
}
1636

    
1637
/* asi moves */
1638
#ifdef TARGET_SPARC64
1639
static inline TCGv gen_get_asi(int insn, TCGv r_addr)
1640
{
1641
    int asi, offset;
1642
    TCGv r_asi;
1643

    
1644
    if (IS_IMM) {
1645
        r_asi = tcg_temp_new(TCG_TYPE_I32);
1646
        offset = GET_FIELD(insn, 25, 31);
1647
        tcg_gen_addi_tl(r_addr, r_addr, offset);
1648
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
1649
    } else {
1650
        asi = GET_FIELD(insn, 19, 26);
1651
        r_asi = tcg_const_i32(asi);
1652
    }
1653
    return r_asi;
1654
}
1655

    
1656
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size, int sign)
1657
{
1658
    TCGv r_asi;
1659

    
1660
    r_asi = gen_get_asi(insn, addr);
1661
    tcg_gen_helper_1_4(helper_ld_asi, dst, addr, r_asi,
1662
                       tcg_const_i32(size), tcg_const_i32(sign));
1663
    tcg_gen_discard_i32(r_asi);
1664
}
1665

    
1666
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1667
{
1668
    TCGv r_asi;
1669

    
1670
    r_asi = gen_get_asi(insn, addr);
1671
    tcg_gen_helper_0_4(helper_st_asi, addr, src, r_asi, tcg_const_i32(size));
1672
    tcg_gen_discard_i32(r_asi);
1673
}
1674

    
1675
static inline void gen_ldf_asi(TCGv addr, int insn, int size, int rd)
1676
{
1677
    TCGv r_asi;
1678

    
1679
    r_asi = gen_get_asi(insn, addr);
1680
    tcg_gen_helper_0_4(helper_ldf_asi, addr, r_asi, tcg_const_i32(size),
1681
                       tcg_const_i32(rd));
1682
    tcg_gen_discard_i32(r_asi);
1683
}
1684

    
1685
static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
1686
{
1687
    TCGv r_asi;
1688

    
1689
    r_asi = gen_get_asi(insn, addr);
1690
    tcg_gen_helper_0_4(helper_stf_asi, addr, r_asi, tcg_const_i32(size),
1691
                       tcg_const_i32(rd));
1692
    tcg_gen_discard_i32(r_asi);
1693
}
1694

    
1695
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1696
{
1697
    TCGv r_temp, r_asi;
1698

    
1699
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1700
    r_asi = gen_get_asi(insn, addr);
1701
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, addr, r_asi,
1702
                       tcg_const_i32(4), tcg_const_i32(0));
1703
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, r_asi,
1704
                       tcg_const_i32(4));
1705
    tcg_gen_extu_i32_tl(dst, r_temp);
1706
    tcg_gen_discard_i32(r_asi);
1707
    tcg_gen_discard_i32(r_temp);
1708
}
1709

    
1710
static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn)
1711
{
1712
    TCGv r_asi;
1713

    
1714
    r_asi = gen_get_asi(insn, addr);
1715
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi,
1716
                       tcg_const_i32(8), tcg_const_i32(0));
1717
    tcg_gen_andi_i64(lo, cpu_tmp64, 0xffffffffULL);
1718
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1719
    tcg_gen_andi_i64(hi, cpu_tmp64, 0xffffffffULL);
1720
    tcg_gen_discard_i32(r_asi);
1721
}
1722

    
1723
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1724
{
1725
    TCGv r_temp, r_asi;
1726

    
1727
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1728
    gen_movl_reg_TN(rd + 1, r_temp);
1729
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi,
1730
                       r_temp);
1731
    r_asi = gen_get_asi(insn, addr);
1732
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi,
1733
                       tcg_const_i32(8));
1734
    tcg_gen_discard_i32(r_asi);
1735
    tcg_gen_discard_i32(r_temp);
1736
}
1737

    
1738
static inline void gen_cas_asi(TCGv dst, TCGv addr, TCGv val2, int insn, int rd)
1739
{
1740
    TCGv r_val1, r_asi;
1741

    
1742
    r_val1 = tcg_temp_new(TCG_TYPE_I32);
1743
    gen_movl_reg_TN(rd, r_val1);
1744
    r_asi = gen_get_asi(insn, addr);
1745
    tcg_gen_helper_1_4(helper_cas_asi, dst, addr, r_val1, val2, r_asi);
1746
    tcg_gen_discard_i32(r_asi);
1747
    tcg_gen_discard_i32(r_val1);
1748
}
1749

    
1750
static inline void gen_casx_asi(TCGv dst, TCGv addr, TCGv val2, int insn, int rd)
1751
{
1752
    TCGv r_asi;
1753

    
1754
    gen_movl_reg_TN(rd, cpu_tmp64);
1755
    r_asi = gen_get_asi(insn, addr);
1756
    tcg_gen_helper_1_4(helper_casx_asi, dst, addr, cpu_tmp64, val2, r_asi);
1757
    tcg_gen_discard_i32(r_asi);
1758
}
1759

    
1760
#elif !defined(CONFIG_USER_ONLY)
1761

    
1762
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size, int sign)
1763
{
1764
    int asi;
1765

    
1766
    asi = GET_FIELD(insn, 19, 26);
1767
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, tcg_const_i32(asi),
1768
                       tcg_const_i32(size), tcg_const_i32(sign));
1769
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1770
}
1771

    
1772
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1773
{
1774
    int asi;
1775

    
1776
    tcg_gen_extu_tl_i64(cpu_tmp64, src);
1777
    asi = GET_FIELD(insn, 19, 26);
1778
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, tcg_const_i32(asi),
1779
                       tcg_const_i32(size));
1780
}
1781

    
1782
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1783
{
1784
    int asi;
1785
    TCGv r_temp;
1786

    
1787
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1788
    asi = GET_FIELD(insn, 19, 26);
1789
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, addr, tcg_const_i32(asi),
1790
                       tcg_const_i32(4), tcg_const_i32(0));
1791
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, tcg_const_i32(asi),
1792
                       tcg_const_i32(4));
1793
    tcg_gen_extu_i32_tl(dst, r_temp);
1794
    tcg_gen_discard_i32(r_temp);
1795
}
1796

    
1797
static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn)
1798
{
1799
    int asi;
1800

    
1801
    asi = GET_FIELD(insn, 19, 26);
1802
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, tcg_const_i32(asi),
1803
                       tcg_const_i32(8), tcg_const_i32(0));
1804
    tcg_gen_trunc_i64_tl(lo, cpu_tmp64);
1805
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1806
    tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
1807
}
1808

    
1809
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1810
{
1811
    int asi;
1812
    TCGv r_temp;
1813

    
1814
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1815
    gen_movl_reg_TN(rd + 1, r_temp);
1816
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi, r_temp);
1817
    asi = GET_FIELD(insn, 19, 26);
1818
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, tcg_const_i32(asi),
1819
                       tcg_const_i32(8));
1820
}
1821
#endif
1822

    
1823
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1824
static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
1825
{
1826
    int asi;
1827

    
1828
    gen_ld_asi(dst, addr, insn, 1, 0);
1829

    
1830
    asi = GET_FIELD(insn, 19, 26);
1831
    tcg_gen_helper_0_4(helper_st_asi, addr, tcg_const_i64(0xffULL),
1832
                       tcg_const_i32(asi), tcg_const_i32(1));
1833
}
1834
#endif
1835

    
1836
/* before an instruction, dc->pc must be static */
1837
static void disas_sparc_insn(DisasContext * dc)
1838
{
1839
    unsigned int insn, opc, rs1, rs2, rd;
1840

    
1841
    insn = ldl_code(dc->pc);
1842
    opc = GET_FIELD(insn, 0, 1);
1843

    
1844
    rd = GET_FIELD(insn, 2, 6);
1845

    
1846
    cpu_dst = cpu_T[0];
1847
    cpu_src1 = cpu_T[0]; // const
1848
    cpu_src2 = cpu_T[1]; // const
1849

    
1850
    // loads and stores
1851
    cpu_addr = cpu_T[0];
1852
    cpu_val = cpu_T[1];
1853

    
1854
    switch (opc) {
1855
    case 0:                     /* branches/sethi */
1856
        {
1857
            unsigned int xop = GET_FIELD(insn, 7, 9);
1858
            int32_t target;
1859
            switch (xop) {
1860
#ifdef TARGET_SPARC64
1861
            case 0x1:           /* V9 BPcc */
1862
                {
1863
                    int cc;
1864

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

    
1946
            gen_movl_TN_reg(15, tcg_const_tl(dc->pc));
1947
            target += dc->pc;
1948
            gen_mov_pc_npc(dc, cpu_cond);
1949
            dc->npc = target;
1950
        }
1951
        goto jmp_insn;
1952
    case 2:                     /* FPU & Logical Operations */
1953
        {
1954
            unsigned int xop = GET_FIELD(insn, 7, 12);
1955
            if (xop == 0x3a) {  /* generate trap */
1956
                int cond;
1957

    
1958
                rs1 = GET_FIELD(insn, 13, 17);
1959
                gen_movl_reg_TN(rs1, cpu_src1);
1960
                if (IS_IMM) {
1961
                    rs2 = GET_FIELD(insn, 25, 31);
1962
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, rs2);
1963
                } else {
1964
                    rs2 = GET_FIELD(insn, 27, 31);
1965
#if defined(OPTIM)
1966
                    if (rs2 != 0) {
1967
#endif
1968
                        gen_movl_reg_TN(rs2, cpu_src2);
1969
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
1970
#if defined(OPTIM)
1971
                    }
1972
#endif
1973
                }
1974
                cond = GET_FIELD(insn, 3, 6);
1975
                if (cond == 0x8) {
1976
                    save_state(dc, cpu_cond);
1977
                    tcg_gen_helper_0_1(helper_trap, cpu_dst);
1978
                } else if (cond != 0) {
1979
                    TCGv r_cond = tcg_temp_new(TCG_TYPE_TL);
1980
#ifdef TARGET_SPARC64
1981
                    /* V9 icc/xcc */
1982
                    int cc = GET_FIELD_SP(insn, 11, 12);
1983

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

    
2033
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2034
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2035
                                       offsetof(CPUState, tick));
2036
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst,
2037
                                           r_tickptr);
2038
                        gen_movl_TN_reg(rd, cpu_dst);
2039
                        tcg_gen_discard_ptr(r_tickptr);
2040
                    }
2041
                    break;
2042
                case 0x5: /* V9 rdpc */
2043
                    tcg_gen_movi_tl(cpu_dst, dc->pc);
2044
                    gen_movl_TN_reg(rd, cpu_dst);
2045
                    break;
2046
                case 0x6: /* V9 rdfprs */
2047
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fprs));
2048
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2049
                    gen_movl_TN_reg(rd, cpu_dst);
2050
                    break;
2051
                case 0xf: /* V9 membar */
2052
                    break; /* no effect */
2053
                case 0x13: /* Graphics Status */
2054
                    if (gen_trap_ifnofpu(dc, cpu_cond))
2055
                        goto jmp_insn;
2056
                    tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, gsr));
2057
                    gen_movl_TN_reg(rd, cpu_dst);
2058
                    break;
2059
                case 0x17: /* Tick compare */
2060
                    tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, tick_cmpr));
2061
                    gen_movl_TN_reg(rd, cpu_dst);
2062
                    break;
2063
                case 0x18: /* System tick */
2064
                    {
2065
                        TCGv r_tickptr;
2066

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

    
2139
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2140
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2141
                                       offsetof(CPUState, tsptr));
2142
                        tcg_gen_ld_tl(cpu_dst, r_tsptr,
2143
                                      offsetof(trap_state, tpc));
2144
                        tcg_gen_discard_ptr(r_tsptr);
2145
                    }
2146
                    break;
2147
                case 1: // tnpc
2148
                    {
2149
                        TCGv r_tsptr;
2150

    
2151
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2152
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2153
                                       offsetof(CPUState, tsptr));
2154
                        tcg_gen_ld_tl(cpu_dst, r_tsptr,
2155
                                      offsetof(trap_state, tnpc));
2156
                        tcg_gen_discard_ptr(r_tsptr);
2157
                    }
2158
                    break;
2159
                case 2: // tstate
2160
                    {
2161
                        TCGv r_tsptr;
2162

    
2163
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2164
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2165
                                       offsetof(CPUState, tsptr));
2166
                        tcg_gen_ld_tl(cpu_dst, r_tsptr,
2167
                                      offsetof(trap_state, tstate));
2168
                        tcg_gen_discard_ptr(r_tsptr);
2169
                    }
2170
                    break;
2171
                case 3: // tt
2172
                    {
2173
                        TCGv r_tsptr;
2174

    
2175
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2176
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2177
                                       offsetof(CPUState, tsptr));
2178
                        tcg_gen_ld_i32(cpu_dst, r_tsptr,
2179
                                       offsetof(trap_state, tt));
2180
                        tcg_gen_discard_ptr(r_tsptr);
2181
                    }
2182
                    break;
2183
                case 4: // tick
2184
                    {
2185
                        TCGv r_tickptr;
2186

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

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

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

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

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

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

    
3164
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
3165
                                                   cpu_src2);
3166
                                    tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState,
3167
                                                                 tick_cmpr));
3168
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3169
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3170
                                                   offsetof(CPUState, tick));
3171
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3172
                                                       r_tickptr, cpu_dst);
3173
                                    tcg_gen_discard_ptr(r_tickptr);
3174
                                }
3175
                                break;
3176
                            case 0x18: /* System tick */
3177
#if !defined(CONFIG_USER_ONLY)
3178
                                if (!supervisor(dc))
3179
                                    goto illegal_insn;
3180
#endif
3181
                                {
3182
                                    TCGv r_tickptr;
3183

    
3184
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
3185
                                                   cpu_src2);
3186
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3187
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3188
                                                   offsetof(CPUState, stick));
3189
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3190
                                                       r_tickptr, cpu_dst);
3191
                                    tcg_gen_discard_ptr(r_tickptr);
3192
                                }
3193
                                break;
3194
                            case 0x19: /* System tick compare */
3195
#if !defined(CONFIG_USER_ONLY)
3196
                                if (!supervisor(dc))
3197
                                    goto illegal_insn;
3198
#endif
3199
                                {
3200
                                    TCGv r_tickptr;
3201

    
3202
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
3203
                                                   cpu_src2);
3204
                                    tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState,
3205
                                                                 stick_cmpr));
3206
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3207
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3208
                                                   offsetof(CPUState, stick));
3209
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3210
                                                       r_tickptr, cpu_dst);
3211
                                    tcg_gen_discard_ptr(r_tickptr);
3212
                                }
3213
                                break;
3214

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

    
3269
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3270
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3271
                                                   offsetof(CPUState, tsptr));
3272
                                    tcg_gen_st_tl(cpu_dst, r_tsptr,
3273
                                                  offsetof(trap_state, tpc));
3274
                                    tcg_gen_discard_ptr(r_tsptr);
3275
                                }
3276
                                break;
3277
                            case 1: // tnpc
3278
                                {
3279
                                    TCGv r_tsptr;
3280

    
3281
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3282
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3283
                                                   offsetof(CPUState, tsptr));
3284
                                    tcg_gen_st_tl(cpu_dst, r_tsptr,
3285
                                                  offsetof(trap_state, tnpc));
3286
                                    tcg_gen_discard_ptr(r_tsptr);
3287
                                }
3288
                                break;
3289
                            case 2: // tstate
3290
                                {
3291
                                    TCGv r_tsptr;
3292

    
3293
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3294
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3295
                                                   offsetof(CPUState, tsptr));
3296
                                    tcg_gen_st_tl(cpu_dst, r_tsptr,
3297
                                                  offsetof(trap_state, tstate));
3298
                                    tcg_gen_discard_ptr(r_tsptr);
3299
                                }
3300
                                break;
3301
                            case 3: // tt
3302
                                {
3303
                                    TCGv r_tsptr;
3304

    
3305
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3306
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3307
                                                   offsetof(CPUState, tsptr));
3308
                                    tcg_gen_st_i32(cpu_dst, r_tsptr,
3309
                                                   offsetof(trap_state, tt));
3310
                                    tcg_gen_discard_ptr(r_tsptr);
3311
                                }
3312
                                break;
3313
                            case 4: // tick
3314
                                {
3315
                                    TCGv r_tickptr;
3316

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

    
3420
                                    tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState,
3421
                                                                 hstick_cmpr));
3422
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3423
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3424
                                                   offsetof(CPUState, hstick));
3425
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3426
                                                       r_tickptr, cpu_dst);
3427
                                    tcg_gen_discard_ptr(r_tickptr);
3428
                                }
3429
                                break;
3430
                            case 6: // hver readonly
3431
                            default:
3432
                                goto illegal_insn;
3433
                            }
3434
#endif
3435
                        }
3436
                        break;
3437
#endif
3438
#ifdef TARGET_SPARC64
3439
                    case 0x2c: /* V9 movcc */
3440
                        {
3441
                            int cc = GET_FIELD_SP(insn, 11, 12);
3442
                            int cond = GET_FIELD_SP(insn, 14, 17);
3443
                            TCGv r_cond;
3444
                            int l1;
3445

    
3446
                            r_cond = tcg_temp_new(TCG_TYPE_TL);
3447
                            if (insn & (1 << 18)) {
3448
                                if (cc == 0)
3449
                                    gen_cond(r_cond, 0, cond);
3450
                                else if (cc == 2)
3451
                                    gen_cond(r_cond, 1, cond);
3452
                                else
3453
                                    goto illegal_insn;
3454
                            } else {
3455
                                gen_fcond(r_cond, cc, cond);
3456
                            }
3457

    
3458
                            l1 = gen_new_label();
3459

    
3460
                            tcg_gen_brcond_tl(TCG_COND_EQ, r_cond,
3461
                                              tcg_const_tl(0), l1);
3462
                            if (IS_IMM) {       /* immediate */
3463
                                rs2 = GET_FIELD_SPs(insn, 0, 10);
3464
                                tcg_gen_movi_tl(cpu_dst, (int)rs2);
3465
                            } else {
3466
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3467
                                gen_movl_reg_TN(rs2, cpu_dst);
3468
                            }
3469
                            gen_movl_TN_reg(rd, cpu_dst);
3470
                            gen_set_label(l1);
3471
                            tcg_gen_discard_tl(r_cond);
3472
                            break;
3473
                        }
3474
                    case 0x2d: /* V9 sdivx */
3475
                        gen_op_sdivx(cpu_dst, cpu_src1, cpu_src2);
3476
                        gen_movl_TN_reg(rd, cpu_dst);
3477
                        break;
3478
                    case 0x2e: /* V9 popc */
3479
                        {
3480
                            if (IS_IMM) {       /* immediate */
3481
                                rs2 = GET_FIELD_SPs(insn, 0, 12);
3482
                                tcg_gen_movi_tl(cpu_src2, (int)rs2);
3483
                                // XXX optimize: popc(constant)
3484
                            }
3485
                            else {
3486
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3487
                                gen_movl_reg_TN(rs2, cpu_src2);
3488
                            }
3489
                            tcg_gen_helper_1_1(helper_popc, cpu_dst,
3490
                                               cpu_src2);
3491
                            gen_movl_TN_reg(rd, cpu_dst);
3492
                        }
3493
                    case 0x2f: /* V9 movr */
3494
                        {
3495
                            int cond = GET_FIELD_SP(insn, 10, 12);
3496
                            int l1;
3497

    
3498
                            rs1 = GET_FIELD(insn, 13, 17);
3499
                            gen_movl_reg_TN(rs1, cpu_src1);
3500

    
3501
                            l1 = gen_new_label();
3502

    
3503
                            tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_src1,
3504
                                              tcg_const_tl(0), l1);
3505
                            if (IS_IMM) {       /* immediate */
3506
                                rs2 = GET_FIELD_SPs(insn, 0, 9);
3507
                                tcg_gen_movi_tl(cpu_dst, (int)rs2);
3508
                            } else {
3509
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3510
                                gen_movl_reg_TN(rs2, cpu_dst);
3511
                            }
3512
                            gen_movl_TN_reg(rd, cpu_dst);
3513
                            gen_set_label(l1);
3514
                            break;
3515
                        }
3516
#endif
3517
                    default:
3518
                        goto illegal_insn;
3519
                    }
3520
                }
3521
            } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
3522
#ifdef TARGET_SPARC64
3523
                int opf = GET_FIELD_SP(insn, 5, 13);
3524
                rs1 = GET_FIELD(insn, 13, 17);
3525
                rs2 = GET_FIELD(insn, 27, 31);
3526
                if (gen_trap_ifnofpu(dc, cpu_cond))
3527
                    goto jmp_insn;
3528

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

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

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

    
4538
static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
4539
{
4540
}
4541

    
4542
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
4543
                                                 int spc, CPUSPARCState *env)
4544
{
4545
    target_ulong pc_start, last_pc;
4546
    uint16_t *gen_opc_end;
4547
    DisasContext dc1, *dc = &dc1;
4548
    int j, lj = -1;
4549

    
4550
    memset(dc, 0, sizeof(DisasContext));
4551
    dc->tb = tb;
4552
    pc_start = tb->pc;
4553
    dc->pc = pc_start;
4554
    last_pc = dc->pc;
4555
    dc->npc = (target_ulong) tb->cs_base;
4556
    dc->mem_idx = cpu_mmu_index(env);
4557
    dc->fpu_enabled = cpu_fpu_enabled(env);
4558
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4559

    
4560
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
4561
    cpu_tmp32 = tcg_temp_new(TCG_TYPE_I32);
4562
    cpu_tmp64 = tcg_temp_new(TCG_TYPE_I64);
4563

    
4564
    cpu_cond = cpu_T[2];
4565

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

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

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

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

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

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

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

    
4713
    def = cpu_sparc_find_by_name(cpu_model);
4714
    if (!def)
4715
        return NULL;
4716

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

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

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

    
4786
    cpu_reset(env);
4787
    
4788
    return env;
4789
}
4790

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

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

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

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

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

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

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

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

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

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

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

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

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

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