Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ 5068cbd9

History | View | Annotate | Download (191.4 kB)

1
/*
2
   SPARC translation
3

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

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

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

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

    
22
#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_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_y;
45
#ifndef CONFIG_USER_ONLY
46
static TCGv cpu_tbr;
47
#endif
48
static TCGv cpu_cond, cpu_src1, cpu_src2, cpu_dst, cpu_addr, cpu_val;
49
#ifdef TARGET_SPARC64
50
static TCGv cpu_xcc, cpu_asi, cpu_fprs, cpu_gsr;
51
static TCGv cpu_tick_cmpr, cpu_stick_cmpr, cpu_hstick_cmpr;
52
static TCGv cpu_hintp, cpu_htba, cpu_hver, cpu_ssr, cpu_ver;
53
#else
54
static TCGv cpu_wim;
55
#endif
56
/* local register indexes (only used inside old micro ops) */
57
static TCGv cpu_tmp0, cpu_tmp32, cpu_tmp64;
58
/* Floating point registers */
59
static TCGv cpu_fpr[TARGET_FPREGS];
60

    
61
#include "gen-icount.h"
62

    
63
typedef struct DisasContext {
64
    target_ulong pc;    /* current Program Counter: integer or DYNAMIC_PC */
65
    target_ulong npc;   /* next PC: integer or DYNAMIC_PC or JUMP_PC */
66
    target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
67
    int is_br;
68
    int mem_idx;
69
    int fpu_enabled;
70
    int address_mask_32bit;
71
    struct TranslationBlock *tb;
72
    sparc_def_t *def;
73
} DisasContext;
74

    
75
// This function uses non-native bit order
76
#define GET_FIELD(X, FROM, TO) \
77
  ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
78

    
79
// This function uses the order in the manuals, i.e. bit 0 is 2^0
80
#define GET_FIELD_SP(X, FROM, TO) \
81
    GET_FIELD(X, 31 - (TO), 31 - (FROM))
82

    
83
#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
84
#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
85

    
86
#ifdef TARGET_SPARC64
87
#define FFPREG(r) (r)
88
#define DFPREG(r) (((r & 1) << 5) | (r & 0x1e))
89
#define QFPREG(r) (((r & 1) << 5) | (r & 0x1c))
90
#else
91
#define FFPREG(r) (r)
92
#define DFPREG(r) (r & 0x1e)
93
#define QFPREG(r) (r & 0x1c)
94
#endif
95

    
96
static int sign_extend(int x, int len)
97
{
98
    len = 32 - len;
99
    return (x << len) >> len;
100
}
101

    
102
#define IS_IMM (insn & (1<<13))
103

    
104
/* floating point registers moves */
105
static void gen_op_load_fpr_DT0(unsigned int src)
106
{
107
    tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, dt0) +
108
                   offsetof(CPU_DoubleU, l.upper));
109
    tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, dt0) +
110
                   offsetof(CPU_DoubleU, l.lower));
111
}
112

    
113
static void gen_op_load_fpr_DT1(unsigned int src)
114
{
115
    tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, dt1) +
116
                   offsetof(CPU_DoubleU, l.upper));
117
    tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, dt1) +
118
                   offsetof(CPU_DoubleU, l.lower));
119
}
120

    
121
static void gen_op_store_DT0_fpr(unsigned int dst)
122
{
123
    tcg_gen_ld_i32(cpu_fpr[dst], cpu_env, offsetof(CPUSPARCState, dt0) +
124
                   offsetof(CPU_DoubleU, l.upper));
125
    tcg_gen_ld_i32(cpu_fpr[dst + 1], cpu_env, offsetof(CPUSPARCState, dt0) +
126
                   offsetof(CPU_DoubleU, l.lower));
127
}
128

    
129
static void gen_op_load_fpr_QT0(unsigned int src)
130
{
131
    tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, qt0) +
132
                   offsetof(CPU_QuadU, l.upmost));
133
    tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, qt0) +
134
                   offsetof(CPU_QuadU, l.upper));
135
    tcg_gen_st_i32(cpu_fpr[src + 2], cpu_env, offsetof(CPUSPARCState, qt0) +
136
                   offsetof(CPU_QuadU, l.lower));
137
    tcg_gen_st_i32(cpu_fpr[src + 3], cpu_env, offsetof(CPUSPARCState, qt0) +
138
                   offsetof(CPU_QuadU, l.lowest));
139
}
140

    
141
static void gen_op_load_fpr_QT1(unsigned int src)
142
{
143
    tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, qt1) +
144
                   offsetof(CPU_QuadU, l.upmost));
145
    tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, qt1) +
146
                   offsetof(CPU_QuadU, l.upper));
147
    tcg_gen_st_i32(cpu_fpr[src + 2], cpu_env, offsetof(CPUSPARCState, qt1) +
148
                   offsetof(CPU_QuadU, l.lower));
149
    tcg_gen_st_i32(cpu_fpr[src + 3], cpu_env, offsetof(CPUSPARCState, qt1) +
150
                   offsetof(CPU_QuadU, l.lowest));
151
}
152

    
153
static void gen_op_store_QT0_fpr(unsigned int dst)
154
{
155
    tcg_gen_ld_i32(cpu_fpr[dst], cpu_env, offsetof(CPUSPARCState, qt0) +
156
                   offsetof(CPU_QuadU, l.upmost));
157
    tcg_gen_ld_i32(cpu_fpr[dst + 1], cpu_env, offsetof(CPUSPARCState, qt0) +
158
                   offsetof(CPU_QuadU, l.upper));
159
    tcg_gen_ld_i32(cpu_fpr[dst + 2], cpu_env, offsetof(CPUSPARCState, qt0) +
160
                   offsetof(CPU_QuadU, l.lower));
161
    tcg_gen_ld_i32(cpu_fpr[dst + 3], cpu_env, offsetof(CPUSPARCState, qt0) +
162
                   offsetof(CPU_QuadU, l.lowest));
163
}
164

    
165
/* moves */
166
#ifdef CONFIG_USER_ONLY
167
#define supervisor(dc) 0
168
#ifdef TARGET_SPARC64
169
#define hypervisor(dc) 0
170
#endif
171
#else
172
#define supervisor(dc) (dc->mem_idx >= 1)
173
#ifdef TARGET_SPARC64
174
#define hypervisor(dc) (dc->mem_idx == 2)
175
#else
176
#endif
177
#endif
178

    
179
#ifdef TARGET_SPARC64
180
#ifndef TARGET_ABI32
181
#define AM_CHECK(dc) ((dc)->address_mask_32bit)
182
#else
183
#define AM_CHECK(dc) (1)
184
#endif
185
#endif
186

    
187
static inline void gen_address_mask(DisasContext *dc, TCGv addr)
188
{
189
#ifdef TARGET_SPARC64
190
    if (AM_CHECK(dc))
191
        tcg_gen_andi_tl(addr, addr, 0xffffffffULL);
192
#endif
193
}
194

    
195
static inline void gen_movl_reg_TN(int reg, TCGv tn)
196
{
197
    if (reg == 0)
198
        tcg_gen_movi_tl(tn, 0);
199
    else if (reg < 8)
200
        tcg_gen_mov_tl(tn, cpu_gregs[reg]);
201
    else {
202
        tcg_gen_ld_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
203
    }
204
}
205

    
206
static inline void gen_movl_TN_reg(int reg, TCGv tn)
207
{
208
    if (reg == 0)
209
        return;
210
    else if (reg < 8)
211
        tcg_gen_mov_tl(cpu_gregs[reg], tn);
212
    else {
213
        tcg_gen_st_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
214
    }
215
}
216

    
217
static inline void gen_goto_tb(DisasContext *s, int tb_num,
218
                               target_ulong pc, target_ulong npc)
219
{
220
    TranslationBlock *tb;
221

    
222
    tb = s->tb;
223
    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
224
        (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK))  {
225
        /* jump to same page: we can use a direct jump */
226
        tcg_gen_goto_tb(tb_num);
227
        tcg_gen_movi_tl(cpu_pc, pc);
228
        tcg_gen_movi_tl(cpu_npc, npc);
229
        tcg_gen_exit_tb((long)tb + tb_num);
230
    } else {
231
        /* jump to another page: currently not optimized */
232
        tcg_gen_movi_tl(cpu_pc, pc);
233
        tcg_gen_movi_tl(cpu_npc, npc);
234
        tcg_gen_exit_tb(0);
235
    }
236
}
237

    
238
// XXX suboptimal
239
static inline void gen_mov_reg_N(TCGv reg, TCGv src)
240
{
241
    tcg_gen_extu_i32_tl(reg, src);
242
    tcg_gen_shri_tl(reg, reg, PSR_NEG_SHIFT);
243
    tcg_gen_andi_tl(reg, reg, 0x1);
244
}
245

    
246
static inline void gen_mov_reg_Z(TCGv reg, TCGv src)
247
{
248
    tcg_gen_extu_i32_tl(reg, src);
249
    tcg_gen_shri_tl(reg, reg, PSR_ZERO_SHIFT);
250
    tcg_gen_andi_tl(reg, reg, 0x1);
251
}
252

    
253
static inline void gen_mov_reg_V(TCGv reg, TCGv src)
254
{
255
    tcg_gen_extu_i32_tl(reg, src);
256
    tcg_gen_shri_tl(reg, reg, PSR_OVF_SHIFT);
257
    tcg_gen_andi_tl(reg, reg, 0x1);
258
}
259

    
260
static inline void gen_mov_reg_C(TCGv reg, TCGv src)
261
{
262
    tcg_gen_extu_i32_tl(reg, src);
263
    tcg_gen_shri_tl(reg, reg, PSR_CARRY_SHIFT);
264
    tcg_gen_andi_tl(reg, reg, 0x1);
265
}
266

    
267
static inline void gen_cc_clear_icc(void)
268
{
269
    tcg_gen_movi_i32(cpu_psr, 0);
270
}
271

    
272
#ifdef TARGET_SPARC64
273
static inline void gen_cc_clear_xcc(void)
274
{
275
    tcg_gen_movi_i32(cpu_xcc, 0);
276
}
277
#endif
278

    
279
/* old op:
280
    if (!T0)
281
        env->psr |= PSR_ZERO;
282
    if ((int32_t) T0 < 0)
283
        env->psr |= PSR_NEG;
284
*/
285
static inline void gen_cc_NZ_icc(TCGv dst)
286
{
287
    TCGv r_temp;
288
    int l1, l2;
289

    
290
    l1 = gen_new_label();
291
    l2 = gen_new_label();
292
    r_temp = tcg_temp_new(TCG_TYPE_TL);
293
    tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
294
    tcg_gen_brcondi_tl(TCG_COND_NE, r_temp, 0, l1);
295
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_ZERO);
296
    gen_set_label(l1);
297
    tcg_gen_ext_i32_tl(r_temp, dst);
298
    tcg_gen_brcondi_tl(TCG_COND_GE, r_temp, 0, l2);
299
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_NEG);
300
    gen_set_label(l2);
301
    tcg_temp_free(r_temp);
302
}
303

    
304
#ifdef TARGET_SPARC64
305
static inline void gen_cc_NZ_xcc(TCGv dst)
306
{
307
    int l1, l2;
308

    
309
    l1 = gen_new_label();
310
    l2 = gen_new_label();
311
    tcg_gen_brcondi_tl(TCG_COND_NE, dst, 0, l1);
312
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_ZERO);
313
    gen_set_label(l1);
314
    tcg_gen_brcondi_tl(TCG_COND_GE, dst, 0, l2);
315
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_NEG);
316
    gen_set_label(l2);
317
}
318
#endif
319

    
320
/* old op:
321
    if (T0 < src1)
322
        env->psr |= PSR_CARRY;
323
*/
324
static inline void gen_cc_C_add_icc(TCGv dst, TCGv src1)
325
{
326
    TCGv r_temp1, r_temp2;
327
    int l1;
328

    
329
    l1 = gen_new_label();
330
    r_temp1 = tcg_temp_new(TCG_TYPE_TL);
331
    r_temp2 = tcg_temp_new(TCG_TYPE_TL);
332
    tcg_gen_andi_tl(r_temp1, dst, 0xffffffffULL);
333
    tcg_gen_andi_tl(r_temp2, src1, 0xffffffffULL);
334
    tcg_gen_brcond_tl(TCG_COND_GEU, r_temp1, r_temp2, l1);
335
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
336
    gen_set_label(l1);
337
    tcg_temp_free(r_temp1);
338
    tcg_temp_free(r_temp2);
339
}
340

    
341
#ifdef TARGET_SPARC64
342
static inline void gen_cc_C_add_xcc(TCGv dst, TCGv src1)
343
{
344
    int l1;
345

    
346
    l1 = gen_new_label();
347
    tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l1);
348
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
349
    gen_set_label(l1);
350
}
351
#endif
352

    
353
/* old op:
354
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
355
        env->psr |= PSR_OVF;
356
*/
357
static inline void gen_cc_V_add_icc(TCGv dst, TCGv src1, TCGv src2)
358
{
359
    TCGv r_temp;
360

    
361
    r_temp = tcg_temp_new(TCG_TYPE_TL);
362
    tcg_gen_xor_tl(r_temp, src1, src2);
363
    tcg_gen_xori_tl(r_temp, r_temp, -1);
364
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
365
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
366
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
367
    tcg_gen_shri_tl(r_temp, r_temp, 31 - PSR_OVF_SHIFT);
368
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
369
    tcg_temp_free(r_temp);
370
    tcg_gen_or_i32(cpu_psr, cpu_psr, cpu_tmp32);
371
}
372

    
373
#ifdef TARGET_SPARC64
374
static inline void gen_cc_V_add_xcc(TCGv dst, TCGv src1, TCGv src2)
375
{
376
    TCGv r_temp;
377

    
378
    r_temp = tcg_temp_new(TCG_TYPE_TL);
379
    tcg_gen_xor_tl(r_temp, src1, src2);
380
    tcg_gen_xori_tl(r_temp, r_temp, -1);
381
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
382
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
383
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
384
    tcg_gen_shri_tl(r_temp, r_temp, 63 - PSR_OVF_SHIFT);
385
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
386
    tcg_temp_free(r_temp);
387
    tcg_gen_or_i32(cpu_xcc, cpu_xcc, cpu_tmp32);
388
}
389
#endif
390

    
391
static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
392
{
393
    TCGv r_temp, r_const;
394
    int l1;
395

    
396
    l1 = gen_new_label();
397

    
398
    r_temp = tcg_temp_new(TCG_TYPE_TL);
399
    tcg_gen_xor_tl(r_temp, src1, src2);
400
    tcg_gen_xori_tl(r_temp, r_temp, -1);
401
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
402
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
403
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
404
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
405
    r_const = tcg_const_i32(TT_TOVF);
406
    tcg_gen_helper_0_1(raise_exception, r_const);
407
    tcg_temp_free(r_const);
408
    gen_set_label(l1);
409
    tcg_temp_free(r_temp);
410
}
411

    
412
static inline void gen_cc_V_tag(TCGv src1, TCGv src2)
413
{
414
    int l1;
415

    
416
    l1 = gen_new_label();
417
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
418
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
419
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
420
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
421
    gen_set_label(l1);
422
}
423

    
424
static inline void gen_tag_tv(TCGv src1, TCGv src2)
425
{
426
    int l1;
427
    TCGv r_const;
428

    
429
    l1 = gen_new_label();
430
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
431
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
432
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
433
    r_const = tcg_const_i32(TT_TOVF);
434
    tcg_gen_helper_0_1(raise_exception, r_const);
435
    tcg_temp_free(r_const);
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(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
444
    gen_cc_clear_icc();
445
    gen_cc_NZ_icc(cpu_cc_dst);
446
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
447
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
448
#ifdef TARGET_SPARC64
449
    gen_cc_clear_xcc();
450
    gen_cc_NZ_xcc(cpu_cc_dst);
451
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
452
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
453
#endif
454
    tcg_gen_mov_tl(dst, cpu_cc_dst);
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(cpu_cc_dst, cpu_cc_src, cpu_tmp0);
463
    gen_cc_clear_icc();
464
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
465
#ifdef TARGET_SPARC64
466
    gen_cc_clear_xcc();
467
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
468
#endif
469
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_dst, cpu_cc_src2);
470
    gen_cc_NZ_icc(cpu_cc_dst);
471
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
472
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
473
#ifdef TARGET_SPARC64
474
    gen_cc_NZ_xcc(cpu_cc_dst);
475
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
476
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
477
#endif
478
    tcg_gen_mov_tl(dst, cpu_cc_dst);
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(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
486
    gen_cc_clear_icc();
487
    gen_cc_NZ_icc(cpu_cc_dst);
488
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
489
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
490
    gen_cc_V_tag(cpu_cc_src, cpu_cc_src2);
491
#ifdef TARGET_SPARC64
492
    gen_cc_clear_xcc();
493
    gen_cc_NZ_xcc(cpu_cc_dst);
494
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
495
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
496
#endif
497
    tcg_gen_mov_tl(dst, cpu_cc_dst);
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(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
506
    gen_add_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
507
    gen_cc_clear_icc();
508
    gen_cc_NZ_icc(cpu_cc_dst);
509
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
510
#ifdef TARGET_SPARC64
511
    gen_cc_clear_xcc();
512
    gen_cc_NZ_xcc(cpu_cc_dst);
513
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
514
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
515
#endif
516
    tcg_gen_mov_tl(dst, cpu_cc_dst);
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
    tcg_temp_free(r_temp1);
537
    tcg_temp_free(r_temp2);
538
}
539

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

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

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

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

    
571
#ifdef TARGET_SPARC64
572
static inline void gen_cc_V_sub_xcc(TCGv dst, TCGv src1, TCGv src2)
573
{
574
    TCGv r_temp;
575

    
576
    r_temp = tcg_temp_new(TCG_TYPE_TL);
577
    tcg_gen_xor_tl(r_temp, src1, src2);
578
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
579
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
580
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
581
    tcg_gen_shri_tl(r_temp, r_temp, 63 - PSR_OVF_SHIFT);
582
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
583
    tcg_gen_or_i32(cpu_xcc, cpu_xcc, cpu_tmp32);
584
    tcg_temp_free(r_temp);
585
}
586
#endif
587

    
588
static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
589
{
590
    TCGv r_temp, r_const;
591
    int l1;
592

    
593
    l1 = gen_new_label();
594

    
595
    r_temp = tcg_temp_new(TCG_TYPE_TL);
596
    tcg_gen_xor_tl(r_temp, src1, src2);
597
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
598
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
599
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
600
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
601
    r_const = tcg_const_i32(TT_TOVF);
602
    tcg_gen_helper_0_1(raise_exception, r_const);
603
    tcg_temp_free(r_const);
604
    gen_set_label(l1);
605
    tcg_temp_free(r_temp);
606
}
607

    
608
static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2)
609
{
610
    tcg_gen_mov_tl(cpu_cc_src, src1);
611
    tcg_gen_mov_tl(cpu_cc_src2, src2);
612
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
613
    gen_cc_clear_icc();
614
    gen_cc_NZ_icc(cpu_cc_dst);
615
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
616
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
617
#ifdef TARGET_SPARC64
618
    gen_cc_clear_xcc();
619
    gen_cc_NZ_xcc(cpu_cc_dst);
620
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
621
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
622
#endif
623
    tcg_gen_mov_tl(dst, cpu_cc_dst);
624
}
625

    
626
static inline void gen_op_subx_cc(TCGv dst, TCGv src1, TCGv src2)
627
{
628
    tcg_gen_mov_tl(cpu_cc_src, src1);
629
    tcg_gen_mov_tl(cpu_cc_src2, src2);
630
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
631
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_tmp0);
632
    gen_cc_clear_icc();
633
    gen_cc_C_sub_icc(cpu_cc_dst, cpu_cc_src);
634
#ifdef TARGET_SPARC64
635
    gen_cc_clear_xcc();
636
    gen_cc_C_sub_xcc(cpu_cc_dst, cpu_cc_src);
637
#endif
638
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_dst, cpu_cc_src2);
639
    gen_cc_NZ_icc(cpu_cc_dst);
640
    gen_cc_C_sub_icc(cpu_cc_dst, cpu_cc_src);
641
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
642
#ifdef TARGET_SPARC64
643
    gen_cc_NZ_xcc(cpu_cc_dst);
