Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ e35298cd

History | View | Annotate | Download (177.7 kB)

1
/*
2
   SPARC translation
3

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

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

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

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

    
22
#include <stdarg.h>
23
#include <stdlib.h>
24
#include <stdio.h>
25
#include <string.h>
26
#include <inttypes.h>
27

    
28
#include "cpu.h"
29
#include "exec-all.h"
30
#include "disas.h"
31
#include "helper.h"
32
#include "tcg-op.h"
33

    
34
#define DEBUG_DISAS
35

    
36
#define DYNAMIC_PC  1 /* dynamic pc value */
37
#define JUMP_PC     2 /* dynamic pc value which takes only two values
38
                         according to jump_pc[T2] */
39

    
40
/* global register indexes */
41
static TCGv cpu_env, cpu_T[2], cpu_regwptr;
42
static TCGv cpu_cc_src, cpu_cc_src2, cpu_cc_dst;
43
static TCGv cpu_psr, cpu_fsr, cpu_pc, cpu_npc, cpu_gregs[8];
44
static TCGv cpu_cond, cpu_src1, cpu_src2, cpu_dst, cpu_addr, cpu_val;
45
#ifdef TARGET_SPARC64
46
static TCGv cpu_xcc;
47
#endif
48
/* local register indexes (only used inside old micro ops) */
49
static TCGv cpu_tmp0, cpu_tmp32, cpu_tmp64;
50

    
51
typedef struct DisasContext {
52
    target_ulong pc;    /* current Program Counter: integer or DYNAMIC_PC */
53
    target_ulong npc;   /* next PC: integer or DYNAMIC_PC or JUMP_PC */
54
    target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
55
    int is_br;
56
    int mem_idx;
57
    int fpu_enabled;
58
    struct TranslationBlock *tb;
59
    uint32_t features;
60
} DisasContext;
61

    
62
// This function uses non-native bit order
63
#define GET_FIELD(X, FROM, TO) \
64
  ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
65

    
66
// This function uses the order in the manuals, i.e. bit 0 is 2^0
67
#define GET_FIELD_SP(X, FROM, TO) \
68
    GET_FIELD(X, 31 - (TO), 31 - (FROM))
69

    
70
#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
71
#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
72

    
73
#ifdef TARGET_SPARC64
74
#define FFPREG(r) (r)
75
#define DFPREG(r) (((r & 1) << 5) | (r & 0x1e))
76
#define QFPREG(r) (((r & 1) << 5) | (r & 0x1c))
77
#else
78
#define FFPREG(r) (r)
79
#define DFPREG(r) (r & 0x1e)
80
#define QFPREG(r) (r & 0x1c)
81
#endif
82

    
83
static int sign_extend(int x, int len)
84
{
85
    len = 32 - len;
86
    return (x << len) >> len;
87
}
88

    
89
#define IS_IMM (insn & (1<<13))
90

    
91
/* floating point registers moves */
92
static void gen_op_load_fpr_FT0(unsigned int src)
93
{
94
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
95
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft0));
96
}
97

    
98
static void gen_op_load_fpr_FT1(unsigned int src)
99
{
100
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
101
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft1));
102
}
103

    
104
static void gen_op_store_FT0_fpr(unsigned int dst)
105
{
106
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft0));
107
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst]));
108
}
109

    
110
static void gen_op_load_fpr_DT0(unsigned int src)
111
{
112
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
113
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) +
114
                   offsetof(CPU_DoubleU, l.upper));
115
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
116
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) +
117
                   offsetof(CPU_DoubleU, l.lower));
118
}
119

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

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

    
140
static void gen_op_load_fpr_QT0(unsigned int src)
141
{
142
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
143
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) +
144
                   offsetof(CPU_QuadU, l.upmost));
145
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
146
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) +
147
                   offsetof(CPU_QuadU, l.upper));
148
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 2]));
149
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) +
150
                   offsetof(CPU_QuadU, l.lower));
151
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 3]));
152
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) +
153
                   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) +
160
                   offsetof(CPU_QuadU, l.upmost));
161
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
162
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) +
163
                   offsetof(CPU_QuadU, l.upper));
164
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 2]));
165
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) +
166
                   offsetof(CPU_QuadU, l.lower));
167
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 3]));
168
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) +
169
                   offsetof(CPU_QuadU, l.lowest));
170
}
171

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

    
188
/* moves */
189
#ifdef CONFIG_USER_ONLY
190
#define supervisor(dc) 0
191
#ifdef TARGET_SPARC64
192
#define hypervisor(dc) 0
193
#endif
194
#else
195
#define supervisor(dc) (dc->mem_idx >= 1)
196
#ifdef TARGET_SPARC64
197
#define hypervisor(dc) (dc->mem_idx == 2)
198
#else
199
#endif
200
#endif
201

    
202
#ifdef TARGET_ABI32
203
#define ABI32_MASK(addr) tcg_gen_andi_tl(addr, addr, 0xffffffffULL);
204
#else
205
#define ABI32_MASK(addr)
206
#endif
207

    
208
static inline void gen_movl_reg_TN(int reg, TCGv tn)
209
{
210
    if (reg == 0)
211
        tcg_gen_movi_tl(tn, 0);
212
    else if (reg < 8)
213
        tcg_gen_mov_tl(tn, cpu_gregs[reg]);
214
    else {
215
        tcg_gen_ld_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
216
    }
217
}
218

    
219
static inline void gen_movl_TN_reg(int reg, TCGv tn)
220
{
221
    if (reg == 0)
222
        return;
223
    else if (reg < 8)
224
        tcg_gen_mov_tl(cpu_gregs[reg], tn);
225
    else {
226
        tcg_gen_st_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
227
    }
228
}
229

    
230
static inline void gen_goto_tb(DisasContext *s, int tb_num,
231
                               target_ulong pc, target_ulong npc)
232
{
233
    TranslationBlock *tb;
234

    
235
    tb = s->tb;
236
    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
237
        (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK))  {
238
        /* jump to same page: we can use a direct jump */
239
        tcg_gen_goto_tb(tb_num);
240
        tcg_gen_movi_tl(cpu_pc, pc);
241
        tcg_gen_movi_tl(cpu_npc, npc);
242
        tcg_gen_exit_tb((long)tb + tb_num);
243
    } else {
244
        /* jump to another page: currently not optimized */
245
        tcg_gen_movi_tl(cpu_pc, pc);
246
        tcg_gen_movi_tl(cpu_npc, npc);
247
        tcg_gen_exit_tb(0);
248
    }
249
}
250

    
251
// XXX suboptimal
252
static inline void gen_mov_reg_N(TCGv reg, TCGv src)
253
{
254
    tcg_gen_extu_i32_tl(reg, src);
255
    tcg_gen_shri_tl(reg, reg, PSR_NEG_SHIFT);
256
    tcg_gen_andi_tl(reg, reg, 0x1);
257
}
258

    
259
static inline void gen_mov_reg_Z(TCGv reg, TCGv src)
260
{
261
    tcg_gen_extu_i32_tl(reg, src);
262
    tcg_gen_shri_tl(reg, reg, PSR_ZERO_SHIFT);
263
    tcg_gen_andi_tl(reg, reg, 0x1);
264
}
265

    
266
static inline void gen_mov_reg_V(TCGv reg, TCGv src)
267
{
268
    tcg_gen_extu_i32_tl(reg, src);
269
    tcg_gen_shri_tl(reg, reg, PSR_OVF_SHIFT);
270
    tcg_gen_andi_tl(reg, reg, 0x1);
271
}
272

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

    
280
static inline void gen_cc_clear_icc(void)
281
{
282
    tcg_gen_movi_i32(cpu_psr, 0);
283
}
284

    
285
#ifdef TARGET_SPARC64
286
static inline void gen_cc_clear_xcc(void)
287
{
288
    tcg_gen_movi_i32(cpu_xcc, 0);
289
}
290
#endif
291

    
292
/* old op:
293
    if (!T0)
294
        env->psr |= PSR_ZERO;
295
    if ((int32_t) T0 < 0)
296
        env->psr |= PSR_NEG;
297
*/
298
static inline void gen_cc_NZ_icc(TCGv dst)
299
{
300
    TCGv r_temp;
301
    int l1, l2;
302

    
303
    l1 = gen_new_label();
304
    l2 = gen_new_label();
305
    r_temp = tcg_temp_new(TCG_TYPE_TL);
306
    tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
307
    tcg_gen_brcond_tl(TCG_COND_NE, r_temp, tcg_const_tl(0), l1);
308
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_ZERO);
309
    gen_set_label(l1);
310
    tcg_gen_ext_i32_tl(r_temp, dst);
311
    tcg_gen_brcond_tl(TCG_COND_GE, r_temp, tcg_const_tl(0), l2);
312
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_NEG);
313
    gen_set_label(l2);
314
}
315

    
316
#ifdef TARGET_SPARC64
317
static inline void gen_cc_NZ_xcc(TCGv dst)
318
{
319
    int l1, l2;
320

    
321
    l1 = gen_new_label();
322
    l2 = gen_new_label();
323
    tcg_gen_brcond_tl(TCG_COND_NE, dst, tcg_const_tl(0), l1);
324
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_ZERO);
325
    gen_set_label(l1);
326
    tcg_gen_brcond_tl(TCG_COND_GE, dst, tcg_const_tl(0), l2);
327
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_NEG);
328
    gen_set_label(l2);
329
}
330
#endif
331

    
332
/* old op:
333
    if (T0 < src1)
334
        env->psr |= PSR_CARRY;
335
*/
336
static inline void gen_cc_C_add_icc(TCGv dst, TCGv src1)
337
{
338
    TCGv r_temp;
339
    int l1;
340

    
341
    l1 = gen_new_label();
342
    r_temp = tcg_temp_new(TCG_TYPE_TL);
343
    tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
344
    tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l1);
345
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
346
    gen_set_label(l1);
347
}
348

    
349
#ifdef TARGET_SPARC64
350
static inline void gen_cc_C_add_xcc(TCGv dst, TCGv src1)
351
{
352
    int l1;
353

    
354
    l1 = gen_new_label();
355
    tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l1);
356
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
357
    gen_set_label(l1);
