Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ a49d9390

History | View | Annotate | Download (173.4 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
extern FILE *logfile;
69
extern int loglevel;
70

    
71
// This function uses non-native bit order
72
#define GET_FIELD(X, FROM, TO) \
73
  ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
74

    
75
// This function uses the order in the manuals, i.e. bit 0 is 2^0
76
#define GET_FIELD_SP(X, FROM, TO) \
77
    GET_FIELD(X, 31 - (TO), 31 - (FROM))
78

    
79
#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
80
#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
81

    
82
#ifdef TARGET_SPARC64
83
#define FFPREG(r) (r)
84
#define DFPREG(r) (((r & 1) << 5) | (r & 0x1e))
85
#define QFPREG(r) (((r & 1) << 5) | (r & 0x1c))
86
#else
87
#define FFPREG(r) (r)
88
#define DFPREG(r) (r & 0x1e)
89
#define QFPREG(r) (r & 0x1c)
90
#endif
91

    
92
static int sign_extend(int x, int len)
93
{
94
    len = 32 - len;
95
    return (x << len) >> len;
96
}
97

    
98
#define IS_IMM (insn & (1<<13))
99

    
100
/* floating point registers moves */
101
static void gen_op_load_fpr_FT0(unsigned int src)
102
{
103
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
104
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft0));
105
}
106

    
107
static void gen_op_load_fpr_FT1(unsigned int src)
108
{
109
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
110
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft1));
111
}
112

    
113
static void gen_op_store_FT0_fpr(unsigned int dst)
114
{
115
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft0));
116
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst]));
117
}
118

    
119
static void gen_op_load_fpr_DT0(unsigned int src)
120
{
121
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
122
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) + offsetof(CPU_DoubleU, l.upper));
123
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
124
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) + offsetof(CPU_DoubleU, l.lower));
125
}
126

    
127
static void gen_op_load_fpr_DT1(unsigned int src)
128
{
129
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
130
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt1) + offsetof(CPU_DoubleU, l.upper));
131
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
132
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt1) + offsetof(CPU_DoubleU, l.lower));
133
}
134

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

    
143
#ifdef CONFIG_USER_ONLY
144
static void gen_op_load_fpr_QT0(unsigned int src)
145
{
146
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
147
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upmost));
148
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
149
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upper));
150
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 2]));
151
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lower));
152
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 3]));
153
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lowest));
154
}
155

    
156
static void gen_op_load_fpr_QT1(unsigned int src)
157
{
158
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
159
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.upmost));
160
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
161
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.upper));
162
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 2]));
163
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.lower));
164
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 3]));
165
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.lowest));
166
}
167

    
168
static void gen_op_store_QT0_fpr(unsigned int dst)
169
{
170
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upmost));
171
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst]));
172
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upper));
173
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 1]));
174
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lower));
175
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 2]));
176
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lowest));
177
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 3]));
178
}
179
#endif
180

    
181
/* moves */
182
#ifdef CONFIG_USER_ONLY
183
#define supervisor(dc) 0
184
#ifdef TARGET_SPARC64
185
#define hypervisor(dc) 0
186
#endif
187
#define gen_op_ldst(name)        gen_op_##name##_raw()
188
#else
189
#define supervisor(dc) (dc->mem_idx >= 1)
190
#ifdef TARGET_SPARC64
191
#define hypervisor(dc) (dc->mem_idx == 2)
192
#define OP_LD_TABLE(width)                                              \
193
    static GenOpFunc * const gen_op_##width[] = {                       \
194
        &gen_op_##width##_user,                                         \
195
        &gen_op_##width##_kernel,                                       \
196
        &gen_op_##width##_hypv,                                         \
197
    };
198
#else
199
#define OP_LD_TABLE(width)                                              \
200
    static GenOpFunc * const gen_op_##width[] = {                       \
201
        &gen_op_##width##_user,                                         \
202
        &gen_op_##width##_kernel,                                       \
203
    };
204
#endif
205
#define gen_op_ldst(name)        (*gen_op_##name[dc->mem_idx])()
206
#endif
207

    
208
#ifndef CONFIG_USER_ONLY
209
#ifdef __i386__
210
OP_LD_TABLE(std);
211
#endif /* __i386__ */
212
OP_LD_TABLE(stdf);
213
OP_LD_TABLE(lddf);
214
#endif
215

    
216
#ifdef TARGET_ABI32
217
#define ABI32_MASK(addr) tcg_gen_andi_tl(addr, addr, 0xffffffffULL);
218
#else
219
#define ABI32_MASK(addr)
220
#endif
221

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

    
233
static inline void gen_movl_TN_reg(int reg, TCGv tn)
234
{
235
    if (reg == 0)
236
        return;
237
    else if (reg < 8)
238
        tcg_gen_mov_tl(cpu_gregs[reg], tn);
239
    else {
240
        tcg_gen_st_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
241
    }
242
}
243

    
244
static inline void gen_goto_tb(DisasContext *s, int tb_num,
245
                               target_ulong pc, target_ulong npc)
246
{
247
    TranslationBlock *tb;
248

    
249
    tb = s->tb;
250
    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
251
        (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK))  {
252
        /* jump to same page: we can use a direct jump */
253
        tcg_gen_goto_tb(tb_num);
254
        tcg_gen_movi_tl(cpu_pc, pc);
255
        tcg_gen_movi_tl(cpu_npc, npc);
256
        tcg_gen_exit_tb((long)tb + tb_num);
257
    } else {
258
        /* jump to another page: currently not optimized */
259
        tcg_gen_movi_tl(cpu_pc, pc);
260
        tcg_gen_movi_tl(cpu_npc, npc);
261
        tcg_gen_exit_tb(0);
262
    }
263
}
264

    
265
// XXX suboptimal
266
static inline void gen_mov_reg_N(TCGv reg, TCGv src)
267
{
268
    tcg_gen_extu_i32_tl(reg, src);
269
    tcg_gen_shri_tl(reg, reg, 23);
270
    tcg_gen_andi_tl(reg, reg, 0x1);
271
}
272

    
273
static inline void gen_mov_reg_Z(TCGv reg, TCGv src)
274
{
275
    tcg_gen_extu_i32_tl(reg, src);
276
    tcg_gen_shri_tl(reg, reg, 22);
277
    tcg_gen_andi_tl(reg, reg, 0x1);
278
}
279

    
280
static inline void gen_mov_reg_V(TCGv reg, TCGv src)
281
{
282
    tcg_gen_extu_i32_tl(reg, src);
283
    tcg_gen_shri_tl(reg, reg, 21);
284
    tcg_gen_andi_tl(reg, reg, 0x1);
285
}
286

    
287
static inline void gen_mov_reg_C(TCGv reg, TCGv src)
288
{
289
    tcg_gen_extu_i32_tl(reg, src);
290
    tcg_gen_shri_tl(reg, reg, 20);
291
    tcg_gen_andi_tl(reg, reg, 0x1);
292
}
293

    
294
static inline void gen_cc_clear_icc(void)
295
{
296
    tcg_gen_movi_i32(cpu_psr, 0);
297
}
298

    
299
#ifdef TARGET_SPARC64
300
static inline void gen_cc_clear_xcc(void)
301
{
302
    tcg_gen_movi_i32(cpu_xcc, 0);
303
}
304
#endif
305

    
306
/* old op:
307
    if (!T0)
308
        env->psr |= PSR_ZERO;
309
    if ((int32_t) T0 < 0)
310
        env->psr |= PSR_NEG;
311
*/
312
static inline void gen_cc_NZ_icc(TCGv dst)
313
{
314
    TCGv r_temp;
315
    int l1, l2;
316

    
317
    l1 = gen_new_label();
318
    l2 = gen_new_label();
319
    r_temp = tcg_temp_new(TCG_TYPE_TL);
320
    tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
321
    tcg_gen_brcond_tl(TCG_COND_NE, r_temp, tcg_const_tl(0), l1);
322
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_ZERO);
323
    gen_set_label(l1);
324
    tcg_gen_ext_i32_tl(r_temp, dst);
325
    tcg_gen_brcond_tl(TCG_COND_GE, r_temp, tcg_const_tl(0), l2);
326
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_NEG);
327
    gen_set_label(l2);
328
}
329

    
330
#ifdef TARGET_SPARC64
331
static inline void gen_cc_NZ_xcc(TCGv dst)
332
{
333
    int l1, l2;
334

    
335
    l1 = gen_new_label();
336
    l2 = gen_new_label();
337
    tcg_gen_brcond_tl(TCG_COND_NE, dst, tcg_const_tl(0), l1);
338
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_ZERO);
339
    gen_set_label(l1);
340
    tcg_gen_brcond_tl(TCG_COND_GE, dst, tcg_const_tl(0), l2);
341
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_NEG);
342
    gen_set_label(l2);
343
}
344
#endif
345

    
346
/* old op:
347
    if (T0 < src1)
348
        env->psr |= PSR_CARRY;
349
*/
350
static inline void gen_cc_C_add_icc(TCGv dst, TCGv src1)
351
{
352
    TCGv r_temp;
353
    int l1;
354

    
355
    l1 = gen_new_label();
356
    r_temp = tcg_temp_new(TCG_TYPE_TL);
357
    tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
358
    tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l1);
359
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
360
    gen_set_label(l1);