644
    gen_cc_C_sub_xcc(cpu_cc_dst, cpu_cc_src);
645
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
646
#endif
647
    tcg_gen_mov_tl(dst, cpu_cc_dst);
648
}
649

    
650
static inline void gen_op_tsub_cc(TCGv dst, TCGv src1, TCGv src2)
651
{
652
    tcg_gen_mov_tl(cpu_cc_src, src1);
653
    tcg_gen_mov_tl(cpu_cc_src2, src2);
654
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
655
    gen_cc_clear_icc();
656
    gen_cc_NZ_icc(cpu_cc_dst);
657
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
658
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
659
    gen_cc_V_tag(cpu_cc_src, cpu_cc_src2);
660
#ifdef TARGET_SPARC64
661
    gen_cc_clear_xcc();
662
    gen_cc_NZ_xcc(cpu_cc_dst);
663
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
664
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
665
#endif
666
    tcg_gen_mov_tl(dst, cpu_cc_dst);
667
}
668

    
669
static inline void gen_op_tsub_ccTV(TCGv dst, TCGv src1, TCGv src2)
670
{
671
    tcg_gen_mov_tl(cpu_cc_src, src1);
672
    tcg_gen_mov_tl(cpu_cc_src2, src2);
673
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
674
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
675
    gen_sub_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
676
    gen_cc_clear_icc();
677
    gen_cc_NZ_icc(cpu_cc_dst);
678
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
679
#ifdef TARGET_SPARC64
680
    gen_cc_clear_xcc();
681
    gen_cc_NZ_xcc(cpu_cc_dst);
682
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
683
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
684
#endif
685
    tcg_gen_mov_tl(dst, cpu_cc_dst);
686
}
687

    
688
static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
689
{
690
    TCGv r_temp;
691
    int l1;
692

    
693
    l1 = gen_new_label();
694
    r_temp = tcg_temp_new(TCG_TYPE_TL);
695

    
696
    /* old op:
697
    if (!(env->y & 1))
698
        T1 = 0;
699
    */
700
    tcg_gen_mov_tl(cpu_cc_src, src1);
701
    tcg_gen_andi_tl(r_temp, cpu_y, 0x1);
702
    tcg_gen_mov_tl(cpu_cc_src2, src2);
703
    tcg_gen_brcondi_tl(TCG_COND_NE, r_temp, 0, l1);
704
    tcg_gen_movi_tl(cpu_cc_src2, 0);
705
    gen_set_label(l1);
706

    
707
    // b2 = T0 & 1;
708
    // env->y = (b2 << 31) | (env->y >> 1);
709
    tcg_gen_andi_tl(r_temp, cpu_cc_src, 0x1);
710
    tcg_gen_shli_tl(r_temp, r_temp, 31);
711
    tcg_gen_shri_tl(cpu_tmp0, cpu_y, 1);
712
    tcg_gen_or_tl(cpu_tmp0, cpu_tmp0, r_temp);
713
    tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
714

    
715
    // b1 = N ^ V;
716
    gen_mov_reg_N(cpu_tmp0, cpu_psr);
717
    gen_mov_reg_V(r_temp, cpu_psr);
718
    tcg_gen_xor_tl(cpu_tmp0, cpu_tmp0, r_temp);
719
    tcg_temp_free(r_temp);
720

    
721
    // T0 = (b1 << 31) | (T0 >> 1);
722
    // src1 = T0;
723
    tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
724
    tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
725
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
726

    
727
    /* do addition and update flags */
728
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
729

    
730
    gen_cc_clear_icc();
731
    gen_cc_NZ_icc(cpu_cc_dst);
732
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
733
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
734
    tcg_gen_mov_tl(dst, cpu_cc_dst);
735
}
736

    
737
static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
738
{
739
    TCGv r_temp, r_temp2;
740

    
741
    r_temp = tcg_temp_new(TCG_TYPE_I64);
742
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);
743

    
744
    tcg_gen_extu_i32_i64(r_temp, src2);
745
    tcg_gen_extu_i32_i64(r_temp2, src1);
746
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
747

    
748
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
749
    tcg_gen_trunc_i64_tl(cpu_tmp0, r_temp);
750
    tcg_temp_free(r_temp);
751
    tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
752
#ifdef TARGET_SPARC64
753
    tcg_gen_mov_i64(dst, r_temp2);
754
#else
755
    tcg_gen_trunc_i64_tl(dst, r_temp2);
756
#endif
757
    tcg_temp_free(r_temp2);
758
}
759

    
760
static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
761
{
762
    TCGv r_temp, r_temp2;
763

    
764
    r_temp = tcg_temp_new(TCG_TYPE_I64);
765
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);
766

    
767
    tcg_gen_ext_i32_i64(r_temp, src2);
768
    tcg_gen_ext_i32_i64(r_temp2, src1);
769
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
770

    
771
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
772
    tcg_gen_trunc_i64_tl(cpu_tmp0, r_temp);
773
    tcg_temp_free(r_temp);
774
    tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
775
#ifdef TARGET_SPARC64
776
    tcg_gen_mov_i64(dst, r_temp2);
777
#else
778
    tcg_gen_trunc_i64_tl(dst, r_temp2);
779
#endif
780
    tcg_temp_free(r_temp2);
781
}
782

    
783
#ifdef TARGET_SPARC64
784
static inline void gen_trap_ifdivzero_tl(TCGv divisor)
785
{
786
    TCGv r_const;
787
    int l1;
788

    
789
    l1 = gen_new_label();
790
    tcg_gen_brcondi_tl(TCG_COND_NE, divisor, 0, l1);
791
    r_const = tcg_const_i32(TT_DIV_ZERO);
792
    tcg_gen_helper_0_1(raise_exception, r_const);
793
    tcg_temp_free(r_const);
794
    gen_set_label(l1);
795
}
796

    
797
static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
798
{
799
    int l1, l2;
800

    
801
    l1 = gen_new_label();
802
    l2 = gen_new_label();
803
    tcg_gen_mov_tl(cpu_cc_src, src1);
804
    tcg_gen_mov_tl(cpu_cc_src2, src2);
805
    gen_trap_ifdivzero_tl(cpu_cc_src2);
806
    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc_src, INT64_MIN, l1);
807
    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc_src2, -1, l1);
808
    tcg_gen_movi_i64(dst, INT64_MIN);
809
    tcg_gen_br(l2);
810
    gen_set_label(l1);
811
    tcg_gen_div_i64(dst, cpu_cc_src, cpu_cc_src2);
812
    gen_set_label(l2);
813
}
814
#endif
815

    
816
static inline void gen_op_div_cc(TCGv dst)
817
{
818
    int l1;
819

    
820
    tcg_gen_mov_tl(cpu_cc_dst, dst);
821
    gen_cc_clear_icc();
822
    gen_cc_NZ_icc(cpu_cc_dst);
823
    l1 = gen_new_label();
824
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cc_src2, 0, l1);
825
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
826
    gen_set_label(l1);
827
}
828

    
829
static inline void gen_op_logic_cc(TCGv dst)
830
{
831
    tcg_gen_mov_tl(cpu_cc_dst, dst);
832

    
833
    gen_cc_clear_icc();
834
    gen_cc_NZ_icc(cpu_cc_dst);
835
#ifdef TARGET_SPARC64
836
    gen_cc_clear_xcc();
837
    gen_cc_NZ_xcc(cpu_cc_dst);
838
#endif
839
}
840

    
841
// 1
842
static inline void gen_op_eval_ba(TCGv dst)
843
{
844
    tcg_gen_movi_tl(dst, 1);
845
}
846

    
847
// Z
848
static inline void gen_op_eval_be(TCGv dst, TCGv src)
849
{
850
    gen_mov_reg_Z(dst, src);
851
}
852

    
853
// Z | (N ^ V)
854
static inline void gen_op_eval_ble(TCGv dst, TCGv src)
855
{
856
    gen_mov_reg_N(cpu_tmp0, src);
857
    gen_mov_reg_V(dst, src);
858
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
859
    gen_mov_reg_Z(cpu_tmp0, src);
860
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
861
}
862

    
863
// N ^ V
864
static inline void gen_op_eval_bl(TCGv dst, TCGv src)
865
{
866
    gen_mov_reg_V(cpu_tmp0, src);
867
    gen_mov_reg_N(dst, src);
868
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
869
}
870

    
871
// C | Z
872
static inline void gen_op_eval_bleu(TCGv dst, TCGv src)
873
{
874
    gen_mov_reg_Z(cpu_tmp0, src);
875
    gen_mov_reg_C(dst, src);
876
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
877
}
878

    
879
// C
880
static inline void gen_op_eval_bcs(TCGv dst, TCGv src)
881
{
882
    gen_mov_reg_C(dst, src);
883
}
884

    
885
// V
886
static inline void gen_op_eval_bvs(TCGv dst, TCGv src)
887
{
888
    gen_mov_reg_V(dst, src);
889
}
890

    
891
// 0
892
static inline void gen_op_eval_bn(TCGv dst)
893
{
894
    tcg_gen_movi_tl(dst, 0);
895
}
896

    
897
// N
898
static inline void gen_op_eval_bneg(TCGv dst, TCGv src)
899
{
900
    gen_mov_reg_N(dst, src);
901
}
902

    
903
// !Z
904
static inline void gen_op_eval_bne(TCGv dst, TCGv src)
905
{
906
    gen_mov_reg_Z(dst, src);
907
    tcg_gen_xori_tl(dst, dst, 0x1);
908
}
909

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

    
921
// !(N ^ V)
922
static inline void gen_op_eval_bge(TCGv dst, TCGv src)
923
{
924
    gen_mov_reg_V(cpu_tmp0, src);
925
    gen_mov_reg_N(dst, src);
926
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
927
    tcg_gen_xori_tl(dst, dst, 0x1);
928
}
929

    
930
// !(C | Z)
931
static inline void gen_op_eval_bgu(TCGv dst, TCGv src)
932
{
933
    gen_mov_reg_Z(cpu_tmp0, src);
934
    gen_mov_reg_C(dst, src);
935
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
936
    tcg_gen_xori_tl(dst, dst, 0x1);
937
}
938

    
939
// !C
940
static inline void gen_op_eval_bcc(TCGv dst, TCGv src)
941
{
942
    gen_mov_reg_C(dst, src);
943
    tcg_gen_xori_tl(dst, dst, 0x1);
944
}
945

    
946
// !N
947
static inline void gen_op_eval_bpos(TCGv dst, TCGv src)
948
{
949
    gen_mov_reg_N(dst, src);
950
    tcg_gen_xori_tl(dst, dst, 0x1);
951
}
952

    
953
// !V
954
static inline void gen_op_eval_bvc(TCGv dst, TCGv src)
955
{
956
    gen_mov_reg_V(dst, src);
957
    tcg_gen_xori_tl(dst, dst, 0x1);
958
}
959

    
960
/*
961
  FPSR bit field FCC1 | FCC0:
962
   0 =
963
   1 <
964
   2 >
965
   3 unordered
966
*/
967
static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src,
968
                                    unsigned int fcc_offset)
969
{
970
    tcg_gen_shri_tl(reg, src, FSR_FCC0_SHIFT + fcc_offset);
971
    tcg_gen_andi_tl(reg, reg, 0x1);
972
}
973

    
974
static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
975
                                    unsigned int fcc_offset)
976
{
977
    tcg_gen_shri_tl(reg, src, FSR_FCC1_SHIFT + fcc_offset);
978
    tcg_gen_andi_tl(reg, reg, 0x1);
979
}
980

    
981
// !0: FCC0 | FCC1
982
static inline void gen_op_eval_fbne(TCGv dst, TCGv src,
983
                                    unsigned int fcc_offset)
984
{
985
    gen_mov_reg_FCC0(dst, src, fcc_offset);
986
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
987
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
988
}
989

    
990
// 1 or 2: FCC0 ^ FCC1
991
static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
992
                                    unsigned int fcc_offset)
993
{
994
    gen_mov_reg_FCC0(dst, src, fcc_offset);
995
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
996
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
997
}
998

    
999
// 1 or 3: FCC0
1000
static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
1001
                                    unsigned int fcc_offset)
1002
{
1003
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1004
}
1005

    
1006
// 1: FCC0 & !FCC1
1007
static inline void gen_op_eval_fbl(TCGv dst, TCGv src,
1008
                                    unsigned int fcc_offset)
1009
{
1010
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1011
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1012
    tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
1013
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1014
}
1015

    
1016
// 2 or 3: FCC1
1017
static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
1018
                                    unsigned int fcc_offset)
1019
{
1020
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1021
}
1022

    
1023
// 2: !FCC0 & FCC1
1024
static inline void gen_op_eval_fbg(TCGv dst, TCGv src,
1025
                                    unsigned int fcc_offset)
1026
{
1027
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1028
    tcg_gen_xori_tl(dst, dst, 0x1);
1029
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1030
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1031
}
1032

    
1033
// 3: FCC0 & FCC1
1034
static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
1035
                                    unsigned int fcc_offset)
1036
{
1037
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1038
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1039
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1040
}
1041

    
1042
// 0: !(FCC0 | FCC1)
1043
static inline void gen_op_eval_fbe(TCGv dst, TCGv src,
1044
                                    unsigned int fcc_offset)
1045
{
1046
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1047
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1048
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
1049
    tcg_gen_xori_tl(dst, dst, 0x1);
1050
}
1051

    
1052
// 0 or 3: !(FCC0 ^ FCC1)
1053
static inline void gen_op_eval_fbue(TCGv dst, TCGv src,
1054
                                    unsigned int fcc_offset)
1055
{
1056
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1057
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1058
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1059
    tcg_gen_xori_tl(dst, dst, 0x1);
1060
}
1061

    
1062
// 0 or 2: !FCC0
1063
static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
1064
                                    unsigned int fcc_offset)
1065
{
1066
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1067
    tcg_gen_xori_tl(dst, dst, 0x1);
1068
}
1069

    
1070
// !1: !(FCC0 & !FCC1)
1071
static inline void gen_op_eval_fbuge(TCGv dst, TCGv src,
1072
                                    unsigned int fcc_offset)
1073
{
1074
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1075
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1076
    tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
1077
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1078
    tcg_gen_xori_tl(dst, dst, 0x1);
1079
}
1080

    
1081
// 0 or 1: !FCC1
1082
static inline void gen_op_eval_fble(TCGv dst, TCGv src,
1083
                                    unsigned int fcc_offset)
1084
{
1085
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1086
    tcg_gen_xori_tl(dst, dst, 0x1);
1087
}
1088

    
1089
// !2: !(!FCC0 & FCC1)
1090
static inline void gen_op_eval_fbule(TCGv dst, TCGv src,
1091
                                    unsigned int fcc_offset)
1092
{
1093
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1094
    tcg_gen_xori_tl(dst, dst, 0x1);
1095
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1096
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1097
    tcg_gen_xori_tl(dst, dst, 0x1);
1098
}
1099

    
1100
// !3: !(FCC0 & FCC1)
1101
static inline void gen_op_eval_fbo(TCGv dst, TCGv src,
1102
                                    unsigned int fcc_offset)
1103
{
1104
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1105
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1106
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1107
    tcg_gen_xori_tl(dst, dst, 0x1);
1108
}
1109

    
1110
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
1111
                               target_ulong pc2, TCGv r_cond)
1112
{
1113
    int l1;
1114

    
1115
    l1 = gen_new_label();
1116

    
1117
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
1118

    
1119
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
1120

    
1121
    gen_set_label(l1);
1122
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
1123
}
1124

    
1125
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
1126
                                target_ulong pc2, TCGv r_cond)
1127
{
1128
    int l1;
1129

    
1130
    l1 = gen_new_label();
1131

    
1132
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
1133

    
1134
    gen_goto_tb(dc, 0, pc2, pc1);
1135

    
1136
    gen_set_label(l1);
1137
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
1138
}
1139

    
1140
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
1141
                                      TCGv r_cond)
1142
{
1143
    int l1, l2;
1144

    
1145
    l1 = gen_new_label();
1146
    l2 = gen_new_label();
1147

    
1148
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
1149

    
1150
    tcg_gen_movi_tl(cpu_npc, npc1);
1151
    tcg_gen_br(l2);
1152

    
1153
    gen_set_label(l1);
1154
    tcg_gen_movi_tl(cpu_npc, npc2);
1155
    gen_set_label(l2);
1156
}
1157

    
1158
/* call this function before using the condition register as it may
1159
   have been set for a jump */
1160
static inline void flush_cond(DisasContext *dc, TCGv cond)
1161
{
1162
    if (dc->npc == JUMP_PC) {
1163
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1164
        dc->npc = DYNAMIC_PC;
1165
    }
1166
}
1167

    
1168
static inline void save_npc(DisasContext *dc, TCGv cond)
1169
{
1170
    if (dc->npc == JUMP_PC) {
1171
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1172
        dc->npc = DYNAMIC_PC;
1173
    } else if (dc->npc != DYNAMIC_PC) {
1174
        tcg_gen_movi_tl(cpu_npc, dc->npc);
1175
    }
1176
}
1177

    
1178
static inline void save_state(DisasContext *dc, TCGv cond)
1179
{
1180
    tcg_gen_movi_tl(cpu_pc, dc->pc);
1181
    save_npc(dc, cond);
1182
}
1183

    
1184
static inline void gen_mov_pc_npc(DisasContext *dc, TCGv cond)
1185
{
1186
    if (dc->npc == JUMP_PC) {
1187
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1188
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1189
        dc->pc = DYNAMIC_PC;
1190
    } else if (dc->npc == DYNAMIC_PC) {
1191
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1192
        dc->pc = DYNAMIC_PC;
1193
    } else {
1194
        dc->pc = dc->npc;
1195
    }
1196
}
1197

    
1198
static inline void gen_op_next_insn(void)
1199
{
1200
    tcg_gen_mov_tl(cpu_pc, cpu_npc);
1201
    tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
1202
}
1203

    
1204
static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond)
1205
{
1206
    TCGv r_src;
1207

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

    
1268
static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
1269
{
1270
    unsigned int offset;
1271

    
1272
    switch (cc) {
1273
    default:
1274
    case 0x0:
1275
        offset = 0;
1276
        break;
1277
    case 0x1:
1278
        offset = 32 - 10;
1279
        break;
1280
    case 0x2:
1281
        offset = 34 - 10;
1282
        break;
1283
    case 0x3:
1284
        offset = 36 - 10;
1285
        break;
1286
    }
1287

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

    
1340
#ifdef TARGET_SPARC64
1341
// Inverted logic
1342
static const int gen_tcg_cond_reg[8] = {
1343
    -1,
1344
    TCG_COND_NE,
1345
    TCG_COND_GT,
1346
    TCG_COND_GE,
1347
    -1,
1348
    TCG_COND_EQ,
1349
    TCG_COND_LE,
1350
    TCG_COND_LT,
1351
};
1352

    
1353
static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
1354
{
1355
    int l1;
1356

    
1357
    l1 = gen_new_label();
1358
    tcg_gen_movi_tl(r_dst, 0);
1359
    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], r_src, 0, l1);
1360
    tcg_gen_movi_tl(r_dst, 1);
1361
    gen_set_label(l1);
1362
}
1363
#endif
1364

    
1365
/* XXX: potentially incorrect if dynamic npc */
1366
static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1367
                      TCGv r_cond)
1368
{
1369
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1370
    target_ulong target = dc->pc + offset;
1371

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

    
1405
/* XXX: potentially incorrect if dynamic npc */
1406
static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1407
                      TCGv r_cond)
1408
{
1409
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1410
    target_ulong target = dc->pc + offset;
1411

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

    
1445
#ifdef TARGET_SPARC64
1446
/* XXX: potentially incorrect if dynamic npc */
1447
static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
1448
                          TCGv r_cond, TCGv r_reg)