358
}
359
#endif
360

    
361
/* old op:
362
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
363
        env->psr |= PSR_OVF;
364
*/
365
static inline void gen_cc_V_add_icc(TCGv dst, TCGv src1, TCGv src2)
366
{
367
    TCGv r_temp;
368

    
369
    r_temp = tcg_temp_new(TCG_TYPE_TL);
370
    tcg_gen_xor_tl(r_temp, src1, src2);
371
    tcg_gen_xori_tl(r_temp, r_temp, -1);
372
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
373
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
374
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
375
    tcg_gen_shri_tl(r_temp, r_temp, 31 - PSR_OVF_SHIFT);
376
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
377
    tcg_gen_or_i32(cpu_psr, cpu_psr, cpu_tmp32);
378
}
379

    
380
#ifdef TARGET_SPARC64
381
static inline void gen_cc_V_add_xcc(TCGv dst, TCGv src1, TCGv src2)
382
{
383
    TCGv r_temp;
384

    
385
    r_temp = tcg_temp_new(TCG_TYPE_TL);
386
    tcg_gen_xor_tl(r_temp, src1, src2);
387
    tcg_gen_xori_tl(r_temp, r_temp, -1);
388
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
389
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
390
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
391
    tcg_gen_shri_tl(r_temp, r_temp, 63 - PSR_OVF_SHIFT);
392
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
393
    tcg_gen_or_i32(cpu_xcc, cpu_xcc, cpu_tmp32);
394
}
395
#endif
396

    
397
static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
398
{
399
    TCGv r_temp;
400
    int l1;
401

    
402
    l1 = gen_new_label();
403

    
404
    r_temp = tcg_temp_new(TCG_TYPE_TL);
405
    tcg_gen_xor_tl(r_temp, src1, src2);
406
    tcg_gen_xori_tl(r_temp, r_temp, -1);
407
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
408
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
409
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
410
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
411
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
412
    gen_set_label(l1);
413
}
414

    
415
static inline void gen_cc_V_tag(TCGv src1, TCGv src2)
416
{
417
    int l1;
418

    
419
    l1 = gen_new_label();
420
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
421
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
422
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
423
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
424
    gen_set_label(l1);
425
}
426

    
427
static inline void gen_tag_tv(TCGv src1, TCGv src2)
428
{
429
    int l1;
430

    
431
    l1 = gen_new_label();
432
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
433
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
434
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
435
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
436
    gen_set_label(l1);
437
}
438

    
439
static inline void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2)
440
{
441
    tcg_gen_mov_tl(cpu_cc_src, src1);
442
    tcg_gen_mov_tl(cpu_cc_src2, src2);
443
    tcg_gen_add_tl(dst, src1, src2);
444
    tcg_gen_mov_tl(cpu_cc_dst, dst);
445
    gen_cc_clear_icc();
446
    gen_cc_NZ_icc(cpu_cc_dst);
447
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
448
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
449
#ifdef TARGET_SPARC64
450
    gen_cc_clear_xcc();
451
    gen_cc_NZ_xcc(cpu_cc_dst);
452
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
453
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
454
#endif
455
}
456

    
457
static inline void gen_op_addx_cc(TCGv dst, TCGv src1, TCGv src2)
458
{
459
    tcg_gen_mov_tl(cpu_cc_src, src1);
460
    tcg_gen_mov_tl(cpu_cc_src2, src2);
461
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
462
    tcg_gen_add_tl(dst, src1, cpu_tmp0);
463
    gen_cc_clear_icc();
464
    gen_cc_C_add_icc(dst, cpu_cc_src);
465
#ifdef TARGET_SPARC64
466
    gen_cc_clear_xcc();
467
    gen_cc_C_add_xcc(dst, cpu_cc_src);
468
#endif
469
    tcg_gen_add_tl(dst, dst, cpu_cc_src2);
470
    tcg_gen_mov_tl(cpu_cc_dst, dst);
471
    gen_cc_NZ_icc(cpu_cc_dst);
472
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
473
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
474
#ifdef TARGET_SPARC64
475
    gen_cc_NZ_xcc(cpu_cc_dst);
476
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
477
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
478
#endif
479
}
480

    
481
static inline void gen_op_tadd_cc(TCGv dst, TCGv src1, TCGv src2)
482
{
483
    tcg_gen_mov_tl(cpu_cc_src, src1);
484
    tcg_gen_mov_tl(cpu_cc_src2, src2);
485
    tcg_gen_add_tl(dst, src1, src2);
486
    tcg_gen_mov_tl(cpu_cc_dst, dst);
487
    gen_cc_clear_icc();
488
    gen_cc_NZ_icc(cpu_cc_dst);
489
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
490
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
491
    gen_cc_V_tag(cpu_cc_src, cpu_cc_src2);
492
#ifdef TARGET_SPARC64
493
    gen_cc_clear_xcc();
494
    gen_cc_NZ_xcc(cpu_cc_dst);
495
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
496
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
497
#endif
498
}
499

    
500
static inline void gen_op_tadd_ccTV(TCGv dst, TCGv src1, TCGv src2)
501
{
502
    tcg_gen_mov_tl(cpu_cc_src, src1);
503
    tcg_gen_mov_tl(cpu_cc_src2, src2);
504
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
505
    tcg_gen_add_tl(dst, src1, src2);
506
    tcg_gen_mov_tl(cpu_cc_dst, dst);
507
    gen_add_tv(dst, cpu_cc_src, cpu_cc_src2);
508
    gen_cc_clear_icc();
509
    gen_cc_NZ_icc(cpu_cc_dst);
510
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
511
#ifdef TARGET_SPARC64
512
    gen_cc_clear_xcc();
513
    gen_cc_NZ_xcc(cpu_cc_dst);
514
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
515
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
516
#endif
517
}
518

    
519
/* old op:
520
    if (src1 < T1)
521
        env->psr |= PSR_CARRY;
522
*/
523
static inline void gen_cc_C_sub_icc(TCGv src1, TCGv src2)
524
{
525
    TCGv r_temp1, r_temp2;
526
    int l1;
527

    
528
    l1 = gen_new_label();
529
    r_temp1 = tcg_temp_new(TCG_TYPE_TL);
530
    r_temp2 = tcg_temp_new(TCG_TYPE_TL);
531
    tcg_gen_andi_tl(r_temp1, src1, 0xffffffffULL);
532
    tcg_gen_andi_tl(r_temp2, src2, 0xffffffffULL);
533
    tcg_gen_brcond_tl(TCG_COND_GEU, r_temp1, r_temp2, l1);
534
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
535
    gen_set_label(l1);
536
}
537

    
538
#ifdef TARGET_SPARC64
539
static inline void gen_cc_C_sub_xcc(TCGv src1, TCGv src2)
540
{
541
    int l1;
542

    
543
    l1 = gen_new_label();
544
    tcg_gen_brcond_tl(TCG_COND_GEU, src1, src2, l1);
545
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
546
    gen_set_label(l1);
547
}
548
#endif
549

    
550
/* old op:
551
    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
552
        env->psr |= PSR_OVF;
553
*/
554
static inline void gen_cc_V_sub_icc(TCGv dst, TCGv src1, TCGv src2)
555
{
556
    TCGv r_temp;
557

    
558
    r_temp = tcg_temp_new(TCG_TYPE_TL);
559
    tcg_gen_xor_tl(r_temp, src1, src2);
560
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
561
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
562
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
563
    tcg_gen_shri_tl(r_temp, r_temp, 31 - PSR_OVF_SHIFT);
564
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
565
    tcg_gen_or_i32(cpu_psr, cpu_psr, cpu_tmp32);
566
}
567

    
568
#ifdef TARGET_SPARC64
569
static inline void gen_cc_V_sub_xcc(TCGv dst, TCGv src1, TCGv src2)
570
{
571
    TCGv r_temp;
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, (1ULL << 63));
578
    tcg_gen_shri_tl(r_temp, r_temp, 63 - PSR_OVF_SHIFT);
579
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
580
    tcg_gen_or_i32(cpu_xcc, cpu_xcc, cpu_tmp32);
581
}
582
#endif
583

    
584
static inline void gen_sub_tv(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, (1 << 31));
596
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
597
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
598
    gen_set_label(l1);
599
}
600

    
601
static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2)
602
{
603
    tcg_gen_mov_tl(cpu_cc_src, src1);
604
    tcg_gen_mov_tl(cpu_cc_src2, src2);
605
    tcg_gen_sub_tl(dst, src1, src2);
606
    tcg_gen_mov_tl(cpu_cc_dst, dst);
607
    gen_cc_clear_icc();
608
    gen_cc_NZ_icc(cpu_cc_dst);
609
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
610
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
611
#ifdef TARGET_SPARC64
612
    gen_cc_clear_xcc();
613
    gen_cc_NZ_xcc(cpu_cc_dst);
614
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
615
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
616
#endif
617
}
618

    
619
static inline void gen_op_subx_cc(TCGv dst, TCGv src1, TCGv src2)
620
{
621
    tcg_gen_mov_tl(cpu_cc_src, src1);
622
    tcg_gen_mov_tl(cpu_cc_src2, src2);
623
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
624
    tcg_gen_sub_tl(dst, src1, cpu_tmp0);
625
    gen_cc_clear_icc();
626
    gen_cc_C_sub_icc(dst, cpu_cc_src);
627
#ifdef TARGET_SPARC64
628
    gen_cc_clear_xcc();
629
    gen_cc_C_sub_xcc(dst, cpu_cc_src);
630
#endif
631
    tcg_gen_sub_tl(dst, dst, cpu_cc_src2);
632
    tcg_gen_mov_tl(cpu_cc_dst, dst);
633
    gen_cc_NZ_icc(cpu_cc_dst);
634
    gen_cc_C_sub_icc(cpu_cc_dst, cpu_cc_src);
635
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
636
#ifdef TARGET_SPARC64
637
    gen_cc_NZ_xcc(cpu_cc_dst);
638
    gen_cc_C_sub_xcc(cpu_cc_dst, cpu_cc_src);
639
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
640
#endif
641
}
642

    
643
static inline void gen_op_tsub_cc(TCGv dst, TCGv src1, TCGv src2)
644
{
645
    tcg_gen_mov_tl(cpu_cc_src, src1);
646
    tcg_gen_mov_tl(cpu_cc_src2, src2);
647
    tcg_gen_sub_tl(dst, src1, src2);
648
    tcg_gen_mov_tl(cpu_cc_dst, dst);
649
    gen_cc_clear_icc();
650
    gen_cc_NZ_icc(cpu_cc_dst);
651
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
652
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
653
    gen_cc_V_tag(cpu_cc_src, cpu_cc_src2);
654
#ifdef TARGET_SPARC64
655
    gen_cc_clear_xcc();
656
    gen_cc_NZ_xcc(cpu_cc_dst);
657
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
658
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
659
#endif
660
}
661

    
662
static inline void gen_op_tsub_ccTV(TCGv dst, TCGv src1, TCGv src2)
663
{
664
    tcg_gen_mov_tl(cpu_cc_src, src1);
665
    tcg_gen_mov_tl(cpu_cc_src2, src2);
666
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
667
    tcg_gen_sub_tl(dst, src1, src2);
668
    tcg_gen_mov_tl(cpu_cc_dst, dst);
669
    gen_sub_tv(dst, cpu_cc_src, cpu_cc_src2);
670
    gen_cc_clear_icc();
671
    gen_cc_NZ_icc(cpu_cc_dst);
672
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
673
#ifdef TARGET_SPARC64
674
    gen_cc_clear_xcc();
675
    gen_cc_NZ_xcc(cpu_cc_dst);
676
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
677
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
678
#endif
679
}
680

    
681
static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
682
{
683
    TCGv r_temp, r_temp2;
684
    int l1;
685

    
686
    l1 = gen_new_label();
687
    r_temp = tcg_temp_new(TCG_TYPE_TL);
688
    r_temp2 = tcg_temp_new(TCG_TYPE_I32);
689

    
690
    /* old op:
691
    if (!(env->y & 1))
692
        T1 = 0;
693
    */
694
    tcg_gen_mov_tl(cpu_cc_src, src1);
695
    tcg_gen_ld32u_tl(r_temp, cpu_env, offsetof(CPUSPARCState, y));
696
    tcg_gen_trunc_tl_i32(r_temp2, r_temp);
697
    tcg_gen_andi_i32(r_temp2, r_temp2, 0x1);
698
    tcg_gen_mov_tl(cpu_cc_src2, src2);
699
    tcg_gen_brcond_i32(TCG_COND_NE, r_temp2, tcg_const_i32(0), l1);
700
    tcg_gen_movi_tl(cpu_cc_src2, 0);
701
    gen_set_label(l1);
702

    
703
    // b2 = T0 & 1;
704
    // env->y = (b2 << 31) | (env->y >> 1);
705
    tcg_gen_trunc_tl_i32(r_temp2, cpu_cc_src);
706
    tcg_gen_andi_i32(r_temp2, r_temp2, 0x1);
707
    tcg_gen_shli_i32(r_temp2, r_temp2, 31);
708
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, y));
709
    tcg_gen_shri_i32(cpu_tmp32, cpu_tmp32, 1);
710
    tcg_gen_or_i32(cpu_tmp32, cpu_tmp32, r_temp2);
711
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, y));
712

    
713
    // b1 = N ^ V;
714
    gen_mov_reg_N(cpu_tmp0, cpu_psr);
715
    gen_mov_reg_V(r_temp, cpu_psr);
716
    tcg_gen_xor_tl(cpu_tmp0, cpu_tmp0, r_temp);
717

    
718
    // T0 = (b1 << 31) | (T0 >> 1);
719
    // src1 = T0;
720
    tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
721
    tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
722
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
723

    
724
    /* do addition and update flags */
725
    tcg_gen_add_tl(dst, cpu_cc_src, cpu_cc_src2);
726
    tcg_gen_mov_tl(cpu_cc_dst, dst);
727

    
728
    gen_cc_clear_icc();
729
    gen_cc_NZ_icc(cpu_cc_dst);
730
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
731
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
732
}
733

    
734
static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
735
{
736
    TCGv r_temp, r_temp2;
737

    
738
    r_temp = tcg_temp_new(TCG_TYPE_I64);
739
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);
740

    
741
    tcg_gen_extu_tl_i64(r_temp, src2);
742
    tcg_gen_extu_tl_i64(r_temp2, src1);
743
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
744

    
745
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
746
    tcg_gen_trunc_i64_i32(r_temp, r_temp);
747
    tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
748
#ifdef TARGET_SPARC64
749
    tcg_gen_mov_i64(dst, r_temp2);
750
#else
751
    tcg_gen_trunc_i64_tl(dst, r_temp2);
752
#endif
753
}
754

    
755
static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
756
{
757
    TCGv r_temp, r_temp2;
758

    
759
    r_temp = tcg_temp_new(TCG_TYPE_I64);
760
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);
761

    
762
    tcg_gen_ext_tl_i64(r_temp, src2);
763
    tcg_gen_ext_tl_i64(r_temp2, src1);
764
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
765

    
766
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
767
    tcg_gen_trunc_i64_i32(r_temp, r_temp);
768
    tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
769
#ifdef TARGET_SPARC64
770
    tcg_gen_mov_i64(dst, r_temp2);
771
#else
772
    tcg_gen_trunc_i64_tl(dst, r_temp2);
773
#endif
774
}
775

    
776
#ifdef TARGET_SPARC64
777
static inline void gen_trap_ifdivzero_tl(TCGv divisor)
778
{
779
    int l1;
780

    
781
    l1 = gen_new_label();
782
    tcg_gen_brcond_tl(TCG_COND_NE, divisor, tcg_const_tl(0), l1);
783
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_DIV_ZERO));
784
    gen_set_label(l1);