361
}
362

    
363
#ifdef TARGET_SPARC64
364
static inline void gen_cc_C_add_xcc(TCGv dst, TCGv src1)
365
{
366
    int l1;
367

    
368
    l1 = gen_new_label();
369
    tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l1);
370
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
371
    gen_set_label(l1);
372
}
373
#endif
374

    
375
/* old op:
376
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
377
        env->psr |= PSR_OVF;
378
*/
379
static inline void gen_cc_V_add_icc(TCGv dst, TCGv src1, TCGv src2)
380
{
381
    TCGv r_temp;
382
    int l1;
383

    
384
    l1 = gen_new_label();
385

    
386
    r_temp = tcg_temp_new(TCG_TYPE_TL);
387
    tcg_gen_xor_tl(r_temp, src1, src2);
388
    tcg_gen_xori_tl(r_temp, r_temp, -1);
389
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
390
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
391
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
392
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
393
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
394
    gen_set_label(l1);
395
}
396

    
397
#ifdef TARGET_SPARC64
398
static inline void gen_cc_V_add_xcc(TCGv dst, TCGv src1, TCGv src2)
399
{
400
    TCGv r_temp;
401
    int l1;
402

    
403
    l1 = gen_new_label();
404

    
405
    r_temp = tcg_temp_new(TCG_TYPE_TL);
406
    tcg_gen_xor_tl(r_temp, src1, src2);
407
    tcg_gen_xori_tl(r_temp, r_temp, -1);
408
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
409
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
410
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
411
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
412
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_OVF);
413
    gen_set_label(l1);
414
}
415
#endif
416

    
417
static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
418
{
419
    TCGv r_temp;
420
    int l1;
421

    
422
    l1 = gen_new_label();
423

    
424
    r_temp = tcg_temp_new(TCG_TYPE_TL);
425
    tcg_gen_xor_tl(r_temp, src1, src2);
426
    tcg_gen_xori_tl(r_temp, r_temp, -1);
427
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
428
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
429
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
430
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
431
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
432
    gen_set_label(l1);
433
}
434

    
435
static inline void gen_cc_V_tag(TCGv src1, TCGv src2)
436
{
437
    int l1;
438

    
439
    l1 = gen_new_label();
440
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
441
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
442
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
443
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
444
    gen_set_label(l1);
445
}
446

    
447
static inline void gen_tag_tv(TCGv src1, TCGv src2)
448
{
449
    int l1;
450

    
451
    l1 = gen_new_label();
452
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
453
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
454
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
455
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
456
    gen_set_label(l1);
457
}
458

    
459
static inline void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2)
460
{
461
    tcg_gen_mov_tl(cpu_cc_src, src1);
462
    tcg_gen_add_tl(dst, src1, src2);
463
    gen_cc_clear_icc();
464
    gen_cc_NZ_icc(dst);
465
    gen_cc_C_add_icc(dst, cpu_cc_src);
466
    gen_cc_V_add_icc(dst, cpu_cc_src, src2);
467
#ifdef TARGET_SPARC64
468
    gen_cc_clear_xcc();
469
    gen_cc_NZ_xcc(dst);
470
    gen_cc_C_add_xcc(dst, cpu_cc_src);
471
    gen_cc_V_add_xcc(dst, cpu_cc_src, src2);
472
#endif
473
}
474

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

    
497
static inline void gen_op_tadd_cc(TCGv dst, TCGv src1, TCGv src2)
498
{
499
    tcg_gen_mov_tl(cpu_cc_src, src1);
500
    tcg_gen_add_tl(dst, src1, src2);
501
    gen_cc_clear_icc();
502
    gen_cc_NZ_icc(dst);
503
    gen_cc_C_add_icc(dst, cpu_cc_src);
504
    gen_cc_V_add_icc(dst, cpu_cc_src, src2);
505
    gen_cc_V_tag(cpu_cc_src, src2);
506
#ifdef TARGET_SPARC64
507
    gen_cc_clear_xcc();
508
    gen_cc_NZ_xcc(dst);
509
    gen_cc_C_add_xcc(dst, cpu_cc_src);
510
    gen_cc_V_add_xcc(dst, cpu_cc_src, src2);
511
#endif
512
}
513

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

    
531
/* old op:
532
    if (src1 < T1)
533
        env->psr |= PSR_CARRY;
534
*/
535
static inline void gen_cc_C_sub_icc(TCGv src1, TCGv src2)
536
{
537
    TCGv r_temp1, r_temp2;
538
    int l1;
539

    
540
    l1 = gen_new_label();
541
    r_temp1 = tcg_temp_new(TCG_TYPE_TL);
542
    r_temp2 = tcg_temp_new(TCG_TYPE_TL);
543
    tcg_gen_andi_tl(r_temp1, src1, 0xffffffffULL);
544
    tcg_gen_andi_tl(r_temp2, src2, 0xffffffffULL);
545
    tcg_gen_brcond_tl(TCG_COND_GEU, r_temp1, r_temp2, l1);
546
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
547
    gen_set_label(l1);
548
}
549

    
550
#ifdef TARGET_SPARC64
551
static inline void gen_cc_C_sub_xcc(TCGv src1, TCGv src2)
552
{
553
    int l1;
554

    
555
    l1 = gen_new_label();
556
    tcg_gen_brcond_tl(TCG_COND_GEU, src1, src2, l1);
557
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
558
    gen_set_label(l1);
559
}
560
#endif
561

    
562
/* old op:
563
    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
564
        env->psr |= PSR_OVF;
565
*/
566
static inline void gen_cc_V_sub_icc(TCGv dst, TCGv src1, TCGv src2)
567
{
568
    TCGv r_temp;
569
    int l1;
570

    
571
    l1 = gen_new_label();
572

    
573
    r_temp = tcg_temp_new(TCG_TYPE_TL);
574
    tcg_gen_xor_tl(r_temp, src1, src2);
575
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
576
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
577
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
578
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
579
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
580
    gen_set_label(l1);
581
}
582

    
583
#ifdef TARGET_SPARC64
584
static inline void gen_cc_V_sub_xcc(TCGv dst, TCGv src1, TCGv src2)
585
{
586
    TCGv r_temp;
587
    int l1;
588

    
589
    l1 = gen_new_label();
590

    
591
    r_temp = tcg_temp_new(TCG_TYPE_TL);
592
    tcg_gen_xor_tl(r_temp, src1, src2);
593
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
594
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
595
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
596
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
597
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_OVF);
598
    gen_set_label(l1);
599
}
600
#endif
601

    
602
static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
603
{
604
    TCGv r_temp;
605
    int l1;
606

    
607
    l1 = gen_new_label();
608

    
609
    r_temp = tcg_temp_new(TCG_TYPE_TL);
610
    tcg_gen_xor_tl(r_temp, src1, src2);
611
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
612
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
613
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
614
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
615
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
616
    gen_set_label(l1);
617
    tcg_gen_discard_tl(r_temp);
618
}
619

    
620
static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2)
621
{
622
    tcg_gen_mov_tl(cpu_cc_src, src1);
623
    tcg_gen_sub_tl(dst, src1, src2);
624
    gen_cc_clear_icc();
625
    gen_cc_NZ_icc(dst);
626
    gen_cc_C_sub_icc(cpu_cc_src, src2);
627
    gen_cc_V_sub_icc(dst, cpu_cc_src, src2);
628
#ifdef TARGET_SPARC64
629
    gen_cc_clear_xcc();
630
    gen_cc_NZ_xcc(dst);
631
    gen_cc_C_sub_xcc(cpu_cc_src, src2);
632
    gen_cc_V_sub_xcc(dst, cpu_cc_src, src2);
633
#endif
634
}
635

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

    
658
static inline void gen_op_tsub_cc(TCGv dst, TCGv src1, TCGv src2)
659
{
660
    tcg_gen_mov_tl(cpu_cc_src, src1);
661
    tcg_gen_sub_tl(dst, src1, src2);
662
    gen_cc_clear_icc();
663
    gen_cc_NZ_icc(dst);
664
    gen_cc_C_sub_icc(cpu_cc_src, src2);
665
    gen_cc_V_sub_icc(dst, cpu_cc_src, src2);
666
    gen_cc_V_tag(cpu_cc_src, src2);
667
#ifdef TARGET_SPARC64
668
    gen_cc_clear_xcc();
669
    gen_cc_NZ_xcc(dst);
670
    gen_cc_C_sub_xcc(cpu_cc_src, src2);
671
    gen_cc_V_sub_xcc(dst, cpu_cc_src, src2);
672
#endif
673
}
674

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

    
692
static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
693
{
694
    TCGv r_temp, r_temp2;
695
    int l1, l2;
696

    
697
    l1 = gen_new_label();
698
    l2 = gen_new_label();
699
    r_temp = tcg_temp_new(TCG_TYPE_TL);
700
    r_temp2 = tcg_temp_new(TCG_TYPE_I32);
701

    
702
    /* old op:
703
    if (!(env->y & 1))
704
        T1 = 0;
705
    */
706
    tcg_gen_ld32u_tl(r_temp, cpu_env, offsetof(CPUSPARCState, y));
707
    tcg_gen_trunc_tl_i32(r_temp2, r_temp);
708
    tcg_gen_andi_i32(r_temp2, r_temp2, 0x1);
709
    tcg_gen_brcond_i32(TCG_COND_EQ, r_temp2, tcg_const_i32(0), l1);
710
    tcg_gen_mov_tl(cpu_cc_src2, src2);
711
    tcg_gen_br(l2);
712
    gen_set_label(l1);
713
    tcg_gen_movi_tl(cpu_cc_src2, 0);
714
    gen_set_label(l2);
715

    
716
    // b2 = T0 & 1;
717
    // env->y = (b2 << 31) | (env->y >> 1);
718
    tcg_gen_trunc_tl_i32(r_temp2, src1);
719
    tcg_gen_andi_i32(r_temp2, r_temp2, 0x1);
720
    tcg_gen_shli_i32(r_temp2, r_temp2, 31);
721
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, y));
722
    tcg_gen_shri_i32(cpu_tmp32, cpu_tmp32, 1);