1449
{
1450
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1451
    target_ulong target = dc->pc + offset;
1452

    
1453
    flush_cond(dc, r_cond);
1454
    gen_cond_reg(r_cond, cond, r_reg);
1455
    if (a) {
1456
        gen_branch_a(dc, target, dc->npc, r_cond);
1457
        dc->is_br = 1;
1458
    } else {
1459
        dc->pc = dc->npc;
1460
        dc->jump_pc[0] = target;
1461
        dc->jump_pc[1] = dc->npc + 4;
1462
        dc->npc = JUMP_PC;
1463
    }
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_fcmped[4] = {
1481
    helper_fcmped,
1482
    helper_fcmped_fcc1,
1483
    helper_fcmped_fcc2,
1484
    helper_fcmped_fcc3,
1485
};
1486

    
1487
static GenOpFunc * const gen_fcmpeq[4] = {
1488
    helper_fcmpeq,
1489
    helper_fcmpeq_fcc1,
1490
    helper_fcmpeq_fcc2,
1491
    helper_fcmpeq_fcc3,
1492
};
1493

    
1494
static inline void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2)
1495
{
1496
    switch (fccno) {
1497
    case 0:
1498
        tcg_gen_helper_0_2(helper_fcmps, r_rs1, r_rs2);
1499
        break;
1500
    case 1:
1501
        tcg_gen_helper_0_2(helper_fcmps_fcc1, r_rs1, r_rs2);
1502
        break;
1503
    case 2:
1504
        tcg_gen_helper_0_2(helper_fcmps_fcc2, r_rs1, r_rs2);
1505
        break;
1506
    case 3:
1507
        tcg_gen_helper_0_2(helper_fcmps_fcc3, r_rs1, r_rs2);
1508
        break;
1509
    }
1510
}
1511

    
1512
static inline void gen_op_fcmpd(int fccno)
1513
{
1514
    tcg_gen_helper_0_0(gen_fcmpd[fccno]);
1515
}
1516

    
1517
static inline void gen_op_fcmpq(int fccno)
1518
{
1519
    tcg_gen_helper_0_0(gen_fcmpq[fccno]);
1520
}
1521

    
1522
static inline void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2)
1523
{
1524
    switch (fccno) {
1525
    case 0:
1526
        tcg_gen_helper_0_2(helper_fcmpes, r_rs1, r_rs2);
1527
        break;
1528
    case 1:
1529
        tcg_gen_helper_0_2(helper_fcmpes_fcc1, r_rs1, r_rs2);
1530
        break;
1531
    case 2:
1532
        tcg_gen_helper_0_2(helper_fcmpes_fcc2, r_rs1, r_rs2);
1533
        break;
1534
    case 3:
1535
        tcg_gen_helper_0_2(helper_fcmpes_fcc3, r_rs1, r_rs2);
1536
        break;
1537
    }
1538
}
1539

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

    
1545
static inline void gen_op_fcmpeq(int fccno)
1546
{
1547
    tcg_gen_helper_0_0(gen_fcmpeq[fccno]);
1548
}
1549

    
1550
#else
1551

    
1552
static inline void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2)
1553
{
1554
    tcg_gen_helper_0_2(helper_fcmps, r_rs1, r_rs2);
1555
}
1556

    
1557
static inline void gen_op_fcmpd(int fccno)
1558
{
1559
    tcg_gen_helper_0_0(helper_fcmpd);
1560
}
1561

    
1562
static inline void gen_op_fcmpq(int fccno)
1563
{
1564
    tcg_gen_helper_0_0(helper_fcmpq);
1565
}
1566

    
1567
static inline void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2)
1568
{
1569
    tcg_gen_helper_0_2(helper_fcmpes, r_rs1, r_rs2);
1570
}
1571

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

    
1577
static inline void gen_op_fcmpeq(int fccno)
1578
{
1579
    tcg_gen_helper_0_0(helper_fcmpeq);
1580
}
1581
#endif
1582

    
1583
static inline void gen_op_fpexception_im(int fsr_flags)
1584
{
1585
    TCGv r_const;
1586

    
1587
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_NMASK);
1588
    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
1589
    r_const = tcg_const_i32(TT_FP_EXCP);
1590
    tcg_gen_helper_0_1(raise_exception, r_const);
1591
    tcg_temp_free(r_const);
1592
}
1593

    
1594
static int gen_trap_ifnofpu(DisasContext *dc, TCGv r_cond)
1595
{
1596
#if !defined(CONFIG_USER_ONLY)
1597
    if (!dc->fpu_enabled) {
1598
        TCGv r_const;
1599

    
1600
        save_state(dc, r_cond);
1601
        r_const = tcg_const_i32(TT_NFPU_INSN);
1602
        tcg_gen_helper_0_1(raise_exception, r_const);
1603
        tcg_temp_free(r_const);
1604
        dc->is_br = 1;
1605
        return 1;
1606
    }
1607
#endif
1608
    return 0;
1609
}
1610

    
1611
static inline void gen_op_clear_ieee_excp_and_FTT(void)
1612
{
1613
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_CEXC_NMASK);
1614
}
1615

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

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

    
1628
    if (IS_IMM) {
1629
        r_asi = tcg_temp_new(TCG_TYPE_I32);
1630
        tcg_gen_mov_i32(r_asi, cpu_asi);
1631
    } else {
1632
        asi = GET_FIELD(insn, 19, 26);
1633
        r_asi = tcg_const_i32(asi);
1634
    }
1635
    return r_asi;
1636
}
1637

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

    
1643
    r_asi = gen_get_asi(insn, addr);
1644
    r_size = tcg_const_i32(size);
1645
    r_sign = tcg_const_i32(sign);
1646
    tcg_gen_helper_1_4(helper_ld_asi, dst, addr, r_asi, r_size, r_sign);
1647
    tcg_temp_free(r_sign);
1648
    tcg_temp_free(r_size);
1649
    tcg_temp_free(r_asi);
1650
}
1651

    
1652
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1653
{
1654
    TCGv r_asi, r_size;
1655

    
1656
    r_asi = gen_get_asi(insn, addr);
1657
    r_size = tcg_const_i32(size);
1658
    tcg_gen_helper_0_4(helper_st_asi, addr, src, r_asi, r_size);
1659
    tcg_temp_free(r_size);
1660
    tcg_temp_free(r_asi);
1661
}
1662

    
1663
static inline void gen_ldf_asi(TCGv addr, int insn, int size, int rd)
1664
{
1665
    TCGv r_asi, r_size, r_rd;
1666

    
1667
    r_asi = gen_get_asi(insn, addr);
1668
    r_size = tcg_const_i32(size);
1669
    r_rd = tcg_const_i32(rd);
1670
    tcg_gen_helper_0_4(helper_ldf_asi, addr, r_asi, r_size, r_rd);
1671
    tcg_temp_free(r_rd);
1672
    tcg_temp_free(r_size);
1673
    tcg_temp_free(r_asi);
1674
}
1675

    
1676
static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
1677
{
1678
    TCGv r_asi, r_size, r_rd;
1679

    
1680
    r_asi = gen_get_asi(insn, addr);
1681
    r_size = tcg_const_i32(size);
1682
    r_rd = tcg_const_i32(rd);
1683
    tcg_gen_helper_0_4(helper_stf_asi, addr, r_asi, r_size, r_rd);
1684
    tcg_temp_free(r_rd);
1685
    tcg_temp_free(r_size);
1686
    tcg_temp_free(r_asi);
1687
}
1688

    
1689
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1690
{
1691
    TCGv r_asi, r_size, r_sign;
1692

    
1693
    r_asi = gen_get_asi(insn, addr);
1694
    r_size = tcg_const_i32(4);
1695
    r_sign = tcg_const_i32(0);
1696
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
1697
    tcg_temp_free(r_sign);
1698
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, r_asi, r_size);
1699
    tcg_temp_free(r_size);
1700
    tcg_temp_free(r_asi);
1701
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1702
}
1703

    
1704
static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
1705
{
1706
    TCGv r_asi, r_rd;
1707

    
1708
    r_asi = gen_get_asi(insn, addr);
1709
    r_rd = tcg_const_i32(rd);
1710
    tcg_gen_helper_0_3(helper_ldda_asi, addr, r_asi, r_rd);
1711
    tcg_temp_free(r_rd);
1712
    tcg_temp_free(r_asi);
1713
}
1714

    
1715
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1716
{
1717
    TCGv r_temp, r_asi, r_size;
1718

    
1719
    r_temp = tcg_temp_new(TCG_TYPE_TL);
1720
    gen_movl_reg_TN(rd + 1, r_temp);
1721
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi,
1722
                       r_temp);
1723
    tcg_temp_free(r_temp);
1724
    r_asi = gen_get_asi(insn, addr);
1725
    r_size = tcg_const_i32(8);
1726
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi, r_size);
1727
    tcg_temp_free(r_size);
1728
    tcg_temp_free(r_asi);
1729
}
1730

    
1731
static inline void gen_cas_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
1732
                               int rd)
1733
{
1734
    TCGv r_val1, r_asi;
1735

    
1736
    r_val1 = tcg_temp_new(TCG_TYPE_TL);
1737
    gen_movl_reg_TN(rd, r_val1);
1738
    r_asi = gen_get_asi(insn, addr);
1739
    tcg_gen_helper_1_4(helper_cas_asi, dst, addr, r_val1, val2, r_asi);
1740
    tcg_temp_free(r_asi);
1741
    tcg_temp_free(r_val1);
1742
}
1743

    
1744
static inline void gen_casx_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
1745
                                int rd)
1746
{
1747
    TCGv r_asi;
1748

    
1749
    gen_movl_reg_TN(rd, cpu_tmp64);
1750
    r_asi = gen_get_asi(insn, addr);
1751
    tcg_gen_helper_1_4(helper_casx_asi, dst, addr, cpu_tmp64, val2, r_asi);
1752
    tcg_temp_free(r_asi);
1753
}
1754

    
1755
#elif !defined(CONFIG_USER_ONLY)
1756

    
1757
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
1758
                              int sign)
1759
{
1760
    TCGv r_asi, r_size, r_sign;
1761

    
1762
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1763
    r_size = tcg_const_i32(size);
1764
    r_sign = tcg_const_i32(sign);
1765
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
1766
    tcg_temp_free(r_sign);
1767
    tcg_temp_free(r_size);
1768
    tcg_temp_free(r_asi);
1769
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1770
}
1771

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

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

    
1784
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1785
{
1786
    TCGv r_asi, r_size, r_sign;
1787

    
1788
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1789
    r_size = tcg_const_i32(4);
1790
    r_sign = tcg_const_i32(0);
1791
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
1792
    tcg_temp_free(r_sign);
1793
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, r_asi, r_size);
1794
    tcg_temp_free(r_size);
1795
    tcg_temp_free(r_asi);
1796
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1797
}
1798

    
1799
static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
1800
{
1801
    TCGv r_asi, r_size, r_sign;
1802

    
1803
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1804
    r_size = tcg_const_i32(8);
1805
    r_sign = tcg_const_i32(0);
1806
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
1807
    tcg_temp_free(r_sign);
1808
    tcg_temp_free(r_size);
1809
    tcg_temp_free(r_asi);
1810
    tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
1811
    gen_movl_TN_reg(rd + 1, cpu_tmp0);
1812
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1813
    tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
1814
    gen_movl_TN_reg(rd, hi);
1815
}
1816

    
1817
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1818
{
1819
    TCGv r_temp, r_asi, r_size;
1820

    
1821
    r_temp = tcg_temp_new(TCG_TYPE_TL);
1822
    gen_movl_reg_TN(rd + 1, r_temp);
1823
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi, r_temp);
1824
    tcg_temp_free(r_temp);
1825
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1826
    r_size = tcg_const_i32(8);
1827
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi, r_size);
1828
    tcg_temp_free(r_size);
1829
    tcg_temp_free(r_asi);
1830
}
1831
#endif
1832

    
1833
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1834
static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
1835
{
1836
    TCGv r_val, r_asi, r_size;
1837

    
1838
    gen_ld_asi(dst, addr, insn, 1, 0);
1839

    
1840
    r_val = tcg_const_i64(0xffULL);
1841
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1842
    r_size = tcg_const_i32(1);
1843
    tcg_gen_helper_0_4(helper_st_asi, addr, r_val, r_asi, r_size);
1844
    tcg_temp_free(r_size);
1845
    tcg_temp_free(r_asi);
1846
    tcg_temp_free(r_val);
1847
}
1848
#endif
1849

    
1850
static inline TCGv get_src1(unsigned int insn, TCGv def)
1851
{
1852
    TCGv r_rs1 = def;
1853
    unsigned int rs1;
1854

    
1855
    rs1 = GET_FIELD(insn, 13, 17);
1856
    if (rs1 == 0)
1857
        r_rs1 = tcg_const_tl(0); // XXX how to free?
1858
    else if (rs1 < 8)
1859
        r_rs1 = cpu_gregs[rs1];
1860
    else
1861
        tcg_gen_ld_tl(def, cpu_regwptr, (rs1 - 8) * sizeof(target_ulong));
1862
    return r_rs1;
1863
}
1864

    
1865
static inline TCGv get_src2(unsigned int insn, TCGv def)
1866
{
1867
    TCGv r_rs2 = def;
1868
    unsigned int rs2;
1869

    
1870
    if (IS_IMM) { /* immediate */
1871
        rs2 = GET_FIELDs(insn, 19, 31);
1872
        r_rs2 = tcg_const_tl((int)rs2); // XXX how to free?
1873
    } else { /* register */
1874
        rs2 = GET_FIELD(insn, 27, 31);
1875
        if (rs2 == 0)
1876
            r_rs2 = tcg_const_tl(0); // XXX how to free?
1877
        else if (rs2 < 8)
1878
            r_rs2 = cpu_gregs[rs2];
1879
        else
1880
            tcg_gen_ld_tl(def, cpu_regwptr, (rs2 - 8) * sizeof(target_ulong));
1881
    }
1882
    return r_rs2;
1883
}
1884

    
1885
#define CHECK_IU_FEATURE(dc, FEATURE)                      \
1886
    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
1887
        goto illegal_insn;
1888
#define CHECK_FPU_FEATURE(dc, FEATURE)                     \
1889
    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
1890
        goto nfpu_insn;
1891

    
1892
/* before an instruction, dc->pc must be static */
1893
static void disas_sparc_insn(DisasContext * dc)
1894
{
1895
    unsigned int insn, opc, rs1, rs2, rd;
1896

    
1897
    if (unlikely(loglevel & CPU_LOG_TB_OP))
1898
        tcg_gen_debug_insn_start(dc->pc);
1899
    insn = ldl_code(dc->pc);
1900
    opc = GET_FIELD(insn, 0, 1);
1901

    
1902
    rd = GET_FIELD(insn, 2, 6);
1903

    
1904
    cpu_src1 = tcg_temp_new(TCG_TYPE_TL); // const
1905
    cpu_src2 = tcg_temp_new(TCG_TYPE_TL); // const
1906

    
1907
    switch (opc) {
1908
    case 0:                     /* branches/sethi */
1909
        {
1910
            unsigned int xop = GET_FIELD(insn, 7, 9);
1911
            int32_t target;
1912
            switch (xop) {
1913
#ifdef TARGET_SPARC64
1914
            case 0x1:           /* V9 BPcc */
1915
                {
1916
                    int cc;
1917

    
1918
                    target = GET_FIELD_SP(insn, 0, 18);
1919
                    target = sign_extend(target, 18);
1920
                    target <<= 2;
1921
                    cc = GET_FIELD_SP(insn, 20, 21);
1922
                    if (cc == 0)
1923
                        do_branch(dc, target, insn, 0, cpu_cond);
1924
                    else if (cc == 2)
1925
                        do_branch(dc, target, insn, 1, cpu_cond);
1926
                    else
1927
                        goto illegal_insn;
1928
                    goto jmp_insn;
1929
                }
1930
            case 0x3:           /* V9 BPr */
1931
                {
1932
                    target = GET_FIELD_SP(insn, 0, 13) |
1933
                        (GET_FIELD_SP(insn, 20, 21) << 14);
1934
                    target = sign_extend(target, 16);
1935
                    target <<= 2;
1936
                    cpu_src1 = get_src1(insn, cpu_src1);
1937
                    do_branch_reg(dc, target, insn, cpu_cond, cpu_src1);
1938
                    goto jmp_insn;
1939
                }
1940
            case 0x5:           /* V9 FBPcc */
1941
                {
1942
                    int cc = GET_FIELD_SP(insn, 20, 21);
1943
                    if (gen_trap_ifnofpu(dc, cpu_cond))
1944
                        goto jmp_insn;
1945
                    target = GET_FIELD_SP(insn, 0, 18);
1946
                    target = sign_extend(target, 19);
1947
                    target <<= 2;
1948
                    do_fbranch(dc, target, insn, cc, cpu_cond);
1949
                    goto jmp_insn;
1950
                }
1951
#else
1952
            case 0x7:           /* CBN+x */
1953
                {
1954
                    goto ncp_insn;
1955
                }
1956
#endif
1957
            case 0x2:           /* BN+x */
1958
                {
1959
                    target = GET_FIELD(insn, 10, 31);
1960
                    target = sign_extend(target, 22);
1961
                    target <<= 2;
1962
                    do_branch(dc, target, insn, 0, cpu_cond);
1963
                    goto jmp_insn;
1964
                }
1965
            case 0x6:           /* FBN+x */
1966
                {
1967
                    if (gen_trap_ifnofpu(dc, cpu_cond))
1968
                        goto jmp_insn;
1969
                    target = GET_FIELD(insn, 10, 31);
1970
                    target = sign_extend(target, 22);
1971
                    target <<= 2;
1972
                    do_fbranch(dc, target, insn, 0, cpu_cond);
1973
                    goto jmp_insn;
1974
                }
1975
            case 0x4:           /* SETHI */
1976
                if (rd) { // nop
1977
                    uint32_t value = GET_FIELD(insn, 10, 31);
1978
                    TCGv r_const;
1979

    
1980
                    r_const = tcg_const_tl(value << 10);
1981
                    gen_movl_TN_reg(rd, r_const);
1982
                    tcg_temp_free(r_const);
1983
                }
1984
                break;
1985
            case 0x0:           /* UNIMPL */
1986
            default:
1987
                goto illegal_insn;
1988
            }
1989
            break;
1990
        }
1991
        break;
1992
    case 1:
1993
        /*CALL*/ {
1994
            target_long target = GET_FIELDs(insn, 2, 31) << 2;
1995
            TCGv r_const;
1996

    
1997
            r_const = tcg_const_tl(dc->pc);
1998
            gen_movl_TN_reg(15, r_const);
1999
            tcg_temp_free(r_const);
2000
            target += dc->pc;
2001
            gen_mov_pc_npc(dc, cpu_cond);
2002
            dc->npc = target;
2003
        }
2004
        goto jmp_insn;
2005
    case 2:                     /* FPU & Logical Operations */
2006
        {
2007
            unsigned int xop = GET_FIELD(insn, 7, 12);
2008
            if (xop == 0x3a) {  /* generate trap */
2009
                int cond;
2010

    
2011
                cpu_src1 = get_src1(insn, cpu_src1);
2012
                if (IS_IMM) {
2013
                    rs2 = GET_FIELD(insn, 25, 31);
2014
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, rs2);
2015
                } else {
2016
                    rs2 = GET_FIELD(insn, 27, 31);
2017
                    if (rs2 != 0) {
2018
                        gen_movl_reg_TN(rs2, cpu_src2);
2019
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
2020
                    } else
2021
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
2022
                }
2023
                cond = GET_FIELD(insn, 3, 6);
2024
                if (cond == 0x8) {
2025
                    save_state(dc, cpu_cond);
2026
                    tcg_gen_helper_0_1(helper_trap, cpu_dst);
2027
                } else if (cond != 0) {
2028
                    TCGv r_cond = tcg_temp_new(TCG_TYPE_TL);
2029
#ifdef TARGET_SPARC64
2030
                    /* V9 icc/xcc */
2031
                    int cc = GET_FIELD_SP(insn, 11, 12);
2032

    
2033
                    save_state(dc, cpu_cond);
2034
                    if (cc == 0)
2035
                        gen_cond(r_cond, 0, cond);
2036
                    else if (cc == 2)
2037
                        gen_cond(r_cond, 1, cond);
2038
                    else
2039
                        goto illegal_insn;
2040
#else
2041
                    save_state(dc, cpu_cond);
2042
                    gen_cond(r_cond, 0, cond);
2043
#endif
2044
                    tcg_gen_helper_0_2(helper_trapcc, cpu_dst, r_cond);
2045
                    tcg_temp_free(r_cond);
2046
                }
2047
                gen_op_next_insn();
2048
                tcg_gen_exit_tb(0);
2049
                dc->is_br = 1;
2050
                goto jmp_insn;
2051
            } else if (xop == 0x28) {
2052
                rs1 = GET_FIELD(insn, 13, 17);
2053
                switch(rs1) {
2054
                case 0: /* rdy */
2055
#ifndef TARGET_SPARC64
2056
                case 0x01 ... 0x0e: /* undefined in the SPARCv8
2057
                                       manual, rdy on the microSPARC
2058
                                       II */
2059
                case 0x0f:          /* stbar in the SPARCv8 manual,
2060
                                       rdy on the microSPARC II */
2061
                case 0x10 ... 0x1f: /* implementation-dependent in the
2062
                                       SPARCv8 manual, rdy on the
2063
                                       microSPARC II */
2064
#endif
2065
                    gen_movl_TN_reg(rd, cpu_y);
2066
                    break;
2067
#ifdef TARGET_SPARC64
2068
                case 0x2: /* V9 rdccr */
2069
                    tcg_gen_helper_1_0(helper_rdccr, cpu_dst);
2070
                    gen_movl_TN_reg(rd, cpu_dst);
2071
                    break;
2072
                case 0x3: /* V9 rdasi */
2073
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_asi);
2074
                    gen_movl_TN_reg(rd, cpu_dst);
2075
                    break;
2076
                case 0x4: /* V9 rdtick */
2077
                    {
2078
                        TCGv r_tickptr;
2079

    
2080
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2081
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2082
                                       offsetof(CPUState, tick));
2083
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst,
2084
                                           r_tickptr);
2085
                        tcg_temp_free(r_tickptr);
2086
                        gen_movl_TN_reg(rd, cpu_dst);
2087
                    }
2088
                    break;
2089
                case 0x5: /* V9 rdpc */
2090
                    {
2091
                        TCGv r_const;
2092

    
2093
                        r_const = tcg_const_tl(dc->pc);
2094
                        gen_movl_TN_reg(rd, r_const);
2095
                        tcg_temp_free(r_const);
2096
                    }
2097
                    break;
2098
                case 0x6: /* V9 rdfprs */
2099
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_fprs);
2100
                    gen_movl_TN_reg(rd, cpu_dst);