785
}
786

    
787
static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
788
{
789
    int l1, l2;
790

    
791
    l1 = gen_new_label();
792
    l2 = gen_new_label();
793
    tcg_gen_mov_tl(cpu_cc_src, src1);
794
    tcg_gen_mov_tl(cpu_cc_src2, src2);
795
    gen_trap_ifdivzero_tl(src2);
796
    tcg_gen_brcond_tl(TCG_COND_NE, cpu_cc_src, tcg_const_tl(INT64_MIN), l1);
797
    tcg_gen_brcond_tl(TCG_COND_NE, cpu_cc_src2, tcg_const_tl(-1), l1);
798
    tcg_gen_movi_i64(dst, INT64_MIN);
799
    tcg_gen_br(l2);
800
    gen_set_label(l1);
801
    tcg_gen_div_i64(dst, cpu_cc_src, cpu_cc_src2);
802
    gen_set_label(l2);
803
}
804
#endif
805

    
806
static inline void gen_op_div_cc(TCGv dst)
807
{
808
    int l1;
809

    
810
    tcg_gen_mov_tl(cpu_cc_dst, dst);
811
    gen_cc_clear_icc();
812
    gen_cc_NZ_icc(cpu_cc_dst);
813
    l1 = gen_new_label();
814
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, cc_src2));
815
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
816
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
817
    gen_set_label(l1);
818
}
819

    
820
static inline void gen_op_logic_cc(TCGv dst)
821
{
822
    tcg_gen_mov_tl(cpu_cc_dst, dst);
823

    
824
    gen_cc_clear_icc();
825
    gen_cc_NZ_icc(cpu_cc_dst);
826
#ifdef TARGET_SPARC64
827
    gen_cc_clear_xcc();
828
    gen_cc_NZ_xcc(cpu_cc_dst);
829
#endif
830
}
831

    
832
// 1
833
static inline void gen_op_eval_ba(TCGv dst)
834
{
835
    tcg_gen_movi_tl(dst, 1);
836
}
837

    
838
// Z
839
static inline void gen_op_eval_be(TCGv dst, TCGv src)
840
{
841
    gen_mov_reg_Z(dst, src);
842
}
843

    
844
// Z | (N ^ V)
845
static inline void gen_op_eval_ble(TCGv dst, TCGv src)
846
{
847
    gen_mov_reg_N(cpu_tmp0, src);
848
    gen_mov_reg_V(dst, src);
849
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
850
    gen_mov_reg_Z(cpu_tmp0, src);
851
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
852
}
853

    
854
// N ^ V
855
static inline void gen_op_eval_bl(TCGv dst, TCGv src)
856
{
857
    gen_mov_reg_V(cpu_tmp0, src);
858
    gen_mov_reg_N(dst, src);
859
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
860
}
861

    
862
// C | Z
863
static inline void gen_op_eval_bleu(TCGv dst, TCGv src)
864
{
865
    gen_mov_reg_Z(cpu_tmp0, src);
866
    gen_mov_reg_C(dst, src);
867
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
868
}
869

    
870
// C
871
static inline void gen_op_eval_bcs(TCGv dst, TCGv src)
872
{
873
    gen_mov_reg_C(dst, src);
874
}
875

    
876
// V
877
static inline void gen_op_eval_bvs(TCGv dst, TCGv src)
878
{
879
    gen_mov_reg_V(dst, src);
880
}
881

    
882
// 0
883
static inline void gen_op_eval_bn(TCGv dst)
884
{
885
    tcg_gen_movi_tl(dst, 0);
886
}
887

    
888
// N
889
static inline void gen_op_eval_bneg(TCGv dst, TCGv src)
890
{
891
    gen_mov_reg_N(dst, src);
892
}
893

    
894
// !Z
895
static inline void gen_op_eval_bne(TCGv dst, TCGv src)
896
{
897
    gen_mov_reg_Z(dst, src);
898
    tcg_gen_xori_tl(dst, dst, 0x1);
899
}
900

    
901
// !(Z | (N ^ V))
902
static inline void gen_op_eval_bg(TCGv dst, TCGv src)
903
{
904
    gen_mov_reg_N(cpu_tmp0, src);
905
    gen_mov_reg_V(dst, src);
906
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
907
    gen_mov_reg_Z(cpu_tmp0, src);
908
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
909
    tcg_gen_xori_tl(dst, dst, 0x1);
910
}
911

    
912
// !(N ^ V)
913
static inline void gen_op_eval_bge(TCGv dst, TCGv src)
914
{
915
    gen_mov_reg_V(cpu_tmp0, src);
916
    gen_mov_reg_N(dst, src);
917
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
918
    tcg_gen_xori_tl(dst, dst, 0x1);
919
}
920

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

    
930
// !C
931
static inline void gen_op_eval_bcc(TCGv dst, TCGv src)
932
{
933
    gen_mov_reg_C(dst, src);
934
    tcg_gen_xori_tl(dst, dst, 0x1);
935
}
936

    
937
// !N
938
static inline void gen_op_eval_bpos(TCGv dst, TCGv src)
939
{
940
    gen_mov_reg_N(dst, src);
941
    tcg_gen_xori_tl(dst, dst, 0x1);
942
}
943

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

    
951
/*
952
  FPSR bit field FCC1 | FCC0:
953
   0 =
954
   1 <
955
   2 >
956
   3 unordered
957
*/
958
static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src,
959
                                    unsigned int fcc_offset)
960
{
961
    tcg_gen_extu_i32_tl(reg, src);
962
    tcg_gen_shri_tl(reg, reg, FSR_FCC0_SHIFT + fcc_offset);
963
    tcg_gen_andi_tl(reg, reg, 0x1);
964
}
965

    
966
static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
967
                                    unsigned int fcc_offset)
968
{
969
    tcg_gen_extu_i32_tl(reg, src);
970
    tcg_gen_shri_tl(reg, reg, FSR_FCC1_SHIFT + fcc_offset);
971
    tcg_gen_andi_tl(reg, reg, 0x1);
972
}
973

    
974
// !0: FCC0 | FCC1
975
static inline void gen_op_eval_fbne(TCGv dst, TCGv src,
976
                                    unsigned int fcc_offset)
977
{
978
    gen_mov_reg_FCC0(dst, src, fcc_offset);
979
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
980
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
981
}
982

    
983
// 1 or 2: FCC0 ^ FCC1
984
static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
985
                                    unsigned int fcc_offset)
986
{
987
    gen_mov_reg_FCC0(dst, src, fcc_offset);
988
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
989
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
990
}
991

    
992
// 1 or 3: FCC0
993
static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
994
                                    unsigned int fcc_offset)
995
{
996
    gen_mov_reg_FCC0(dst, src, fcc_offset);
997
}
998

    
999
// 1: FCC0 & !FCC1
1000
static inline void gen_op_eval_fbl(TCGv dst, TCGv src,
1001
                                    unsigned int fcc_offset)
1002
{
1003
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1004
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1005
    tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
1006
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1007
}
1008

    
1009
// 2 or 3: FCC1
1010
static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
1011
                                    unsigned int fcc_offset)
1012
{
1013
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1014
}
1015

    
1016
// 2: !FCC0 & FCC1
1017
static inline void gen_op_eval_fbg(TCGv dst, TCGv src,
1018
                                    unsigned int fcc_offset)
1019
{
1020
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1021
    tcg_gen_xori_tl(dst, dst, 0x1);
1022
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1023
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1024
}
1025

    
1026
// 3: FCC0 & FCC1
1027
static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
1028
                                    unsigned int fcc_offset)
1029
{
1030
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1031
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1032
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1033
}
1034

    
1035
// 0: !(FCC0 | FCC1)
1036
static inline void gen_op_eval_fbe(TCGv dst, TCGv src,
1037
                                    unsigned int fcc_offset)
1038
{
1039
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1040
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1041
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
1042
    tcg_gen_xori_tl(dst, dst, 0x1);
1043
}
1044

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

    
1055
// 0 or 2: !FCC0
1056
static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
1057
                                    unsigned int fcc_offset)
1058
{
1059
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1060
    tcg_gen_xori_tl(dst, dst, 0x1);
1061
}
1062

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

    
1074
// 0 or 1: !FCC1
1075
static inline void gen_op_eval_fble(TCGv dst, TCGv src,
1076
                                    unsigned int fcc_offset)
1077
{
1078
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1079
    tcg_gen_xori_tl(dst, dst, 0x1);
1080
}
1081

    
1082
// !2: !(!FCC0 & FCC1)
1083
static inline void gen_op_eval_fbule(TCGv dst, TCGv src,
1084
                                    unsigned int fcc_offset)
1085
{
1086
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1087
    tcg_gen_xori_tl(dst, dst, 0x1);
1088
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1089
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1090
    tcg_gen_xori_tl(dst, dst, 0x1);
1091
}
1092

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

    
1103
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
1104
                               target_ulong pc2, TCGv r_cond)
1105
{
1106
    int l1;
1107

    
1108
    l1 = gen_new_label();
1109

    
1110
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1111

    
1112
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
1113

    
1114
    gen_set_label(l1);
1115
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
1116
}
1117

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

    
1123
    l1 = gen_new_label();
1124

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

    
1127
    gen_goto_tb(dc, 0, pc2, pc1);
1128

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

    
1133
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
1134
                                      TCGv r_cond)
1135
{
1136
    int l1, l2;
1137

    
1138
    l1 = gen_new_label();
1139
    l2 = gen_new_label();
1140

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

    
1143
    tcg_gen_movi_tl(cpu_npc, npc1);
1144
    tcg_gen_br(l2);
1145

    
1146
    gen_set_label(l1);
1147
    tcg_gen_movi_tl(cpu_npc, npc2);
1148
    gen_set_label(l2);
1149
}
1150

    
1151
/* call this function before using the condition register as it may
1152
   have been set for a jump */
1153
static inline void flush_cond(DisasContext *dc, TCGv cond)
1154
{
1155
    if (dc->npc == JUMP_PC) {
1156
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1157
        dc->npc = DYNAMIC_PC;
1158
    }
1159
}
1160

    
1161
static inline void save_npc(DisasContext *dc, TCGv cond)
1162
{
1163
    if (dc->npc == JUMP_PC) {
1164
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1165
        dc->npc = DYNAMIC_PC;
1166
    } else if (dc->npc != DYNAMIC_PC) {
1167
        tcg_gen_movi_tl(cpu_npc, dc->npc);
1168
    }
1169
}
1170

    
1171
static inline void save_state(DisasContext *dc, TCGv cond)
1172
{
1173
    tcg_gen_movi_tl(cpu_pc, dc->pc);
1174
    save_npc(dc, cond);
1175
}
1176

    
1177
static inline void gen_mov_pc_npc(DisasContext *dc, TCGv cond)
1178
{
1179
    if (dc->npc == JUMP_PC) {
1180
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1181
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1182
        dc->pc = DYNAMIC_PC;
1183
    } else if (dc->npc == DYNAMIC_PC) {
1184
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1185
        dc->pc = DYNAMIC_PC;
1186
    } else {
1187
        dc->pc = dc->npc;
1188
    }
1189
}
1190

    
1191
static inline void gen_op_next_insn(void)
1192
{
1193
    tcg_gen_mov_tl(cpu_pc, cpu_npc);
1194
    tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
1195
}
1196

    
1197
static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond)
1198
{
1199
    TCGv r_src;
1200

    
1201
#ifdef TARGET_SPARC64
1202
    if (cc)
1203
        r_src = cpu_xcc;
1204
    else
1205
        r_src = cpu_psr;
1206
#else
1207
    r_src = cpu_psr;
1208
#endif
1209
    switch (cond) {
1210
    case 0x0:
1211
        gen_op_eval_bn(r_dst);
1212
        break;
1213
    case 0x1:
1214
        gen_op_eval_be(r_dst, r_src);
1215
        break;
1216
    case 0x2:
1217
        gen_op_eval_ble(r_dst, r_src);
1218
        break;
1219
    case 0x3:
1220
        gen_op_eval_bl(r_dst, r_src);
1221
        break;
1222
    case 0x4:
1223
        gen_op_eval_bleu(r_dst, r_src);
1224
        break;
1225
    case 0x5:
1226
        gen_op_eval_bcs(r_dst, r_src);
1227
        break;
1228
    case 0x6:
1229
        gen_op_eval_bneg(r_dst, r_src);
1230
        break;
1231
    case 0x7:
1232
        gen_op_eval_bvs(r_dst, r_src);
1233
        break;
1234
    case 0x8:
1235
        gen_op_eval_ba(r_dst);
1236
        break;
1237
    case 0x9:
1238
        gen_op_eval_bne(r_dst, r_src);
1239
        break;
1240
    case 0xa:
1241
        gen_op_eval_bg(r_dst, r_src);
1242
        break;
1243
    case 0xb:
1244
        gen_op_eval_bge(r_dst, r_src);
1245
        break;
1246
    case 0xc:
1247
        gen_op_eval_bgu(r_dst, r_src);
1248
        break;
1249
    case 0xd:
1250
        gen_op_eval_bcc(r_dst, r_src);
1251
        break;
1252
    case 0xe:
1253
        gen_op_eval_bpos(r_dst, r_src);
1254
        break;
1255
    case 0xf:
1256
        gen_op_eval_bvc(r_dst, r_src);
1257
        break;
1258
    }
1259
}
1260

    
1261
static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
1262
{
1263
    unsigned int offset;
1264

    
1265
    switch (cc) {
1266
    default:
1267
    case 0x0:
1268
        offset = 0;
1269
        break;
1270
    case 0x1:
1271
        offset = 32 - 10;
1272
        break;
1273
    case 0x2:
1274
        offset = 34 - 10;
1275
        break;
1276
    case 0x3:
1277
        offset = 36 - 10;
1278
        break;
1279
    }
1280

    
1281
    switch (cond) {
1282
    case 0x0:
1283
        gen_op_eval_bn(r_dst);
1284
        break;
1285
    case 0x1:
1286
        gen_op_eval_fbne(r_dst, cpu_fsr, offset);
1287
        break;
1288
    case 0x2:
1289
        gen_op_eval_fblg(r_dst, cpu_fsr, offset);
1290
        break;
1291
    case 0x3:
1292
        gen_op_eval_fbul(r_dst, cpu_fsr, offset);
1293
        break;
1294
    case 0x4:
1295
        gen_op_eval_fbl(r_dst, cpu_fsr, offset);
1296
        break;
1297
    case 0x5:
1298
        gen_op_eval_fbug(r_dst, cpu_fsr, offset);
1299
        break;
1300
    case 0x6:
1301
        gen_op_eval_fbg(r_dst, cpu_fsr, offset);
1302
        break;
1303
    case 0x7:
1304
        gen_op_eval_fbu(r_dst, cpu_fsr, offset);
1305
        break;
1306
    case 0x8:
1307
        gen_op_eval_ba(r_dst);
1308
        break;
1309
    case 0x9:
1310
        gen_op_eval_fbe(r_dst, cpu_fsr, offset);
1311
        break;
1312
    case 0xa:
1313
        gen_op_eval_fbue(r_dst, cpu_fsr, offset);
1314
        break;
1315
    case 0xb:
1316
        gen_op_eval_fbge(r_dst, cpu_fsr, offset);
1317
        break;
1318
    case 0xc:
1319
        gen_op_eval_fbuge(r_dst, cpu_fsr, offset);
1320
        break;
1321
    case 0xd:
1322
        gen_op_eval_fble(r_dst, cpu_fsr, offset);
1323
        break;
1324
    case 0xe:
1325
        gen_op_eval_fbule(r_dst, cpu_fsr, offset);
1326
        break;
1327
    case 0xf:
1328
        gen_op_eval_fbo(r_dst, cpu_fsr, offset);
1329
        break;
1330
    }
1331
}
1332

    
1333
#ifdef TARGET_SPARC64
1334
// Inverted logic
1335
static const int gen_tcg_cond_reg[8] = {
1336
    -1,
1337
    TCG_COND_NE,
1338
    TCG_COND_GT,
1339
    TCG_COND_GE,
1340
    -1,
1341
    TCG_COND_EQ,
1342
    TCG_COND_LE,
1343
    TCG_COND_LT,
1344
};
1345

    
1346
static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
1347
{
1348
    int l1;
1349

    
1350
    l1 = gen_new_label();
1351
    tcg_gen_movi_tl(r_dst, 0);
1352
    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], r_src, tcg_const_tl(0), l1);