723
    tcg_gen_or_i32(cpu_tmp32, cpu_tmp32, r_temp2);
724
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, y));
725

    
726
    // b1 = N ^ V;
727
    gen_mov_reg_N(cpu_tmp0, cpu_psr);
728
    gen_mov_reg_V(r_temp, cpu_psr);
729
    tcg_gen_xor_tl(cpu_tmp0, cpu_tmp0, r_temp);
730

    
731
    // T0 = (b1 << 31) | (T0 >> 1);
732
    // src1 = T0;
733
    tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
734
    tcg_gen_shri_tl(cpu_cc_src, src1, 1);
735
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
736

    
737
    /* do addition and update flags */
738
    tcg_gen_add_tl(dst, cpu_cc_src, cpu_cc_src2);
739
    tcg_gen_discard_tl(r_temp);
740

    
741
    gen_cc_clear_icc();
742
    gen_cc_NZ_icc(dst);
743
    gen_cc_V_add_icc(dst, cpu_cc_src, cpu_cc_src2);
744
    gen_cc_C_add_icc(dst, cpu_cc_src);
745
}
746

    
747
static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
748
{
749
    TCGv r_temp, r_temp2;
750

    
751
    r_temp = tcg_temp_new(TCG_TYPE_I64);
752
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);
753

    
754
    tcg_gen_extu_tl_i64(r_temp, src2);
755
    tcg_gen_extu_tl_i64(r_temp2, src1);
756
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
757

    
758
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
759
    tcg_gen_trunc_i64_i32(r_temp, r_temp);
760
    tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
761
#ifdef TARGET_SPARC64
762
    tcg_gen_mov_i64(dst, r_temp2);
763
#else
764
    tcg_gen_trunc_i64_tl(dst, r_temp2);
765
#endif
766

    
767
    tcg_gen_discard_i64(r_temp);
768
    tcg_gen_discard_i64(r_temp2);
769
}
770

    
771
static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
772
{
773
    TCGv r_temp, r_temp2;
774

    
775
    r_temp = tcg_temp_new(TCG_TYPE_I64);
776
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);
777

    
778
    tcg_gen_ext_tl_i64(r_temp, src2);
779
    tcg_gen_ext_tl_i64(r_temp2, src1);
780
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
781

    
782
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
783
    tcg_gen_trunc_i64_i32(r_temp, r_temp);
784
    tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
785
#ifdef TARGET_SPARC64
786
    tcg_gen_mov_i64(dst, r_temp2);
787
#else
788
    tcg_gen_trunc_i64_tl(dst, r_temp2);
789
#endif
790

    
791
    tcg_gen_discard_i64(r_temp);
792
    tcg_gen_discard_i64(r_temp2);
793
}
794

    
795
#ifdef TARGET_SPARC64
796
static inline void gen_trap_ifdivzero_tl(TCGv divisor)
797
{
798
    int l1;
799

    
800
    l1 = gen_new_label();
801
    tcg_gen_brcond_tl(TCG_COND_NE, divisor, tcg_const_tl(0), l1);
802
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_DIV_ZERO));
803
    gen_set_label(l1);
804
}
805

    
806
static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
807
{
808
    int l1, l2;
809

    
810
    l1 = gen_new_label();
811
    l2 = gen_new_label();
812
    gen_trap_ifdivzero_tl(src2);
813
    tcg_gen_brcond_tl(TCG_COND_NE, src1, tcg_const_tl(INT64_MIN), l1);
814
    tcg_gen_brcond_tl(TCG_COND_NE, src2, tcg_const_tl(-1), l1);
815
    tcg_gen_movi_i64(dst, INT64_MIN);
816
    tcg_gen_br(l2);
817
    gen_set_label(l1);
818
    tcg_gen_div_i64(dst, src1, src2);
819
    gen_set_label(l2);
820
}
821
#endif
822

    
823
static inline void gen_op_div_cc(TCGv dst)
824
{
825
    int l1;
826

    
827
    gen_cc_clear_icc();
828
    gen_cc_NZ_icc(dst);
829
    l1 = gen_new_label();
830
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, cc_src2));
831
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
832
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
833
    gen_set_label(l1);
834
}
835

    
836
static inline void gen_op_logic_cc(TCGv dst)
837
{
838
    gen_cc_clear_icc();
839
    gen_cc_NZ_icc(dst);
840
#ifdef TARGET_SPARC64
841
    gen_cc_clear_xcc();
842
    gen_cc_NZ_xcc(dst);
843
#endif
844
}
845

    
846
// 1
847
static inline void gen_op_eval_ba(TCGv dst)
848
{
849
    tcg_gen_movi_tl(dst, 1);
850
}
851

    
852
// Z
853
static inline void gen_op_eval_be(TCGv dst, TCGv src)
854
{
855
    gen_mov_reg_Z(dst, src);
856
}
857

    
858
// Z | (N ^ V)
859
static inline void gen_op_eval_ble(TCGv dst, TCGv src)
860
{
861
    gen_mov_reg_N(cpu_tmp0, src);
862
    gen_mov_reg_V(dst, src);
863
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
864
    gen_mov_reg_Z(cpu_tmp0, src);
865
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
866
}
867

    
868
// N ^ V
869
static inline void gen_op_eval_bl(TCGv dst, TCGv src)
870
{
871
    gen_mov_reg_V(cpu_tmp0, src);
872
    gen_mov_reg_N(dst, src);
873
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
874
}
875

    
876
// C | Z
877
static inline void gen_op_eval_bleu(TCGv dst, TCGv src)
878
{
879
    gen_mov_reg_Z(cpu_tmp0, src);
880
    gen_mov_reg_C(dst, src);
881
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
882
}
883

    
884
// C
885
static inline void gen_op_eval_bcs(TCGv dst, TCGv src)
886
{
887
    gen_mov_reg_C(dst, src);
888
}
889

    
890
// V
891
static inline void gen_op_eval_bvs(TCGv dst, TCGv src)
892
{
893
    gen_mov_reg_V(dst, src);
894
}
895

    
896
// 0
897
static inline void gen_op_eval_bn(TCGv dst)
898
{
899
    tcg_gen_movi_tl(dst, 0);
900
}
901

    
902
// N
903
static inline void gen_op_eval_bneg(TCGv dst, TCGv src)
904
{
905
    gen_mov_reg_N(dst, src);
906
}
907

    
908
// !Z
909
static inline void gen_op_eval_bne(TCGv dst, TCGv src)
910
{
911
    gen_mov_reg_Z(dst, src);
912
    tcg_gen_xori_tl(dst, dst, 0x1);
913
}
914

    
915
// !(Z | (N ^ V))
916
static inline void gen_op_eval_bg(TCGv dst, TCGv src)
917
{
918
    gen_mov_reg_N(cpu_tmp0, src);
919
    gen_mov_reg_V(dst, src);
920
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
921
    gen_mov_reg_Z(cpu_tmp0, src);
922
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
923
    tcg_gen_xori_tl(dst, dst, 0x1);
924
}
925

    
926
// !(N ^ V)
927
static inline void gen_op_eval_bge(TCGv dst, TCGv src)
928
{
929
    gen_mov_reg_V(cpu_tmp0, src);
930
    gen_mov_reg_N(dst, src);
931
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
932
    tcg_gen_xori_tl(dst, dst, 0x1);
933
}
934

    
935
// !(C | Z)
936
static inline void gen_op_eval_bgu(TCGv dst, TCGv src)
937
{
938
    gen_mov_reg_Z(cpu_tmp0, src);
939
    gen_mov_reg_C(dst, src);
940
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
941
    tcg_gen_xori_tl(dst, dst, 0x1);
942
}
943

    
944
// !C
945
static inline void gen_op_eval_bcc(TCGv dst, TCGv src)
946
{
947
    gen_mov_reg_C(dst, src);
948
    tcg_gen_xori_tl(dst, dst, 0x1);
949
}
950

    
951
// !N
952
static inline void gen_op_eval_bpos(TCGv dst, TCGv src)
953
{
954
    gen_mov_reg_N(dst, src);
955
    tcg_gen_xori_tl(dst, dst, 0x1);
956
}
957

    
958
// !V
959
static inline void gen_op_eval_bvc(TCGv dst, TCGv src)
960
{
961
    gen_mov_reg_V(dst, src);
962
    tcg_gen_xori_tl(dst, dst, 0x1);
963
}
964

    
965
/*
966
  FPSR bit field FCC1 | FCC0:
967
   0 =
968
   1 <
969
   2 >
970
   3 unordered
971
*/
972
static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src,
973
                                    unsigned int fcc_offset)