2101
                    break;
2102
                case 0xf: /* V9 membar */
2103
                    break; /* no effect */
2104
                case 0x13: /* Graphics Status */
2105
                    if (gen_trap_ifnofpu(dc, cpu_cond))
2106
                        goto jmp_insn;
2107
                    gen_movl_TN_reg(rd, cpu_gsr);
2108
                    break;
2109
                case 0x17: /* Tick compare */
2110
                    gen_movl_TN_reg(rd, cpu_tick_cmpr);
2111
                    break;
2112
                case 0x18: /* System tick */
2113
                    {
2114
                        TCGv r_tickptr;
2115

    
2116
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2117
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2118
                                       offsetof(CPUState, stick));
2119
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst,
2120
                                           r_tickptr);
2121
                        tcg_temp_free(r_tickptr);
2122
                        gen_movl_TN_reg(rd, cpu_dst);
2123
                    }
2124
                    break;
2125
                case 0x19: /* System tick compare */
2126
                    gen_movl_TN_reg(rd, cpu_stick_cmpr);
2127
                    break;
2128
                case 0x10: /* Performance Control */
2129
                case 0x11: /* Performance Instrumentation Counter */
2130
                case 0x12: /* Dispatch Control */
2131
                case 0x14: /* Softint set, WO */
2132
                case 0x15: /* Softint clear, WO */
2133
                case 0x16: /* Softint write */
2134
#endif
2135
                default:
2136
                    goto illegal_insn;
2137
                }
2138
#if !defined(CONFIG_USER_ONLY)
2139
            } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
2140
#ifndef TARGET_SPARC64
2141
                if (!supervisor(dc))
2142
                    goto priv_insn;
2143
                tcg_gen_helper_1_0(helper_rdpsr, cpu_dst);
2144
#else
2145
                CHECK_IU_FEATURE(dc, HYPV);
2146
                if (!hypervisor(dc))
2147
                    goto priv_insn;
2148
                rs1 = GET_FIELD(insn, 13, 17);
2149
                switch (rs1) {
2150
                case 0: // hpstate
2151
                    // gen_op_rdhpstate();
2152
                    break;
2153
                case 1: // htstate
2154
                    // gen_op_rdhtstate();
2155
                    break;
2156
                case 3: // hintp
2157
                    tcg_gen_mov_tl(cpu_dst, cpu_hintp);
2158
                    break;
2159
                case 5: // htba
2160
                    tcg_gen_mov_tl(cpu_dst, cpu_htba);
2161
                    break;
2162
                case 6: // hver
2163
                    tcg_gen_mov_tl(cpu_dst, cpu_hver);
2164
                    break;
2165
                case 31: // hstick_cmpr
2166
                    tcg_gen_mov_tl(cpu_dst, cpu_hstick_cmpr);
2167
                    break;
2168
                default:
2169
                    goto illegal_insn;
2170
                }
2171
#endif
2172
                gen_movl_TN_reg(rd, cpu_dst);
2173
                break;
2174
            } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
2175
                if (!supervisor(dc))
2176
                    goto priv_insn;
2177
#ifdef TARGET_SPARC64
2178
                rs1 = GET_FIELD(insn, 13, 17);
2179
                switch (rs1) {
2180
                case 0: // tpc
2181
                    {
2182
                        TCGv r_tsptr;
2183

    
2184
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2185
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2186
                                       offsetof(CPUState, tsptr));
2187
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2188
                                      offsetof(trap_state, tpc));
2189
                        tcg_temp_free(r_tsptr);
2190
                    }
2191
                    break;
2192
                case 1: // tnpc
2193
                    {
2194
                        TCGv r_tsptr;
2195

    
2196
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2197
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2198
                                       offsetof(CPUState, tsptr));
2199
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2200
                                      offsetof(trap_state, tnpc));
2201
                        tcg_temp_free(r_tsptr);
2202
                    }
2203
                    break;
2204
                case 2: // tstate
2205
                    {
2206
                        TCGv r_tsptr;
2207

    
2208
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2209
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2210
                                       offsetof(CPUState, tsptr));
2211
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2212
                                      offsetof(trap_state, tstate));
2213
                        tcg_temp_free(r_tsptr);
2214
                    }
2215
                    break;
2216
                case 3: // tt
2217
                    {
2218
                        TCGv r_tsptr;
2219

    
2220
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2221
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2222
                                       offsetof(CPUState, tsptr));
2223
                        tcg_gen_ld_i32(cpu_tmp0, r_tsptr,
2224
                                       offsetof(trap_state, tt));
2225
                        tcg_temp_free(r_tsptr);
2226
                    }
2227
                    break;
2228
                case 4: // tick
2229
                    {
2230
                        TCGv r_tickptr;
2231

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

    
2658
                    l1 = gen_new_label();
2659
                    cond = GET_FIELD_SP(insn, 14, 17);
2660
                    cpu_src1 = get_src1(insn, cpu_src1);
2661
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2662
                                       0, l1);
2663
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);
2664
                    gen_set_label(l1);
2665
                    break;
2666
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
2667
                    int l1;
2668

    
2669
                    l1 = gen_new_label();
2670
                    cond = GET_FIELD_SP(insn, 14, 17);
2671
                    cpu_src1 = get_src1(insn, cpu_src1);
2672
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2673
                                       0, l1);
2674
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)]);
2675
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], cpu_fpr[DFPREG(rs2) + 1]);
2676
                    gen_set_label(l1);
2677
                    break;
2678
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
2679
                    int l1;
2680

    
2681
                    CHECK_FPU_FEATURE(dc, FLOAT128);
2682
                    l1 = gen_new_label();
2683
                    cond = GET_FIELD_SP(insn, 14, 17);
2684
                    cpu_src1 = get_src1(insn, cpu_src1);
2685
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2686
                                       0, l1);
2687
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], cpu_fpr[QFPREG(rs2)]);
2688
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], cpu_fpr[QFPREG(rs2) + 1]);
2689
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], cpu_fpr[QFPREG(rs2) + 2]);
2690
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], cpu_fpr[QFPREG(rs2) + 3]);
2691
                    gen_set_label(l1);
2692
                    break;
2693
                }
2694
#endif
2695
                switch (xop) {
2696
#ifdef TARGET_SPARC64
2697
#define FMOVSCC(fcc)                                                    \
2698
                    {                                                   \
2699
                        TCGv r_cond;                                    \
2700
                        int l1;                                         \
2701
                                                                        \
2702
                        l1 = gen_new_label();                           \
2703
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2704
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2705
                        gen_fcond(r_cond, fcc, cond);                   \
2706
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2707
                                           0, l1);                      \
2708
                        tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);     \
2709
                        gen_set_label(l1);                              \
2710
                        tcg_temp_free(r_cond);                          \
2711
                    }
2712
#define FMOVDCC(fcc)                                                    \
2713
                    {                                                   \
2714
                        TCGv r_cond;                                    \
2715
                        int l1;                                         \
2716
                                                                        \
2717
                        l1 = gen_new_label();                           \
2718
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2719
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2720
                        gen_fcond(r_cond, fcc, cond);                   \
2721
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2722
                                           0, l1);                      \
2723
                        tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)],            \
2724
                                        cpu_fpr[DFPREG(rs2)]);          \
2725
                        tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1],        \
2726
                                        cpu_fpr[DFPREG(rs2) + 1]);      \
2727
                        gen_set_label(l1);                              \
2728
                        tcg_temp_free(r_cond);                          \
2729
                    }
2730
#define FMOVQCC(fcc)                                                    \
2731
                    {                                                   \
2732
                        TCGv r_cond;                                    \
2733
                        int l1;                                         \
2734
                                                                        \
2735
                        l1 = gen_new_label();                           \
2736
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2737
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2738
                        gen_fcond(r_cond, fcc, cond);                   \
2739
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2740
                                           0, l1);                      \
2741
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)],            \
2742
                                        cpu_fpr[QFPREG(rs2)]);          \
2743
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1],        \
2744
                                        cpu_fpr[QFPREG(rs2) + 1]);      \
2745
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2],        \
2746
                                        cpu_fpr[QFPREG(rs2) + 2]);      \
2747
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3],        \
2748
                                        cpu_fpr[QFPREG(rs2) + 3]);      \
2749
                        gen_set_label(l1);                              \
2750
                        tcg_temp_free(r_cond);                          \
2751
                    }
2752
                    case 0x001: /* V9 fmovscc %fcc0 */
2753
                        FMOVSCC(0);
2754
                        break;
2755
                    case 0x002: /* V9 fmovdcc %fcc0 */
2756
                        FMOVDCC(0);
2757
                        break;
2758
                    case 0x003: /* V9 fmovqcc %fcc0 */
2759
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2760
                        FMOVQCC(0);
2761
                        break;
2762
                    case 0x041: /* V9 fmovscc %fcc1 */
2763
                        FMOVSCC(1);
2764
                        break;
2765
                    case 0x042: /* V9 fmovdcc %fcc1 */
2766
                        FMOVDCC(1);
2767
                        break;
2768
                    case 0x043: /* V9 fmovqcc %fcc1 */
2769
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2770
                        FMOVQCC(1);
2771
                        break;
2772
                    case 0x081: /* V9 fmovscc %fcc2 */
2773
                        FMOVSCC(2);
2774
                        break;
2775
                    case 0x082: /* V9 fmovdcc %fcc2 */
2776
                        FMOVDCC(2);
2777
                        break;
2778
                    case 0x083: /* V9 fmovqcc %fcc2 */
2779
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2780
                        FMOVQCC(2);
2781
                        break;
2782
                    case 0x0c1: /* V9 fmovscc %fcc3 */
2783
                        FMOVSCC(3);
2784
                        break;
2785
                    case 0x0c2: /* V9 fmovdcc %fcc3 */
2786
                        FMOVDCC(3);
2787
                        break;
2788
                    case 0x0c3: /* V9 fmovqcc %fcc3 */
2789
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2790
                        FMOVQCC(3);
2791
                        break;
2792
#undef FMOVSCC
2793
#undef FMOVDCC
2794
#undef FMOVQCC
2795
#define FMOVCC(size_FDQ, icc)                                           \
2796
                    {                                                   \
2797
                        TCGv r_cond;                                    \
2798
                        int l1;                                         \
2799
                                                                        \
2800
                        l1 = gen_new_label();                           \
2801
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2802
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2803
                        gen_cond(r_cond, icc, cond);                    \
2804
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2805
                                           0, l1);                      \
2806
                        glue(glue(gen_op_load_fpr_, size_FDQ), T0)      \
2807
                            (glue(size_FDQ, FPREG(rs2)));               \
2808
                        glue(glue(gen_op_store_, size_FDQ), T0_fpr)     \
2809
                            (glue(size_FDQ, FPREG(rd)));                \
2810
                        gen_set_label(l1);                              \
2811
                        tcg_temp_free(r_cond);                          \
2812
                    }
2813
#define FMOVSCC(icc)                                                    \
2814
                    {                                                   \
2815
                        TCGv r_cond;                                    \
2816
                        int l1;                                         \
2817
                                                                        \
2818
                        l1 = gen_new_label();                           \
2819
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2820
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2821
                        gen_cond(r_cond, icc, cond);                    \
2822
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2823
                                           0, l1);                      \
2824
                        tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);     \
2825
                        gen_set_label(l1);                              \
2826
                        tcg_temp_free(r_cond);                          \
2827
                    }
2828
#define FMOVDCC(icc)                                                    \
2829
                    {                                                   \
2830
                        TCGv r_cond;                                    \
2831
                        int l1;                                         \
2832
                                                                        \
2833
                        l1 = gen_new_label();                           \
2834
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2835
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2836
                        gen_cond(r_cond, icc, cond);                    \
2837
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2838
                                           0, l1);                      \
2839
                        tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)],            \
2840
                                        cpu_fpr[DFPREG(rs2)]);          \
2841
                        tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1],        \
2842
                                        cpu_fpr[DFPREG(rs2) + 1]);      \
2843
                        gen_set_label(l1);                              \
2844
                        tcg_temp_free(r_cond);                          \
2845
                    }
2846
#define FMOVQCC(icc)                                                    \
2847
                    {                                                   \
2848
                        TCGv r_cond;                                    \
2849
                        int l1;                                         \
2850
                                                                        \
2851
                        l1 = gen_new_label();                           \
2852
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2853
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2854
                        gen_cond(r_cond, icc, cond);                    \
2855
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2856
                                           0, l1);                      \
2857
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)],            \
2858
                                        cpu_fpr[QFPREG(rs2)]);          \
2859
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1],        \
2860
                                        cpu_fpr[QFPREG(rs2) + 1]);      \
2861
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2],        \
2862
                                        cpu_fpr[QFPREG(rs2) + 2]);      \
2863
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3],        \
2864
                                        cpu_fpr[QFPREG(rs2) + 3]);      \
2865
                        gen_set_label(l1);                              \
2866
                        tcg_temp_free(r_cond);                          \
2867
                    }
2868

    
2869
                    case 0x101: /* V9 fmovscc %icc */
2870
                        FMOVSCC(0);
2871
                        break;
2872
                    case 0x102: /* V9 fmovdcc %icc */
2873
                        FMOVDCC(0);
2874
                    case 0x103: /* V9 fmovqcc %icc */
2875
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2876
                        FMOVQCC(0);
2877
                        break;
2878
                    case 0x181: /* V9 fmovscc %xcc */
2879
                        FMOVSCC(1);
2880
                        break;
2881
                    case 0x182: /* V9 fmovdcc %xcc */
2882
                        FMOVDCC(1);
2883
                        break;
2884
                    case 0x183: /* V9 fmovqcc %xcc */
2885
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2886
                        FMOVQCC(1);
2887
                        break;
2888
#undef FMOVSCC
2889
#undef FMOVDCC
2890
#undef FMOVQCC
2891
#endif
2892
                    case 0x51: /* fcmps, V9 %fcc */
2893
                        gen_op_fcmps(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]);
2894
                        break;
2895
                    case 0x52: /* fcmpd, V9 %fcc */
2896
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2897
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2898
                        gen_op_fcmpd(rd & 3);
2899
                        break;
2900
                    case 0x53: /* fcmpq, V9 %fcc */
2901
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2902
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2903
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2904
                        gen_op_fcmpq(rd & 3);
2905
                        break;
2906
                    case 0x55: /* fcmpes, V9 %fcc */
2907
                        gen_op_fcmpes(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]);
2908
                        break;
2909
                    case 0x56: /* fcmped, V9 %fcc */
2910
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2911
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2912
                        gen_op_fcmped(rd & 3);
2913
                        break;
2914
                    case 0x57: /* fcmpeq, V9 %fcc */
2915
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2916
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2917
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2918
                        gen_op_fcmpeq(rd & 3);
2919
                        break;
2920
                    default:
2921
                        goto illegal_insn;
2922
                }
2923
            } else if (xop == 0x2) {
2924
                // clr/mov shortcut
2925

    
2926
                rs1 = GET_FIELD(insn, 13, 17);
2927
                if (rs1 == 0) {
2928
                    // or %g0, x, y -> mov T0, x; mov y, T0
2929
                    if (IS_IMM) {       /* immediate */
2930
                        TCGv r_const;
2931

    
2932
                        rs2 = GET_FIELDs(insn, 19, 31);
2933
                        r_const = tcg_const_tl((int)rs2);
2934
                        gen_movl_TN_reg(rd, r_const);
2935
                        tcg_temp_free(r_const);
2936
                    } else {            /* register */
2937
                        rs2 = GET_FIELD(insn, 27, 31);
2938
                        gen_movl_reg_TN(rs2, cpu_dst);
2939
                        gen_movl_TN_reg(rd, cpu_dst);
2940
                    }
2941
                } else {
2942
                    cpu_src1 = get_src1(insn, cpu_src1);
2943
                    if (IS_IMM) {       /* immediate */
2944
                        rs2 = GET_FIELDs(insn, 19, 31);
2945
                        tcg_gen_ori_tl(cpu_dst, cpu_src1, (int)rs2);
2946
                        gen_movl_TN_reg(rd, cpu_dst);
2947
                    } else {            /* register */
2948
                        // or x, %g0, y -> mov T1, x; mov y, T1
2949
                        rs2 = GET_FIELD(insn, 27, 31);
2950
                        if (rs2 != 0) {
2951
                            gen_movl_reg_TN(rs2, cpu_src2);
2952
                            tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
2953
                            gen_movl_TN_reg(rd, cpu_dst);
2954
                        } else
2955
                            gen_movl_TN_reg(rd, cpu_src1);
2956
                    }
2957
                }
2958
#ifdef TARGET_SPARC64
2959
            } else if (xop == 0x25) { /* sll, V9 sllx */
2960
                cpu_src1 = get_src1(insn, cpu_src1);
2961
                if (IS_IMM) {   /* immediate */
2962
                    rs2 = GET_FIELDs(insn, 20, 31);
2963
                    if (insn & (1 << 12)) {
2964
                        tcg_gen_shli_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
2965
                    } else {
2966
                        tcg_gen_shli_i64(cpu_dst, cpu_src1, rs2 & 0x1f);
2967
                    }
2968
                } else {                /* register */
2969
                    rs2 = GET_FIELD(insn, 27, 31);
2970
                    gen_movl_reg_TN(rs2, cpu_src2);
2971
                    if (insn & (1 << 12)) {
2972
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2973
                    } else {
2974
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2975
                    }
2976
                    tcg_gen_shl_i64(cpu_dst, cpu_src1, cpu_tmp0);
2977
                }
2978
                gen_movl_TN_reg(rd, cpu_dst);
2979
            } else if (xop == 0x26) { /* srl, V9 srlx */
2980
                cpu_src1 = get_src1(insn, cpu_src1);
2981
                if (IS_IMM) {   /* immediate */
2982
                    rs2 = GET_FIELDs(insn, 20, 31);
2983
                    if (insn & (1 << 12)) {
2984
                        tcg_gen_shri_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
2985
                    } else {
2986
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2987
                        tcg_gen_shri_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
2988
                    }
2989
                } else {                /* register */
2990
                    rs2 = GET_FIELD(insn, 27, 31);
2991
                    gen_movl_reg_TN(rs2, cpu_src2);
2992
                    if (insn & (1 << 12)) {
2993
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2994
                        tcg_gen_shr_i64(cpu_dst, cpu_src1, cpu_tmp0);
2995
                    } else {
2996
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2997
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2998
                        tcg_gen_shr_i64(cpu_dst, cpu_dst, cpu_tmp0);
2999
                    }
3000
                }
3001
                gen_movl_TN_reg(rd, cpu_dst);
3002
            } else if (xop == 0x27) { /* sra, V9 srax */
3003
                cpu_src1 = get_src1(insn, cpu_src1);
3004
                if (IS_IMM) {   /* immediate */
3005
                    rs2 = GET_FIELDs(insn, 20, 31);
3006
                    if (insn & (1 << 12)) {
3007
                        tcg_gen_sari_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
3008
                    } else {
3009
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
3010
                        tcg_gen_ext_i32_i64(cpu_dst, cpu_dst);
3011
                        tcg_gen_sari_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
3012
                    }
3013
                } else {                /* register */
3014
                    rs2 = GET_FIELD(insn, 27, 31);
3015
                    gen_movl_reg_TN(rs2, cpu_src2);
3016
                    if (insn & (1 << 12)) {
3017
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
3018
                        tcg_gen_sar_i64(cpu_dst, cpu_src1, cpu_tmp0);
3019
                    } else {
3020
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
3021
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
3022
                        tcg_gen_ext_i32_i64(cpu_dst, cpu_dst);
3023
                        tcg_gen_sar_i64(cpu_dst, cpu_dst, cpu_tmp0);
3024
                    }
3025
                }
3026
                gen_movl_TN_reg(rd, cpu_dst);
3027
#endif
3028
            } else if (xop < 0x36) {
3029
                cpu_src1 = get_src1(insn, cpu_src1);
3030
                cpu_src2 = get_src2(insn, cpu_src2);
3031
                if (xop < 0x20) {
3032
                    switch (xop & ~0x10) {
3033
                    case 0x0:
3034
                        if (xop & 0x10)
3035
                            gen_op_add_cc(cpu_dst, cpu_src1, cpu_src2);
3036
                        else
3037
                            tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
3038
                        break;
3039
                    case 0x1:
3040
                        tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_src2);
3041
                        if (xop & 0x10)
3042
                            gen_op_logic_cc(cpu_dst);
3043
                        break;
3044
                    case 0x2:
3045
                        tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
3046
                        if (xop & 0x10)
3047
                            gen_op_logic_cc(cpu_dst);
3048
                        break;
3049
                    case 0x3:
3050
                        tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3051
                        if (xop & 0x10)
3052
                            gen_op_logic_cc(cpu_dst);
3053
                        break;
3054
                    case 0x4:
3055
                        if (xop & 0x10)
3056
                            gen_op_sub_cc(cpu_dst, cpu_src1, cpu_src2);
3057
                        else
3058
                            tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_src2);
3059
                        break;
3060
                    case 0x5:
3061
                        tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
3062
                        tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_tmp0);