1353
    tcg_gen_movi_tl(r_dst, 1);
1354
    gen_set_label(l1);
1355
}
1356
#endif
1357

    
1358
/* XXX: potentially incorrect if dynamic npc */
1359
static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1360
                      TCGv r_cond)
1361
{
1362
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1363
    target_ulong target = dc->pc + offset;
1364

    
1365
    if (cond == 0x0) {
1366
        /* unconditional not taken */
1367
        if (a) {
1368
            dc->pc = dc->npc + 4;
1369
            dc->npc = dc->pc + 4;
1370
        } else {
1371
            dc->pc = dc->npc;
1372
            dc->npc = dc->pc + 4;
1373
        }
1374
    } else if (cond == 0x8) {
1375
        /* unconditional taken */
1376
        if (a) {
1377
            dc->pc = target;
1378
            dc->npc = dc->pc + 4;
1379
        } else {
1380
            dc->pc = dc->npc;
1381
            dc->npc = target;
1382
        }
1383
    } else {
1384
        flush_cond(dc, r_cond);
1385
        gen_cond(r_cond, cc, cond);
1386
        if (a) {
1387
            gen_branch_a(dc, target, dc->npc, r_cond);
1388
            dc->is_br = 1;
1389
        } else {
1390
            dc->pc = dc->npc;
1391
            dc->jump_pc[0] = target;
1392
            dc->jump_pc[1] = dc->npc + 4;
1393
            dc->npc = JUMP_PC;
1394
        }
1395
    }
1396
}
1397

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

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

    
1438
#ifdef TARGET_SPARC64
1439
/* XXX: potentially incorrect if dynamic npc */
1440
static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
1441
                          TCGv r_cond, TCGv r_reg)
1442
{
1443
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1444
    target_ulong target = dc->pc + offset;
1445

    
1446
    flush_cond(dc, r_cond);
1447
    gen_cond_reg(r_cond, cond, r_reg);
1448
    if (a) {
1449
        gen_branch_a(dc, target, dc->npc, r_cond);
1450
        dc->is_br = 1;
1451
    } else {
1452
        dc->pc = dc->npc;
1453
        dc->jump_pc[0] = target;
1454
        dc->jump_pc[1] = dc->npc + 4;
1455
        dc->npc = JUMP_PC;
1456
    }
1457
}
1458

    
1459
static GenOpFunc * const gen_fcmps[4] = {
1460
    helper_fcmps,
1461
    helper_fcmps_fcc1,
1462
    helper_fcmps_fcc2,
1463
    helper_fcmps_fcc3,
1464
};
1465

    
1466
static GenOpFunc * const gen_fcmpd[4] = {
1467
    helper_fcmpd,
1468
    helper_fcmpd_fcc1,
1469
    helper_fcmpd_fcc2,
1470
    helper_fcmpd_fcc3,
1471
};
1472

    
1473
static GenOpFunc * const gen_fcmpq[4] = {
1474
    helper_fcmpq,
1475
    helper_fcmpq_fcc1,
1476
    helper_fcmpq_fcc2,
1477
    helper_fcmpq_fcc3,
1478
};
1479

    
1480
static GenOpFunc * const gen_fcmpes[4] = {
1481
    helper_fcmpes,
1482
    helper_fcmpes_fcc1,
1483
    helper_fcmpes_fcc2,
1484
    helper_fcmpes_fcc3,
1485
};
1486

    
1487
static GenOpFunc * const gen_fcmped[4] = {
1488
    helper_fcmped,
1489
    helper_fcmped_fcc1,
1490
    helper_fcmped_fcc2,
1491
    helper_fcmped_fcc3,
1492
};
1493

    
1494
static GenOpFunc * const gen_fcmpeq[4] = {
1495
    helper_fcmpeq,
1496
    helper_fcmpeq_fcc1,
1497
    helper_fcmpeq_fcc2,
1498
    helper_fcmpeq_fcc3,
1499
};
1500

    
1501
static inline void gen_op_fcmps(int fccno)
1502
{
1503
    tcg_gen_helper_0_0(gen_fcmps[fccno]);
1504
}
1505

    
1506
static inline void gen_op_fcmpd(int fccno)
1507
{
1508
    tcg_gen_helper_0_0(gen_fcmpd[fccno]);
1509
}
1510

    
1511
static inline void gen_op_fcmpq(int fccno)
1512
{
1513
    tcg_gen_helper_0_0(gen_fcmpq[fccno]);
1514
}
1515

    
1516
static inline void gen_op_fcmpes(int fccno)
1517
{
1518
    tcg_gen_helper_0_0(gen_fcmpes[fccno]);
1519
}
1520

    
1521
static inline void gen_op_fcmped(int fccno)
1522
{
1523
    tcg_gen_helper_0_0(gen_fcmped[fccno]);
1524
}
1525

    
1526
static inline void gen_op_fcmpeq(int fccno)
1527
{
1528
    tcg_gen_helper_0_0(gen_fcmpeq[fccno]);
1529
}
1530

    
1531
#else
1532

    
1533
static inline void gen_op_fcmps(int fccno)
1534
{
1535
    tcg_gen_helper_0_0(helper_fcmps);
1536
}
1537

    
1538
static inline void gen_op_fcmpd(int fccno)
1539
{
1540
    tcg_gen_helper_0_0(helper_fcmpd);
1541
}
1542

    
1543
static inline void gen_op_fcmpq(int fccno)
1544
{
1545
    tcg_gen_helper_0_0(helper_fcmpq);
1546
}
1547

    
1548
static inline void gen_op_fcmpes(int fccno)
1549
{
1550
    tcg_gen_helper_0_0(helper_fcmpes);
1551
}
1552

    
1553
static inline void gen_op_fcmped(int fccno)
1554
{
1555
    tcg_gen_helper_0_0(helper_fcmped);
1556
}
1557

    
1558
static inline void gen_op_fcmpeq(int fccno)
1559
{
1560
    tcg_gen_helper_0_0(helper_fcmpeq);
1561
}
1562
#endif
1563

    
1564
static inline void gen_op_fpexception_im(int fsr_flags)
1565
{
1566
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~FSR_FTT_MASK);
1567
    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
1568
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_FP_EXCP));
1569
}
1570

    
1571
static int gen_trap_ifnofpu(DisasContext *dc, TCGv r_cond)
1572
{
1573
#if !defined(CONFIG_USER_ONLY)
1574
    if (!dc->fpu_enabled) {
1575
        save_state(dc, r_cond);
1576
        tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_NFPU_INSN));
1577
        dc->is_br = 1;
1578
        return 1;
1579
    }
1580
#endif
1581
    return 0;
1582
}
1583

    
1584
static inline void gen_op_clear_ieee_excp_and_FTT(void)
1585
{
1586
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~(FSR_FTT_MASK | FSR_CEXC_MASK));
1587
}
1588

    
1589
static inline void gen_clear_float_exceptions(void)
1590
{
1591
    tcg_gen_helper_0_0(helper_clear_float_exceptions);
1592
}
1593

    
1594
/* asi moves */
1595
#ifdef TARGET_SPARC64
1596
static inline TCGv gen_get_asi(int insn, TCGv r_addr)
1597
{
1598
    int asi, offset;
1599
    TCGv r_asi;
1600

    
1601
    if (IS_IMM) {
1602
        r_asi = tcg_temp_new(TCG_TYPE_I32);
1603
        offset = GET_FIELD(insn, 25, 31);
1604
        tcg_gen_addi_tl(r_addr, r_addr, offset);
1605
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
1606
    } else {
1607
        asi = GET_FIELD(insn, 19, 26);
1608
        r_asi = tcg_const_i32(asi);
1609
    }
1610
    return r_asi;
1611
}
1612

    
1613
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
1614
                              int sign)
1615
{
1616
    TCGv r_asi;
1617

    
1618
    r_asi = gen_get_asi(insn, addr);
1619
    tcg_gen_helper_1_4(helper_ld_asi, dst, addr, r_asi,
1620
                       tcg_const_i32(size), tcg_const_i32(sign));
1621
}
1622

    
1623
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1624
{
1625
    TCGv r_asi;
1626

    
1627
    r_asi = gen_get_asi(insn, addr);
1628
    tcg_gen_helper_0_4(helper_st_asi, addr, src, r_asi, tcg_const_i32(size));
1629
}
1630

    
1631
static inline void gen_ldf_asi(TCGv addr, int insn, int size, int rd)
1632
{
1633
    TCGv r_asi;
1634

    
1635
    r_asi = gen_get_asi(insn, addr);
1636
    tcg_gen_helper_0_4(helper_ldf_asi, addr, r_asi, tcg_const_i32(size),
1637
                       tcg_const_i32(rd));
1638
}
1639

    
1640
static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
1641
{
1642
    TCGv r_asi;
1643

    
1644
    r_asi = gen_get_asi(insn, addr);
1645
    tcg_gen_helper_0_4(helper_stf_asi, addr, r_asi, tcg_const_i32(size),
1646
                       tcg_const_i32(rd));
1647
}
1648

    
1649
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1650
{
1651
    TCGv r_temp, r_asi;
1652

    
1653
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1654
    r_asi = gen_get_asi(insn, addr);
1655
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, addr, r_asi,
1656
                       tcg_const_i32(4), tcg_const_i32(0));
1657
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, r_asi,
1658
                       tcg_const_i32(4));
1659
    tcg_gen_extu_i32_tl(dst, r_temp);
1660
}
1661

    
1662
static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn)
1663
{
1664
    TCGv r_asi;
1665

    
1666
    r_asi = gen_get_asi(insn, addr);
1667
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi,
1668
                       tcg_const_i32(8), tcg_const_i32(0));
1669
    tcg_gen_andi_i64(lo, cpu_tmp64, 0xffffffffULL);
1670
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1671
    tcg_gen_andi_i64(hi, cpu_tmp64, 0xffffffffULL);
1672
}
1673

    
1674
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1675
{
1676
    TCGv r_temp, r_asi;
1677

    
1678
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1679
    gen_movl_reg_TN(rd + 1, r_temp);
1680
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi,
1681
                       r_temp);
1682
    r_asi = gen_get_asi(insn, addr);
1683
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi,
1684
                       tcg_const_i32(8));
1685
}
1686

    
1687
static inline void gen_cas_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
1688
                               int rd)