974
{
975
    tcg_gen_extu_i32_tl(reg, src);
976
    tcg_gen_shri_tl(reg, reg, 10 + fcc_offset);
977
    tcg_gen_andi_tl(reg, reg, 0x1);
978
}
979

    
980
static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
981
                                    unsigned int fcc_offset)
982
{
983
    tcg_gen_extu_i32_tl(reg, src);
984
    tcg_gen_shri_tl(reg, reg, 11 + fcc_offset);
985
    tcg_gen_andi_tl(reg, reg, 0x1);
986
}
987

    
988
// !0: FCC0 | FCC1
989
static inline void gen_op_eval_fbne(TCGv dst, TCGv src,
990
                                    unsigned int fcc_offset)
991
{
992
    gen_mov_reg_FCC0(dst, src, fcc_offset);
993
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
994
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
995
}
996

    
997
// 1 or 2: FCC0 ^ FCC1
998
static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
999
                                    unsigned int fcc_offset)
1000
{
1001
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1002
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1003
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1004
}
1005

    
1006
// 1 or 3: FCC0
1007
static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
1008
                                    unsigned int fcc_offset)
1009
{
1010
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1011
}
1012

    
1013
// 1: FCC0 & !FCC1
1014
static inline void gen_op_eval_fbl(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_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
1020
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1021
}
1022

    
1023
// 2 or 3: FCC1
1024
static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
1025
                                    unsigned int fcc_offset)
1026
{
1027
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1028
}
1029

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

    
1040
// 3: FCC0 & FCC1
1041
static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
1042
                                    unsigned int fcc_offset)
1043
{
1044
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1045
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1046
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1047
}
1048

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

    
1059
// 0 or 3: !(FCC0 ^ FCC1)
1060
static inline void gen_op_eval_fbue(TCGv dst, TCGv src,
1061
                                    unsigned int fcc_offset)
1062
{
1063
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1064
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1065
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1066
    tcg_gen_xori_tl(dst, dst, 0x1);
1067
}
1068

    
1069
// 0 or 2: !FCC0
1070
static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
1071
                                    unsigned int fcc_offset)
1072
{
1073
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1074
    tcg_gen_xori_tl(dst, dst, 0x1);
1075
}
1076

    
1077
// !1: !(FCC0 & !FCC1)
1078
static inline void gen_op_eval_fbuge(TCGv dst, TCGv src,
1079
                                    unsigned int fcc_offset)
1080
{
1081
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1082
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1083
    tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
1084
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1085
    tcg_gen_xori_tl(dst, dst, 0x1);
1086
}
1087

    
1088
// 0 or 1: !FCC1
1089
static inline void gen_op_eval_fble(TCGv dst, TCGv src,
1090
                                    unsigned int fcc_offset)
1091
{
1092
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1093
    tcg_gen_xori_tl(dst, dst, 0x1);
1094
}
1095

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

    
1107
// !3: !(FCC0 & FCC1)
1108
static inline void gen_op_eval_fbo(TCGv dst, TCGv src,
1109
                                    unsigned int fcc_offset)
1110
{
1111
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1112
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1113
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1114
    tcg_gen_xori_tl(dst, dst, 0x1);
1115
}
1116

    
1117
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
1118
                               target_ulong pc2, TCGv r_cond)
1119
{
1120
    int l1;
1121

    
1122
    l1 = gen_new_label();
1123

    
1124
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1125

    
1126
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
1127

    
1128
    gen_set_label(l1);
1129
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
1130
}
1131

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

    
1137
    l1 = gen_new_label();
1138

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

    
1141
    gen_goto_tb(dc, 0, pc2, pc1);
1142

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

    
1147
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
1148
                                      TCGv r_cond)
1149
{
1150
    int l1, l2;
1151

    
1152
    l1 = gen_new_label();
1153
    l2 = gen_new_label();
1154

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

    
1157
    tcg_gen_movi_tl(cpu_npc, npc1);
1158
    tcg_gen_br(l2);
1159

    
1160
    gen_set_label(l1);
1161
    tcg_gen_movi_tl(cpu_npc, npc2);
1162
    gen_set_label(l2);
1163
}
1164

    
1165
/* call this function before using the condition register as it may
1166
   have been set for a jump */
1167
static inline void flush_cond(DisasContext *dc, TCGv cond)
1168
{
1169
    if (dc->npc == JUMP_PC) {
1170
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1171
        dc->npc = DYNAMIC_PC;
1172
    }
1173
}
1174

    
1175
static inline void save_npc(DisasContext *dc, TCGv cond)
1176
{
1177
    if (dc->npc == JUMP_PC) {
1178
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1179
        dc->npc = DYNAMIC_PC;
1180
    } else if (dc->npc != DYNAMIC_PC) {
1181
        tcg_gen_movi_tl(cpu_npc, dc->npc);
1182
    }
1183
}
1184

    
1185
static inline void save_state(DisasContext *dc, TCGv cond)
1186
{
1187
    tcg_gen_movi_tl(cpu_pc, dc->pc);
1188
    save_npc(dc, cond);
1189
}
1190

    
1191
static inline void gen_mov_pc_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
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1196
        dc->pc = DYNAMIC_PC;
1197
    } else if (dc->npc == DYNAMIC_PC) {
1198
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1199
        dc->pc = DYNAMIC_PC;
1200
    } else {
1201
        dc->pc = dc->npc;
1202
    }
1203
}
1204

    
1205
static inline void gen_op_next_insn(void)
1206
{
1207
    tcg_gen_mov_tl(cpu_pc, cpu_npc);
1208
    tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
1209
}
1210

    
1211
static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond)
1212
{
1213
    TCGv r_src;
1214

    
1215
#ifdef TARGET_SPARC64
1216
    if (cc)
1217
        r_src = cpu_xcc;
1218
    else
1219
        r_src = cpu_psr;
1220
#else
1221
    r_src = cpu_psr;
1222
#endif
1223
    switch (cond) {
1224
    case 0x0:
1225
        gen_op_eval_bn(r_dst);
1226
        break;
1227
    case 0x1:
1228
        gen_op_eval_be(r_dst, r_src);
1229
        break;
1230
    case 0x2:
1231
        gen_op_eval_ble(r_dst, r_src);
1232
        break;
1233
    case 0x3:
1234
        gen_op_eval_bl(r_dst, r_src);
1235
        break;
1236
    case 0x4:
1237
        gen_op_eval_bleu(r_dst, r_src);
1238
        break;
1239
    case 0x5:
1240
        gen_op_eval_bcs(r_dst, r_src);
1241
        break;
1242
    case 0x6:
1243
        gen_op_eval_bneg(r_dst, r_src);
1244
        break;
1245
    case 0x7:
1246
        gen_op_eval_bvs(r_dst, r_src);
1247
        break;
1248
    case 0x8:
1249
        gen_op_eval_ba(r_dst);
1250
        break;
1251
    case 0x9:
1252
        gen_op_eval_bne(r_dst, r_src);
1253
        break;
1254
    case 0xa:
1255
        gen_op_eval_bg(r_dst, r_src);
1256
        break;
1257
    case 0xb:
1258
        gen_op_eval_bge(r_dst, r_src);
1259
        break;
1260
    case 0xc:
1261
        gen_op_eval_bgu(r_dst, r_src);
1262
        break;
1263
    case 0xd:
1264
        gen_op_eval_bcc(r_dst, r_src);
1265
        break;
1266
    case 0xe:
1267
        gen_op_eval_bpos(r_dst, r_src);
1268
        break;
1269
    case 0xf:
1270
        gen_op_eval_bvc(r_dst, r_src);
1271
        break;
1272
    }
1273
}
1274

    
1275
static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
1276
{
1277
    unsigned int offset;
1278

    
1279
    switch (cc) {
1280
    default:
1281
    case 0x0:
1282
        offset = 0;
1283
        break;
1284
    case 0x1:
1285
        offset = 32 - 10;
1286
        break;
1287
    case 0x2:
1288
        offset = 34 - 10;
1289
        break;
1290
    case 0x3:
1291
        offset = 36 - 10;
1292
        break;
1293
    }
1294

    
1295
    switch (cond) {
1296
    case 0x0:
1297
        gen_op_eval_bn(r_dst);
1298
        break;
1299
    case 0x1:
1300
        gen_op_eval_fbne(r_dst, cpu_fsr, offset);
1301
        break;
1302
    case 0x2:
1303
        gen_op_eval_fblg(r_dst, cpu_fsr, offset);
1304
        break;
1305
    case 0x3:
1306
        gen_op_eval_fbul(r_dst, cpu_fsr, offset);
1307
        break;
1308
    case 0x4:
1309
        gen_op_eval_fbl(r_dst, cpu_fsr, offset);
1310
        break;
1311
    case 0x5:
1312
        gen_op_eval_fbug(r_dst, cpu_fsr, offset);
1313
        break;
1314
    case 0x6:
1315
        gen_op_eval_fbg(r_dst, cpu_fsr, offset);
1316
        break;
1317
    case 0x7:
1318
        gen_op_eval_fbu(r_dst, cpu_fsr, offset);
1319
        break;
1320
    case 0x8:
1321
        gen_op_eval_ba(r_dst);
1322
        break;
1323
    case 0x9:
1324
        gen_op_eval_fbe(r_dst, cpu_fsr, offset);
1325
        break;
1326
    case 0xa:
1327
        gen_op_eval_fbue(r_dst, cpu_fsr, offset);
1328
        break;
1329
    case 0xb:
1330
        gen_op_eval_fbge(r_dst, cpu_fsr, offset);
1331
        break;
1332
    case 0xc:
1333
        gen_op_eval_fbuge(r_dst, cpu_fsr, offset);
1334
        break;
1335
    case 0xd:
1336
        gen_op_eval_fble(r_dst, cpu_fsr, offset);
1337
        break;
1338
    case 0xe:
1339
        gen_op_eval_fbule(r_dst, cpu_fsr, offset);
1340
        break;
1341
    case 0xf:
1342
        gen_op_eval_fbo(r_dst, cpu_fsr, offset);
1343
        break;
1344
    }
1345
}
1346

    
1347
#ifdef TARGET_SPARC64
1348
// Inverted logic
1349
static const int gen_tcg_cond_reg[8] = {
1350
    -1,
1351
    TCG_COND_NE,
1352
    TCG_COND_GT,
1353
    TCG_COND_GE,
1354
    -1,
1355
    TCG_COND_EQ,
1356
    TCG_COND_LE,
1357
    TCG_COND_LT,
1358
};
1359

    
1360
static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
1361
{
1362
    int l1;
1363

    
1364
    l1 = gen_new_label();
1365
    tcg_gen_movi_tl(r_dst, 0);
1366
    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], r_src, tcg_const_tl(0), l1);