3063
                        if (xop & 0x10)
3064
                            gen_op_logic_cc(cpu_dst);
3065
                        break;
3066
                    case 0x6:
3067
                        tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
3068
                        tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_tmp0);
3069
                        if (xop & 0x10)
3070
                            gen_op_logic_cc(cpu_dst);
3071
                        break;
3072
                    case 0x7:
3073
                        tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
3074
                        tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_tmp0);
3075
                        if (xop & 0x10)
3076
                            gen_op_logic_cc(cpu_dst);
3077
                        break;
3078
                    case 0x8:
3079
                        if (xop & 0x10)
3080
                            gen_op_addx_cc(cpu_dst, cpu_src1, cpu_src2);
3081
                        else {
3082
                            gen_mov_reg_C(cpu_tmp0, cpu_psr);
3083
                            tcg_gen_add_tl(cpu_tmp0, cpu_src2, cpu_tmp0);
3084
                            tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_tmp0);
3085
                        }
3086
                        break;
3087
#ifdef TARGET_SPARC64
3088
                    case 0x9: /* V9 mulx */
3089
                        tcg_gen_mul_i64(cpu_dst, cpu_src1, cpu_src2);
3090
                        break;
3091
#endif
3092
                    case 0xa:
3093
                        CHECK_IU_FEATURE(dc, MUL);
3094
                        gen_op_umul(cpu_dst, cpu_src1, cpu_src2);
3095
                        if (xop & 0x10)
3096
                            gen_op_logic_cc(cpu_dst);
3097
                        break;
3098
                    case 0xb:
3099
                        CHECK_IU_FEATURE(dc, MUL);
3100
                        gen_op_smul(cpu_dst, cpu_src1, cpu_src2);
3101
                        if (xop & 0x10)
3102
                            gen_op_logic_cc(cpu_dst);
3103
                        break;
3104
                    case 0xc:
3105
                        if (xop & 0x10)
3106
                            gen_op_subx_cc(cpu_dst, cpu_src1, cpu_src2);
3107
                        else {
3108
                            gen_mov_reg_C(cpu_tmp0, cpu_psr);
3109
                            tcg_gen_add_tl(cpu_tmp0, cpu_src2, cpu_tmp0);
3110
                            tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_tmp0);
3111
                        }
3112
                        break;
3113
#ifdef TARGET_SPARC64
3114
                    case 0xd: /* V9 udivx */
3115
                        tcg_gen_mov_tl(cpu_cc_src, cpu_src1);
3116
                        tcg_gen_mov_tl(cpu_cc_src2, cpu_src2);
3117
                        gen_trap_ifdivzero_tl(cpu_cc_src2);
3118
                        tcg_gen_divu_i64(cpu_dst, cpu_cc_src, cpu_cc_src2);
3119
                        break;
3120
#endif
3121
                    case 0xe:
3122
                        CHECK_IU_FEATURE(dc, DIV);
3123
                        tcg_gen_helper_1_2(helper_udiv, cpu_dst, cpu_src1,
3124
                                           cpu_src2);
3125
                        if (xop & 0x10)
3126
                            gen_op_div_cc(cpu_dst);
3127
                        break;
3128
                    case 0xf:
3129
                        CHECK_IU_FEATURE(dc, DIV);
3130
                        tcg_gen_helper_1_2(helper_sdiv, cpu_dst, cpu_src1,
3131
                                           cpu_src2);
3132
                        if (xop & 0x10)
3133
                            gen_op_div_cc(cpu_dst);
3134
                        break;
3135
                    default:
3136
                        goto illegal_insn;
3137
                    }
3138
                    gen_movl_TN_reg(rd, cpu_dst);
3139
                } else {
3140
                    switch (xop) {
3141
                    case 0x20: /* taddcc */
3142
                        gen_op_tadd_cc(cpu_dst, cpu_src1, cpu_src2);
3143
                        gen_movl_TN_reg(rd, cpu_dst);
3144
                        break;
3145
                    case 0x21: /* tsubcc */
3146
                        gen_op_tsub_cc(cpu_dst, cpu_src1, cpu_src2);
3147
                        gen_movl_TN_reg(rd, cpu_dst);
3148
                        break;
3149
                    case 0x22: /* taddcctv */
3150
                        save_state(dc, cpu_cond);
3151
                        gen_op_tadd_ccTV(cpu_dst, cpu_src1, cpu_src2);
3152
                        gen_movl_TN_reg(rd, cpu_dst);
3153
                        break;
3154
                    case 0x23: /* tsubcctv */
3155
                        save_state(dc, cpu_cond);
3156
                        gen_op_tsub_ccTV(cpu_dst, cpu_src1, cpu_src2);
3157
                        gen_movl_TN_reg(rd, cpu_dst);
3158
                        break;
3159
                    case 0x24: /* mulscc */
3160
                        gen_op_mulscc(cpu_dst, cpu_src1, cpu_src2);
3161
                        gen_movl_TN_reg(rd, cpu_dst);
3162
                        break;
3163
#ifndef TARGET_SPARC64
3164
                    case 0x25:  /* sll */
3165
                        if (IS_IMM) { /* immediate */
3166
                            rs2 = GET_FIELDs(insn, 20, 31);
3167
                            tcg_gen_shli_tl(cpu_dst, cpu_src1, rs2 & 0x1f);
3168
                        } else { /* register */
3169
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3170
                            tcg_gen_shl_tl(cpu_dst, cpu_src1, cpu_tmp0);
3171
                        }
3172
                        gen_movl_TN_reg(rd, cpu_dst);
3173
                        break;
3174
                    case 0x26:  /* srl */
3175
                        if (IS_IMM) { /* immediate */
3176
                            rs2 = GET_FIELDs(insn, 20, 31);
3177
                            tcg_gen_shri_tl(cpu_dst, cpu_src1, rs2 & 0x1f);
3178
                        } else { /* register */
3179
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3180
                            tcg_gen_shr_tl(cpu_dst, cpu_src1, cpu_tmp0);
3181
                        }
3182
                        gen_movl_TN_reg(rd, cpu_dst);
3183
                        break;
3184
                    case 0x27:  /* sra */
3185
                        if (IS_IMM) { /* immediate */
3186
                            rs2 = GET_FIELDs(insn, 20, 31);
3187
                            tcg_gen_sari_tl(cpu_dst, cpu_src1, rs2 & 0x1f);
3188
                        } else { /* register */
3189
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3190
                            tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0);
3191
                        }
3192
                        gen_movl_TN_reg(rd, cpu_dst);
3193
                        break;
3194
#endif
3195
                    case 0x30:
3196
                        {
3197
                            switch(rd) {
3198
                            case 0: /* wry */
3199
                                tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
3200
                                tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
3201
                                break;
3202
#ifndef TARGET_SPARC64
3203
                            case 0x01 ... 0x0f: /* undefined in the
3204
                                                   SPARCv8 manual, nop
3205
                                                   on the microSPARC
3206
                                                   II */
3207
                            case 0x10 ... 0x1f: /* implementation-dependent
3208
                                                   in the SPARCv8
3209
                                                   manual, nop on the
3210
                                                   microSPARC II */
3211
                                break;
3212
#else
3213
                            case 0x2: /* V9 wrccr */
3214
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3215
                                tcg_gen_helper_0_1(helper_wrccr, cpu_dst);
3216
                                break;
3217
                            case 0x3: /* V9 wrasi */
3218
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3219
                                tcg_gen_trunc_tl_i32(cpu_asi, cpu_dst);
3220
                                break;
3221
                            case 0x6: /* V9 wrfprs */
3222
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3223
                                tcg_gen_trunc_tl_i32(cpu_fprs, cpu_dst);
3224
                                save_state(dc, cpu_cond);
3225
                                gen_op_next_insn();
3226
                                tcg_gen_exit_tb(0);
3227
                                dc->is_br = 1;
3228
                                break;
3229
                            case 0xf: /* V9 sir, nop if user */
3230
#if !defined(CONFIG_USER_ONLY)
3231
                                if (supervisor(dc))
3232
                                    ; // XXX
3233
#endif
3234
                                break;
3235
                            case 0x13: /* Graphics Status */
3236
                                if (gen_trap_ifnofpu(dc, cpu_cond))
3237
                                    goto jmp_insn;
3238
                                tcg_gen_xor_tl(cpu_gsr, cpu_src1, cpu_src2);
3239
                                break;
3240
                            case 0x17: /* Tick compare */
3241
#if !defined(CONFIG_USER_ONLY)
3242
                                if (!supervisor(dc))
3243
                                    goto illegal_insn;
3244
#endif
3245
                                {
3246
                                    TCGv r_tickptr;
3247

    
3248
                                    tcg_gen_xor_tl(cpu_tick_cmpr, cpu_src1,
3249
                                                   cpu_src2);
3250
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3251
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3252
                                                   offsetof(CPUState, tick));
3253
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3254
                                                       r_tickptr, cpu_tick_cmpr);
3255
                                    tcg_temp_free(r_tickptr);
3256
                                }
3257
                                break;
3258
                            case 0x18: /* System tick */
3259
#if !defined(CONFIG_USER_ONLY)
3260
                                if (!supervisor(dc))
3261
                                    goto illegal_insn;
3262
#endif
3263
                                {
3264
                                    TCGv r_tickptr;
3265

    
3266
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
3267
                                                   cpu_src2);
3268
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3269
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3270
                                                   offsetof(CPUState, stick));
3271
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3272
                                                       r_tickptr, cpu_dst);
3273
                                    tcg_temp_free(r_tickptr);
3274
                                }
3275
                                break;
3276
                            case 0x19: /* System tick compare */
3277
#if !defined(CONFIG_USER_ONLY)
3278
                                if (!supervisor(dc))
3279
                                    goto illegal_insn;
3280
#endif
3281
                                {
3282
                                    TCGv r_tickptr;
3283

    
3284
                                    tcg_gen_xor_tl(cpu_stick_cmpr, cpu_src1,
3285
                                                   cpu_src2);
3286
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3287
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3288
                                                   offsetof(CPUState, stick));
3289
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3290
                                                       r_tickptr, cpu_stick_cmpr);
3291
                                    tcg_temp_free(r_tickptr);
3292
                                }
3293
                                break;
3294

    
3295
                            case 0x10: /* Performance Control */
3296
                            case 0x11: /* Performance Instrumentation
3297
                                          Counter */
3298
                            case 0x12: /* Dispatch Control */
3299
                            case 0x14: /* Softint set */
3300
                            case 0x15: /* Softint clear */
3301
                            case 0x16: /* Softint write */
3302
#endif
3303
                            default:
3304
                                goto illegal_insn;
3305
                            }
3306
                        }
3307
                        break;
3308
#if !defined(CONFIG_USER_ONLY)
3309
                    case 0x31: /* wrpsr, V9 saved, restored */
3310
                        {
3311
                            if (!supervisor(dc))
3312
                                goto priv_insn;
3313
#ifdef TARGET_SPARC64
3314
                            switch (rd) {
3315
                            case 0:
3316
                                tcg_gen_helper_0_0(helper_saved);
3317
                                break;
3318
                            case 1:
3319
                                tcg_gen_helper_0_0(helper_restored);
3320
                                break;
3321
                            case 2: /* UA2005 allclean */
3322
                            case 3: /* UA2005 otherw */
3323
                            case 4: /* UA2005 normalw */
3324
                            case 5: /* UA2005 invalw */
3325
                                // XXX
3326
                            default:
3327
                                goto illegal_insn;
3328
                            }
3329
#else
3330
                            tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3331
                            tcg_gen_helper_0_1(helper_wrpsr, cpu_dst);
3332
                            save_state(dc, cpu_cond);
3333
                            gen_op_next_insn();
3334
                            tcg_gen_exit_tb(0);
3335
                            dc->is_br = 1;
3336
#endif
3337
                        }
3338
                        break;
3339
                    case 0x32: /* wrwim, V9 wrpr */
3340
                        {
3341
                            if (!supervisor(dc))
3342
                                goto priv_insn;
3343
                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
3344
#ifdef TARGET_SPARC64
3345
                            switch (rd) {
3346
                            case 0: // tpc
3347
                                {
3348
                                    TCGv r_tsptr;
3349

    
3350
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3351
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3352
                                                   offsetof(CPUState, tsptr));
3353
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3354
                                                  offsetof(trap_state, tpc));
3355
                                    tcg_temp_free(r_tsptr);
3356
                                }
3357
                                break;
3358
                            case 1: // tnpc
3359
                                {
3360
                                    TCGv r_tsptr;
3361

    
3362
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3363
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3364
                                                   offsetof(CPUState, tsptr));
3365
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3366
                                                  offsetof(trap_state, tnpc));
3367
                                    tcg_temp_free(r_tsptr);
3368
                                }
3369
                                break;
3370
                            case 2: // tstate
3371
                                {
3372
                                    TCGv r_tsptr;
3373

    
3374
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3375
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3376
                                                   offsetof(CPUState, tsptr));
3377
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3378
                                                  offsetof(trap_state,
3379
                                                           tstate));
3380
                                    tcg_temp_free(r_tsptr);
3381
                                }
3382
                                break;
3383
                            case 3: // tt
3384
                                {
3385
                                    TCGv r_tsptr;
3386

    
3387
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3388
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3389
                                                   offsetof(CPUState, tsptr));
3390
                                    tcg_gen_st_i32(cpu_tmp0, r_tsptr,
3391
                                                   offsetof(trap_state, tt));
3392
                                    tcg_temp_free(r_tsptr);
3393
                                }
3394
                                break;
3395
                            case 4: // tick
3396
                                {
3397
                                    TCGv r_tickptr;
3398

    
3399
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3400
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3401
                                                   offsetof(CPUState, tick));
3402
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3403
                                                       r_tickptr, cpu_tmp0);
3404
                                    tcg_temp_free(r_tickptr);
3405
                                }
3406
                                break;
3407
                            case 5: // tba
3408
                                tcg_gen_mov_tl(cpu_tbr, cpu_tmp0);
3409
                                break;
3410
                            case 6: // pstate
3411
                                save_state(dc, cpu_cond);
3412
                                tcg_gen_helper_0_1(helper_wrpstate, cpu_tmp0);
3413
                                gen_op_next_insn();
3414
                                tcg_gen_exit_tb(0);
3415
                                dc->is_br = 1;
3416
                                break;
3417
                            case 7: // tl
3418
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3419
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3420
                                               offsetof(CPUSPARCState, tl));
3421
                                break;
3422
                            case 8: // pil
3423
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3424
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3425
                                               offsetof(CPUSPARCState,
3426
                                                        psrpil));
3427
                                break;
3428
                            case 9: // cwp
3429
                                tcg_gen_helper_0_1(helper_wrcwp, cpu_tmp0);
3430
                                break;
3431
                            case 10: // cansave
3432
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3433
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3434
                                               offsetof(CPUSPARCState,
3435
                                                        cansave));
3436
                                break;
3437
                            case 11: // canrestore
3438
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3439
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3440
                                               offsetof(CPUSPARCState,
3441
                                                        canrestore));
3442
                                break;
3443
                            case 12: // cleanwin
3444
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3445
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3446
                                               offsetof(CPUSPARCState,
3447
                                                        cleanwin));
3448
                                break;
3449
                            case 13: // otherwin
3450
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3451
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3452
                                               offsetof(CPUSPARCState,
3453
                                                        otherwin));
3454
                                break;
3455
                            case 14: // wstate
3456
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3457
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3458
                                               offsetof(CPUSPARCState,
3459
                                                        wstate));
3460
                                break;
3461
                            case 16: // UA2005 gl
3462
                                CHECK_IU_FEATURE(dc, GL);
3463
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3464
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3465
                                               offsetof(CPUSPARCState, gl));
3466
                                break;
3467
                            case 26: // UA2005 strand status
3468
                                CHECK_IU_FEATURE(dc, HYPV);
3469
                                if (!hypervisor(dc))
3470
                                    goto priv_insn;
3471
                                tcg_gen_trunc_tl_i32(cpu_ssr, cpu_tmp0);
3472
                                break;
3473
                            default:
3474
                                goto illegal_insn;
3475
                            }
3476
#else
3477
                            tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3478
                            if (dc->def->nwindows != 32)
3479
                                tcg_gen_andi_tl(cpu_tmp32, cpu_tmp32,
3480
                                                (1 << dc->def->nwindows) - 1);
3481
                            tcg_gen_mov_i32(cpu_wim, cpu_tmp32);
3482
#endif
3483
                        }
3484
                        break;
3485
                    case 0x33: /* wrtbr, UA2005 wrhpr */
3486
                        {
3487
#ifndef TARGET_SPARC64
3488
                            if (!supervisor(dc))
3489
                                goto priv_insn;
3490
                            tcg_gen_xor_tl(cpu_tbr, cpu_src1, cpu_src2);
3491
#else
3492
                            CHECK_IU_FEATURE(dc, HYPV);
3493
                            if (!hypervisor(dc))
3494
                                goto priv_insn;
3495
                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
3496
                            switch (rd) {
3497
                            case 0: // hpstate
3498
                                // XXX gen_op_wrhpstate();
3499
                                save_state(dc, cpu_cond);
3500
                                gen_op_next_insn();
3501
                                tcg_gen_exit_tb(0);
3502
                                dc->is_br = 1;
3503
                                break;
3504
                            case 1: // htstate
3505
                                // XXX gen_op_wrhtstate();
3506
                                break;
3507
                            case 3: // hintp
3508
                                tcg_gen_mov_tl(cpu_hintp, cpu_tmp0);
3509
                                break;
3510
                            case 5: // htba
3511
                                tcg_gen_mov_tl(cpu_htba, cpu_tmp0);
3512
                                break;
3513
                            case 31: // hstick_cmpr
3514
                                {
3515
                                    TCGv r_tickptr;
3516

    
3517
                                    tcg_gen_mov_tl(cpu_hstick_cmpr, cpu_tmp0);
3518
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3519
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3520
                                                   offsetof(CPUState, hstick));
3521
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3522
                                                       r_tickptr, cpu_hstick_cmpr);
3523
                                    tcg_temp_free(r_tickptr);
3524
                                }