1689
{
1690
    TCGv r_val1, r_asi;
1691

    
1692
    r_val1 = tcg_temp_new(TCG_TYPE_I32);
1693
    gen_movl_reg_TN(rd, r_val1);
1694
    r_asi = gen_get_asi(insn, addr);
1695
    tcg_gen_helper_1_4(helper_cas_asi, dst, addr, r_val1, val2, r_asi);
1696
}
1697

    
1698
static inline void gen_casx_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
1699
                                int rd)
1700
{
1701
    TCGv r_asi;
1702

    
1703
    gen_movl_reg_TN(rd, cpu_tmp64);
1704
    r_asi = gen_get_asi(insn, addr);
1705
    tcg_gen_helper_1_4(helper_casx_asi, dst, addr, cpu_tmp64, val2, r_asi);
1706
}
1707

    
1708
#elif !defined(CONFIG_USER_ONLY)
1709

    
1710
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
1711
                              int sign)
1712
{
1713
    int asi;
1714

    
1715
    asi = GET_FIELD(insn, 19, 26);
1716
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, tcg_const_i32(asi),
1717
                       tcg_const_i32(size), tcg_const_i32(sign));
1718
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1719
}
1720

    
1721
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1722
{
1723
    int asi;
1724

    
1725
    tcg_gen_extu_tl_i64(cpu_tmp64, src);
1726
    asi = GET_FIELD(insn, 19, 26);
1727
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, tcg_const_i32(asi),
1728
                       tcg_const_i32(size));
1729
}
1730

    
1731
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1732
{
1733
    int asi;
1734
    TCGv r_temp;
1735

    
1736
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1737
    asi = GET_FIELD(insn, 19, 26);
1738
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, addr, tcg_const_i32(asi),
1739
                       tcg_const_i32(4), tcg_const_i32(0));
1740
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, tcg_const_i32(asi),
1741
                       tcg_const_i32(4));
1742
    tcg_gen_extu_i32_tl(dst, r_temp);
1743
}
1744

    
1745
static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn)
1746
{
1747
    int asi;
1748

    
1749
    asi = GET_FIELD(insn, 19, 26);
1750
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, tcg_const_i32(asi),
1751
                       tcg_const_i32(8), tcg_const_i32(0));
1752
    tcg_gen_trunc_i64_tl(lo, cpu_tmp64);
1753
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1754
    tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
1755
}
1756

    
1757
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1758
{
1759
    int asi;
1760
    TCGv r_temp;
1761

    
1762
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1763
    gen_movl_reg_TN(rd + 1, r_temp);
1764
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi, r_temp);
1765
    asi = GET_FIELD(insn, 19, 26);
1766
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, tcg_const_i32(asi),
1767
                       tcg_const_i32(8));
1768
}
1769
#endif
1770

    
1771
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1772
static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
1773
{
1774
    int asi;
1775

    
1776
    gen_ld_asi(dst, addr, insn, 1, 0);
1777

    
1778
    asi = GET_FIELD(insn, 19, 26);
1779
    tcg_gen_helper_0_4(helper_st_asi, addr, tcg_const_i64(0xffULL),
1780
                       tcg_const_i32(asi), tcg_const_i32(1));
1781
}
1782
#endif
1783

    
1784
static inline TCGv get_src1(unsigned int insn, TCGv def)
1785
{
1786
    TCGv r_rs1 = def;
1787
    unsigned int rs1;
1788

    
1789
    rs1 = GET_FIELD(insn, 13, 17);
1790
    if (rs1 == 0)
1791
        //r_rs1 = tcg_const_tl(0);
1792
        tcg_gen_movi_tl(def, 0);
1793
    else if (rs1 < 8)
1794
        //r_rs1 = cpu_gregs[rs1];
1795
        tcg_gen_mov_tl(def, cpu_gregs[rs1]);
1796
    else
1797
        tcg_gen_ld_tl(def, cpu_regwptr, (rs1 - 8) * sizeof(target_ulong));
1798
    return r_rs1;
1799
}
1800

    
1801
static inline TCGv get_src2(unsigned int insn, TCGv def)
1802
{
1803
    TCGv r_rs2 = def;
1804
    unsigned int rs2;
1805

    
1806
    if (IS_IMM) { /* immediate */
1807
        rs2 = GET_FIELDs(insn, 19, 31);
1808
        r_rs2 = tcg_const_tl((int)rs2);
1809
    } else { /* register */
1810
        rs2 = GET_FIELD(insn, 27, 31);
1811
        if (rs2 == 0)
1812
            r_rs2 = tcg_const_tl(0);
1813
        else if (rs2 < 8)
1814
            r_rs2 = cpu_gregs[rs2];
1815
        else
1816
            tcg_gen_ld_tl(def, cpu_regwptr, (rs2 - 8) * sizeof(target_ulong));
1817
    }
1818
    return r_rs2;
1819
}
1820

    
1821
#define CHECK_IU_FEATURE(dc, FEATURE)                      \
1822
    if (!((dc)->features & CPU_FEATURE_ ## FEATURE))       \
1823
        goto illegal_insn;
1824
#define CHECK_FPU_FEATURE(dc, FEATURE)                     \
1825
    if (!((dc)->features & CPU_FEATURE_ ## FEATURE))       \
1826
        goto nfpu_insn;
1827

    
1828
/* before an instruction, dc->pc must be static */
1829
static void disas_sparc_insn(DisasContext * dc)
1830
{
1831
    unsigned int insn, opc, rs1, rs2, rd;
1832

    
1833
    insn = ldl_code(dc->pc);
1834
    opc = GET_FIELD(insn, 0, 1);
1835

    
1836
    rd = GET_FIELD(insn, 2, 6);
1837

    
1838
    cpu_dst = cpu_T[0];
1839
    cpu_src1 = cpu_T[0]; // const
1840
    cpu_src2 = cpu_T[1]; // const
1841

    
1842
    // loads and stores
1843
    cpu_addr = cpu_T[0];
1844
    cpu_val = cpu_T[1];
1845

    
1846
    switch (opc) {
1847
    case 0:                     /* branches/sethi */
1848
        {
1849
            unsigned int xop = GET_FIELD(insn, 7, 9);
1850
            int32_t target;
1851
            switch (xop) {
1852
#ifdef TARGET_SPARC64
1853
            case 0x1:           /* V9 BPcc */
1854
                {
1855
                    int cc;
1856

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

    
1931
            gen_movl_TN_reg(15, tcg_const_tl(dc->pc));
1932
            target += dc->pc;
1933
            gen_mov_pc_npc(dc, cpu_cond);
1934
            dc->npc = target;
1935
        }
1936
        goto jmp_insn;
1937
    case 2:                     /* FPU & Logical Operations */
1938
        {
1939
            unsigned int xop = GET_FIELD(insn, 7, 12);
1940
            if (xop == 0x3a) {  /* generate trap */
1941
                int cond;
1942

    
1943
                cpu_src1 = get_src1(insn, cpu_src1);
1944
                if (IS_IMM) {
1945
                    rs2 = GET_FIELD(insn, 25, 31);
1946
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, rs2);
1947
                } else {
1948
                    rs2 = GET_FIELD(insn, 27, 31);
1949
                    if (rs2 != 0) {
1950
                        gen_movl_reg_TN(rs2, cpu_src2);
1951
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
1952
                    } else
1953
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
1954
                }
1955
                cond = GET_FIELD(insn, 3, 6);
1956
                if (cond == 0x8) {
1957
                    save_state(dc, cpu_cond);
1958
                    tcg_gen_helper_0_1(helper_trap, cpu_dst);
1959
                } else if (cond != 0) {
1960
                    TCGv r_cond = tcg_temp_new(TCG_TYPE_TL);
1961
#ifdef TARGET_SPARC64
1962
                    /* V9 icc/xcc */
1963
                    int cc = GET_FIELD_SP(insn, 11, 12);
1964

    
1965
                    save_state(dc, cpu_cond);
1966
                    if (cc == 0)
1967
                        gen_cond(r_cond, 0, cond);
1968
                    else if (cc == 2)
1969
                        gen_cond(r_cond, 1, cond);
1970
                    else
1971
                        goto illegal_insn;
1972
#else
1973
                    save_state(dc, cpu_cond);
1974
                    gen_cond(r_cond, 0, cond);
1975
#endif
1976
                    tcg_gen_helper_0_2(helper_trapcc, cpu_dst, r_cond);
1977
                }
1978
                gen_op_next_insn();
1979
                tcg_gen_exit_tb(0);
1980
                dc->is_br = 1;
1981
                goto jmp_insn;
1982
            } else if (xop == 0x28) {
1983
                rs1 = GET_FIELD(insn, 13, 17);
1984
                switch(rs1) {
1985
                case 0: /* rdy */
1986
#ifndef TARGET_SPARC64
1987
                case 0x01 ... 0x0e: /* undefined in the SPARCv8
1988
                                       manual, rdy on the microSPARC
1989
                                       II */
1990
                case 0x0f:          /* stbar in the SPARCv8 manual,
1991
                                       rdy on the microSPARC II */
1992
                case 0x10 ... 0x1f: /* implementation-dependent in the
1993
                                       SPARCv8 manual, rdy on the
1994
                                       microSPARC II */
1995
#endif
1996
                    tcg_gen_ld_tl(cpu_dst, cpu_env,
1997
                                  offsetof(CPUSPARCState, y));
1998
                    gen_movl_TN_reg(rd, cpu_dst);
1999
                    break;
2000
#ifdef TARGET_SPARC64
2001
                case 0x2: /* V9 rdccr */
2002
                    tcg_gen_helper_1_0(helper_rdccr, cpu_dst);
2003
                    gen_movl_TN_reg(rd, cpu_dst);
2004
                    break;
2005
                case 0x3: /* V9 rdasi */
2006
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2007
                                   offsetof(CPUSPARCState, asi));
2008
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2009
                    gen_movl_TN_reg(rd, cpu_dst);
2010
                    break;
2011
                case 0x4: /* V9 rdtick */
2012
                    {
2013
                        TCGv r_tickptr;
2014

    
2015
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2016
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2017
                                       offsetof(CPUState, tick));
2018
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst,
2019
                                           r_tickptr);
2020
                        gen_movl_TN_reg(rd, cpu_dst);
2021
                    }
2022
                    break;
2023
                case 0x5: /* V9 rdpc */
2024
                    gen_movl_TN_reg(rd, tcg_const_tl(dc->pc));
2025
                    break;
2026
                case 0x6: /* V9 rdfprs */
2027
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2028
                                   offsetof(CPUSPARCState, fprs));
2029
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2030
                    gen_movl_TN_reg(rd, cpu_dst);
2031
                    break;
2032
                case 0xf: /* V9 membar */
2033
                    break; /* no effect */
2034
                case 0x13: /* Graphics Status */
2035
                    if (gen_trap_ifnofpu(dc, cpu_cond))
2036
                        goto jmp_insn;
2037
                    tcg_gen_ld_tl(cpu_dst, cpu_env,
2038
                                  offsetof(CPUSPARCState, gsr));
2039
                    gen_movl_TN_reg(rd, cpu_dst);
2040
                    break;
2041
                case 0x17: /* Tick compare */
2042
                    tcg_gen_ld_tl(cpu_dst, cpu_env,
2043
                                  offsetof(CPUSPARCState, tick_cmpr));
2044
                    gen_movl_TN_reg(rd, cpu_dst);
2045
                    break;
2046
                case 0x18: /* System tick */
2047
                    {
2048
                        TCGv r_tickptr;
2049

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

    
2126
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2127
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2128
                                       offsetof(CPUState, tsptr));
2129
                        tcg_gen_ld_tl(cpu_dst, r_tsptr,
2130
                                      offsetof(trap_state, tpc));
2131
                    }
2132
                    break;
2133
                case 1: // tnpc
2134
                    {
2135
                        TCGv r_tsptr;
2136

    
2137
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2138
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2139
                                       offsetof(CPUState, tsptr));
2140
                        tcg_gen_ld_tl(cpu_dst, r_tsptr,
2141
                                      offsetof(trap_state, tnpc));
2142
                    }
2143
                    break;
2144
                case 2: // tstate
2145
                    {
2146
                        TCGv r_tsptr;
2147

    
2148
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2149
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2150
                                       offsetof(CPUState, tsptr));
2151
                        tcg_gen_ld_tl(cpu_dst, r_tsptr,
2152
                                      offsetof(trap_state, tstate));
2153
                    }
2154
                    break;
2155
                case 3: // tt
2156
                    {
2157
                        TCGv r_tsptr;
2158

    
2159
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2160
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2161
                                       offsetof(CPUState, tsptr));
2162
                        tcg_gen_ld_i32(cpu_dst, r_tsptr,
2163
                                       offsetof(trap_state, tt));
2164
                    }
2165
                    break;
2166
                case 4: // tick
2167
                    {
2168
                        TCGv r_tickptr;
2169

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

    
2603
                    l1 = gen_new_label();
2604
                    cond = GET_FIELD_SP(insn, 14, 17);
2605
                    cpu_src1 = get_src1(insn, cpu_src1);
2606
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_src1,
2607
                                      tcg_const_tl(0), l1);
2608
                    gen_op_load_fpr_FT0(rs2);
2609
                    gen_op_store_FT0_fpr(rd);
2610
                    gen_set_label(l1);
2611
                    break;
2612
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
2613
                    int l1;
2614

    
2615
                    l1 = gen_new_label();
2616
                    cond = GET_FIELD_SP(insn, 14, 17);
2617
                    cpu_src1 = get_src1(insn, cpu_src1);
2618
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_src1,
2619
                                      tcg_const_tl(0), l1);
2620
                    gen_op_load_fpr_DT0(DFPREG(rs2));
2621
                    gen_op_store_DT0_fpr(DFPREG(rd));
2622
                    gen_set_label(l1);
2623
                    break;
2624
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
2625
                    int l1;
2626

    
2627
                    CHECK_FPU_FEATURE(dc, FLOAT128);
2628
                    l1 = gen_new_label();
2629
                    cond = GET_FIELD_SP(insn, 14, 17);
2630
                    cpu_src1 = get_src1(insn, cpu_src1);
2631
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_src1,
2632
                                      tcg_const_tl(0), l1);