1367
    tcg_gen_movi_tl(r_dst, 1);
1368
    gen_set_label(l1);
1369
}
1370
#endif
1371

    
1372
/* XXX: potentially incorrect if dynamic npc */
1373
static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1374
                      TCGv r_cond)
1375
{
1376
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1377
    target_ulong target = dc->pc + offset;
1378

    
1379
    if (cond == 0x0) {
1380
        /* unconditional not taken */
1381
        if (a) {
1382
            dc->pc = dc->npc + 4;
1383
            dc->npc = dc->pc + 4;
1384
        } else {
1385
            dc->pc = dc->npc;
1386
            dc->npc = dc->pc + 4;
1387
        }
1388
    } else if (cond == 0x8) {
1389
        /* unconditional taken */
1390
        if (a) {
1391
            dc->pc = target;
1392
            dc->npc = dc->pc + 4;
1393
        } else {
1394
            dc->pc = dc->npc;
1395
            dc->npc = target;
1396
        }
1397
    } else {
1398
        flush_cond(dc, r_cond);
1399
        gen_cond(r_cond, cc, cond);
1400
        if (a) {
1401
            gen_branch_a(dc, target, dc->npc, r_cond);
1402
            dc->is_br = 1;
1403
        } else {
1404
            dc->pc = dc->npc;
1405
            dc->jump_pc[0] = target;
1406
            dc->jump_pc[1] = dc->npc + 4;
1407
            dc->npc = JUMP_PC;
1408
        }
1409
    }
1410
}
1411

    
1412
/* XXX: potentially incorrect if dynamic npc */
1413
static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1414
                      TCGv r_cond)
1415
{
1416
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1417
    target_ulong target = dc->pc + offset;
1418

    
1419
    if (cond == 0x0) {
1420
        /* unconditional not taken */
1421
        if (a) {
1422
            dc->pc = dc->npc + 4;
1423
            dc->npc = dc->pc + 4;
1424
        } else {
1425
            dc->pc = dc->npc;
1426
            dc->npc = dc->pc + 4;
1427
        }
1428
    } else if (cond == 0x8) {
1429
        /* unconditional taken */
1430
        if (a) {
1431
            dc->pc = target;
1432
            dc->npc = dc->pc + 4;
1433
        } else {
1434
            dc->pc = dc->npc;
1435
            dc->npc = target;
1436
        }
1437
    } else {
1438
        flush_cond(dc, r_cond);
1439
        gen_fcond(r_cond, cc, cond);
1440
        if (a) {
1441
            gen_branch_a(dc, target, dc->npc, r_cond);
1442
            dc->is_br = 1;
1443
        } else {
1444
            dc->pc = dc->npc;
1445
            dc->jump_pc[0] = target;
1446
            dc->jump_pc[1] = dc->npc + 4;
1447
            dc->npc = JUMP_PC;
1448
        }
1449
    }
1450
}
1451

    
1452
#ifdef TARGET_SPARC64
1453
/* XXX: potentially incorrect if dynamic npc */
1454
static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
1455
                          TCGv r_cond, TCGv r_reg)
1456
{
1457
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1458
    target_ulong target = dc->pc + offset;
1459

    
1460
    flush_cond(dc, r_cond);
1461
    gen_cond_reg(r_cond, cond, r_reg);
1462
    if (a) {
1463
        gen_branch_a(dc, target, dc->npc, r_cond);
1464
        dc->is_br = 1;
1465
    } else {
1466
        dc->pc = dc->npc;
1467
        dc->jump_pc[0] = target;
1468
        dc->jump_pc[1] = dc->npc + 4;
1469
        dc->npc = JUMP_PC;
1470
    }
1471
}
1472

    
1473
static GenOpFunc * const gen_fcmps[4] = {
1474
    helper_fcmps,
1475
    helper_fcmps_fcc1,
1476
    helper_fcmps_fcc2,
1477
    helper_fcmps_fcc3,
1478
};
1479

    
1480
static GenOpFunc * const gen_fcmpd[4] = {
1481
    helper_fcmpd,
1482
    helper_fcmpd_fcc1,
1483
    helper_fcmpd_fcc2,
1484
    helper_fcmpd_fcc3,
1485
};
1486

    
1487
#if defined(CONFIG_USER_ONLY)
1488
static GenOpFunc * const gen_fcmpq[4] = {
1489
    helper_fcmpq,
1490
    helper_fcmpq_fcc1,
1491
    helper_fcmpq_fcc2,
1492
    helper_fcmpq_fcc3,
1493
};
1494
#endif
1495

    
1496
static GenOpFunc * const gen_fcmpes[4] = {
1497
    helper_fcmpes,
1498
    helper_fcmpes_fcc1,
1499
    helper_fcmpes_fcc2,
1500
    helper_fcmpes_fcc3,
1501
};
1502

    
1503
static GenOpFunc * const gen_fcmped[4] = {
1504
    helper_fcmped,
1505
    helper_fcmped_fcc1,
1506
    helper_fcmped_fcc2,
1507
    helper_fcmped_fcc3,
1508
};
1509

    
1510
#if defined(CONFIG_USER_ONLY)
1511
static GenOpFunc * const gen_fcmpeq[4] = {
1512
    helper_fcmpeq,
1513
    helper_fcmpeq_fcc1,
1514
    helper_fcmpeq_fcc2,
1515
    helper_fcmpeq_fcc3,
1516
};
1517
#endif
1518

    
1519
static inline void gen_op_fcmps(int fccno)
1520
{
1521
    tcg_gen_helper_0_0(gen_fcmps[fccno]);
1522
}
1523

    
1524
static inline void gen_op_fcmpd(int fccno)
1525
{
1526
    tcg_gen_helper_0_0(gen_fcmpd[fccno]);
1527
}
1528

    
1529
#if defined(CONFIG_USER_ONLY)
1530
static inline void gen_op_fcmpq(int fccno)
1531
{
1532
    tcg_gen_helper_0_0(gen_fcmpq[fccno]);
1533
}
1534
#endif
1535

    
1536
static inline void gen_op_fcmpes(int fccno)
1537
{
1538
    tcg_gen_helper_0_0(gen_fcmpes[fccno]);
1539
}
1540

    
1541
static inline void gen_op_fcmped(int fccno)
1542
{
1543
    tcg_gen_helper_0_0(gen_fcmped[fccno]);
1544
}
1545

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

    
1553
#else
1554

    
1555
static inline void gen_op_fcmps(int fccno)
1556
{
1557
    tcg_gen_helper_0_0(helper_fcmps);
1558
}
1559

    
1560
static inline void gen_op_fcmpd(int fccno)
1561
{
1562
    tcg_gen_helper_0_0(helper_fcmpd);
1563
}
1564

    
1565
#if defined(CONFIG_USER_ONLY)
1566
static inline void gen_op_fcmpq(int fccno)
1567
{
1568
    tcg_gen_helper_0_0(helper_fcmpq);
1569
}
1570
#endif
1571

    
1572
static inline void gen_op_fcmpes(int fccno)
1573
{
1574
    tcg_gen_helper_0_0(helper_fcmpes);
1575
}
1576

    
1577
static inline void gen_op_fcmped(int fccno)
1578
{
1579
    tcg_gen_helper_0_0(helper_fcmped);
1580
}
1581

    
1582
#if defined(CONFIG_USER_ONLY)
1583
static inline void gen_op_fcmpeq(int fccno)
1584
{
1585
    tcg_gen_helper_0_0(helper_fcmpeq);
1586
}
1587
#endif
1588

    
1589
#endif
1590

    
1591
static inline void gen_op_fpexception_im(int fsr_flags)
1592
{
1593
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~FSR_FTT_MASK);
1594
    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
1595
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_FP_EXCP));
1596
}
1597

    
1598
static int gen_trap_ifnofpu(DisasContext *dc, TCGv r_cond)
1599
{
1600
#if !defined(CONFIG_USER_ONLY)
1601
    if (!dc->fpu_enabled) {
1602
        save_state(dc, r_cond);
1603
        tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_NFPU_INSN));