3525
                                break;
3526
                            case 6: // hver readonly
3527
                            default:
3528
                                goto illegal_insn;
3529
                            }
3530
#endif
3531
                        }
3532
                        break;
3533
#endif
3534
#ifdef TARGET_SPARC64
3535
                    case 0x2c: /* V9 movcc */
3536
                        {
3537
                            int cc = GET_FIELD_SP(insn, 11, 12);
3538
                            int cond = GET_FIELD_SP(insn, 14, 17);
3539
                            TCGv r_cond;
3540
                            int l1;
3541

    
3542
                            r_cond = tcg_temp_new(TCG_TYPE_TL);
3543
                            if (insn & (1 << 18)) {
3544
                                if (cc == 0)
3545
                                    gen_cond(r_cond, 0, cond);
3546
                                else if (cc == 2)
3547
                                    gen_cond(r_cond, 1, cond);
3548
                                else
3549
                                    goto illegal_insn;
3550
                            } else {
3551
                                gen_fcond(r_cond, cc, cond);
3552
                            }
3553

    
3554
                            l1 = gen_new_label();
3555

    
3556
                            tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
3557
                            if (IS_IMM) {       /* immediate */
3558
                                TCGv r_const;
3559

    
3560
                                rs2 = GET_FIELD_SPs(insn, 0, 10);
3561
                                r_const = tcg_const_tl((int)rs2);
3562
                                gen_movl_TN_reg(rd, r_const);
3563
                                tcg_temp_free(r_const);
3564
                            } else {
3565
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3566
                                gen_movl_reg_TN(rs2, cpu_tmp0);
3567
                                gen_movl_TN_reg(rd, cpu_tmp0);
3568
                            }
3569
                            gen_set_label(l1);
3570
                            tcg_temp_free(r_cond);
3571
                            break;
3572
                        }
3573
                    case 0x2d: /* V9 sdivx */
3574
                        gen_op_sdivx(cpu_dst, cpu_src1, cpu_src2);
3575
                        gen_movl_TN_reg(rd, cpu_dst);
3576
                        break;
3577
                    case 0x2e: /* V9 popc */
3578
                        {
3579
                            cpu_src2 = get_src2(insn, cpu_src2);
3580
                            tcg_gen_helper_1_1(helper_popc, cpu_dst,
3581
                                               cpu_src2);
3582
                            gen_movl_TN_reg(rd, cpu_dst);
3583
                        }
3584
                    case 0x2f: /* V9 movr */
3585
                        {
3586
                            int cond = GET_FIELD_SP(insn, 10, 12);
3587
                            int l1;
3588

    
3589
                            cpu_src1 = get_src1(insn, cpu_src1);
3590

    
3591
                            l1 = gen_new_label();
3592

    
3593
                            tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond],
3594
                                              cpu_src1, 0, l1);
3595
                            if (IS_IMM) {       /* immediate */
3596
                                TCGv r_const;
3597

    
3598
                                rs2 = GET_FIELD_SPs(insn, 0, 9);
3599
                                r_const = tcg_const_tl((int)rs2);
3600
                                gen_movl_TN_reg(rd, r_const);
3601
                                tcg_temp_free(r_const);
3602
                            } else {
3603
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3604
                                gen_movl_reg_TN(rs2, cpu_tmp0);
3605
                                gen_movl_TN_reg(rd, cpu_tmp0);
3606
                            }
3607
                            gen_set_label(l1);
3608
                            break;
3609
                        }
3610
#endif
3611
                    default:
3612
                        goto illegal_insn;
3613
                    }
3614
                }
3615
            } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
3616
#ifdef TARGET_SPARC64
3617
                int opf = GET_FIELD_SP(insn, 5, 13);
3618
                rs1 = GET_FIELD(insn, 13, 17);
3619
                rs2 = GET_FIELD(insn, 27, 31);
3620
                if (gen_trap_ifnofpu(dc, cpu_cond))
3621
                    goto jmp_insn;
3622

    
3623
                switch (opf) {
3624
                case 0x000: /* VIS I edge8cc */
3625
                case 0x001: /* VIS II edge8n */
3626
                case 0x002: /* VIS I edge8lcc */
3627
                case 0x003: /* VIS II edge8ln */
3628
                case 0x004: /* VIS I edge16cc */
3629
                case 0x005: /* VIS II edge16n */
3630
                case 0x006: /* VIS I edge16lcc */
3631
                case 0x007: /* VIS II edge16ln */
3632
                case 0x008: /* VIS I edge32cc */
3633
                case 0x009: /* VIS II edge32n */
3634
                case 0x00a: /* VIS I edge32lcc */
3635
                case 0x00b: /* VIS II edge32ln */
3636
                    // XXX
3637
                    goto illegal_insn;
3638
                case 0x010: /* VIS I array8 */
3639
                    CHECK_FPU_FEATURE(dc, VIS1);
3640
                    cpu_src1 = get_src1(insn, cpu_src1);
3641
                    gen_movl_reg_TN(rs2, cpu_src2);
3642
                    tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
3643
                                       cpu_src2);
3644
                    gen_movl_TN_reg(rd, cpu_dst);
3645
                    break;
3646
                case 0x012: /* VIS I array16 */
3647
                    CHECK_FPU_FEATURE(dc, VIS1);
3648
                    cpu_src1 = get_src1(insn, cpu_src1);
3649
                    gen_movl_reg_TN(rs2, cpu_src2);
3650
                    tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
3651
                                       cpu_src2);
3652
                    tcg_gen_shli_i64(cpu_dst, cpu_dst, 1);
3653
                    gen_movl_TN_reg(rd, cpu_dst);
3654
                    break;
3655
                case 0x014: /* VIS I array32 */
3656
                    CHECK_FPU_FEATURE(dc, VIS1);
3657
                    cpu_src1 = get_src1(insn, cpu_src1);
3658
                    gen_movl_reg_TN(rs2, cpu_src2);
3659
                    tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
3660
                                       cpu_src2);
3661
                    tcg_gen_shli_i64(cpu_dst, cpu_dst, 2);
3662
                    gen_movl_TN_reg(rd, cpu_dst);
3663
                    break;
3664
                case 0x018: /* VIS I alignaddr */
3665
                    CHECK_FPU_FEATURE(dc, VIS1);
3666
                    cpu_src1 = get_src1(insn, cpu_src1);
3667
                    gen_movl_reg_TN(rs2, cpu_src2);
3668
                    tcg_gen_helper_1_2(helper_alignaddr, cpu_dst, cpu_src1,
3669
                                       cpu_src2);
3670
                    gen_movl_TN_reg(rd, cpu_dst);
3671
                    break;
3672
                case 0x019: /* VIS II bmask */
3673
                case 0x01a: /* VIS I alignaddrl */
3674
                    // XXX
3675
                    goto illegal_insn;
3676
                case 0x020: /* VIS I fcmple16 */
3677
                    CHECK_FPU_FEATURE(dc, VIS1);
3678
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3679
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3680
                    tcg_gen_helper_0_0(helper_fcmple16);
3681
                    gen_op_store_DT0_fpr(DFPREG(rd));
3682
                    break;
3683
                case 0x022: /* VIS I fcmpne16 */
3684
                    CHECK_FPU_FEATURE(dc, VIS1);
3685
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3686
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3687
                    tcg_gen_helper_0_0(helper_fcmpne16);
3688
                    gen_op_store_DT0_fpr(DFPREG(rd));
3689
                    break;
3690
                case 0x024: /* VIS I fcmple32 */
3691
                    CHECK_FPU_FEATURE(dc, VIS1);
3692
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3693
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3694
                    tcg_gen_helper_0_0(helper_fcmple32);
3695
                    gen_op_store_DT0_fpr(DFPREG(rd));
3696
                    break;
3697
                case 0x026: /* VIS I fcmpne32 */
3698
                    CHECK_FPU_FEATURE(dc, VIS1);
3699
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3700
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3701
                    tcg_gen_helper_0_0(helper_fcmpne32);
3702
                    gen_op_store_DT0_fpr(DFPREG(rd));
3703
                    break;
3704
                case 0x028: /* VIS I fcmpgt16 */
3705
                    CHECK_FPU_FEATURE(dc, VIS1);
3706
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3707
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3708
                    tcg_gen_helper_0_0(helper_fcmpgt16);
3709
                    gen_op_store_DT0_fpr(DFPREG(rd));
3710
                    break;
3711
                case 0x02a: /* VIS I fcmpeq16 */
3712
                    CHECK_FPU_FEATURE(dc, VIS1);
3713
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3714
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3715
                    tcg_gen_helper_0_0(helper_fcmpeq16);
3716
                    gen_op_store_DT0_fpr(DFPREG(rd));
3717
                    break;
3718
                case 0x02c: /* VIS I fcmpgt32 */
3719
                    CHECK_FPU_FEATURE(dc, VIS1);
3720
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3721
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3722
                    tcg_gen_helper_0_0(helper_fcmpgt32);
3723
                    gen_op_store_DT0_fpr(DFPREG(rd));
3724
                    break;
3725
                case 0x02e: /* VIS I fcmpeq32 */
3726
                    CHECK_FPU_FEATURE(dc, VIS1);
3727
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3728
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3729
                    tcg_gen_helper_0_0(helper_fcmpeq32);
3730
                    gen_op_store_DT0_fpr(DFPREG(rd));
3731
                    break;
3732
                case 0x031: /* VIS I fmul8x16 */
3733
                    CHECK_FPU_FEATURE(dc, VIS1);
3734
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3735
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3736
                    tcg_gen_helper_0_0(helper_fmul8x16);
3737
                    gen_op_store_DT0_fpr(DFPREG(rd));
3738
                    break;
3739
                case 0x033: /* VIS I fmul8x16au */
3740
                    CHECK_FPU_FEATURE(dc, VIS1);
3741
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3742
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3743
                    tcg_gen_helper_0_0(helper_fmul8x16au);
3744
                    gen_op_store_DT0_fpr(DFPREG(rd));
3745
                    break;
3746
                case 0x035: /* VIS I fmul8x16al */
3747
                    CHECK_FPU_FEATURE(dc, VIS1);
3748
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3749
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3750
                    tcg_gen_helper_0_0(helper_fmul8x16al);
3751
                    gen_op_store_DT0_fpr(DFPREG(rd));
3752
                    break;
3753
                case 0x036: /* VIS I fmul8sux16 */
3754
                    CHECK_FPU_FEATURE(dc, VIS1);
3755
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3756
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3757
                    tcg_gen_helper_0_0(helper_fmul8sux16);
3758
                    gen_op_store_DT0_fpr(DFPREG(rd));
3759
                    break;
3760
                case 0x037: /* VIS I fmul8ulx16 */
3761
                    CHECK_FPU_FEATURE(dc, VIS1);
3762
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3763
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3764
                    tcg_gen_helper_0_0(helper_fmul8ulx16);
3765
                    gen_op_store_DT0_fpr(DFPREG(rd));
3766
                    break;
3767
                case 0x038: /* VIS I fmuld8sux16 */
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_fmuld8sux16);
3772
                    gen_op_store_DT0_fpr(DFPREG(rd));
3773
                    break;
3774
                case 0x039: /* VIS I fmuld8ulx16 */
3775
                    CHECK_FPU_FEATURE(dc, VIS1);
3776
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3777
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3778
                    tcg_gen_helper_0_0(helper_fmuld8ulx16);
3779
                    gen_op_store_DT0_fpr(DFPREG(rd));
3780
                    break;
3781
                case 0x03a: /* VIS I fpack32 */
3782
                case 0x03b: /* VIS I fpack16 */
3783
                case 0x03d: /* VIS I fpackfix */
3784
                case 0x03e: /* VIS I pdist */
3785
                    // XXX
3786
                    goto illegal_insn;
3787
                case 0x048: /* VIS I faligndata */
3788
                    CHECK_FPU_FEATURE(dc, VIS1);
3789
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3790
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3791
                    tcg_gen_helper_0_0(helper_faligndata);
3792
                    gen_op_store_DT0_fpr(DFPREG(rd));
3793
                    break;
3794
                case 0x04b: /* VIS I fpmerge */
3795
                    CHECK_FPU_FEATURE(dc, VIS1);
3796
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3797
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3798
                    tcg_gen_helper_0_0(helper_fpmerge);
3799
                    gen_op_store_DT0_fpr(DFPREG(rd));
3800
                    break;
3801
                case 0x04c: /* VIS II bshuffle */
3802
                    // XXX
3803
                    goto illegal_insn;
3804
                case 0x04d: /* VIS I fexpand */
3805
                    CHECK_FPU_FEATURE(dc, VIS1);
3806
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3807
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3808
                    tcg_gen_helper_0_0(helper_fexpand);
3809
                    gen_op_store_DT0_fpr(DFPREG(rd));
3810
                    break;
3811
                case 0x050: /* VIS I fpadd16 */
3812
                    CHECK_FPU_FEATURE(dc, VIS1);
3813
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3814
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3815
                    tcg_gen_helper_0_0(helper_fpadd16);
3816
                    gen_op_store_DT0_fpr(DFPREG(rd));
3817
                    break;
3818
                case 0x051: /* VIS I fpadd16s */
3819
                    CHECK_FPU_FEATURE(dc, VIS1);
3820
                    tcg_gen_helper_1_2(helper_fpadd16s, cpu_fpr[rd],
3821
                                       cpu_fpr[rs1], cpu_fpr[rs2]);
3822
                    break;
3823
                case 0x052: /* VIS I fpadd32 */
3824
                    CHECK_FPU_FEATURE(dc, VIS1);
3825
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3826
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3827
                    tcg_gen_helper_0_0(helper_fpadd32);
3828
                    gen_op_store_DT0_fpr(DFPREG(rd));
3829
                    break;
3830
                case 0x053: /* VIS I fpadd32s */
3831
                    CHECK_FPU_FEATURE(dc, VIS1);
3832
                    tcg_gen_helper_1_2(helper_fpadd32s, cpu_fpr[rd],
3833
                                       cpu_fpr[rs1], cpu_fpr[rs2]);
3834
                    break;
3835
                case 0x054: /* VIS I fpsub16 */
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_fpsub16);
3840
                    gen_op_store_DT0_fpr(DFPREG(rd));
3841
                    break;
3842
                case 0x055: /* VIS I fpsub16s */
3843
                    CHECK_FPU_FEATURE(dc, VIS1);
3844
                    tcg_gen_helper_1_2(helper_fpsub16s, cpu_fpr[rd],
3845
                                       cpu_fpr[rs1], cpu_fpr[rs2]);
3846
                    break;
3847
                case 0x056: /* VIS I fpsub32 */
3848
                    CHECK_FPU_FEATURE(dc, VIS1);
3849
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3850
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3851
                    tcg_gen_helper_0_0(helper_fpsub32);
3852
                    gen_op_store_DT0_fpr(DFPREG(rd));
3853
                    break;
3854
                case 0x057: /* VIS I fpsub32s */
3855
                    CHECK_FPU_FEATURE(dc, VIS1);
3856
                    tcg_gen_helper_1_2(helper_fpsub32s, cpu_fpr[rd],
3857
                                       cpu_fpr[rs1], cpu_fpr[rs2]);
3858
                    break;
3859
                case 0x060: /* VIS I fzero */
3860
                    CHECK_FPU_FEATURE(dc, VIS1);
3861
                    tcg_gen_movi_i32(cpu_fpr[DFPREG(rd)], 0);
3862
                    tcg_gen_movi_i32(cpu_fpr[DFPREG(rd) + 1], 0);
3863
                    break;
3864
                case 0x061: /* VIS I fzeros */
3865
                    CHECK_FPU_FEATURE(dc, VIS1);
3866
                    tcg_gen_movi_i32(cpu_fpr[rd], 0);
3867
                    break;
3868
                case 0x062: /* VIS I fnor */
3869
                    CHECK_FPU_FEATURE(dc, VIS1);
3870
                    tcg_gen_or_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1)],
3871
                                   cpu_fpr[DFPREG(rs2)]);
3872
                    tcg_gen_xori_i32(cpu_fpr[DFPREG(rd)], cpu_tmp32, -1);
3873
                    tcg_gen_or_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1) + 1],
3874
                                   cpu_fpr[DFPREG(rs2) + 1]);
3875
                    tcg_gen_xori_i32(cpu_fpr[DFPREG(rd) + 1], cpu_tmp32, -1);
3876
                    break;
3877
                case 0x063: /* VIS I fnors */
3878
                    CHECK_FPU_FEATURE(dc, VIS1);
3879
                    tcg_gen_or_i32(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
3880
                    tcg_gen_xori_i32(cpu_fpr[rd], cpu_tmp32, -1);
3881
                    break;
3882
                case 0x064: /* VIS I fandnot2 */
3883
                    CHECK_FPU_FEATURE(dc, VIS1);
3884
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1)], -1);
3885
                    tcg_gen_and_i32(cpu_fpr[DFPREG(rd)], cpu_tmp32,
3886
                                    cpu_fpr[DFPREG(rs2)]);
3887
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1) + 1], -1);
3888
                    tcg_gen_and_i32(cpu_fpr[DFPREG(rd) + 1], cpu_tmp32,
3889
                                    cpu_fpr[DFPREG(rs2) + 1]);
3890
                    break;
3891
                case 0x065: /* VIS I fandnot2s */
3892
                    CHECK_FPU_FEATURE(dc, VIS1);
3893
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[rs1], -1);
3894
                    tcg_gen_and_i32(cpu_fpr[rd], cpu_tmp32, cpu_fpr[rs2]);
3895
                    break;
3896
                case 0x066: /* VIS I fnot2 */
3897
                    CHECK_FPU_FEATURE(dc, VIS1);
3898
                    tcg_gen_xori_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)],
3899
                                     -1);
3900
                    tcg_gen_xori_i32(cpu_fpr[DFPREG(rd) + 1],
3901
                                     cpu_fpr[DFPREG(rs2) + 1], -1);
3902
                    break;
3903
                case 0x067: /* VIS I fnot2s */
3904
                    CHECK_FPU_FEATURE(dc, VIS1);
3905
                    tcg_gen_xori_i32(cpu_fpr[rd], cpu_fpr[rs2], -1);
3906
                    break;
3907
                case 0x068: /* VIS I fandnot1 */
3908
                    CHECK_FPU_FEATURE(dc, VIS1);
3909
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs2)], -1);
3910
                    tcg_gen_and_i32(cpu_fpr[DFPREG(rd)], cpu_tmp32,
3911
                                    cpu_fpr[DFPREG(rs1)]);
3912
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs2)], -1);
3913
                    tcg_gen_and_i32(cpu_fpr[DFPREG(rd) + 1], cpu_tmp32,
3914
                                    cpu_fpr[DFPREG(rs1) + 1]);
3915
                    break;
3916
                case 0x069: /* VIS I fandnot1s */
3917
                    CHECK_FPU_FEATURE(dc, VIS1);
3918
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[rs2], -1);
3919
                    tcg_gen_and_i32(cpu_fpr[rd], cpu_tmp32, cpu_fpr[rs1]);
3920
                    break;
3921
                case 0x06a: /* VIS I fnot1 */
3922
                    CHECK_FPU_FEATURE(dc, VIS1);
3923
                    tcg_gen_xori_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
3924
                                     -1);
3925
                    tcg_gen_xori_i32(cpu_fpr[DFPREG(rd) + 1],
3926
                                     cpu_fpr[DFPREG(rs1) + 1], -1);
3927
                    break;
3928
                case 0x06b: /* VIS I fnot1s */
3929
                    CHECK_FPU_FEATURE(dc, VIS1);
3930
                    tcg_gen_xori_i32(cpu_fpr[rd], cpu_fpr[rs1], -1);
3931
                    break;
3932
                case 0x06c: /* VIS I fxor */
3933
                    CHECK_FPU_FEATURE(dc, VIS1);