2633
                    gen_op_load_fpr_QT0(QFPREG(rs2));
2634
                    gen_op_store_QT0_fpr(QFPREG(rd));
2635
                    gen_set_label(l1);
2636
                    break;
2637
                }
2638
#endif
2639
                switch (xop) {
2640
#ifdef TARGET_SPARC64
2641
#define FMOVCC(size_FDQ, fcc)                                           \
2642
                    {                                                   \
2643
                        TCGv r_cond;                                    \
2644
                        int l1;                                         \
2645
                                                                        \
2646
                        l1 = gen_new_label();                           \
2647
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2648
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2649
                        gen_fcond(r_cond, fcc, cond);                   \
2650
                        tcg_gen_brcond_tl(TCG_COND_EQ, r_cond,          \
2651
                                          tcg_const_tl(0), l1);         \
2652
                        glue(glue(gen_op_load_fpr_, size_FDQ), T0)      \
2653
                            (glue(size_FDQ, FPREG(rs2)));               \
2654
                        glue(glue(gen_op_store_, size_FDQ), T0_fpr)     \
2655
                            (glue(size_FDQ, FPREG(rd)));                \
2656
                        gen_set_label(l1);                              \
2657
                    }
2658
                    case 0x001: /* V9 fmovscc %fcc0 */
2659
                        FMOVCC(F, 0);
2660
                        break;
2661
                    case 0x002: /* V9 fmovdcc %fcc0 */
2662
                        FMOVCC(D, 0);
2663
                        break;
2664
                    case 0x003: /* V9 fmovqcc %fcc0 */
2665
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2666
                        FMOVCC(Q, 0);
2667
                        break;
2668
                    case 0x041: /* V9 fmovscc %fcc1 */
2669
                        FMOVCC(F, 1);
2670
                        break;
2671
                    case 0x042: /* V9 fmovdcc %fcc1 */
2672
                        FMOVCC(D, 1);
2673
                        break;
2674
                    case 0x043: /* V9 fmovqcc %fcc1 */
2675
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2676
                        FMOVCC(Q, 1);
2677
                        break;
2678
                    case 0x081: /* V9 fmovscc %fcc2 */
2679
                        FMOVCC(F, 2);
2680
                        break;
2681
                    case 0x082: /* V9 fmovdcc %fcc2 */
2682
                        FMOVCC(D, 2);
2683
                        break;
2684
                    case 0x083: /* V9 fmovqcc %fcc2 */
2685
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2686
                        FMOVCC(Q, 2);
2687
                        break;
2688
                    case 0x0c1: /* V9 fmovscc %fcc3 */
2689
                        FMOVCC(F, 3);
2690
                        break;
2691
                    case 0x0c2: /* V9 fmovdcc %fcc3 */
2692
                        FMOVCC(D, 3);
2693
                        break;
2694
                    case 0x0c3: /* V9 fmovqcc %fcc3 */
2695
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2696
                        FMOVCC(Q, 3);
2697
                        break;
2698
#undef FMOVCC
2699
#define FMOVCC(size_FDQ, icc)                                           \
2700
                    {                                                   \
2701
                        TCGv r_cond;                                    \
2702
                        int l1;                                         \
2703
                                                                        \
2704
                        l1 = gen_new_label();                           \
2705
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2706
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2707
                        gen_cond(r_cond, icc, cond);                    \
2708
                        tcg_gen_brcond_tl(TCG_COND_EQ, r_cond,          \
2709
                                          tcg_const_tl(0), l1);         \
2710
                        glue(glue(gen_op_load_fpr_, size_FDQ), T0)      \
2711
                            (glue(size_FDQ, FPREG(rs2)));               \
2712
                        glue(glue(gen_op_store_, size_FDQ), T0_fpr)     \
2713
                            (glue(size_FDQ, FPREG(rd)));                \
2714
                        gen_set_label(l1);                              \
2715
                    }
2716

    
2717
                    case 0x101: /* V9 fmovscc %icc */
2718
                        FMOVCC(F, 0);
2719
                        break;
2720
                    case 0x102: /* V9 fmovdcc %icc */
2721
                        FMOVCC(D, 0);
2722
                    case 0x103: /* V9 fmovqcc %icc */
2723
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2724
                        FMOVCC(Q, 0);
2725
                        break;
2726
                    case 0x181: /* V9 fmovscc %xcc */
2727
                        FMOVCC(F, 1);
2728
                        break;
2729
                    case 0x182: /* V9 fmovdcc %xcc */
2730
                        FMOVCC(D, 1);
2731
                        break;
2732
                    case 0x183: /* V9 fmovqcc %xcc */
2733
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2734
                        FMOVCC(Q, 1);
2735
                        break;
2736
#undef FMOVCC
2737
#endif
2738
                    case 0x51: /* fcmps, V9 %fcc */
2739
                        gen_op_load_fpr_FT0(rs1);
2740
                        gen_op_load_fpr_FT1(rs2);
2741
                        gen_op_fcmps(rd & 3);
2742
                        break;
2743
                    case 0x52: /* fcmpd, V9 %fcc */
2744
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2745
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2746
                        gen_op_fcmpd(rd & 3);
2747
                        break;
2748
                    case 0x53: /* fcmpq, V9 %fcc */
2749
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2750
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2751
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2752
                        gen_op_fcmpq(rd & 3);
2753
                        break;
2754
                    case 0x55: /* fcmpes, V9 %fcc */
2755
                        gen_op_load_fpr_FT0(rs1);
2756
                        gen_op_load_fpr_FT1(rs2);
2757
                        gen_op_fcmpes(rd & 3);
2758
                        break;
2759
                    case 0x56: /* fcmped, V9 %fcc */
2760
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2761
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2762
                        gen_op_fcmped(rd & 3);
2763
                        break;
2764
                    case 0x57: /* fcmpeq, V9 %fcc */
2765
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2766
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2767
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2768
                        gen_op_fcmpeq(rd & 3);
2769
                        break;
2770
                    default:
2771
                        goto illegal_insn;
2772
                }
2773
            } else if (xop == 0x2) {
2774
                // clr/mov shortcut
2775

    
2776
                rs1 = GET_FIELD(insn, 13, 17);
2777
                if (rs1 == 0) {
2778
                    // or %g0, x, y -> mov T0, x; mov y, T0
2779
                    if (IS_IMM) {       /* immediate */
2780
                        rs2 = GET_FIELDs(insn, 19, 31);
2781
                        gen_movl_TN_reg(rd, tcg_const_tl((int)rs2));
2782
                    } else {            /* register */
2783
                        rs2 = GET_FIELD(insn, 27, 31);
2784
                        gen_movl_reg_TN(rs2, cpu_dst);
2785
                        gen_movl_TN_reg(rd, cpu_dst);
2786
                    }
2787
                } else {
2788
                    cpu_src1 = get_src1(insn, cpu_src1);
2789
                    if (IS_IMM) {       /* immediate */
2790
                        rs2 = GET_FIELDs(insn, 19, 31);
2791
                        tcg_gen_ori_tl(cpu_dst, cpu_src1, (int)rs2);
2792
                        gen_movl_TN_reg(rd, cpu_dst);
2793
                    } else {            /* register */
2794
                        // or x, %g0, y -> mov T1, x; mov y, T1
2795
                        rs2 = GET_FIELD(insn, 27, 31);
2796
                        if (rs2 != 0) {
2797
                            gen_movl_reg_TN(rs2, cpu_src2);
2798
                            tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
2799
                            gen_movl_TN_reg(rd, cpu_dst);
2800
                        } else
2801
                            gen_movl_TN_reg(rd, cpu_src1);
2802
                    }
2803
                }
2804
#ifdef TARGET_SPARC64
2805
            } else if (xop == 0x25) { /* sll, V9 sllx */
2806
                cpu_src1 = get_src1(insn, cpu_src1);
2807
                if (IS_IMM) {   /* immediate */
2808
                    rs2 = GET_FIELDs(insn, 20, 31);
2809
                    if (insn & (1 << 12)) {
2810
                        tcg_gen_shli_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
2811
                    } else {
2812
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2813
                        tcg_gen_shli_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
2814
                    }
2815
                } else {                /* register */
2816
                    rs2 = GET_FIELD(insn, 27, 31);
2817
                    gen_movl_reg_TN(rs2, cpu_src2);
2818
                    if (insn & (1 << 12)) {
2819
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2820
                        tcg_gen_shl_i64(cpu_dst, cpu_src1, cpu_tmp0);
2821
                    } else {
2822
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2823
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2824
                        tcg_gen_shl_i64(cpu_dst, cpu_dst, cpu_tmp0);
2825
                    }
2826
                }
2827
                gen_movl_TN_reg(rd, cpu_dst);
2828
            } else if (xop == 0x26) { /* srl, V9 srlx */
2829
                cpu_src1 = get_src1(insn, cpu_src1);
2830
                if (IS_IMM) {   /* immediate */
2831
                    rs2 = GET_FIELDs(insn, 20, 31);
2832
                    if (insn & (1 << 12)) {
2833
                        tcg_gen_shri_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
2834
                    } else {
2835
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2836
                        tcg_gen_shri_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
2837
                    }
2838
                } else {                /* register */
2839
                    rs2 = GET_FIELD(insn, 27, 31);
2840
                    gen_movl_reg_TN(rs2, cpu_src2);
2841
                    if (insn & (1 << 12)) {
2842
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2843
                        tcg_gen_shr_i64(cpu_dst, cpu_src1, cpu_tmp0);
2844
                    } else {
2845
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2846
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2847
                        tcg_gen_shr_i64(cpu_dst, cpu_dst, cpu_tmp0);
2848
                    }
2849
                }
2850
                gen_movl_TN_reg(rd, cpu_dst);
2851
            } else if (xop == 0x27) { /* sra, V9 srax */
2852
                cpu_src1 = get_src1(insn, cpu_src1);
2853
                if (IS_IMM) {   /* immediate */
2854
                    rs2 = GET_FIELDs(insn, 20, 31);
2855
                    if (insn & (1 << 12)) {
2856
                        tcg_gen_sari_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
2857
                    } else {
2858
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2859
                        tcg_gen_ext_i32_i64(cpu_dst, cpu_dst);
2860
                        tcg_gen_sari_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
2861
                    }
2862
                } else {                /* register */
2863
                    rs2 = GET_FIELD(insn, 27, 31);
2864
                    gen_movl_reg_TN(rs2, cpu_src2);
2865
                    if (insn & (1 << 12)) {
2866
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2867
                        tcg_gen_sar_i64(cpu_dst, cpu_src1, cpu_tmp0);
2868
                    } else {
2869
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2870
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2871
                        tcg_gen_sar_i64(cpu_dst, cpu_dst, cpu_tmp0);
2872
                    }
2873
                }
2874
                gen_movl_TN_reg(rd, cpu_dst);
2875
#endif
2876
            } else if (xop < 0x36) {
2877
                cpu_src1 = get_src1(insn, cpu_src1);
2878
                cpu_src2 = get_src2(insn, cpu_src2);
2879
                if (xop < 0x20) {
2880
                    switch (xop & ~0x10) {
2881
                    case 0x0:
2882
                        if (xop & 0x10)
2883
                            gen_op_add_cc(cpu_dst, cpu_src1, cpu_src2);
2884
                        else
2885
                            tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
2886
                        break;
2887
                    case 0x1:
2888
                        tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_src2);
2889
                        if (xop & 0x10)
2890
                            gen_op_logic_cc(cpu_dst);
2891
                        break;
2892
                    case 0x2:
2893
                        tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
2894
                        if (xop & 0x10)
2895
                            gen_op_logic_cc(cpu_dst);
2896
                        break;
2897
                    case 0x3:
2898
                        tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
2899
                        if (xop & 0x10)
2900
                            gen_op_logic_cc(cpu_dst);
2901
                        break;
2902
                    case 0x4:
2903
                        if (xop & 0x10)
2904
                            gen_op_sub_cc(cpu_dst, cpu_src1, cpu_src2);
2905
                        else
2906
                            tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_src2);
2907
                        break;
2908
                    case 0x5:
2909
                        tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
2910
                        tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_tmp0);
2911
                        if (xop & 0x10)
2912
                            gen_op_logic_cc(cpu_dst);
2913
                        break;
2914
                    case 0x6:
2915
                        tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
2916
                        tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_tmp0);
2917
                        if (xop & 0x10)
2918
                            gen_op_logic_cc(cpu_dst);