1604
        dc->is_br = 1;
1605
        return 1;
1606
    }
1607
#endif
1608
    return 0;
1609
}
1610

    
1611
static inline void gen_op_clear_ieee_excp_and_FTT(void)
1612
{
1613
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~(FSR_FTT_MASK | FSR_CEXC_MASK));
1614
}
1615

    
1616
static inline void gen_clear_float_exceptions(void)
1617
{
1618
    tcg_gen_helper_0_0(helper_clear_float_exceptions);
1619
}
1620

    
1621
/* asi moves */
1622
#ifdef TARGET_SPARC64
1623
static inline TCGv gen_get_asi(int insn, TCGv r_addr)
1624
{
1625
    int asi, offset;
1626
    TCGv r_asi;
1627

    
1628
    if (IS_IMM) {
1629
        r_asi = tcg_temp_new(TCG_TYPE_I32);
1630
        offset = GET_FIELD(insn, 25, 31);
1631
        tcg_gen_addi_tl(r_addr, r_addr, offset);
1632
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
1633
    } else {
1634
        asi = GET_FIELD(insn, 19, 26);
1635
        r_asi = tcg_const_i32(asi);
1636
    }
1637
    return r_asi;
1638
}
1639

    
1640
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size, int sign)
1641
{
1642
    TCGv r_asi;
1643

    
1644
    r_asi = gen_get_asi(insn, addr);
1645
    tcg_gen_helper_1_4(helper_ld_asi, dst, addr, r_asi,
1646
                       tcg_const_i32(size), tcg_const_i32(sign));
1647
    tcg_gen_discard_i32(r_asi);
1648
}
1649

    
1650
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1651
{
1652
    TCGv r_asi;
1653

    
1654
    r_asi = gen_get_asi(insn, addr);
1655
    tcg_gen_helper_0_4(helper_st_asi, addr, src, r_asi, tcg_const_i32(size));
1656
    tcg_gen_discard_i32(r_asi);
1657
}
1658

    
1659
static inline void gen_ldf_asi(TCGv addr, int insn, int size, int rd)
1660
{
1661
    TCGv r_asi;
1662

    
1663
    r_asi = gen_get_asi(insn, addr);
1664
    tcg_gen_helper_0_4(helper_ldf_asi, addr, r_asi, tcg_const_i32(size),
1665
                       tcg_const_i32(rd));
1666
    tcg_gen_discard_i32(r_asi);
1667
}
1668

    
1669
static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
1670
{
1671
    TCGv r_asi;
1672

    
1673
    r_asi = gen_get_asi(insn, addr);
1674
    tcg_gen_helper_0_4(helper_stf_asi, addr, r_asi, tcg_const_i32(size),
1675
                       tcg_const_i32(rd));
1676
    tcg_gen_discard_i32(r_asi);
1677
}
1678

    
1679
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1680
{
1681
    TCGv r_temp, r_asi;
1682

    
1683
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1684
    r_asi = gen_get_asi(insn, addr);
1685
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, addr, r_asi,
1686
                       tcg_const_i32(4), tcg_const_i32(0));
1687
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, r_asi,
1688
                       tcg_const_i32(4));
1689
    tcg_gen_extu_i32_tl(dst, r_temp);
1690
    tcg_gen_discard_i32(r_asi);
1691
    tcg_gen_discard_i32(r_temp);
1692
}
1693

    
1694
static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn)
1695
{
1696
    TCGv r_asi;
1697

    
1698
    r_asi = gen_get_asi(insn, addr);
1699
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi,
1700
                       tcg_const_i32(8), tcg_const_i32(0));
1701
    tcg_gen_andi_i64(lo, cpu_tmp64, 0xffffffffULL);
1702
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1703
    tcg_gen_andi_i64(hi, cpu_tmp64, 0xffffffffULL);
1704
    tcg_gen_discard_i32(r_asi);
1705
}
1706

    
1707
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1708
{
1709
    TCGv r_temp, r_asi;
1710

    
1711
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1712
    gen_movl_reg_TN(rd + 1, r_temp);
1713
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi,
1714
                       r_temp);
1715
    r_asi = gen_get_asi(insn, addr);
1716
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi,
1717
                       tcg_const_i32(8));
1718
    tcg_gen_discard_i32(r_asi);
1719
    tcg_gen_discard_i32(r_temp);
1720
}
1721

    
1722
static inline void gen_cas_asi(TCGv dst, TCGv addr, TCGv val2, int insn, int rd)
1723
{
1724
    TCGv r_val1, r_asi;
1725

    
1726
    r_val1 = tcg_temp_new(TCG_TYPE_I32);
1727
    gen_movl_reg_TN(rd, r_val1);
1728
    r_asi = gen_get_asi(insn, addr);
1729
    tcg_gen_helper_1_4(helper_cas_asi, dst, addr, r_val1, val2, r_asi);
1730
    tcg_gen_discard_i32(r_asi);
1731
    tcg_gen_discard_i32(r_val1);
1732
}
1733

    
1734
static inline void gen_casx_asi(TCGv dst, TCGv addr, TCGv val2, int insn, int rd)
1735
{
1736
    TCGv r_asi;
1737

    
1738
    gen_movl_reg_TN(rd, cpu_tmp64);
1739
    r_asi = gen_get_asi(insn, addr);
1740
    tcg_gen_helper_1_4(helper_casx_asi, dst, addr, cpu_tmp64, val2, r_asi);
1741
    tcg_gen_discard_i32(r_asi);
1742
}
1743

    
1744
#elif !defined(CONFIG_USER_ONLY)
1745

    
1746
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size, int sign)
1747
{
1748
    int asi;
1749

    
1750
    asi = GET_FIELD(insn, 19, 26);
1751
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, tcg_const_i32(asi),
1752
                       tcg_const_i32(size), tcg_const_i32(sign));
1753
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1754
}
1755

    
1756
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1757
{
1758
    int asi;
1759

    
1760
    tcg_gen_extu_tl_i64(cpu_tmp64, src);
1761
    asi = GET_FIELD(insn, 19, 26);
1762
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, tcg_const_i32(asi),
1763
                       tcg_const_i32(size));
1764
}
1765

    
1766
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1767
{
1768
    int asi;
1769
    TCGv r_temp;
1770

    
1771
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1772
    asi = GET_FIELD(insn, 19, 26);
1773
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, addr, tcg_const_i32(asi),
1774
                       tcg_const_i32(4), tcg_const_i32(0));
1775
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, tcg_const_i32(asi),
1776
                       tcg_const_i32(4));
1777
    tcg_gen_extu_i32_tl(dst, r_temp);
1778
    tcg_gen_discard_i32(r_temp);
1779
}
1780

    
1781
static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn)
1782
{
1783
    int asi;
1784

    
1785
    asi = GET_FIELD(insn, 19, 26);
1786
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, tcg_const_i32(asi),
1787
                       tcg_const_i32(8), tcg_const_i32(0));
1788
    tcg_gen_trunc_i64_tl(lo, cpu_tmp64);
1789
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1790
    tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
1791
}
1792

    
1793
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1794
{
1795
    int asi;
1796
    TCGv r_temp;
1797

    
1798
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1799
    gen_movl_reg_TN(rd + 1, r_temp);
1800
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi, r_temp);
1801
    asi = GET_FIELD(insn, 19, 26);
1802
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, tcg_const_i32(asi),
1803
                       tcg_const_i32(8));
1804
}
1805
#endif
1806

    
1807
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1808
static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
1809
{
1810
    int asi;
1811

    
1812
    gen_ld_asi(dst, addr, insn, 1, 0);
1813

    
1814
    asi = GET_FIELD(insn, 19, 26);
1815
    tcg_gen_helper_0_4(helper_st_asi, addr, tcg_const_i64(0xffULL),
1816
                       tcg_const_i32(asi), tcg_const_i32(1));
1817
}
1818
#endif
1819

    
1820
static inline TCGv get_src1(unsigned int insn, TCGv def)
1821
{
1822
    TCGv r_rs1 = def;
1823
    unsigned int rs1;
1824

    
1825
    rs1 = GET_FIELD(insn, 13, 17);
1826
    if (rs1 == 0)
1827
        //r_rs1 = tcg_const_tl(0);
1828
        tcg_gen_movi_tl(def, 0);
1829
    else if (rs1 < 8)
1830
        //r_rs1 = cpu_gregs[rs1];
1831
        tcg_gen_mov_tl(def, cpu_gregs[rs1]);
1832
    else
1833
        tcg_gen_ld_tl(def, cpu_regwptr, (rs1 - 8) * sizeof(target_ulong));
1834
    return r_rs1;
1835
}
1836

    
1837
static inline TCGv get_src2(unsigned int insn, TCGv def)
1838
{
1839
    TCGv r_rs2 = def;
1840
    unsigned int rs2;
1841

    
1842
    if (IS_IMM) { /* immediate */
1843
        rs2 = GET_FIELDs(insn, 19, 31);
1844
        r_rs2 = tcg_const_tl((int)rs2);
1845
    } else { /* register */
1846
        rs2 = GET_FIELD(insn, 27, 31);
1847
        if (rs2 == 0)
1848
            r_rs2 = tcg_const_tl(0);
1849
        else if (rs2 < 8)
1850
            r_rs2 = cpu_gregs[rs2];
1851
        else
1852
            tcg_gen_ld_tl(def, cpu_regwptr, (rs2 - 8) * sizeof(target_ulong));
1853
    }
1854
    return r_rs2;
1855
}
1856

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

    
1862
    insn = ldl_code(dc->pc);