3934
                    tcg_gen_xor_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
3935
                                    cpu_fpr[DFPREG(rs2)]);
3936
                    tcg_gen_xor_i32(cpu_fpr[DFPREG(rd) + 1],
3937
                                    cpu_fpr[DFPREG(rs1) + 1],
3938
                                    cpu_fpr[DFPREG(rs2) + 1]);
3939
                    break;
3940
                case 0x06d: /* VIS I fxors */
3941
                    CHECK_FPU_FEATURE(dc, VIS1);
3942
                    tcg_gen_xor_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
3943
                    break;
3944
                case 0x06e: /* VIS I fnand */
3945
                    CHECK_FPU_FEATURE(dc, VIS1);
3946
                    tcg_gen_and_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1)],
3947
                                    cpu_fpr[DFPREG(rs2)]);
3948
                    tcg_gen_xori_i32(cpu_fpr[DFPREG(rd)], cpu_tmp32, -1);
3949
                    tcg_gen_and_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1) + 1],
3950
                                    cpu_fpr[DFPREG(rs2) + 1]);
3951
                    tcg_gen_xori_i32(cpu_fpr[DFPREG(rd) + 1], cpu_tmp32, -1);
3952
                    break;
3953
                case 0x06f: /* VIS I fnands */
3954
                    CHECK_FPU_FEATURE(dc, VIS1);
3955
                    tcg_gen_and_i32(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
3956
                    tcg_gen_xori_i32(cpu_fpr[rd], cpu_tmp32, -1);
3957
                    break;
3958
                case 0x070: /* VIS I fand */
3959
                    CHECK_FPU_FEATURE(dc, VIS1);
3960
                    tcg_gen_and_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
3961
                                    cpu_fpr[DFPREG(rs2)]);
3962
                    tcg_gen_and_i32(cpu_fpr[DFPREG(rd) + 1],
3963
                                    cpu_fpr[DFPREG(rs1) + 1],
3964
                                    cpu_fpr[DFPREG(rs2) + 1]);
3965
                    break;
3966
                case 0x071: /* VIS I fands */
3967
                    CHECK_FPU_FEATURE(dc, VIS1);
3968
                    tcg_gen_and_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
3969
                    break;
3970
                case 0x072: /* VIS I fxnor */
3971
                    CHECK_FPU_FEATURE(dc, VIS1);
3972
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs2)], -1);
3973
                    tcg_gen_xor_i32(cpu_fpr[DFPREG(rd)], cpu_tmp32,
3974
                                    cpu_fpr[DFPREG(rs1)]);
3975
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs2) + 1], -1);
3976
                    tcg_gen_xor_i32(cpu_fpr[DFPREG(rd) + 1], cpu_tmp32,
3977
                                    cpu_fpr[DFPREG(rs1) + 1]);
3978
                    break;
3979
                case 0x073: /* VIS I fxnors */
3980
                    CHECK_FPU_FEATURE(dc, VIS1);
3981
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[rs2], -1);
3982
                    tcg_gen_xor_i32(cpu_fpr[rd], cpu_tmp32, cpu_fpr[rs1]);
3983
                    break;
3984
                case 0x074: /* VIS I fsrc1 */
3985
                    CHECK_FPU_FEATURE(dc, VIS1);
3986
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)]);
3987
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1],
3988
                                    cpu_fpr[DFPREG(rs1) + 1]);
3989
                    break;
3990
                case 0x075: /* VIS I fsrc1s */
3991
                    CHECK_FPU_FEATURE(dc, VIS1);
3992
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs1]);
3993
                    break;
3994
                case 0x076: /* VIS I fornot2 */
3995
                    CHECK_FPU_FEATURE(dc, VIS1);
3996
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1)], -1);
3997
                    tcg_gen_or_i32(cpu_fpr[DFPREG(rd)], cpu_tmp32,
3998
                                   cpu_fpr[DFPREG(rs2)]);
3999
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1) + 1], -1);
4000
                    tcg_gen_or_i32(cpu_fpr[DFPREG(rd) + 1], cpu_tmp32,
4001
                                   cpu_fpr[DFPREG(rs2) + 1]);
4002
                    break;
4003
                case 0x077: /* VIS I fornot2s */
4004
                    CHECK_FPU_FEATURE(dc, VIS1);
4005
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[rs1], -1);
4006
                    tcg_gen_or_i32(cpu_fpr[rd], cpu_tmp32, cpu_fpr[rs2]);
4007
                    break;
4008
                case 0x078: /* VIS I fsrc2 */
4009
                    CHECK_FPU_FEATURE(dc, VIS1);
4010
                    gen_op_load_fpr_DT0(DFPREG(rs2));
4011
                    gen_op_store_DT0_fpr(DFPREG(rd));
4012
                    break;
4013
                case 0x079: /* VIS I fsrc2s */
4014
                    CHECK_FPU_FEATURE(dc, VIS1);
4015
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);
4016
                    break;
4017
                case 0x07a: /* VIS I fornot1 */
4018
                    CHECK_FPU_FEATURE(dc, VIS1);
4019
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs2)], -1);
4020
                    tcg_gen_or_i32(cpu_fpr[DFPREG(rd)], cpu_tmp32,
4021
                                   cpu_fpr[DFPREG(rs1)]);
4022
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs2) + 1], -1);
4023
                    tcg_gen_or_i32(cpu_fpr[DFPREG(rd) + 1], cpu_tmp32,
4024
                                   cpu_fpr[DFPREG(rs1) + 1]);
4025
                    break;
4026
                case 0x07b: /* VIS I fornot1s */
4027
                    CHECK_FPU_FEATURE(dc, VIS1);
4028
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[rs2], -1);
4029
                    tcg_gen_or_i32(cpu_fpr[rd], cpu_tmp32, cpu_fpr[rs1]);
4030
                    break;
4031
                case 0x07c: /* VIS I for */
4032
                    CHECK_FPU_FEATURE(dc, VIS1);
4033
                    tcg_gen_or_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
4034
                                   cpu_fpr[DFPREG(rs2)]);
4035
                    tcg_gen_or_i32(cpu_fpr[DFPREG(rd) + 1],
4036
                                   cpu_fpr[DFPREG(rs1) + 1],
4037
                                   cpu_fpr[DFPREG(rs2) + 1]);
4038
                    break;
4039
                case 0x07d: /* VIS I fors */
4040
                    CHECK_FPU_FEATURE(dc, VIS1);
4041
                    tcg_gen_or_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
4042
                    break;
4043
                case 0x07e: /* VIS I fone */
4044
                    CHECK_FPU_FEATURE(dc, VIS1);
4045
                    tcg_gen_movi_i32(cpu_fpr[DFPREG(rd)], -1);
4046
                    tcg_gen_movi_i32(cpu_fpr[DFPREG(rd) + 1], -1);
4047
                    break;
4048
                case 0x07f: /* VIS I fones */
4049
                    CHECK_FPU_FEATURE(dc, VIS1);
4050
                    tcg_gen_movi_i32(cpu_fpr[rd], -1);
4051
                    break;
4052
                case 0x080: /* VIS I shutdown */
4053
                case 0x081: /* VIS II siam */
4054
                    // XXX
4055
                    goto illegal_insn;
4056
                default:
4057
                    goto illegal_insn;
4058
                }
4059
#else
4060
                goto ncp_insn;
4061
#endif
4062
            } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
4063
#ifdef TARGET_SPARC64
4064
                goto illegal_insn;
4065
#else
4066
                goto ncp_insn;
4067
#endif
4068
#ifdef TARGET_SPARC64
4069
            } else if (xop == 0x39) { /* V9 return */
4070
                TCGv r_const;
4071

    
4072
                save_state(dc, cpu_cond);
4073
                cpu_src1 = get_src1(insn, cpu_src1);
4074
                if (IS_IMM) {   /* immediate */
4075
                    rs2 = GET_FIELDs(insn, 19, 31);
4076
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, (int)rs2);
4077
                } else {                /* register */
4078
                    rs2 = GET_FIELD(insn, 27, 31);
4079
                    if (rs2) {
4080
                        gen_movl_reg_TN(rs2, cpu_src2);
4081
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
4082
                    } else
4083
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
4084
                }
4085
                tcg_gen_helper_0_0(helper_restore);
4086
                gen_mov_pc_npc(dc, cpu_cond);
4087
                r_const = tcg_const_i32(3);
4088
                tcg_gen_helper_0_2(helper_check_align, cpu_dst, r_const);
4089
                tcg_temp_free(r_const);
4090
                tcg_gen_mov_tl(cpu_npc, cpu_dst);
4091
                dc->npc = DYNAMIC_PC;
4092
                goto jmp_insn;
4093
#endif
4094
            } else {
4095
                cpu_src1 = get_src1(insn, cpu_src1);
4096
                if (IS_IMM) {   /* immediate */
4097
                    rs2 = GET_FIELDs(insn, 19, 31);
4098
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, (int)rs2);
4099
                } else {                /* register */
4100
                    rs2 = GET_FIELD(insn, 27, 31);
4101
                    if (rs2) {
4102
                        gen_movl_reg_TN(rs2, cpu_src2);
4103
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
4104
                    } else
4105
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
4106
                }
4107
                switch (xop) {
4108
                case 0x38:      /* jmpl */
4109
                    {
4110
                        TCGv r_const;
4111

    
4112
                        r_const = tcg_const_tl(dc->pc);
4113
                        gen_movl_TN_reg(rd, r_const);
4114
                        tcg_temp_free(r_const);
4115
                        gen_mov_pc_npc(dc, cpu_cond);
4116
                        r_const = tcg_const_i32(3);
4117
                        tcg_gen_helper_0_2(helper_check_align, cpu_dst,
4118
                                           r_const);
4119
                        tcg_temp_free(r_const);
4120
                        tcg_gen_mov_tl(cpu_npc, cpu_dst);
4121
                        dc->npc = DYNAMIC_PC;
4122
                    }
4123
                    goto jmp_insn;
4124
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
4125
                case 0x39:      /* rett, V9 return */
4126
                    {
4127
                        TCGv r_const;
4128

    
4129
                        if (!supervisor(dc))
4130
                            goto priv_insn;
4131
                        gen_mov_pc_npc(dc, cpu_cond);
4132
                        r_const = tcg_const_i32(3);
4133
                        tcg_gen_helper_0_2(helper_check_align, cpu_dst,
4134
                                           r_const);
4135
                        tcg_temp_free(r_const);
4136
                        tcg_gen_mov_tl(cpu_npc, cpu_dst);
4137
                        dc->npc = DYNAMIC_PC;
4138
                        tcg_gen_helper_0_0(helper_rett);
4139
                    }
4140
                    goto jmp_insn;
4141
#endif
4142
                case 0x3b: /* flush */
4143
                    if (!((dc)->def->features & CPU_FEATURE_FLUSH))
4144
                        goto unimp_flush;
4145
                    tcg_gen_helper_0_1(helper_flush, cpu_dst);
4146
                    break;
4147
                case 0x3c:      /* save */
4148
                    save_state(dc, cpu_cond);
4149
                    tcg_gen_helper_0_0(helper_save);
4150
                    gen_movl_TN_reg(rd, cpu_dst);
4151
                    break;
4152
                case 0x3d:      /* restore */
4153
                    save_state(dc, cpu_cond);
4154
                    tcg_gen_helper_0_0(helper_restore);
4155
                    gen_movl_TN_reg(rd, cpu_dst);
4156
                    break;
4157
#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
4158
                case 0x3e:      /* V9 done/retry */
4159
                    {
4160
                        switch (rd) {
4161
                        case 0:
4162
                            if (!supervisor(dc))
4163
                                goto priv_insn;
4164
                            dc->npc = DYNAMIC_PC;
4165
                            dc->pc = DYNAMIC_PC;
4166
                            tcg_gen_helper_0_0(helper_done);
4167
                            goto jmp_insn;
4168
                        case 1:
4169
                            if (!supervisor(dc))
4170
                                goto priv_insn;
4171
                            dc->npc = DYNAMIC_PC;
4172
                            dc->pc = DYNAMIC_PC;
4173
                            tcg_gen_helper_0_0(helper_retry);
4174
                            goto jmp_insn;
4175
                        default:
4176
                            goto illegal_insn;
4177
                        }
4178
                    }
4179
                    break;
4180
#endif
4181
                default:
4182
                    goto illegal_insn;
4183
                }
4184
            }
4185
            break;
4186
        }
4187
        break;
4188
    case 3:                     /* load/store instructions */
4189
        {
4190
            unsigned int xop = GET_FIELD(insn, 7, 12);
4191

    
4192
            cpu_src1 = get_src1(insn, cpu_src1);
4193
            if (xop == 0x3c || xop == 0x3e) { // V9 casa/casxa
4194
                rs2 = GET_FIELD(insn, 27, 31);
4195
                gen_movl_reg_TN(rs2, cpu_src2);
4196
                tcg_gen_mov_tl(cpu_addr, cpu_src1);
4197
            } else if (IS_IMM) {     /* immediate */
4198
                rs2 = GET_FIELDs(insn, 19, 31);
4199
                tcg_gen_addi_tl(cpu_addr, cpu_src1, (int)rs2);
4200
            } else {            /* register */
4201
                rs2 = GET_FIELD(insn, 27, 31);
4202
                if (rs2 != 0) {
4203
                    gen_movl_reg_TN(rs2, cpu_src2);
4204
                    tcg_gen_add_tl(cpu_addr, cpu_src1, cpu_src2);
4205
                } else
4206
                    tcg_gen_mov_tl(cpu_addr, cpu_src1);
4207
            }
4208
            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
4209
                (xop > 0x17 && xop <= 0x1d ) ||
4210
                (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
4211
                switch (xop) {
4212
                case 0x0:       /* load unsigned word */
4213
                    gen_address_mask(dc, cpu_addr);
4214
                    tcg_gen_qemu_ld32u(cpu_val, cpu_addr, dc->mem_idx);
4215
                    break;
4216
                case 0x1:       /* load unsigned byte */
4217
                    gen_address_mask(dc, cpu_addr);
4218
                    tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx);
4219
                    break;
4220
                case 0x2:       /* load unsigned halfword */
4221
                    gen_address_mask(dc, cpu_addr);
4222
                    tcg_gen_qemu_ld16u(cpu_val, cpu_addr, dc->mem_idx);
4223
                    break;
4224
                case 0x3:       /* load double word */
4225
                    if (rd & 1)
4226
                        goto illegal_insn;
4227
                    else {
4228
                        TCGv r_const;
4229

    
4230
                        save_state(dc, cpu_cond);
4231
                        r_const = tcg_const_i32(7);
4232
                        tcg_gen_helper_0_2(helper_check_align, cpu_addr,
4233
                                           r_const); // XXX remove
4234
                        tcg_temp_free(r_const);
4235
                        gen_address_mask(dc, cpu_addr);
4236
                        tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
4237
                        tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
4238
                        tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffffULL);
4239
                        gen_movl_TN_reg(rd + 1, cpu_tmp0);
4240
                        tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
4241
                        tcg_gen_trunc_i64_tl(cpu_val, cpu_tmp64);
4242
                        tcg_gen_andi_tl(cpu_val, cpu_val, 0xffffffffULL);
4243
                    }
4244
                    break;
4245
                case 0x9:       /* load signed byte */
4246
                    gen_address_mask(dc, cpu_addr);
4247
                    tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
4248
                    break;
4249
                case 0xa:       /* load signed halfword */
4250
                    gen_address_mask(dc, cpu_addr);
4251
                    tcg_gen_qemu_ld16s(cpu_val, cpu_addr, dc->mem_idx);
4252
                    break;
4253
                case 0xd:       /* ldstub -- XXX: should be atomically */
4254
                    {
4255
                        TCGv r_const;
4256

    
4257
                        gen_address_mask(dc, cpu_addr);
4258
                        tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
4259
                        r_const = tcg_const_tl(0xff);
4260
                        tcg_gen_qemu_st8(r_const, cpu_addr, dc->mem_idx);
4261
                        tcg_temp_free(r_const);
4262
                    }
4263
                    break;
4264
                case 0x0f:      /* swap register with memory. Also
4265
                                   atomically */
4266
                    CHECK_IU_FEATURE(dc, SWAP);
4267
                    gen_movl_reg_TN(rd, cpu_val);
4268
                    gen_address_mask(dc, cpu_addr);
4269
                    tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
4270
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
4271
                    tcg_gen_extu_i32_tl(cpu_val, cpu_tmp32);
4272
                    break;
4273
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4274
                case 0x10:      /* load word alternate */
4275
#ifndef TARGET_SPARC64
4276
                    if (IS_IMM)
4277
                        goto illegal_insn;
4278
                    if (!supervisor(dc))
4279
                        goto priv_insn;
4280
#endif
4281
                    save_state(dc, cpu_cond);
4282
                    gen_ld_asi(cpu_val, cpu_addr, insn, 4, 0);
4283
                    break;
4284
                case 0x11:      /* load unsigned byte alternate */
4285
#ifndef TARGET_SPARC64
4286
                    if (IS_IMM)
4287
                        goto illegal_insn;
4288
                    if (!supervisor(dc))
4289
                        goto priv_insn;
4290
#endif
4291
                    save_state(dc, cpu_cond);
4292
                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 0);
4293
                    break;
4294
                case 0x12:      /* load unsigned halfword alternate */
4295
#ifndef TARGET_SPARC64
4296
                    if (IS_IMM)
4297
                        goto illegal_insn;
4298
                    if (!supervisor(dc))
4299
                        goto priv_insn;
4300
#endif
4301
                    save_state(dc, cpu_cond);
4302
                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 0);
4303
                    break;
4304
                case 0x13:      /* load double word alternate */
4305
#ifndef TARGET_SPARC64
4306
                    if (IS_IMM)
4307
                        goto illegal_insn;
4308
                    if (!supervisor(dc))
4309
                        goto priv_insn;
4310
#endif
4311
                    if (rd & 1)
4312
                        goto illegal_insn;
4313
                    save_state(dc, cpu_cond);
4314
                    gen_ldda_asi(cpu_val, cpu_addr, insn, rd);
4315
                    goto skip_move;
4316
                case 0x19:      /* load signed byte alternate */
4317
#ifndef TARGET_SPARC64
4318
                    if (IS_IMM)
4319
                        goto illegal_insn;
4320
                    if (!supervisor(dc))
4321
                        goto priv_insn;
4322
#endif
4323
                    save_state(dc, cpu_cond);
4324
                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 1);
4325
                    break;
4326
                case 0x1a:      /* load signed halfword alternate */
4327
#ifndef TARGET_SPARC64
4328
                    if (IS_IMM)
4329
                        goto illegal_insn;
4330
                    if (!supervisor(dc))
4331
                        goto priv_insn;
4332
#endif
4333
                    save_state(dc, cpu_cond);
4334
                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 1);
4335
                    break;
4336
                case 0x1d:      /* ldstuba -- XXX: should be atomically */
4337
#ifndef TARGET_SPARC64
4338
                    if (IS_IMM)
4339
                        goto illegal_insn;
4340
                    if (!supervisor(dc))
4341
                        goto priv_insn;
4342
#endif
4343
                    save_state(dc, cpu_cond);
4344
                    gen_ldstub_asi(cpu_val, cpu_addr, insn);
4345
                    break;
4346
                case 0x1f:      /* swap reg with alt. memory. Also
4347
                                   atomically */
4348
                    CHECK_IU_FEATURE(dc, SWAP);
4349
#ifndef TARGET_SPARC64
4350
                    if (IS_IMM)
4351
                        goto illegal_insn;
4352
                    if (!supervisor(dc))
4353
                        goto priv_insn;
4354
#endif
4355
                    save_state(dc, cpu_cond);
4356
                    gen_movl_reg_TN(rd, cpu_val);
4357
                    gen_swap_asi(cpu_val, cpu_addr, insn);
4358
                    break;
4359

    
4360
#ifndef TARGET_SPARC64
4361
                case 0x30: /* ldc */
4362
                case 0x31: /* ldcsr */
4363
                case 0x33: /* lddc */
4364
                    goto ncp_insn;
4365
#endif
4366
#endif
4367
#ifdef TARGET_SPARC64
4368
                case 0x08: /* V9 ldsw */
4369
                    gen_address_mask(dc, cpu_addr);