2919
                        break;
2920
                    case 0x7:
2921
                        tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
2922
                        tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_tmp0);
2923
                        if (xop & 0x10)
2924
                            gen_op_logic_cc(cpu_dst);
2925
                        break;
2926
                    case 0x8:
2927
                        if (xop & 0x10)
2928
                            gen_op_addx_cc(cpu_dst, cpu_src1, cpu_src2);
2929
                        else {
2930
                            gen_mov_reg_C(cpu_tmp0, cpu_psr);
2931
                            tcg_gen_add_tl(cpu_tmp0, cpu_src2, cpu_tmp0);
2932
                            tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_tmp0);
2933
                        }
2934
                        break;
2935
#ifdef TARGET_SPARC64
2936
                    case 0x9: /* V9 mulx */
2937
                        tcg_gen_mul_i64(cpu_dst, cpu_src1, cpu_src2);
2938
                        break;
2939
#endif
2940
                    case 0xa:
2941
                        CHECK_IU_FEATURE(dc, MUL);
2942
                        gen_op_umul(cpu_dst, cpu_src1, cpu_src2);
2943
                        if (xop & 0x10)
2944
                            gen_op_logic_cc(cpu_dst);
2945
                        break;
2946
                    case 0xb:
2947
                        CHECK_IU_FEATURE(dc, MUL);
2948
                        gen_op_smul(cpu_dst, cpu_src1, cpu_src2);
2949
                        if (xop & 0x10)
2950
                            gen_op_logic_cc(cpu_dst);
2951
                        break;
2952
                    case 0xc:
2953
                        if (xop & 0x10)
2954
                            gen_op_subx_cc(cpu_dst, cpu_src1, cpu_src2);
2955
                        else {
2956
                            gen_mov_reg_C(cpu_tmp0, cpu_psr);
2957
                            tcg_gen_add_tl(cpu_tmp0, cpu_src2, cpu_tmp0);
2958
                            tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_tmp0);
2959
                        }
2960
                        break;
2961
#ifdef TARGET_SPARC64
2962
                    case 0xd: /* V9 udivx */
2963
                        gen_trap_ifdivzero_tl(cpu_src2);
2964
                        tcg_gen_divu_i64(cpu_dst, cpu_src1, cpu_src2);
2965
                        break;
2966
#endif
2967
                    case 0xe:
2968
                        CHECK_IU_FEATURE(dc, DIV);
2969
                        tcg_gen_helper_1_2(helper_udiv, cpu_dst, cpu_src1,
2970
                                           cpu_src2);
2971
                        if (xop & 0x10)
2972
                            gen_op_div_cc(cpu_dst);
2973
                        break;
2974
                    case 0xf:
2975
                        CHECK_IU_FEATURE(dc, DIV);
2976
                        tcg_gen_helper_1_2(helper_sdiv, cpu_dst, cpu_src1,
2977
                                           cpu_src2);
2978
                        if (xop & 0x10)
2979
                            gen_op_div_cc(cpu_dst);
2980
                        break;
2981
                    default:
2982
                        goto illegal_insn;
2983
                    }
2984
                    gen_movl_TN_reg(rd, cpu_dst);
2985
                } else {
2986
                    switch (xop) {
2987
                    case 0x20: /* taddcc */
2988
                        gen_op_tadd_cc(cpu_dst, cpu_src1, cpu_src2);
2989
                        gen_movl_TN_reg(rd, cpu_dst);
2990
                        break;
2991
                    case 0x21: /* tsubcc */
2992
                        gen_op_tsub_cc(cpu_dst, cpu_src1, cpu_src2);
2993
                        gen_movl_TN_reg(rd, cpu_dst);
2994
                        break;
2995
                    case 0x22: /* taddcctv */
2996
                        save_state(dc, cpu_cond);
2997
                        gen_op_tadd_ccTV(cpu_dst, cpu_src1, cpu_src2);
2998
                        gen_movl_TN_reg(rd, cpu_dst);
2999
                        break;
3000
                    case 0x23: /* tsubcctv */
3001
                        save_state(dc, cpu_cond);
3002
                        gen_op_tsub_ccTV(cpu_dst, cpu_src1, cpu_src2);
3003
                        gen_movl_TN_reg(rd, cpu_dst);
3004
                        break;
3005
                    case 0x24: /* mulscc */
3006
                        gen_op_mulscc(cpu_dst, cpu_src1, cpu_src2);
3007
                        gen_movl_TN_reg(rd, cpu_dst);
3008
                        break;
3009
#ifndef TARGET_SPARC64
3010
                    case 0x25:  /* sll */
3011
                        if (IS_IMM) { /* immediate */
3012
                            rs2 = GET_FIELDs(insn, 20, 31);
3013
                            tcg_gen_shli_tl(cpu_dst, cpu_src1, rs2 & 0x1f);
3014
                        } else { /* register */
3015
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3016
                            tcg_gen_shl_tl(cpu_dst, cpu_src1, cpu_tmp0);
3017
                        }
3018
                        gen_movl_TN_reg(rd, cpu_dst);
3019
                        break;
3020
                    case 0x26:  /* srl */
3021
                        if (IS_IMM) { /* immediate */
3022
                            rs2 = GET_FIELDs(insn, 20, 31);
3023
                            tcg_gen_shri_tl(cpu_dst, cpu_src1, rs2 & 0x1f);
3024
                        } else { /* register */
3025
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3026
                            tcg_gen_shr_tl(cpu_dst, cpu_src1, cpu_tmp0);
3027
                        }
3028
                        gen_movl_TN_reg(rd, cpu_dst);
3029
                        break;
3030
                    case 0x27:  /* sra */
3031
                        if (IS_IMM) { /* immediate */
3032
                            rs2 = GET_FIELDs(insn, 20, 31);
3033
                            tcg_gen_sari_tl(cpu_dst, cpu_src1, rs2 & 0x1f);
3034
                        } else { /* register */
3035
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3036
                            tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0);
3037
                        }
3038
                        gen_movl_TN_reg(rd, cpu_dst);
3039
                        break;
3040
#endif
3041
                    case 0x30:
3042
                        {
3043
                            switch(rd) {
3044
                            case 0: /* wry */
3045
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3046
                                tcg_gen_st_tl(cpu_dst, cpu_env,
3047
                                              offsetof(CPUSPARCState, y));
3048
                                break;
3049
#ifndef TARGET_SPARC64
3050
                            case 0x01 ... 0x0f: /* undefined in the
3051
                                                   SPARCv8 manual, nop
3052
                                                   on the microSPARC
3053
                                                   II */
3054
                            case 0x10 ... 0x1f: /* implementation-dependent
3055
                                                   in the SPARCv8
3056
                                                   manual, nop on the
3057
                                                   microSPARC II */
3058
                                break;
3059
#else
3060
                            case 0x2: /* V9 wrccr */
3061
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3062
                                tcg_gen_helper_0_1(helper_wrccr, cpu_dst);
3063
                                break;
3064
                            case 0x3: /* V9 wrasi */
3065
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3066
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3067
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3068
                                               offsetof(CPUSPARCState, asi));
3069
                                break;
3070
                            case 0x6: /* V9 wrfprs */
3071
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3072
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3073
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3074
                                               offsetof(CPUSPARCState, fprs));
3075
                                save_state(dc, cpu_cond);
3076
                                gen_op_next_insn();
3077
                                tcg_gen_exit_tb(0);
3078
                                dc->is_br = 1;
3079
                                break;
3080
                            case 0xf: /* V9 sir, nop if user */
3081
#if !defined(CONFIG_USER_ONLY)
3082
                                if (supervisor(dc))
3083
                                    ; // XXX
3084
#endif
3085
                                break;
3086
                            case 0x13: /* Graphics Status */
3087
                                if (gen_trap_ifnofpu(dc, cpu_cond))
3088
                                    goto jmp_insn;
3089
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3090
                                tcg_gen_st_tl(cpu_dst, cpu_env,
3091
                                              offsetof(CPUSPARCState, gsr));
3092
                                break;
3093
                            case 0x17: /* Tick compare */
3094
#if !defined(CONFIG_USER_ONLY)
3095
                                if (!supervisor(dc))
3096
                                    goto illegal_insn;
3097
#endif
3098
                                {
3099
                                    TCGv r_tickptr;
3100

    
3101
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
3102
                                                   cpu_src2);
3103
                                    tcg_gen_st_tl(cpu_dst, cpu_env,
3104
                                                  offsetof(CPUSPARCState,
3105
                                                           tick_cmpr));
3106
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3107
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3108
                                                   offsetof(CPUState, tick));
3109
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3110
                                                       r_tickptr, cpu_dst);
3111
                                }
3112
                                break;
3113
                            case 0x18: /* System tick */
3114
#if !defined(CONFIG_USER_ONLY)
3115
                                if (!supervisor(dc))
3116
                                    goto illegal_insn;
3117
#endif
3118
                                {
3119
                                    TCGv r_tickptr;
3120

    
3121
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
3122
                                                   cpu_src2);
3123
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3124
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3125
                                                   offsetof(CPUState, stick));
3126
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3127
                                                       r_tickptr, cpu_dst);
3128
                                }
3129
                                break;
3130
                            case 0x19: /* System tick compare */
3131
#if !defined(CONFIG_USER_ONLY)
3132
                                if (!supervisor(dc))
3133
                                    goto illegal_insn;
3134
#endif
3135
                                {
3136
                                    TCGv r_tickptr;
3137

    
3138
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
3139
                                                   cpu_src2);
3140
                                    tcg_gen_st_tl(cpu_dst, cpu_env,
3141
                                                  offsetof(CPUSPARCState,
3142
                                                           stick_cmpr));
3143
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3144
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3145
                                                   offsetof(CPUState, stick));
3146
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3147
                                                       r_tickptr, cpu_dst);
3148
                                }
3149
                                break;
3150

    
3151
                            case 0x10: /* Performance Control */
3152
                            case 0x11: /* Performance Instrumentation
3153
                                          Counter */
3154
                            case 0x12: /* Dispatch Control */
3155
                            case 0x14: /* Softint set */
3156
                            case 0x15: /* Softint clear */
3157
                            case 0x16: /* Softint write */
3158
#endif
3159
                            default:
3160
                                goto illegal_insn;
3161
                            }
3162
                        }
3163
                        break;
3164
#if !defined(CONFIG_USER_ONLY)
3165
                    case 0x31: /* wrpsr, V9 saved, restored */
3166
                        {
3167
                            if (!supervisor(dc))
3168
                                goto priv_insn;
3169
#ifdef TARGET_SPARC64
3170
                            switch (rd) {
3171
                            case 0:
3172
                                tcg_gen_helper_0_0(helper_saved);
3173
                                break;
3174
                            case 1:
3175
                                tcg_gen_helper_0_0(helper_restored);
3176
                                break;
3177
                            case 2: /* UA2005 allclean */
3178
                            case 3: /* UA2005 otherw */
3179
                            case 4: /* UA2005 normalw */
3180
                            case 5: /* UA2005 invalw */
3181
                                // XXX
3182
                            default:
3183
                                goto illegal_insn;
3184
                            }
3185
#else
3186
                            tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3187
                            tcg_gen_helper_0_1(helper_wrpsr, cpu_dst);
3188
                            save_state(dc, cpu_cond);
3189
                            gen_op_next_insn();
3190
                            tcg_gen_exit_tb(0);
3191
                            dc->is_br = 1;
3192
#endif
3193
                        }
3194
                        break;
3195
                    case 0x32: /* wrwim, V9 wrpr */
3196
                        {
3197
                            if (!supervisor(dc))
3198
                                goto priv_insn;
3199
                            tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3200
#ifdef TARGET_SPARC64
3201
                            switch (rd) {
3202
                            case 0: // tpc
3203
                                {
3204
                                    TCGv r_tsptr;
3205

    
3206
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3207
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3208
                                                   offsetof(CPUState, tsptr));
3209
                                    tcg_gen_st_tl(cpu_dst, r_tsptr,
3210
                                                  offsetof(trap_state, tpc));
3211
                                }
3212
                                break;
3213
                            case 1: // tnpc
3214
                                {
3215
                                    TCGv r_tsptr;
3216

    
3217
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3218
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3219
                                                   offsetof(CPUState, tsptr));
3220
                                    tcg_gen_st_tl(cpu_dst, r_tsptr,
3221
                                                  offsetof(trap_state, tnpc));
3222
                                }
3223
                                break;
3224
                            case 2: // tstate
3225
                                {
3226
                                    TCGv r_tsptr;
3227

    
3228
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3229
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3230
                                                   offsetof(CPUState, tsptr));
3231
                                    tcg_gen_st_tl(cpu_dst, r_tsptr,
3232
                                                  offsetof(trap_state,
3233
                                                           tstate));
3234
                                }
3235
                                break;
3236
                            case 3: // tt
3237
                                {
3238
                                    TCGv r_tsptr;
3239

    
3240
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3241
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3242
                                                   offsetof(CPUState, tsptr));
3243
                                    tcg_gen_st_i32(cpu_dst, r_tsptr,
3244
                                                   offsetof(trap_state, tt));
3245
                                }
3246
                                break;
3247
                            case 4: // tick