1863
    opc = GET_FIELD(insn, 0, 1);
1864

    
1865
    rd = GET_FIELD(insn, 2, 6);
1866

    
1867
    cpu_dst = cpu_T[0];
1868
    cpu_src1 = cpu_T[0]; // const
1869
    cpu_src2 = cpu_T[1]; // const
1870

    
1871
    // loads and stores
1872
    cpu_addr = cpu_T[0];
1873
    cpu_val = cpu_T[1];
1874

    
1875
    switch (opc) {
1876
    case 0:                     /* branches/sethi */
1877
        {
1878
            unsigned int xop = GET_FIELD(insn, 7, 9);
1879
            int32_t target;
1880
            switch (xop) {
1881
#ifdef TARGET_SPARC64
1882
            case 0x1:           /* V9 BPcc */
1883
                {
1884
                    int cc;
1885

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

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

    
1978
                cpu_src1 = get_src1(insn, cpu_src1);
1979
                if (IS_IMM) {
1980
                    rs2 = GET_FIELD(insn, 25, 31);
1981
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, rs2);
1982
                } else {
1983
                    rs2 = GET_FIELD(insn, 27, 31);
1984
#if defined(OPTIM)
1985
                    if (rs2 != 0) {
1986
#endif
1987
                        gen_movl_reg_TN(rs2, cpu_src2);
1988
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
1989
#if defined(OPTIM)
1990
                    }
1991
#endif
1992
                }
1993
                cond = GET_FIELD(insn, 3, 6);
1994
                if (cond == 0x8) {
1995
                    save_state(dc, cpu_cond);
1996
                    tcg_gen_helper_0_1(helper_trap, cpu_dst);
1997
                } else if (cond != 0) {
1998
                    TCGv r_cond = tcg_temp_new(TCG_TYPE_TL);
1999
#ifdef TARGET_SPARC64
2000
                    /* V9 icc/xcc */
2001
                    int cc = GET_FIELD_SP(insn, 11, 12);
2002

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

    
2052
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2053
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2054
                                       offsetof(CPUState, tick));
2055
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst,
2056
                                           r_tickptr);
2057
                        gen_movl_TN_reg(rd, cpu_dst);
2058
                        tcg_gen_discard_ptr(r_tickptr);
2059
                    }
2060
                    break;
2061
                case 0x5: /* V9 rdpc */
2062
                    tcg_gen_movi_tl(cpu_dst, dc->pc);
2063
                    gen_movl_TN_reg(rd, cpu_dst);
2064
                    break;
2065
                case 0x6: /* V9 rdfprs */
2066
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fprs));
2067
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2068
                    gen_movl_TN_reg(rd, cpu_dst);
2069
                    break;
2070
                case 0xf: /* V9 membar */
2071
                    break; /* no effect */
2072
                case 0x13: /* Graphics Status */
2073
                    if (gen_trap_ifnofpu(dc, cpu_cond))
2074
                        goto jmp_insn;
2075
                    tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, gsr));
2076
                    gen_movl_TN_reg(rd, cpu_dst);
2077
                    break;
2078
                case 0x17: /* Tick compare */
2079
                    tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, tick_cmpr));
2080
                    gen_movl_TN_reg(rd, cpu_dst);
2081
                    break;
2082
                case 0x18: /* System tick */
2083
                    {
2084
                        TCGv r_tickptr;
2085

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

    
2158
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2159
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2160
                                       offsetof(CPUState, tsptr));
2161
                        tcg_gen_ld_tl(cpu_dst, r_tsptr,
2162
                                      offsetof(trap_state, tpc));
2163
                        tcg_gen_discard_ptr(r_tsptr);
2164
                    }
2165
                    break;
2166
                case 1: // tnpc
2167
                    {
2168
                        TCGv r_tsptr;
2169

    
2170
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2171
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2172
                                       offsetof(CPUState, tsptr));
2173
                        tcg_gen_ld_tl(cpu_dst, r_tsptr,
2174
                                      offsetof(trap_state, tnpc));
2175
                        tcg_gen_discard_ptr(r_tsptr);
2176
                    }
2177
                    break;
2178
                case 2: // tstate
2179
                    {
2180
                        TCGv r_tsptr;
2181

    
2182
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2183
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2184
                                       offsetof(CPUState, tsptr));
2185
                        tcg_gen_ld_tl(cpu_dst, r_tsptr,
2186
                                      offsetof(trap_state, tstate));
2187
                        tcg_gen_discard_ptr(r_tsptr);
2188
                    }
2189
                    break;
2190
                case 3: // tt
2191
                    {
2192
                        TCGv r_tsptr;
2193

    
2194
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2195
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2196
                                       offsetof(CPUState, tsptr));
2197
                        tcg_gen_ld_i32(cpu_dst, r_tsptr,
2198
                                       offsetof(trap_state, tt));
2199
                        tcg_gen_discard_ptr(r_tsptr);
2200
                    }
2201
                    break;
2202
                case 4: // tick
2203
                    {
2204
                        TCGv r_tickptr;
2205

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

    
2673
                    l1 = gen_new_label();
2674
                    cond = GET_FIELD_SP(insn, 14, 17);
2675
                    cpu_src1 = get_src1(insn, cpu_src1);
2676
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_src1,
2677
                                      tcg_const_tl(0), l1);
2678
                    gen_op_load_fpr_FT0(rs2);
2679
                    gen_op_store_FT0_fpr(rd);
2680
                    gen_set_label(l1);
2681
                    break;
2682
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
2683
                    int l1;
2684

    
2685
                    l1 = gen_new_label();
2686
                    cond = GET_FIELD_SP(insn, 14, 17);
2687
                    cpu_src1 = get_src1(insn, cpu_src1);
2688
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_src1,
2689
                                      tcg_const_tl(0), l1);
2690
                    gen_op_load_fpr_DT0(DFPREG(rs2));
2691
                    gen_op_store_DT0_fpr(DFPREG(rd));
2692
                    gen_set_label(l1);
2693
                    break;
2694
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
2695
#if defined(CONFIG_USER_ONLY)
2696
                    int l1;
2697

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

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

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

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

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

    
3208
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
3209
                                                   cpu_src2);
3210
                                    tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState,
3211
                                                                 stick_cmpr));
3212
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3213
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3214
                                                   offsetof(CPUState, stick));
3215
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3216
                                                       r_tickptr, cpu_dst);
3217
                                    tcg_gen_discard_ptr(r_tickptr);
3218
                                }
3219
                                break;
3220

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

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

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

    
3299
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3300
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3301
                                                   offsetof(CPUState, tsptr));
3302
                                    tcg_gen_st_tl(cpu_dst, r_tsptr,
3303
                                                  offsetof(trap_state, tstate));
3304
                                    tcg_gen_discard_ptr(r_tsptr);
3305
                                }
3306
                                break;
3307
                            case 3: // tt
3308
                                {
3309
                                    TCGv r_tsptr;
3310

    
3311
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3312
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3313
                                                   offsetof(CPUState, tsptr));
3314
                                    tcg_gen_st_i32(cpu_dst, r_tsptr,
3315
                                                   offsetof(trap_state, tt));
3316
                                    tcg_gen_discard_ptr(r_tsptr);
3317
                                }
3318
                                break;
3319
                            case 4: // tick