4370
                    tcg_gen_qemu_ld32s(cpu_val, cpu_addr, dc->mem_idx);
4371
                    break;
4372
                case 0x0b: /* V9 ldx */
4373
                    gen_address_mask(dc, cpu_addr);
4374
                    tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx);
4375
                    break;
4376
                case 0x18: /* V9 ldswa */
4377
                    save_state(dc, cpu_cond);
4378
                    gen_ld_asi(cpu_val, cpu_addr, insn, 4, 1);
4379
                    break;
4380
                case 0x1b: /* V9 ldxa */
4381
                    save_state(dc, cpu_cond);
4382
                    gen_ld_asi(cpu_val, cpu_addr, insn, 8, 0);
4383
                    break;
4384
                case 0x2d: /* V9 prefetch, no effect */
4385
                    goto skip_move;
4386
                case 0x30: /* V9 ldfa */
4387
                    save_state(dc, cpu_cond);
4388
                    gen_ldf_asi(cpu_addr, insn, 4, rd);
4389
                    goto skip_move;
4390
                case 0x33: /* V9 lddfa */
4391
                    save_state(dc, cpu_cond);
4392
                    gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd));
4393
                    goto skip_move;
4394
                case 0x3d: /* V9 prefetcha, no effect */
4395
                    goto skip_move;
4396
                case 0x32: /* V9 ldqfa */
4397
                    CHECK_FPU_FEATURE(dc, FLOAT128);
4398
                    save_state(dc, cpu_cond);
4399
                    gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd));
4400
                    goto skip_move;
4401
#endif
4402
                default:
4403
                    goto illegal_insn;
4404
                }
4405
                gen_movl_TN_reg(rd, cpu_val);
4406
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4407
            skip_move: ;
4408
#endif
4409
            } else if (xop >= 0x20 && xop < 0x24) {
4410
                if (gen_trap_ifnofpu(dc, cpu_cond))
4411
                    goto jmp_insn;
4412
                save_state(dc, cpu_cond);
4413
                switch (xop) {
4414
                case 0x20:      /* load fpreg */
4415
                    gen_address_mask(dc, cpu_addr);
4416
                    tcg_gen_qemu_ld32u(cpu_fpr[rd], cpu_addr, dc->mem_idx);
4417
                    break;
4418
                case 0x21:      /* ldfsr, V9 ldxfsr */
4419
#ifdef TARGET_SPARC64
4420
                    gen_address_mask(dc, cpu_addr);
4421
                    if (rd == 1) {
4422
                        tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
4423
                        tcg_gen_helper_0_1(helper_ldxfsr, cpu_tmp64);
4424
                    } else
4425
#else
4426
                    {
4427
                        tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
4428
                        tcg_gen_helper_0_1(helper_ldfsr, cpu_tmp32);
4429
                    }
4430
#endif
4431
                    break;
4432
                case 0x22:      /* load quad fpreg */
4433
                    {
4434
                        TCGv r_const;
4435

    
4436
                        CHECK_FPU_FEATURE(dc, FLOAT128);
4437
                        r_const = tcg_const_i32(dc->mem_idx);
4438
                        tcg_gen_helper_0_2(helper_ldqf, cpu_addr, r_const);
4439
                        tcg_temp_free(r_const);
4440
                        gen_op_store_QT0_fpr(QFPREG(rd));
4441
                    }
4442
                    break;
4443
                case 0x23:      /* load double fpreg */
4444
                    {
4445
                        TCGv r_const;
4446

    
4447
                        r_const = tcg_const_i32(dc->mem_idx);
4448
                        tcg_gen_helper_0_2(helper_lddf, cpu_addr, r_const);
4449
                        tcg_temp_free(r_const);
4450
                        gen_op_store_DT0_fpr(DFPREG(rd));
4451
                    }
4452
                    break;
4453
                default:
4454
                    goto illegal_insn;
4455
                }
4456
            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) || \
4457
                       xop == 0xe || xop == 0x1e) {
4458
                gen_movl_reg_TN(rd, cpu_val);
4459
                switch (xop) {
4460
                case 0x4: /* store word */
4461
                    gen_address_mask(dc, cpu_addr);
4462
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
4463
                    break;
4464
                case 0x5: /* store byte */
4465
                    gen_address_mask(dc, cpu_addr);
4466
                    tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx);
4467
                    break;
4468
                case 0x6: /* store halfword */
4469
                    gen_address_mask(dc, cpu_addr);
4470
                    tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx);
4471
                    break;
4472
                case 0x7: /* store double word */
4473
                    if (rd & 1)
4474
                        goto illegal_insn;
4475
                    else {
4476
                        TCGv r_low, r_const;
4477

    
4478
                        save_state(dc, cpu_cond);
4479
                        gen_address_mask(dc, cpu_addr);
4480
                        r_const = tcg_const_i32(7);
4481
                        tcg_gen_helper_0_2(helper_check_align, cpu_addr,
4482
                                           r_const); // XXX remove
4483
                        tcg_temp_free(r_const);
4484
                        r_low = tcg_temp_new(TCG_TYPE_TL);
4485
                        gen_movl_reg_TN(rd + 1, r_low);
4486
                        tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, cpu_val,
4487
                                           r_low);
4488
                        tcg_temp_free(r_low);
4489
                        tcg_gen_qemu_st64(cpu_tmp64, cpu_addr, dc->mem_idx);
4490
                    }
4491
                    break;
4492
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4493
                case 0x14: /* store word alternate */
4494
#ifndef TARGET_SPARC64
4495
                    if (IS_IMM)
4496
                        goto illegal_insn;
4497
                    if (!supervisor(dc))
4498
                        goto priv_insn;
4499
#endif
4500
                    save_state(dc, cpu_cond);
4501
                    gen_st_asi(cpu_val, cpu_addr, insn, 4);
4502
                    break;
4503
                case 0x15: /* store byte alternate */
4504
#ifndef TARGET_SPARC64
4505
                    if (IS_IMM)
4506
                        goto illegal_insn;
4507
                    if (!supervisor(dc))
4508
                        goto priv_insn;
4509
#endif
4510
                    save_state(dc, cpu_cond);
4511
                    gen_st_asi(cpu_val, cpu_addr, insn, 1);
4512
                    break;
4513
                case 0x16: /* store halfword alternate */
4514
#ifndef TARGET_SPARC64
4515
                    if (IS_IMM)
4516
                        goto illegal_insn;
4517
                    if (!supervisor(dc))
4518
                        goto priv_insn;
4519
#endif
4520
                    save_state(dc, cpu_cond);
4521
                    gen_st_asi(cpu_val, cpu_addr, insn, 2);
4522
                    break;
4523
                case 0x17: /* store double word alternate */
4524
#ifndef TARGET_SPARC64
4525
                    if (IS_IMM)
4526
                        goto illegal_insn;
4527
                    if (!supervisor(dc))
4528
                        goto priv_insn;
4529
#endif
4530
                    if (rd & 1)
4531
                        goto illegal_insn;
4532
                    else {
4533
                        save_state(dc, cpu_cond);
4534
                        gen_stda_asi(cpu_val, cpu_addr, insn, rd);
4535
                    }
4536
                    break;
4537
#endif
4538
#ifdef TARGET_SPARC64
4539
                case 0x0e: /* V9 stx */
4540
                    gen_address_mask(dc, cpu_addr);
4541
                    tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx);
4542
                    break;
4543
                case 0x1e: /* V9 stxa */
4544
                    save_state(dc, cpu_cond);
4545
                    gen_st_asi(cpu_val, cpu_addr, insn, 8);
4546
                    break;
4547
#endif
4548
                default:
4549
                    goto illegal_insn;
4550
                }
4551
            } else if (xop > 0x23 && xop < 0x28) {
4552
                if (gen_trap_ifnofpu(dc, cpu_cond))
4553
                    goto jmp_insn;
4554
                save_state(dc, cpu_cond);
4555
                switch (xop) {
4556
                case 0x24: /* store fpreg */
4557
                    gen_address_mask(dc, cpu_addr);
4558
                    tcg_gen_qemu_st32(cpu_fpr[rd], cpu_addr, dc->mem_idx);
4559
                    break;
4560
                case 0x25: /* stfsr, V9 stxfsr */
4561
#ifdef TARGET_SPARC64
4562
                    gen_address_mask(dc, cpu_addr);
4563
                    tcg_gen_ld_i64(cpu_tmp64, cpu_env, offsetof(CPUState, fsr));
4564
                    if (rd == 1)
4565
                        tcg_gen_qemu_st64(cpu_tmp64, cpu_addr, dc->mem_idx);
4566
                    else {
4567
                        tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp64);
4568
                        tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx);
4569
                    }
4570
#else
4571
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUState, fsr));
4572
                    tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx);
4573
#endif
4574
                    break;
4575
                case 0x26:
4576
#ifdef TARGET_SPARC64
4577
                    /* V9 stqf, store quad fpreg */
4578
                    {
4579
                        TCGv r_const;
4580

    
4581
                        CHECK_FPU_FEATURE(dc, FLOAT128);
4582
                        gen_op_load_fpr_QT0(QFPREG(rd));
4583
                        r_const = tcg_const_i32(dc->mem_idx);
4584
                        tcg_gen_helper_0_2(helper_stqf, cpu_addr, r_const);
4585
                        tcg_temp_free(r_const);
4586
                    }
4587
                    break;
4588
#else /* !TARGET_SPARC64 */
4589
                    /* stdfq, store floating point queue */
4590
#if defined(CONFIG_USER_ONLY)
4591
                    goto illegal_insn;
4592
#else
4593
                    if (!supervisor(dc))
4594
                        goto priv_insn;
4595
                    if (gen_trap_ifnofpu(dc, cpu_cond))
4596
                        goto jmp_insn;
4597
                    goto nfq_insn;
4598
#endif
4599
#endif
4600
                case 0x27: /* store double fpreg */
4601
                    {
4602
                        TCGv r_const;
4603

    
4604
                        gen_op_load_fpr_DT0(DFPREG(rd));
4605
                        r_const = tcg_const_i32(dc->mem_idx);
4606
                        tcg_gen_helper_0_2(helper_stdf, cpu_addr, r_const);
4607
                        tcg_temp_free(r_const);
4608
                    }
4609
                    break;
4610
                default:
4611
                    goto illegal_insn;
4612
                }
4613
            } else if (xop > 0x33 && xop < 0x3f) {
4614
                save_state(dc, cpu_cond);
4615
                switch (xop) {
4616
#ifdef TARGET_SPARC64
4617
                case 0x34: /* V9 stfa */
4618
                    gen_stf_asi(cpu_addr, insn, 4, rd);
4619
                    break;
4620
                case 0x36: /* V9 stqfa */
4621
                    {
4622
                        TCGv r_const;
4623

    
4624
                        CHECK_FPU_FEATURE(dc, FLOAT128);
4625
                        r_const = tcg_const_i32(7);
4626
                        tcg_gen_helper_0_2(helper_check_align, cpu_addr,
4627
                                           r_const);
4628
                        tcg_temp_free(r_const);
4629
                        gen_op_load_fpr_QT0(QFPREG(rd));
4630
                        gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd));
4631
                    }
4632
                    break;
4633
                case 0x37: /* V9 stdfa */
4634
                    gen_op_load_fpr_DT0(DFPREG(rd));
4635
                    gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
4636
                    break;
4637
                case 0x3c: /* V9 casa */
4638
                    gen_cas_asi(cpu_val, cpu_addr, cpu_src2, insn, rd);
4639
                    gen_movl_TN_reg(rd, cpu_val);
4640
                    break;
4641
                case 0x3e: /* V9 casxa */
4642
                    gen_casx_asi(cpu_val, cpu_addr, cpu_src2, insn, rd);
4643
                    gen_movl_TN_reg(rd, cpu_val);
4644
                    break;
4645
#else
4646
                case 0x34: /* stc */
4647
                case 0x35: /* stcsr */
4648
                case 0x36: /* stdcq */
4649
                case 0x37: /* stdc */
4650
                    goto ncp_insn;
4651
#endif
4652
                default:
4653
                    goto illegal_insn;
4654
                }
4655
            }
4656
            else
4657
                goto illegal_insn;
4658
        }
4659
        break;
4660
    }
4661
    /* default case for non jump instructions */
4662
    if (dc->npc == DYNAMIC_PC) {
4663
        dc->pc = DYNAMIC_PC;
4664
        gen_op_next_insn();
4665
    } else if (dc->npc == JUMP_PC) {
4666
        /* we can do a static jump */
4667
        gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
4668
        dc->is_br = 1;
4669
    } else {
4670
        dc->pc = dc->npc;
4671
        dc->npc = dc->npc + 4;
4672
    }
4673
 jmp_insn:
4674
    return;
4675
 illegal_insn:
4676
    {
4677
        TCGv r_const;
4678

    
4679
        save_state(dc, cpu_cond);
4680
        r_const = tcg_const_i32(TT_ILL_INSN);
4681
        tcg_gen_helper_0_1(raise_exception, r_const);
4682
        tcg_temp_free(r_const);
4683
        dc->is_br = 1;
4684
    }
4685
    return;
4686
 unimp_flush:
4687
    {
4688
        TCGv r_const;
4689

    
4690
        save_state(dc, cpu_cond);
4691
        r_const = tcg_const_i32(TT_UNIMP_FLUSH);
4692
        tcg_gen_helper_0_1(raise_exception, r_const);
4693
        tcg_temp_free(r_const);
4694
        dc->is_br = 1;
4695
    }
4696
    return;
4697
#if !defined(CONFIG_USER_ONLY)
4698
 priv_insn:
4699
    {
4700
        TCGv r_const;
4701

    
4702
        save_state(dc, cpu_cond);
4703
        r_const = tcg_const_i32(TT_PRIV_INSN);
4704
        tcg_gen_helper_0_1(raise_exception, r_const);
4705
        tcg_temp_free(r_const);
4706
        dc->is_br = 1;
4707
    }
4708
    return;
4709
#endif
4710
 nfpu_insn:
4711
    save_state(dc, cpu_cond);
4712
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
4713
    dc->is_br = 1;
4714
    return;
4715
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
4716
 nfq_insn:
4717
    save_state(dc, cpu_cond);
4718
    gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
4719
    dc->is_br = 1;
4720
    return;
4721
#endif
4722
#ifndef TARGET_SPARC64
4723
 ncp_insn:
4724
    {
4725
        TCGv r_const;
4726

    
4727
        save_state(dc, cpu_cond);
4728
        r_const = tcg_const_i32(TT_NCP_INSN);
4729
        tcg_gen_helper_0_1(raise_exception, r_const);
4730
        tcg_temp_free(r_const);
4731
        dc->is_br = 1;
4732
    }
4733
    return;
4734
#endif
4735
}
4736

    
4737
static inline void gen_intermediate_code_internal(TranslationBlock * tb,
4738
                                                  int spc, CPUSPARCState *env)
4739
{
4740
    target_ulong pc_start, last_pc;
4741
    uint16_t *gen_opc_end;
4742
    DisasContext dc1, *dc = &dc1;
4743
    int j, lj = -1;
4744
    int num_insns;
4745
    int max_insns;
4746

    
4747
    memset(dc, 0, sizeof(DisasContext));
4748
    dc->tb = tb;
4749
    pc_start = tb->pc;
4750
    dc->pc = pc_start;
4751
    last_pc = dc->pc;
4752
    dc->npc = (target_ulong) tb->cs_base;
4753
    dc->mem_idx = cpu_mmu_index(env);
4754
    dc->def = env->def;
4755
    if ((dc->def->features & CPU_FEATURE_FLOAT))
4756
        dc->fpu_enabled = cpu_fpu_enabled(env);
4757
    else
4758
        dc->fpu_enabled = 0;
4759
#ifdef TARGET_SPARC64
4760
    dc->address_mask_32bit = env->pstate & PS_AM;
4761
#endif
4762
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4763

    
4764
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
4765
    cpu_tmp32 = tcg_temp_new(TCG_TYPE_I32);
4766
    cpu_tmp64 = tcg_temp_new(TCG_TYPE_I64);
4767

    
4768
    cpu_dst = tcg_temp_local_new(TCG_TYPE_TL);
4769

    
4770
    // loads and stores
4771
    cpu_val = tcg_temp_local_new(TCG_TYPE_TL);
4772
    cpu_addr = tcg_temp_local_new(TCG_TYPE_TL);
4773

    
4774
    num_insns = 0;
4775
    max_insns = tb->cflags & CF_COUNT_MASK;
4776
    if (max_insns == 0)
4777
        max_insns = CF_COUNT_MASK;
4778
    gen_icount_start();
4779
    do {
4780
        if (env->nb_breakpoints > 0) {
4781
            for(j = 0; j < env->nb_breakpoints; j++) {
4782
                if (env->breakpoints[j] == dc->pc) {
4783
                    if (dc->pc != pc_start)
4784
                        save_state(dc, cpu_cond);
4785
                    tcg_gen_helper_0_0(helper_debug);
4786
                    tcg_gen_exit_tb(0);
4787
                    dc->is_br = 1;
4788
                    goto exit_gen_loop;
4789
                }
4790
            }
4791
        }
4792
        if (spc) {
4793
            if (loglevel > 0)
4794
                fprintf(logfile, "Search PC...\n");
4795
            j = gen_opc_ptr - gen_opc_buf;
4796
            if (lj < j) {
4797
                lj++;
4798
                while (lj < j)
4799
                    gen_opc_instr_start[lj++] = 0;
4800
                gen_opc_pc[lj] = dc->pc;
4801
                gen_opc_npc[lj] = dc->npc;
4802
                gen_opc_instr_start[lj] = 1;
4803
                gen_opc_icount[lj] = num_insns;
4804
            }
4805
        }
4806
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
4807
            gen_io_start();
4808
        last_pc = dc->pc;
4809
        disas_sparc_insn(dc);
4810
        num_insns++;
4811

    
4812
        if (dc->is_br)
4813
            break;
4814
        /* if the next PC is different, we abort now */
4815
        if (dc->pc != (last_pc + 4))
4816
            break;
4817
        /* if we reach a page boundary, we stop generation so that the
4818
           PC of a TT_TFAULT exception is always in the right page */
4819
        if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
4820
            break;
4821
        /* if single step mode, we generate only one instruction and
4822
           generate an exception */
4823
        if (env->singlestep_enabled) {
4824
            tcg_gen_movi_tl(cpu_pc, dc->pc);
4825
            tcg_gen_exit_tb(0);
4826
            break;
4827
        }
4828
    } while ((gen_opc_ptr < gen_opc_end) &&
4829
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32) &&
4830
             num_insns < max_insns);
4831

    
4832
 exit_gen_loop:
4833
    tcg_temp_free(cpu_addr);
4834
    tcg_temp_free(cpu_val);
4835
    tcg_temp_free(cpu_dst);
4836
    tcg_temp_free(cpu_tmp64);
4837
    tcg_temp_free(cpu_tmp32);
4838
    tcg_temp_free(cpu_tmp0);
4839
    if (tb->cflags & CF_LAST_IO)
4840
        gen_io_end();
4841
    if (!dc->is_br) {
4842
        if (dc->pc != DYNAMIC_PC &&
4843
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
4844
            /* static PC and NPC: we can use direct chaining */
4845
            gen_goto_tb(dc, 0, dc->pc, dc->npc);
4846
        } else {
4847
            if (dc->pc != DYNAMIC_PC)
4848
                tcg_gen_movi_tl(cpu_pc, dc->pc);
4849
            save_npc(dc, cpu_cond);
4850
            tcg_gen_exit_tb(0);
4851
        }
4852
    }
4853
    gen_icount_end(tb, num_insns);
4854
    *gen_opc_ptr = INDEX_op_end;
4855
    if (spc) {
4856
        j = gen_opc_ptr - gen_opc_buf;
4857
        lj++;
4858
        while (lj <= j)
4859
            gen_opc_instr_start[lj++] = 0;
4860
#if 0
4861
        if (loglevel > 0) {
4862
            page_dump(logfile);
4863
        }
4864
#endif
4865
        gen_opc_jump_pc[0] = dc->jump_pc[0];
4866
        gen_opc_jump_pc[1] = dc->jump_pc[1];
4867
    } else {
4868
        tb->size = last_pc + 4 - pc_start;
4869
        tb->icount = num_insns;
4870
    }
4871
#ifdef DEBUG_DISAS