3248
                                {
3249
                                    TCGv r_tickptr;
3250

    
3251
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3252
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3253
                                                   offsetof(CPUState, tick));
3254
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3255
                                                       r_tickptr, cpu_dst);
3256
                                }
3257
                                break;
3258
                            case 5: // tba
3259
                                tcg_gen_st_tl(cpu_dst, cpu_env,
3260
                                              offsetof(CPUSPARCState, tbr));
3261
                                break;
3262
                            case 6: // pstate
3263
                                save_state(dc, cpu_cond);
3264
                                tcg_gen_helper_0_1(helper_wrpstate, cpu_dst);
3265
                                gen_op_next_insn();
3266
                                tcg_gen_exit_tb(0);
3267
                                dc->is_br = 1;
3268
                                break;
3269
                            case 7: // tl
3270
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3271
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3272
                                               offsetof(CPUSPARCState, tl));
3273
                                break;
3274
                            case 8: // pil
3275
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3276
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3277
                                               offsetof(CPUSPARCState,
3278
                                                        psrpil));
3279
                                break;
3280
                            case 9: // cwp
3281
                                tcg_gen_helper_0_1(helper_wrcwp, cpu_dst);
3282
                                break;
3283
                            case 10: // cansave
3284
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3285
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3286
                                               offsetof(CPUSPARCState,
3287
                                                        cansave));
3288
                                break;
3289
                            case 11: // canrestore
3290
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3291
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3292
                                               offsetof(CPUSPARCState,
3293
                                                        canrestore));
3294
                                break;
3295
                            case 12: // cleanwin
3296
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3297
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3298
                                               offsetof(CPUSPARCState,
3299
                                                        cleanwin));
3300
                                break;
3301
                            case 13: // otherwin
3302
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3303
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3304
                                               offsetof(CPUSPARCState,
3305
                                                        otherwin));
3306
                                break;
3307
                            case 14: // wstate
3308
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3309
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3310
                                               offsetof(CPUSPARCState,
3311
                                                        wstate));
3312
                                break;
3313
                            case 16: // UA2005 gl
3314
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3315
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3316
                                               offsetof(CPUSPARCState, gl));
3317
                                break;
3318
                            case 26: // UA2005 strand status
3319
                                if (!hypervisor(dc))
3320
                                    goto priv_insn;
3321
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3322
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3323
                                               offsetof(CPUSPARCState, ssr));
3324
                                break;
3325
                            default:
3326
                                goto illegal_insn;
3327
                            }
3328
#else
3329
                            tcg_gen_andi_tl(cpu_dst, cpu_dst,
3330
                                            ((1 << NWINDOWS) - 1));
3331
                            tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3332
                            tcg_gen_st_i32(cpu_tmp32, cpu_env,
3333
                                           offsetof(CPUSPARCState, wim));
3334
#endif
3335
                        }
3336
                        break;
3337
                    case 0x33: /* wrtbr, UA2005 wrhpr */
3338
                        {
3339
#ifndef TARGET_SPARC64
3340
                            if (!supervisor(dc))
3341
                                goto priv_insn;
3342
                            tcg_gen_xor_tl(cpu_dst, cpu_dst, cpu_src2);
3343
                            tcg_gen_st_tl(cpu_dst, cpu_env,
3344
                                          offsetof(CPUSPARCState, tbr));
3345
#else
3346
                            if (!hypervisor(dc))
3347
                                goto priv_insn;
3348
                            tcg_gen_xor_tl(cpu_dst, cpu_dst, cpu_src2);
3349
                            switch (rd) {
3350
                            case 0: // hpstate
3351
                                // XXX gen_op_wrhpstate();
3352
                                save_state(dc, cpu_cond);
3353
                                gen_op_next_insn();
3354
                                tcg_gen_exit_tb(0);
3355
                                dc->is_br = 1;
3356
                                break;
3357
                            case 1: // htstate
3358
                                // XXX gen_op_wrhtstate();
3359
                                break;
3360
                            case 3: // hintp
3361
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3362
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3363
                                               offsetof(CPUSPARCState, hintp));
3364
                                break;
3365
                            case 5: // htba
3366
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3367
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3368
                                               offsetof(CPUSPARCState, htba));
3369
                                break;
3370
                            case 31: // hstick_cmpr
3371
                                {
3372
                                    TCGv r_tickptr;
3373

    
3374
                                    tcg_gen_st_tl(cpu_dst, cpu_env,
3375
                                                  offsetof(CPUSPARCState,
3376
                                                           hstick_cmpr));
3377
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3378
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3379
                                                   offsetof(CPUState, hstick));
3380
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3381
                                                       r_tickptr, cpu_dst);
3382
                                }
3383
                                break;
3384
                            case 6: // hver readonly
3385
                            default:
3386
                                goto illegal_insn;
3387
                            }
3388
#endif
3389
                        }
3390
                        break;
3391
#endif
3392
#ifdef TARGET_SPARC64
3393
                    case 0x2c: /* V9 movcc */
3394
                        {
3395
                            int cc = GET_FIELD_SP(insn, 11, 12);
3396
                            int cond = GET_FIELD_SP(insn, 14, 17);
3397
                            TCGv r_cond;
3398
                            int l1;
3399

    
3400
                            r_cond = tcg_temp_new(TCG_TYPE_TL);
3401
                            if (insn & (1 << 18)) {
3402
                                if (cc == 0)
3403
                                    gen_cond(r_cond, 0, cond);
3404
                                else if (cc == 2)
3405
                                    gen_cond(r_cond, 1, cond);
3406
                                else
3407
                                    goto illegal_insn;
3408
                            } else {
3409
                                gen_fcond(r_cond, cc, cond);
3410
                            }
3411

    
3412
                            l1 = gen_new_label();
3413

    
3414
                            tcg_gen_brcond_tl(TCG_COND_EQ, r_cond,
3415
                                              tcg_const_tl(0), l1);
3416
                            if (IS_IMM) {       /* immediate */
3417
                                rs2 = GET_FIELD_SPs(insn, 0, 10);
3418
                                gen_movl_TN_reg(rd, tcg_const_tl((int)rs2));
3419
                            } else {
3420
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3421
                                gen_movl_reg_TN(rs2, cpu_tmp0);
3422
                                gen_movl_TN_reg(rd, cpu_tmp0);
3423
                            }
3424
                            gen_set_label(l1);
3425
                            break;
3426
                        }
3427
                    case 0x2d: /* V9 sdivx */
3428
                        gen_op_sdivx(cpu_dst, cpu_src1, cpu_src2);
3429
                        gen_movl_TN_reg(rd, cpu_dst);
3430
                        break;
3431
                    case 0x2e: /* V9 popc */
3432
                        {
3433
                            cpu_src2 = get_src2(insn, cpu_src2);
3434
                            tcg_gen_helper_1_1(helper_popc, cpu_dst,
3435
                                               cpu_src2);
3436
                            gen_movl_TN_reg(rd, cpu_dst);
3437
                        }
3438
                    case 0x2f: /* V9 movr */
3439
                        {
3440
                            int cond = GET_FIELD_SP(insn, 10, 12);
3441
                            int l1;
3442

    
3443
                            cpu_src1 = get_src1(insn, cpu_src1);
3444

    
3445
                            l1 = gen_new_label();
3446

    
3447
                            tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_src1,
3448
                                              tcg_const_tl(0), l1);
3449
                            if (IS_IMM) {       /* immediate */
3450
                                rs2 = GET_FIELD_SPs(insn, 0, 9);
3451
                                gen_movl_TN_reg(rd, tcg_const_tl((int)rs2));
3452
                            } else {
3453
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3454
                                gen_movl_reg_TN(rs2, cpu_tmp0);
3455
                                gen_movl_TN_reg(rd, cpu_tmp0);
3456
                            }
3457
                            gen_set_label(l1);
3458
                            break;
3459
                        }
3460
#endif
3461
                    default:
3462
                        goto illegal_insn;
3463
                    }
3464
                }
3465
            } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
3466
#ifdef TARGET_SPARC64
3467
                int opf = GET_FIELD_SP(insn, 5, 13);
3468
                rs1 = GET_FIELD(insn, 13, 17);
3469
                rs2 = GET_FIELD(insn, 27, 31);
3470
                if (gen_trap_ifnofpu(dc, cpu_cond))
3471
                    goto jmp_insn;
3472

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

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

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

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

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

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

    
4533
    memset(dc, 0, sizeof(DisasContext));
4534
    dc->tb = tb;
4535
    pc_start = tb->pc;
4536
    dc->pc = pc_start;
4537
    last_pc = dc->pc;
4538
    dc->npc = (target_ulong) tb->cs_base;
4539
    dc->mem_idx = cpu_mmu_index(env);
4540
    dc->features = env->features;
4541
    if ((dc->features & CPU_FEATURE_FLOAT)) {
4542
        dc->fpu_enabled = cpu_fpu_enabled(env);
4543
#if defined(CONFIG_USER_ONLY)
4544
        dc->features |= CPU_FEATURE_FLOAT128;
4545
#endif
4546
    } else
4547
        dc->fpu_enabled = 0;
4548
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4549

    
4550
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
4551
    cpu_tmp32 = tcg_temp_new(TCG_TYPE_I32);
4552
    cpu_tmp64 = tcg_temp_new(TCG_TYPE_I64);
4553

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

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

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

    
4642
int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
4643
{
4644
    return gen_intermediate_code_internal(tb, 0, env);
4645
}
4646

    
4647
int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
4648
{
4649
    return gen_intermediate_code_internal(tb, 1, env);
4650
}
4651

    
4652
void gen_intermediate_code_init(CPUSPARCState *env)
4653
{
4654
    unsigned int i;
4655
    static int inited;
4656
    static const char * const gregnames[8] = {
4657
        NULL, // g0 not used
4658
        "g1",
4659
        "g2",
4660
        "g3",
4661
        "g4",
4662
        "g5",
4663
        "g6",
4664
        "g7",
4665
    };
4666

    
4667
    /* init various static tables */
4668
    if (!inited) {
4669
        inited = 1;
4670

    
4671
        tcg_set_macro_func(&tcg_ctx, tcg_macro_func);
4672
        cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
4673
        cpu_regwptr = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
4674
                                         offsetof(CPUState, regwptr),
4675
                                         "regwptr");
4676
#ifdef TARGET_SPARC64
4677
        cpu_xcc = tcg_global_mem_new(TCG_TYPE_I32,
4678
                                     TCG_AREG0, offsetof(CPUState, xcc),
4679
                                     "xcc");
4680
#endif
4681
        /* XXX: T0 and T1 should be temporaries */
4682
        cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
4683
                                      TCG_AREG0, offsetof(CPUState, t0), "T0");
4684
        cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
4685
                                      TCG_AREG0, offsetof(CPUState, t1), "T1");
4686
        cpu_cond = tcg_global_mem_new(TCG_TYPE_TL,
4687
                                      TCG_AREG0, offsetof(CPUState, cond),
4688
                                      "cond");
4689
        cpu_cc_src = tcg_global_mem_new(TCG_TYPE_TL,
4690
                                        TCG_AREG0, offsetof(CPUState, cc_src),
4691
                                        "cc_src");
4692
        cpu_cc_src2 = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4693
                                         offsetof(CPUState, cc_src2),
4694
                                         "cc_src2");
4695
        cpu_cc_dst = tcg_global_mem_new(TCG_TYPE_TL,
4696
                                        TCG_AREG0, offsetof(CPUState, cc_dst),
4697
                                        "cc_dst");
4698
        cpu_psr = tcg_global_mem_new(TCG_TYPE_I32,
4699
                                     TCG_AREG0, offsetof(CPUState, psr),
4700
                                     "psr");
4701
        cpu_fsr = tcg_global_mem_new(TCG_TYPE_TL,
4702
                                     TCG_AREG0, offsetof(CPUState, fsr),
4703
                                     "fsr");
4704
        cpu_pc = tcg_global_mem_new(TCG_TYPE_TL,
4705
                                    TCG_AREG0, offsetof(CPUState, pc),
4706
                                    "pc");
4707
        cpu_npc = tcg_global_mem_new(TCG_TYPE_TL,
4708
                                    TCG_AREG0, offsetof(CPUState, npc),
4709
                                    "npc");
4710
        for (i = 1; i < 8; i++)
4711
            cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4712
                                              offsetof(CPUState, gregs[i]),
4713
                                              gregnames[i]);
4714
    }
4715
}
4716

    
4717
void gen_pc_load(CPUState *env, TranslationBlock *tb,
4718
                unsigned long searched_pc, int pc_pos, void *puc)
4719
{
4720
    target_ulong npc;
4721
    env->pc = gen_opc_pc[pc_pos];
4722
    npc = gen_opc_npc[pc_pos];
4723
    if (npc == 1) {
4724
        /* dynamic NPC: already stored */
4725
    } else if (npc == 2) {
4726
        target_ulong t2 = (target_ulong)(unsigned long)puc;
4727
        /* jump PC: use T2 and the jump targets of the translation */
4728
        if (t2)
4729
            env->npc = gen_opc_jump_pc[0];
4730
        else
4731
            env->npc = gen_opc_jump_pc[1];
4732
    } else {
4733
        env->npc = npc;
4734
    }
4735
}