3320
                                {
3321
                                    TCGv r_tickptr;
3322

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

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

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

    
3464
                            l1 = gen_new_label();
3465

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

    
3496
                            cpu_src1 = get_src1(insn, cpu_src1);
3497

    
3498
                            l1 = gen_new_label();
3499

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

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

    
4043
            save_state(dc, cpu_cond);
4044
            cpu_src1 = get_src1(insn, cpu_src1);
4045
            if (xop == 0x3c || xop == 0x3e)
4046
            {
4047
                rs2 = GET_FIELD(insn, 27, 31);
4048
                gen_movl_reg_TN(rs2, cpu_src2);
4049
            }
4050
            else if (IS_IMM) {       /* immediate */
4051
                rs2 = GET_FIELDs(insn, 19, 31);
4052
                tcg_gen_addi_tl(cpu_addr, cpu_src1, (int)rs2);
4053
            } else {            /* register */
4054
                rs2 = GET_FIELD(insn, 27, 31);
4055
#if defined(OPTIM)
4056
                if (rs2 != 0) {
4057
#endif
4058
                    gen_movl_reg_TN(rs2, cpu_src2);
4059
                    tcg_gen_add_tl(cpu_addr, cpu_src1, cpu_src2);
4060
#if defined(OPTIM)
4061
                }
4062
#endif
4063
            }
4064
            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
4065
                (xop > 0x17 && xop <= 0x1d ) ||
4066
                (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
4067
                switch (xop) {
4068
                case 0x0:       /* load unsigned word */
4069
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4070
                    ABI32_MASK(cpu_addr);
4071
                    tcg_gen_qemu_ld32u(cpu_val, cpu_addr, dc->mem_idx);
4072
                    break;
4073
                case 0x1:       /* load unsigned byte */
4074
                    ABI32_MASK(cpu_addr);
4075
                    tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx);
4076
                    break;
4077
                case 0x2:       /* load unsigned halfword */
4078
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
4079
                    ABI32_MASK(cpu_addr);
4080
                    tcg_gen_qemu_ld16u(cpu_val, cpu_addr, dc->mem_idx);
4081
                    break;
4082
                case 0x3:       /* load double word */
4083
                    if (rd & 1)
4084
                        goto illegal_insn;
4085
                    else {
4086
                        tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4087
                        ABI32_MASK(cpu_addr);
4088
                        tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
4089
                        tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
4090
                        tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffffULL);
4091
                        gen_movl_TN_reg(rd + 1, cpu_tmp0);
4092
                        tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
4093
                        tcg_gen_trunc_i64_tl(cpu_val, cpu_tmp64);
4094
                        tcg_gen_andi_tl(cpu_val, cpu_val, 0xffffffffULL);
4095
                    }
4096
                    break;
4097
                case 0x9:       /* load signed byte */
4098
                    ABI32_MASK(cpu_addr);
4099
                    tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
4100
                    break;
4101
                case 0xa:       /* load signed halfword */
4102
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
4103
                    ABI32_MASK(cpu_addr);
4104
                    tcg_gen_qemu_ld16s(cpu_val, cpu_addr, dc->mem_idx);
4105
                    break;
4106
                case 0xd:       /* ldstub -- XXX: should be atomically */
4107
                    ABI32_MASK(cpu_addr);
4108
                    tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
4109
                    tcg_gen_qemu_st8(tcg_const_tl(0xff), cpu_addr, dc->mem_idx);
4110
                    break;
4111
                case 0x0f:      /* swap register with memory. Also atomically */
4112
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4113
                    gen_movl_reg_TN(rd, cpu_val);
4114
                    ABI32_MASK(cpu_addr);
4115
                    tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
4116
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
4117
                    tcg_gen_extu_i32_tl(cpu_val, cpu_tmp32);
4118
                    break;
4119
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4120
                case 0x10:      /* load word alternate */
4121
#ifndef TARGET_SPARC64
4122
                    if (IS_IMM)
4123
                        goto illegal_insn;
4124
                    if (!supervisor(dc))
4125
                        goto priv_insn;
4126
#endif
4127
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4128
                    gen_ld_asi(cpu_val, cpu_addr, insn, 4, 0);
4129
                    break;
4130
                case 0x11:      /* load unsigned byte alternate */
4131
#ifndef TARGET_SPARC64
4132
                    if (IS_IMM)
4133
                        goto illegal_insn;
4134
                    if (!supervisor(dc))
4135
                        goto priv_insn;
4136
#endif
4137
                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 0);
4138
                    break;
4139
                case 0x12:      /* load unsigned halfword alternate */
4140
#ifndef TARGET_SPARC64
4141
                    if (IS_IMM)
4142
                        goto illegal_insn;
4143
                    if (!supervisor(dc))
4144
                        goto priv_insn;
4145
#endif
4146
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
4147
                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 0);
4148
                    break;
4149
                case 0x13:      /* load double word alternate */
4150
#ifndef TARGET_SPARC64
4151
                    if (IS_IMM)
4152
                        goto illegal_insn;
4153
                    if (!supervisor(dc))
4154
                        goto priv_insn;
4155
#endif
4156
                    if (rd & 1)
4157
                        goto illegal_insn;
4158
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4159
                    gen_ldda_asi(cpu_tmp0, cpu_val, cpu_addr, insn);
4160
                    gen_movl_TN_reg(rd + 1, cpu_tmp0);
4161
                    break;
4162
                case 0x19:      /* load signed byte alternate */
4163
#ifndef TARGET_SPARC64
4164
                    if (IS_IMM)
4165
                        goto illegal_insn;
4166
                    if (!supervisor(dc))
4167
                        goto priv_insn;
4168
#endif
4169
                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 1);
4170
                    break;
4171
                case 0x1a:      /* load signed halfword alternate */
4172
#ifndef TARGET_SPARC64
4173
                    if (IS_IMM)
4174
                        goto illegal_insn;
4175
                    if (!supervisor(dc))
4176
                        goto priv_insn;
4177
#endif
4178
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
4179
                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 1);
4180
                    break;
4181
                case 0x1d:      /* ldstuba -- XXX: should be atomically */
4182
#ifndef TARGET_SPARC64
4183
                    if (IS_IMM)
4184
                        goto illegal_insn;
4185
                    if (!supervisor(dc))
4186
                        goto priv_insn;
4187
#endif
4188
                    gen_ldstub_asi(cpu_val, cpu_addr, insn);
4189
                    break;
4190
                case 0x1f:      /* swap reg with alt. memory. Also atomically */
4191
#ifndef TARGET_SPARC64
4192
                    if (IS_IMM)
4193
                        goto illegal_insn;
4194
                    if (!supervisor(dc))
4195
                        goto priv_insn;
4196
#endif
4197
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4198
                    gen_movl_reg_TN(rd, cpu_val);
4199
                    gen_swap_asi(cpu_val, cpu_addr, insn);
4200
                    break;
4201

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

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

    
4533
static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
4534
{
4535
}
4536

    
4537
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
4538
                                                 int spc, CPUSPARCState *env)
4539
{
4540
    target_ulong pc_start, last_pc;
4541
    uint16_t *gen_opc_end;
4542
    DisasContext dc1, *dc = &dc1;
4543
    int j, lj = -1;
4544

    
4545
    memset(dc, 0, sizeof(DisasContext));
4546
    dc->tb = tb;
4547
    pc_start = tb->pc;
4548
    dc->pc = pc_start;
4549
    last_pc = dc->pc;
4550
    dc->npc = (target_ulong) tb->cs_base;
4551
    dc->mem_idx = cpu_mmu_index(env);
4552
    dc->fpu_enabled = cpu_fpu_enabled(env);
4553
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4554

    
4555
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
4556
    cpu_tmp32 = tcg_temp_new(TCG_TYPE_I32);
4557
    cpu_tmp64 = tcg_temp_new(TCG_TYPE_I64);
4558

    
4559
    cpu_cond = cpu_T[2];
4560

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

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

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

    
4649
int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
4650
{
4651
    return gen_intermediate_code_internal(tb, 0, env);
4652
}
4653

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

    
4659
void gen_intermediate_code_init(CPUSPARCState *env)
4660
{
4661
    unsigned int i;
4662
    static int inited;
4663
    static const char * const gregnames[8] = {
4664
        NULL, // g0 not used
4665
        "g1",
4666
        "g2",
4667
        "g3",
4668
        "g4",
4669
        "g5",
4670
        "g6",
4671
        "g7",
4672
    };
4673

    
4674
    /* init various static tables */
4675
    if (!inited) {
4676
        inited = 1;
4677

    
4678
        tcg_set_macro_func(&tcg_ctx, tcg_macro_func);
4679
        cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
4680
        cpu_regwptr = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
4681
                                         offsetof(CPUState, regwptr),
4682
                                         "regwptr");
4683
        //#if TARGET_LONG_BITS > HOST_LONG_BITS
4684
#ifdef TARGET_SPARC64
4685
        cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
4686
                                      TCG_AREG0, offsetof(CPUState, t0), "T0");
4687
        cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
4688
                                      TCG_AREG0, offsetof(CPUState, t1), "T1");
4689
        cpu_T[2] = tcg_global_mem_new(TCG_TYPE_TL,
4690
                                      TCG_AREG0, offsetof(CPUState, t2), "T2");
4691
        cpu_xcc = tcg_global_mem_new(TCG_TYPE_I32,
4692
                                     TCG_AREG0, offsetof(CPUState, xcc),
4693
                                     "xcc");
4694
#else
4695
        cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
4696
        cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
4697
        cpu_T[2] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T2");
4698
#endif
4699
        cpu_cc_src = tcg_global_mem_new(TCG_TYPE_TL,
4700
                                        TCG_AREG0, offsetof(CPUState, cc_src),
4701
                                        "cc_src");
4702
        cpu_cc_src2 = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4703
                                         offsetof(CPUState, cc_src2),
4704
                                         "cc_src2");
4705
        cpu_cc_dst = tcg_global_mem_new(TCG_TYPE_TL,
4706
                                        TCG_AREG0, offsetof(CPUState, cc_dst),
4707
                                        "cc_dst");
4708
        cpu_psr = tcg_global_mem_new(TCG_TYPE_I32,
4709
                                     TCG_AREG0, offsetof(CPUState, psr),
4710
                                     "psr");
4711
        cpu_fsr = tcg_global_mem_new(TCG_TYPE_TL,
4712
                                     TCG_AREG0, offsetof(CPUState, fsr),
4713
                                     "fsr");
4714
        cpu_pc = tcg_global_mem_new(TCG_TYPE_TL,
4715
                                    TCG_AREG0, offsetof(CPUState, pc),
4716
                                    "pc");
4717
        cpu_npc = tcg_global_mem_new(TCG_TYPE_TL,
4718
                                    TCG_AREG0, offsetof(CPUState, npc),
4719
                                    "npc");
4720
        for (i = 1; i < 8; i++)
4721
            cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4722
                                              offsetof(CPUState, gregs[i]),
4723
                                              gregnames[i]);
4724
    }
4725
}