~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to target/sparc/translate.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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, see <http://www.gnu.org/licenses/>.
 
19
 */
 
20
 
 
21
#include "qemu/osdep.h"
 
22
 
 
23
#include "cpu.h"
 
24
#include "disas/disas.h"
 
25
#include "exec/helper-proto.h"
 
26
#include "exec/exec-all.h"
 
27
#include "tcg-op.h"
 
28
#include "exec/cpu_ldst.h"
 
29
 
 
30
#include "exec/helper-gen.h"
 
31
 
 
32
#include "trace-tcg.h"
 
33
#include "exec/log.h"
 
34
#include "asi.h"
 
35
 
 
36
 
 
37
#define DEBUG_DISAS
 
38
 
 
39
#define DYNAMIC_PC  1 /* dynamic pc value */
 
40
#define JUMP_PC     2 /* dynamic pc value which takes only two values
 
41
                         according to jump_pc[T2] */
 
42
 
 
43
/* global register indexes */
 
44
static TCGv_env cpu_env;
 
45
static TCGv_ptr cpu_regwptr;
 
46
static TCGv cpu_cc_src, cpu_cc_src2, cpu_cc_dst;
 
47
static TCGv_i32 cpu_cc_op;
 
48
static TCGv_i32 cpu_psr;
 
49
static TCGv cpu_fsr, cpu_pc, cpu_npc;
 
50
static TCGv cpu_regs[32];
 
51
static TCGv cpu_y;
 
52
#ifndef CONFIG_USER_ONLY
 
53
static TCGv cpu_tbr;
 
54
#endif
 
55
static TCGv cpu_cond;
 
56
#ifdef TARGET_SPARC64
 
57
static TCGv_i32 cpu_xcc, cpu_fprs;
 
58
static TCGv cpu_gsr;
 
59
static TCGv cpu_tick_cmpr, cpu_stick_cmpr, cpu_hstick_cmpr;
 
60
static TCGv cpu_hintp, cpu_htba, cpu_hver, cpu_ssr, cpu_ver;
 
61
#else
 
62
static TCGv cpu_wim;
 
63
#endif
 
64
/* Floating point registers */
 
65
static TCGv_i64 cpu_fpr[TARGET_DPREGS];
 
66
 
 
67
#include "exec/gen-icount.h"
 
68
 
 
69
typedef struct DisasContext {
 
70
    target_ulong pc;    /* current Program Counter: integer or DYNAMIC_PC */
 
71
    target_ulong npc;   /* next PC: integer or DYNAMIC_PC or JUMP_PC */
 
72
    target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
 
73
    int is_br;
 
74
    int mem_idx;
 
75
    bool fpu_enabled;
 
76
    bool address_mask_32bit;
 
77
    bool singlestep;
 
78
#ifndef CONFIG_USER_ONLY
 
79
    bool supervisor;
 
80
#ifdef TARGET_SPARC64
 
81
    bool hypervisor;
 
82
#endif
 
83
#endif
 
84
 
 
85
    uint32_t cc_op;  /* current CC operation */
 
86
    struct TranslationBlock *tb;
 
87
    sparc_def_t *def;
 
88
    TCGv_i32 t32[3];
 
89
    TCGv ttl[5];
 
90
    int n_t32;
 
91
    int n_ttl;
 
92
#ifdef TARGET_SPARC64
 
93
    int fprs_dirty;
 
94
    int asi;
 
95
#endif
 
96
} DisasContext;
 
97
 
 
98
typedef struct {
 
99
    TCGCond cond;
 
100
    bool is_bool;
 
101
    bool g1, g2;
 
102
    TCGv c1, c2;
 
103
} DisasCompare;
 
104
 
 
105
// This function uses non-native bit order
 
106
#define GET_FIELD(X, FROM, TO)                                  \
 
107
    ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
 
108
 
 
109
// This function uses the order in the manuals, i.e. bit 0 is 2^0
 
110
#define GET_FIELD_SP(X, FROM, TO)               \
 
111
    GET_FIELD(X, 31 - (TO), 31 - (FROM))
 
112
 
 
113
#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
 
114
#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
 
115
 
 
116
#ifdef TARGET_SPARC64
 
117
#define DFPREG(r) (((r & 1) << 5) | (r & 0x1e))
 
118
#define QFPREG(r) (((r & 1) << 5) | (r & 0x1c))
 
119
#else
 
120
#define DFPREG(r) (r & 0x1e)
 
121
#define QFPREG(r) (r & 0x1c)
 
122
#endif
 
123
 
 
124
#define UA2005_HTRAP_MASK 0xff
 
125
#define V8_TRAP_MASK 0x7f
 
126
 
 
127
static int sign_extend(int x, int len)
 
128
{
 
129
    len = 32 - len;
 
130
    return (x << len) >> len;
 
131
}
 
132
 
 
133
#define IS_IMM (insn & (1<<13))
 
134
 
 
135
static inline TCGv_i32 get_temp_i32(DisasContext *dc)
 
136
{
 
137
    TCGv_i32 t;
 
138
    assert(dc->n_t32 < ARRAY_SIZE(dc->t32));
 
139
    dc->t32[dc->n_t32++] = t = tcg_temp_new_i32();
 
140
    return t;
 
141
}
 
142
 
 
143
static inline TCGv get_temp_tl(DisasContext *dc)
 
144
{
 
145
    TCGv t;
 
146
    assert(dc->n_ttl < ARRAY_SIZE(dc->ttl));
 
147
    dc->ttl[dc->n_ttl++] = t = tcg_temp_new();
 
148
    return t;
 
149
}
 
150
 
 
151
static inline void gen_update_fprs_dirty(DisasContext *dc, int rd)
 
152
{
 
153
#if defined(TARGET_SPARC64)
 
154
    int bit = (rd < 32) ? 1 : 2;
 
155
    /* If we know we've already set this bit within the TB,
 
156
       we can avoid setting it again.  */
 
157
    if (!(dc->fprs_dirty & bit)) {
 
158
        dc->fprs_dirty |= bit;
 
159
        tcg_gen_ori_i32(cpu_fprs, cpu_fprs, bit);
 
160
    }
 
161
#endif
 
162
}
 
163
 
 
164
/* floating point registers moves */
 
165
static TCGv_i32 gen_load_fpr_F(DisasContext *dc, unsigned int src)
 
166
{
 
167
#if TCG_TARGET_REG_BITS == 32
 
168
    if (src & 1) {
 
169
        return TCGV_LOW(cpu_fpr[src / 2]);
 
170
    } else {
 
171
        return TCGV_HIGH(cpu_fpr[src / 2]);
 
172
    }
 
173
#else
 
174
    if (src & 1) {
 
175
        return MAKE_TCGV_I32(GET_TCGV_I64(cpu_fpr[src / 2]));
 
176
    } else {
 
177
        TCGv_i32 ret = get_temp_i32(dc);
 
178
        TCGv_i64 t = tcg_temp_new_i64();
 
179
 
 
180
        tcg_gen_shri_i64(t, cpu_fpr[src / 2], 32);
 
181
        tcg_gen_extrl_i64_i32(ret, t);
 
182
        tcg_temp_free_i64(t);
 
183
 
 
184
        return ret;
 
185
    }
 
186
#endif
 
187
}
 
188
 
 
189
static void gen_store_fpr_F(DisasContext *dc, unsigned int dst, TCGv_i32 v)
 
190
{
 
191
#if TCG_TARGET_REG_BITS == 32
 
192
    if (dst & 1) {
 
193
        tcg_gen_mov_i32(TCGV_LOW(cpu_fpr[dst / 2]), v);
 
194
    } else {
 
195
        tcg_gen_mov_i32(TCGV_HIGH(cpu_fpr[dst / 2]), v);
 
196
    }
 
197
#else
 
198
    TCGv_i64 t = MAKE_TCGV_I64(GET_TCGV_I32(v));
 
199
    tcg_gen_deposit_i64(cpu_fpr[dst / 2], cpu_fpr[dst / 2], t,
 
200
                        (dst & 1 ? 0 : 32), 32);
 
201
#endif
 
202
    gen_update_fprs_dirty(dc, dst);
 
203
}
 
204
 
 
205
static TCGv_i32 gen_dest_fpr_F(DisasContext *dc)
 
206
{
 
207
    return get_temp_i32(dc);
 
208
}
 
209
 
 
210
static TCGv_i64 gen_load_fpr_D(DisasContext *dc, unsigned int src)
 
211
{
 
212
    src = DFPREG(src);
 
213
    return cpu_fpr[src / 2];
 
214
}
 
215
 
 
216
static void gen_store_fpr_D(DisasContext *dc, unsigned int dst, TCGv_i64 v)
 
217
{
 
218
    dst = DFPREG(dst);
 
219
    tcg_gen_mov_i64(cpu_fpr[dst / 2], v);
 
220
    gen_update_fprs_dirty(dc, dst);
 
221
}
 
222
 
 
223
static TCGv_i64 gen_dest_fpr_D(DisasContext *dc, unsigned int dst)
 
224
{
 
225
    return cpu_fpr[DFPREG(dst) / 2];
 
226
}
 
227
 
 
228
static void gen_op_load_fpr_QT0(unsigned int src)
 
229
{
 
230
    tcg_gen_st_i64(cpu_fpr[src / 2], cpu_env, offsetof(CPUSPARCState, qt0) +
 
231
                   offsetof(CPU_QuadU, ll.upper));
 
232
    tcg_gen_st_i64(cpu_fpr[src/2 + 1], cpu_env, offsetof(CPUSPARCState, qt0) +
 
233
                   offsetof(CPU_QuadU, ll.lower));
 
234
}
 
235
 
 
236
static void gen_op_load_fpr_QT1(unsigned int src)
 
237
{
 
238
    tcg_gen_st_i64(cpu_fpr[src / 2], cpu_env, offsetof(CPUSPARCState, qt1) +
 
239
                   offsetof(CPU_QuadU, ll.upper));
 
240
    tcg_gen_st_i64(cpu_fpr[src/2 + 1], cpu_env, offsetof(CPUSPARCState, qt1) +
 
241
                   offsetof(CPU_QuadU, ll.lower));
 
242
}
 
243
 
 
244
static void gen_op_store_QT0_fpr(unsigned int dst)
 
245
{
 
246
    tcg_gen_ld_i64(cpu_fpr[dst / 2], cpu_env, offsetof(CPUSPARCState, qt0) +
 
247
                   offsetof(CPU_QuadU, ll.upper));
 
248
    tcg_gen_ld_i64(cpu_fpr[dst/2 + 1], cpu_env, offsetof(CPUSPARCState, qt0) +
 
249
                   offsetof(CPU_QuadU, ll.lower));
 
250
}
 
251
 
 
252
static void gen_store_fpr_Q(DisasContext *dc, unsigned int dst,
 
253
                            TCGv_i64 v1, TCGv_i64 v2)
 
254
{
 
255
    dst = QFPREG(dst);
 
256
 
 
257
    tcg_gen_mov_i64(cpu_fpr[dst / 2], v1);
 
258
    tcg_gen_mov_i64(cpu_fpr[dst / 2 + 1], v2);
 
259
    gen_update_fprs_dirty(dc, dst);
 
260
}
 
261
 
 
262
#ifdef TARGET_SPARC64
 
263
static TCGv_i64 gen_load_fpr_Q0(DisasContext *dc, unsigned int src)
 
264
{
 
265
    src = QFPREG(src);
 
266
    return cpu_fpr[src / 2];
 
267
}
 
268
 
 
269
static TCGv_i64 gen_load_fpr_Q1(DisasContext *dc, unsigned int src)
 
270
{
 
271
    src = QFPREG(src);
 
272
    return cpu_fpr[src / 2 + 1];
 
273
}
 
274
 
 
275
static void gen_move_Q(DisasContext *dc, unsigned int rd, unsigned int rs)
 
276
{
 
277
    rd = QFPREG(rd);
 
278
    rs = QFPREG(rs);
 
279
 
 
280
    tcg_gen_mov_i64(cpu_fpr[rd / 2], cpu_fpr[rs / 2]);
 
281
    tcg_gen_mov_i64(cpu_fpr[rd / 2 + 1], cpu_fpr[rs / 2 + 1]);
 
282
    gen_update_fprs_dirty(dc, rd);
 
283
}
 
284
#endif
 
285
 
 
286
/* moves */
 
287
#ifdef CONFIG_USER_ONLY
 
288
#define supervisor(dc) 0
 
289
#ifdef TARGET_SPARC64
 
290
#define hypervisor(dc) 0
 
291
#endif
 
292
#else
 
293
#ifdef TARGET_SPARC64
 
294
#define hypervisor(dc) (dc->hypervisor)
 
295
#define supervisor(dc) (dc->supervisor | dc->hypervisor)
 
296
#else
 
297
#define supervisor(dc) (dc->supervisor)
 
298
#endif
 
299
#endif
 
300
 
 
301
#ifdef TARGET_SPARC64
 
302
#ifndef TARGET_ABI32
 
303
#define AM_CHECK(dc) ((dc)->address_mask_32bit)
 
304
#else
 
305
#define AM_CHECK(dc) (1)
 
306
#endif
 
307
#endif
 
308
 
 
309
static inline void gen_address_mask(DisasContext *dc, TCGv addr)
 
310
{
 
311
#ifdef TARGET_SPARC64
 
312
    if (AM_CHECK(dc))
 
313
        tcg_gen_andi_tl(addr, addr, 0xffffffffULL);
 
314
#endif
 
315
}
 
316
 
 
317
static inline TCGv gen_load_gpr(DisasContext *dc, int reg)
 
318
{
 
319
    if (reg > 0) {
 
320
        assert(reg < 32);
 
321
        return cpu_regs[reg];
 
322
    } else {
 
323
        TCGv t = get_temp_tl(dc);
 
324
        tcg_gen_movi_tl(t, 0);
 
325
        return t;
 
326
    }
 
327
}
 
328
 
 
329
static inline void gen_store_gpr(DisasContext *dc, int reg, TCGv v)
 
330
{
 
331
    if (reg > 0) {
 
332
        assert(reg < 32);
 
333
        tcg_gen_mov_tl(cpu_regs[reg], v);
 
334
    }
 
335
}
 
336
 
 
337
static inline TCGv gen_dest_gpr(DisasContext *dc, int reg)
 
338
{
 
339
    if (reg > 0) {
 
340
        assert(reg < 32);
 
341
        return cpu_regs[reg];
 
342
    } else {
 
343
        return get_temp_tl(dc);
 
344
    }
 
345
}
 
346
 
 
347
static inline bool use_goto_tb(DisasContext *s, target_ulong pc,
 
348
                               target_ulong npc)
 
349
{
 
350
    if (unlikely(s->singlestep)) {
 
351
        return false;
 
352
    }
 
353
 
 
354
#ifndef CONFIG_USER_ONLY
 
355
    return (pc & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK) &&
 
356
           (npc & TARGET_PAGE_MASK) == (s->tb->pc & TARGET_PAGE_MASK);
 
357
#else
 
358
    return true;
 
359
#endif
 
360
}
 
361
 
 
362
static inline void gen_goto_tb(DisasContext *s, int tb_num,
 
363
                               target_ulong pc, target_ulong npc)
 
364
{
 
365
    if (use_goto_tb(s, pc, npc))  {
 
366
        /* jump to same page: we can use a direct jump */
 
367
        tcg_gen_goto_tb(tb_num);
 
368
        tcg_gen_movi_tl(cpu_pc, pc);
 
369
        tcg_gen_movi_tl(cpu_npc, npc);
 
370
        tcg_gen_exit_tb((uintptr_t)s->tb + tb_num);
 
371
    } else {
 
372
        /* jump to another page: currently not optimized */
 
373
        tcg_gen_movi_tl(cpu_pc, pc);
 
374
        tcg_gen_movi_tl(cpu_npc, npc);
 
375
        tcg_gen_exit_tb(0);
 
376
    }
 
377
}
 
378
 
 
379
// XXX suboptimal
 
380
static inline void gen_mov_reg_N(TCGv reg, TCGv_i32 src)
 
381
{
 
382
    tcg_gen_extu_i32_tl(reg, src);
 
383
    tcg_gen_shri_tl(reg, reg, PSR_NEG_SHIFT);
 
384
    tcg_gen_andi_tl(reg, reg, 0x1);
 
385
}
 
386
 
 
387
static inline void gen_mov_reg_Z(TCGv reg, TCGv_i32 src)
 
388
{
 
389
    tcg_gen_extu_i32_tl(reg, src);
 
390
    tcg_gen_shri_tl(reg, reg, PSR_ZERO_SHIFT);
 
391
    tcg_gen_andi_tl(reg, reg, 0x1);
 
392
}
 
393
 
 
394
static inline void gen_mov_reg_V(TCGv reg, TCGv_i32 src)
 
395
{
 
396
    tcg_gen_extu_i32_tl(reg, src);
 
397
    tcg_gen_shri_tl(reg, reg, PSR_OVF_SHIFT);
 
398
    tcg_gen_andi_tl(reg, reg, 0x1);
 
399
}
 
400
 
 
401
static inline void gen_mov_reg_C(TCGv reg, TCGv_i32 src)
 
402
{
 
403
    tcg_gen_extu_i32_tl(reg, src);
 
404
    tcg_gen_shri_tl(reg, reg, PSR_CARRY_SHIFT);
 
405
    tcg_gen_andi_tl(reg, reg, 0x1);
 
406
}
 
407
 
 
408
static inline void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2)
 
409
{
 
410
    tcg_gen_mov_tl(cpu_cc_src, src1);
 
411
    tcg_gen_mov_tl(cpu_cc_src2, src2);
 
412
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
 
413
    tcg_gen_mov_tl(dst, cpu_cc_dst);
 
414
}
 
415
 
 
416
static TCGv_i32 gen_add32_carry32(void)
 
417
{
 
418
    TCGv_i32 carry_32, cc_src1_32, cc_src2_32;
 
419
 
 
420
    /* Carry is computed from a previous add: (dst < src)  */
 
421
#if TARGET_LONG_BITS == 64
 
422
    cc_src1_32 = tcg_temp_new_i32();
 
423
    cc_src2_32 = tcg_temp_new_i32();
 
424
    tcg_gen_extrl_i64_i32(cc_src1_32, cpu_cc_dst);
 
425
    tcg_gen_extrl_i64_i32(cc_src2_32, cpu_cc_src);
 
426
#else
 
427
    cc_src1_32 = cpu_cc_dst;
 
428
    cc_src2_32 = cpu_cc_src;
 
429
#endif
 
430
 
 
431
    carry_32 = tcg_temp_new_i32();
 
432
    tcg_gen_setcond_i32(TCG_COND_LTU, carry_32, cc_src1_32, cc_src2_32);
 
433
 
 
434
#if TARGET_LONG_BITS == 64
 
435
    tcg_temp_free_i32(cc_src1_32);
 
436
    tcg_temp_free_i32(cc_src2_32);
 
437
#endif
 
438
 
 
439
    return carry_32;
 
440
}
 
441
 
 
442
static TCGv_i32 gen_sub32_carry32(void)
 
443
{
 
444
    TCGv_i32 carry_32, cc_src1_32, cc_src2_32;
 
445
 
 
446
    /* Carry is computed from a previous borrow: (src1 < src2)  */
 
447
#if TARGET_LONG_BITS == 64
 
448
    cc_src1_32 = tcg_temp_new_i32();
 
449
    cc_src2_32 = tcg_temp_new_i32();
 
450
    tcg_gen_extrl_i64_i32(cc_src1_32, cpu_cc_src);
 
451
    tcg_gen_extrl_i64_i32(cc_src2_32, cpu_cc_src2);
 
452
#else
 
453
    cc_src1_32 = cpu_cc_src;
 
454
    cc_src2_32 = cpu_cc_src2;
 
455
#endif
 
456
 
 
457
    carry_32 = tcg_temp_new_i32();
 
458
    tcg_gen_setcond_i32(TCG_COND_LTU, carry_32, cc_src1_32, cc_src2_32);
 
459
 
 
460
#if TARGET_LONG_BITS == 64
 
461
    tcg_temp_free_i32(cc_src1_32);
 
462
    tcg_temp_free_i32(cc_src2_32);
 
463
#endif
 
464
 
 
465
    return carry_32;
 
466
}
 
467
 
 
468
static void gen_op_addx_int(DisasContext *dc, TCGv dst, TCGv src1,
 
469
                            TCGv src2, int update_cc)
 
470
{
 
471
    TCGv_i32 carry_32;
 
472
    TCGv carry;
 
473
 
 
474
    switch (dc->cc_op) {
 
475
    case CC_OP_DIV:
 
476
    case CC_OP_LOGIC:
 
477
        /* Carry is known to be zero.  Fall back to plain ADD.  */
 
478
        if (update_cc) {
 
479
            gen_op_add_cc(dst, src1, src2);
 
480
        } else {
 
481
            tcg_gen_add_tl(dst, src1, src2);
 
482
        }
 
483
        return;
 
484
 
 
485
    case CC_OP_ADD:
 
486
    case CC_OP_TADD:
 
487
    case CC_OP_TADDTV:
 
488
        if (TARGET_LONG_BITS == 32) {
 
489
            /* We can re-use the host's hardware carry generation by using
 
490
               an ADD2 opcode.  We discard the low part of the output.
 
491
               Ideally we'd combine this operation with the add that
 
492
               generated the carry in the first place.  */
 
493
            carry = tcg_temp_new();
 
494
            tcg_gen_add2_tl(carry, dst, cpu_cc_src, src1, cpu_cc_src2, src2);
 
495
            tcg_temp_free(carry);
 
496
            goto add_done;
 
497
        }
 
498
        carry_32 = gen_add32_carry32();
 
499
        break;
 
500
 
 
501
    case CC_OP_SUB:
 
502
    case CC_OP_TSUB:
 
503
    case CC_OP_TSUBTV:
 
504
        carry_32 = gen_sub32_carry32();
 
505
        break;
 
506
 
 
507
    default:
 
508
        /* We need external help to produce the carry.  */
 
509
        carry_32 = tcg_temp_new_i32();
 
510
        gen_helper_compute_C_icc(carry_32, cpu_env);
 
511
        break;
 
512
    }
 
513
 
 
514
#if TARGET_LONG_BITS == 64
 
515
    carry = tcg_temp_new();
 
516
    tcg_gen_extu_i32_i64(carry, carry_32);
 
517
#else
 
518
    carry = carry_32;
 
519
#endif
 
520
 
 
521
    tcg_gen_add_tl(dst, src1, src2);
 
522
    tcg_gen_add_tl(dst, dst, carry);
 
523
 
 
524
    tcg_temp_free_i32(carry_32);
 
525
#if TARGET_LONG_BITS == 64
 
526
    tcg_temp_free(carry);
 
527
#endif
 
528
 
 
529
 add_done:
 
530
    if (update_cc) {
 
531
        tcg_gen_mov_tl(cpu_cc_src, src1);
 
532
        tcg_gen_mov_tl(cpu_cc_src2, src2);
 
533
        tcg_gen_mov_tl(cpu_cc_dst, dst);
 
534
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADDX);
 
535
        dc->cc_op = CC_OP_ADDX;
 
536
    }
 
537
}
 
538
 
 
539
static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2)
 
540
{
 
541
    tcg_gen_mov_tl(cpu_cc_src, src1);
 
542
    tcg_gen_mov_tl(cpu_cc_src2, src2);
 
543
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
 
544
    tcg_gen_mov_tl(dst, cpu_cc_dst);
 
545
}
 
546
 
 
547
static void gen_op_subx_int(DisasContext *dc, TCGv dst, TCGv src1,
 
548
                            TCGv src2, int update_cc)
 
549
{
 
550
    TCGv_i32 carry_32;
 
551
    TCGv carry;
 
552
 
 
553
    switch (dc->cc_op) {
 
554
    case CC_OP_DIV:
 
555
    case CC_OP_LOGIC:
 
556
        /* Carry is known to be zero.  Fall back to plain SUB.  */
 
557
        if (update_cc) {
 
558
            gen_op_sub_cc(dst, src1, src2);
 
559
        } else {
 
560
            tcg_gen_sub_tl(dst, src1, src2);
 
561
        }
 
562
        return;
 
563
 
 
564
    case CC_OP_ADD:
 
565
    case CC_OP_TADD:
 
566
    case CC_OP_TADDTV:
 
567
        carry_32 = gen_add32_carry32();
 
568
        break;
 
569
 
 
570
    case CC_OP_SUB:
 
571
    case CC_OP_TSUB:
 
572
    case CC_OP_TSUBTV:
 
573
        if (TARGET_LONG_BITS == 32) {
 
574
            /* We can re-use the host's hardware carry generation by using
 
575
               a SUB2 opcode.  We discard the low part of the output.
 
576
               Ideally we'd combine this operation with the add that
 
577
               generated the carry in the first place.  */
 
578
            carry = tcg_temp_new();
 
579
            tcg_gen_sub2_tl(carry, dst, cpu_cc_src, src1, cpu_cc_src2, src2);
 
580
            tcg_temp_free(carry);
 
581
            goto sub_done;
 
582
        }
 
583
        carry_32 = gen_sub32_carry32();
 
584
        break;
 
585
 
 
586
    default:
 
587
        /* We need external help to produce the carry.  */
 
588
        carry_32 = tcg_temp_new_i32();
 
589
        gen_helper_compute_C_icc(carry_32, cpu_env);
 
590
        break;
 
591
    }
 
592
 
 
593
#if TARGET_LONG_BITS == 64
 
594
    carry = tcg_temp_new();
 
595
    tcg_gen_extu_i32_i64(carry, carry_32);
 
596
#else
 
597
    carry = carry_32;
 
598
#endif
 
599
 
 
600
    tcg_gen_sub_tl(dst, src1, src2);
 
601
    tcg_gen_sub_tl(dst, dst, carry);
 
602
 
 
603
    tcg_temp_free_i32(carry_32);
 
604
#if TARGET_LONG_BITS == 64
 
605
    tcg_temp_free(carry);
 
606
#endif
 
607
 
 
608
 sub_done:
 
609
    if (update_cc) {
 
610
        tcg_gen_mov_tl(cpu_cc_src, src1);
 
611
        tcg_gen_mov_tl(cpu_cc_src2, src2);
 
612
        tcg_gen_mov_tl(cpu_cc_dst, dst);
 
613
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUBX);
 
614
        dc->cc_op = CC_OP_SUBX;
 
615
    }
 
616
}
 
617
 
 
618
static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
 
619
{
 
620
    TCGv r_temp, zero, t0;
 
621
 
 
622
    r_temp = tcg_temp_new();
 
623
    t0 = tcg_temp_new();
 
624
 
 
625
    /* old op:
 
626
    if (!(env->y & 1))
 
627
        T1 = 0;
 
628
    */
 
629
    zero = tcg_const_tl(0);
 
630
    tcg_gen_andi_tl(cpu_cc_src, src1, 0xffffffff);
 
631
    tcg_gen_andi_tl(r_temp, cpu_y, 0x1);
 
632
    tcg_gen_andi_tl(cpu_cc_src2, src2, 0xffffffff);
 
633
    tcg_gen_movcond_tl(TCG_COND_EQ, cpu_cc_src2, r_temp, zero,
 
634
                       zero, cpu_cc_src2);
 
635
    tcg_temp_free(zero);
 
636
 
 
637
    // b2 = T0 & 1;
 
638
    // env->y = (b2 << 31) | (env->y >> 1);
 
639
    tcg_gen_andi_tl(r_temp, cpu_cc_src, 0x1);
 
640
    tcg_gen_shli_tl(r_temp, r_temp, 31);
 
641
    tcg_gen_shri_tl(t0, cpu_y, 1);
 
642
    tcg_gen_andi_tl(t0, t0, 0x7fffffff);
 
643
    tcg_gen_or_tl(t0, t0, r_temp);
 
644
    tcg_gen_andi_tl(cpu_y, t0, 0xffffffff);
 
645
 
 
646
    // b1 = N ^ V;
 
647
    gen_mov_reg_N(t0, cpu_psr);
 
648
    gen_mov_reg_V(r_temp, cpu_psr);
 
649
    tcg_gen_xor_tl(t0, t0, r_temp);
 
650
    tcg_temp_free(r_temp);
 
651
 
 
652
    // T0 = (b1 << 31) | (T0 >> 1);
 
653
    // src1 = T0;
 
654
    tcg_gen_shli_tl(t0, t0, 31);
 
655
    tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
 
656
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0);
 
657
    tcg_temp_free(t0);
 
658
 
 
659
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
 
660
 
 
661
    tcg_gen_mov_tl(dst, cpu_cc_dst);
 
662
}
 
663
 
 
664
static inline void gen_op_multiply(TCGv dst, TCGv src1, TCGv src2, int sign_ext)
 
665
{
 
666
#if TARGET_LONG_BITS == 32
 
667
    if (sign_ext) {
 
668
        tcg_gen_muls2_tl(dst, cpu_y, src1, src2);
 
669
    } else {
 
670
        tcg_gen_mulu2_tl(dst, cpu_y, src1, src2);
 
671
    }
 
672
#else
 
673
    TCGv t0 = tcg_temp_new_i64();
 
674
    TCGv t1 = tcg_temp_new_i64();
 
675
 
 
676
    if (sign_ext) {
 
677
        tcg_gen_ext32s_i64(t0, src1);
 
678
        tcg_gen_ext32s_i64(t1, src2);
 
679
    } else {
 
680
        tcg_gen_ext32u_i64(t0, src1);
 
681
        tcg_gen_ext32u_i64(t1, src2);
 
682
    }
 
683
 
 
684
    tcg_gen_mul_i64(dst, t0, t1);
 
685
    tcg_temp_free(t0);
 
686
    tcg_temp_free(t1);
 
687
 
 
688
    tcg_gen_shri_i64(cpu_y, dst, 32);
 
689
#endif
 
690
}
 
691
 
 
692
static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
 
693
{
 
694
    /* zero-extend truncated operands before multiplication */
 
695
    gen_op_multiply(dst, src1, src2, 0);
 
696
}
 
697
 
 
698
static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
 
699
{
 
700
    /* sign-extend truncated operands before multiplication */
 
701
    gen_op_multiply(dst, src1, src2, 1);
 
702
}
 
703
 
 
704
// 1
 
705
static inline void gen_op_eval_ba(TCGv dst)
 
706
{
 
707
    tcg_gen_movi_tl(dst, 1);
 
708
}
 
709
 
 
710
// Z
 
711
static inline void gen_op_eval_be(TCGv dst, TCGv_i32 src)
 
712
{
 
713
    gen_mov_reg_Z(dst, src);
 
714
}
 
715
 
 
716
// Z | (N ^ V)
 
717
static inline void gen_op_eval_ble(TCGv dst, TCGv_i32 src)
 
718
{
 
719
    TCGv t0 = tcg_temp_new();
 
720
    gen_mov_reg_N(t0, src);
 
721
    gen_mov_reg_V(dst, src);
 
722
    tcg_gen_xor_tl(dst, dst, t0);
 
723
    gen_mov_reg_Z(t0, src);
 
724
    tcg_gen_or_tl(dst, dst, t0);
 
725
    tcg_temp_free(t0);
 
726
}
 
727
 
 
728
// N ^ V
 
729
static inline void gen_op_eval_bl(TCGv dst, TCGv_i32 src)
 
730
{
 
731
    TCGv t0 = tcg_temp_new();
 
732
    gen_mov_reg_V(t0, src);
 
733
    gen_mov_reg_N(dst, src);
 
734
    tcg_gen_xor_tl(dst, dst, t0);
 
735
    tcg_temp_free(t0);
 
736
}
 
737
 
 
738
// C | Z
 
739
static inline void gen_op_eval_bleu(TCGv dst, TCGv_i32 src)
 
740
{
 
741
    TCGv t0 = tcg_temp_new();
 
742
    gen_mov_reg_Z(t0, src);
 
743
    gen_mov_reg_C(dst, src);
 
744
    tcg_gen_or_tl(dst, dst, t0);
 
745
    tcg_temp_free(t0);
 
746
}
 
747
 
 
748
// C
 
749
static inline void gen_op_eval_bcs(TCGv dst, TCGv_i32 src)
 
750
{
 
751
    gen_mov_reg_C(dst, src);
 
752
}
 
753
 
 
754
// V
 
755
static inline void gen_op_eval_bvs(TCGv dst, TCGv_i32 src)
 
756
{
 
757
    gen_mov_reg_V(dst, src);
 
758
}
 
759
 
 
760
// 0
 
761
static inline void gen_op_eval_bn(TCGv dst)
 
762
{
 
763
    tcg_gen_movi_tl(dst, 0);
 
764
}
 
765
 
 
766
// N
 
767
static inline void gen_op_eval_bneg(TCGv dst, TCGv_i32 src)
 
768
{
 
769
    gen_mov_reg_N(dst, src);
 
770
}
 
771
 
 
772
// !Z
 
773
static inline void gen_op_eval_bne(TCGv dst, TCGv_i32 src)
 
774
{
 
775
    gen_mov_reg_Z(dst, src);
 
776
    tcg_gen_xori_tl(dst, dst, 0x1);
 
777
}
 
778
 
 
779
// !(Z | (N ^ V))
 
780
static inline void gen_op_eval_bg(TCGv dst, TCGv_i32 src)
 
781
{
 
782
    gen_op_eval_ble(dst, src);
 
783
    tcg_gen_xori_tl(dst, dst, 0x1);
 
784
}
 
785
 
 
786
// !(N ^ V)
 
787
static inline void gen_op_eval_bge(TCGv dst, TCGv_i32 src)
 
788
{
 
789
    gen_op_eval_bl(dst, src);
 
790
    tcg_gen_xori_tl(dst, dst, 0x1);
 
791
}
 
792
 
 
793
// !(C | Z)
 
794
static inline void gen_op_eval_bgu(TCGv dst, TCGv_i32 src)
 
795
{
 
796
    gen_op_eval_bleu(dst, src);
 
797
    tcg_gen_xori_tl(dst, dst, 0x1);
 
798
}
 
799
 
 
800
// !C
 
801
static inline void gen_op_eval_bcc(TCGv dst, TCGv_i32 src)
 
802
{
 
803
    gen_mov_reg_C(dst, src);
 
804
    tcg_gen_xori_tl(dst, dst, 0x1);
 
805
}
 
806
 
 
807
// !N
 
808
static inline void gen_op_eval_bpos(TCGv dst, TCGv_i32 src)
 
809
{
 
810
    gen_mov_reg_N(dst, src);
 
811
    tcg_gen_xori_tl(dst, dst, 0x1);
 
812
}
 
813
 
 
814
// !V
 
815
static inline void gen_op_eval_bvc(TCGv dst, TCGv_i32 src)
 
816
{
 
817
    gen_mov_reg_V(dst, src);
 
818
    tcg_gen_xori_tl(dst, dst, 0x1);
 
819
}
 
820
 
 
821
/*
 
822
  FPSR bit field FCC1 | FCC0:
 
823
   0 =
 
824
   1 <
 
825
   2 >
 
826
   3 unordered
 
827
*/
 
828
static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src,
 
829
                                    unsigned int fcc_offset)
 
830
{
 
831
    tcg_gen_shri_tl(reg, src, FSR_FCC0_SHIFT + fcc_offset);
 
832
    tcg_gen_andi_tl(reg, reg, 0x1);
 
833
}
 
834
 
 
835
static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
 
836
                                    unsigned int fcc_offset)
 
837
{
 
838
    tcg_gen_shri_tl(reg, src, FSR_FCC1_SHIFT + fcc_offset);
 
839
    tcg_gen_andi_tl(reg, reg, 0x1);
 
840
}
 
841
 
 
842
// !0: FCC0 | FCC1
 
843
static inline void gen_op_eval_fbne(TCGv dst, TCGv src,
 
844
                                    unsigned int fcc_offset)
 
845
{
 
846
    TCGv t0 = tcg_temp_new();
 
847
    gen_mov_reg_FCC0(dst, src, fcc_offset);
 
848
    gen_mov_reg_FCC1(t0, src, fcc_offset);
 
849
    tcg_gen_or_tl(dst, dst, t0);
 
850
    tcg_temp_free(t0);
 
851
}
 
852
 
 
853
// 1 or 2: FCC0 ^ FCC1
 
854
static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
 
855
                                    unsigned int fcc_offset)
 
856
{
 
857
    TCGv t0 = tcg_temp_new();
 
858
    gen_mov_reg_FCC0(dst, src, fcc_offset);
 
859
    gen_mov_reg_FCC1(t0, src, fcc_offset);
 
860
    tcg_gen_xor_tl(dst, dst, t0);
 
861
    tcg_temp_free(t0);
 
862
}
 
863
 
 
864
// 1 or 3: FCC0
 
865
static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
 
866
                                    unsigned int fcc_offset)
 
867
{
 
868
    gen_mov_reg_FCC0(dst, src, fcc_offset);
 
869
}
 
870
 
 
871
// 1: FCC0 & !FCC1
 
872
static inline void gen_op_eval_fbl(TCGv dst, TCGv src,
 
873
                                    unsigned int fcc_offset)
 
874
{
 
875
    TCGv t0 = tcg_temp_new();
 
876
    gen_mov_reg_FCC0(dst, src, fcc_offset);
 
877
    gen_mov_reg_FCC1(t0, src, fcc_offset);
 
878
    tcg_gen_andc_tl(dst, dst, t0);
 
879
    tcg_temp_free(t0);
 
880
}
 
881
 
 
882
// 2 or 3: FCC1
 
883
static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
 
884
                                    unsigned int fcc_offset)
 
885
{
 
886
    gen_mov_reg_FCC1(dst, src, fcc_offset);
 
887
}
 
888
 
 
889
// 2: !FCC0 & FCC1
 
890
static inline void gen_op_eval_fbg(TCGv dst, TCGv src,
 
891
                                    unsigned int fcc_offset)
 
892
{
 
893
    TCGv t0 = tcg_temp_new();
 
894
    gen_mov_reg_FCC0(dst, src, fcc_offset);
 
895
    gen_mov_reg_FCC1(t0, src, fcc_offset);
 
896
    tcg_gen_andc_tl(dst, t0, dst);
 
897
    tcg_temp_free(t0);
 
898
}
 
899
 
 
900
// 3: FCC0 & FCC1
 
901
static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
 
902
                                    unsigned int fcc_offset)
 
903
{
 
904
    TCGv t0 = tcg_temp_new();
 
905
    gen_mov_reg_FCC0(dst, src, fcc_offset);
 
906
    gen_mov_reg_FCC1(t0, src, fcc_offset);
 
907
    tcg_gen_and_tl(dst, dst, t0);
 
908
    tcg_temp_free(t0);
 
909
}
 
910
 
 
911
// 0: !(FCC0 | FCC1)
 
912
static inline void gen_op_eval_fbe(TCGv dst, TCGv src,
 
913
                                    unsigned int fcc_offset)
 
914
{
 
915
    TCGv t0 = tcg_temp_new();
 
916
    gen_mov_reg_FCC0(dst, src, fcc_offset);
 
917
    gen_mov_reg_FCC1(t0, src, fcc_offset);
 
918
    tcg_gen_or_tl(dst, dst, t0);
 
919
    tcg_gen_xori_tl(dst, dst, 0x1);
 
920
    tcg_temp_free(t0);
 
921
}
 
922
 
 
923
// 0 or 3: !(FCC0 ^ FCC1)
 
924
static inline void gen_op_eval_fbue(TCGv dst, TCGv src,
 
925
                                    unsigned int fcc_offset)
 
926
{
 
927
    TCGv t0 = tcg_temp_new();
 
928
    gen_mov_reg_FCC0(dst, src, fcc_offset);
 
929
    gen_mov_reg_FCC1(t0, src, fcc_offset);
 
930
    tcg_gen_xor_tl(dst, dst, t0);
 
931
    tcg_gen_xori_tl(dst, dst, 0x1);
 
932
    tcg_temp_free(t0);
 
933
}
 
934
 
 
935
// 0 or 2: !FCC0
 
936
static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
 
937
                                    unsigned int fcc_offset)
 
938
{
 
939
    gen_mov_reg_FCC0(dst, src, fcc_offset);
 
940
    tcg_gen_xori_tl(dst, dst, 0x1);
 
941
}
 
942
 
 
943
// !1: !(FCC0 & !FCC1)
 
944
static inline void gen_op_eval_fbuge(TCGv dst, TCGv src,
 
945
                                    unsigned int fcc_offset)
 
946
{
 
947
    TCGv t0 = tcg_temp_new();
 
948
    gen_mov_reg_FCC0(dst, src, fcc_offset);
 
949
    gen_mov_reg_FCC1(t0, src, fcc_offset);
 
950
    tcg_gen_andc_tl(dst, dst, t0);
 
951
    tcg_gen_xori_tl(dst, dst, 0x1);
 
952
    tcg_temp_free(t0);
 
953
}
 
954
 
 
955
// 0 or 1: !FCC1
 
956
static inline void gen_op_eval_fble(TCGv dst, TCGv src,
 
957
                                    unsigned int fcc_offset)
 
958
{
 
959
    gen_mov_reg_FCC1(dst, src, fcc_offset);
 
960
    tcg_gen_xori_tl(dst, dst, 0x1);
 
961
}
 
962
 
 
963
// !2: !(!FCC0 & FCC1)
 
964
static inline void gen_op_eval_fbule(TCGv dst, TCGv src,
 
965
                                    unsigned int fcc_offset)
 
966
{
 
967
    TCGv t0 = tcg_temp_new();
 
968
    gen_mov_reg_FCC0(dst, src, fcc_offset);
 
969
    gen_mov_reg_FCC1(t0, src, fcc_offset);
 
970
    tcg_gen_andc_tl(dst, t0, dst);
 
971
    tcg_gen_xori_tl(dst, dst, 0x1);
 
972
    tcg_temp_free(t0);
 
973
}
 
974
 
 
975
// !3: !(FCC0 & FCC1)
 
976
static inline void gen_op_eval_fbo(TCGv dst, TCGv src,
 
977
                                    unsigned int fcc_offset)
 
978
{
 
979
    TCGv t0 = tcg_temp_new();
 
980
    gen_mov_reg_FCC0(dst, src, fcc_offset);
 
981
    gen_mov_reg_FCC1(t0, src, fcc_offset);
 
982
    tcg_gen_and_tl(dst, dst, t0);
 
983
    tcg_gen_xori_tl(dst, dst, 0x1);
 
984
    tcg_temp_free(t0);
 
985
}
 
986
 
 
987
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
 
988
                               target_ulong pc2, TCGv r_cond)
 
989
{
 
990
    TCGLabel *l1 = gen_new_label();
 
991
 
 
992
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
 
993
 
 
994
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
 
995
 
 
996
    gen_set_label(l1);
 
997
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
 
998
}
 
999
 
 
1000
static void gen_branch_a(DisasContext *dc, target_ulong pc1)
 
1001
{
 
1002
    TCGLabel *l1 = gen_new_label();
 
1003
    target_ulong npc = dc->npc;
 
1004
 
 
1005
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cond, 0, l1);
 
1006
 
 
1007
    gen_goto_tb(dc, 0, npc, pc1);
 
1008
 
 
1009
    gen_set_label(l1);
 
1010
    gen_goto_tb(dc, 1, npc + 4, npc + 8);
 
1011
 
 
1012
    dc->is_br = 1;
 
1013
}
 
1014
 
 
1015
static void gen_branch_n(DisasContext *dc, target_ulong pc1)
 
1016
{
 
1017
    target_ulong npc = dc->npc;
 
1018
 
 
1019
    if (likely(npc != DYNAMIC_PC)) {
 
1020
        dc->pc = npc;
 
1021
        dc->jump_pc[0] = pc1;
 
1022
        dc->jump_pc[1] = npc + 4;
 
1023
        dc->npc = JUMP_PC;
 
1024
    } else {
 
1025
        TCGv t, z;
 
1026
 
 
1027
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
 
1028
 
 
1029
        tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
 
1030
        t = tcg_const_tl(pc1);
 
1031
        z = tcg_const_tl(0);
 
1032
        tcg_gen_movcond_tl(TCG_COND_NE, cpu_npc, cpu_cond, z, t, cpu_npc);
 
1033
        tcg_temp_free(t);
 
1034
        tcg_temp_free(z);
 
1035
 
 
1036
        dc->pc = DYNAMIC_PC;
 
1037
    }
 
1038
}
 
1039
 
 
1040
static inline void gen_generic_branch(DisasContext *dc)
 
1041
{
 
1042
    TCGv npc0 = tcg_const_tl(dc->jump_pc[0]);
 
1043
    TCGv npc1 = tcg_const_tl(dc->jump_pc[1]);
 
1044
    TCGv zero = tcg_const_tl(0);
 
1045
 
 
1046
    tcg_gen_movcond_tl(TCG_COND_NE, cpu_npc, cpu_cond, zero, npc0, npc1);
 
1047
 
 
1048
    tcg_temp_free(npc0);
 
1049
    tcg_temp_free(npc1);
 
1050
    tcg_temp_free(zero);
 
1051
}
 
1052
 
 
1053
/* call this function before using the condition register as it may
 
1054
   have been set for a jump */
 
1055
static inline void flush_cond(DisasContext *dc)
 
1056
{
 
1057
    if (dc->npc == JUMP_PC) {
 
1058
        gen_generic_branch(dc);
 
1059
        dc->npc = DYNAMIC_PC;
 
1060
    }
 
1061
}
 
1062
 
 
1063
static inline void save_npc(DisasContext *dc)
 
1064
{
 
1065
    if (dc->npc == JUMP_PC) {
 
1066
        gen_generic_branch(dc);
 
1067
        dc->npc = DYNAMIC_PC;
 
1068
    } else if (dc->npc != DYNAMIC_PC) {
 
1069
        tcg_gen_movi_tl(cpu_npc, dc->npc);
 
1070
    }
 
1071
}
 
1072
 
 
1073
static inline void update_psr(DisasContext *dc)
 
1074
{
 
1075
    if (dc->cc_op != CC_OP_FLAGS) {
 
1076
        dc->cc_op = CC_OP_FLAGS;
 
1077
        gen_helper_compute_psr(cpu_env);
 
1078
    }
 
1079
}
 
1080
 
 
1081
static inline void save_state(DisasContext *dc)
 
1082
{
 
1083
    tcg_gen_movi_tl(cpu_pc, dc->pc);
 
1084
    save_npc(dc);
 
1085
}
 
1086
 
 
1087
static void gen_exception(DisasContext *dc, int which)
 
1088
{
 
1089
    TCGv_i32 t;
 
1090
 
 
1091
    save_state(dc);
 
1092
    t = tcg_const_i32(which);
 
1093
    gen_helper_raise_exception(cpu_env, t);
 
1094
    tcg_temp_free_i32(t);
 
1095
    dc->is_br = 1;
 
1096
}
 
1097
 
 
1098
static void gen_check_align(TCGv addr, int mask)
 
1099
{
 
1100
    TCGv_i32 r_mask = tcg_const_i32(mask);
 
1101
    gen_helper_check_align(cpu_env, addr, r_mask);
 
1102
    tcg_temp_free_i32(r_mask);
 
1103
}
 
1104
 
 
1105
static inline void gen_mov_pc_npc(DisasContext *dc)
 
1106
{
 
1107
    if (dc->npc == JUMP_PC) {
 
1108
        gen_generic_branch(dc);
 
1109
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
 
1110
        dc->pc = DYNAMIC_PC;
 
1111
    } else if (dc->npc == DYNAMIC_PC) {
 
1112
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
 
1113
        dc->pc = DYNAMIC_PC;
 
1114
    } else {
 
1115
        dc->pc = dc->npc;
 
1116
    }
 
1117
}
 
1118
 
 
1119
static inline void gen_op_next_insn(void)
 
1120
{
 
1121
    tcg_gen_mov_tl(cpu_pc, cpu_npc);
 
1122
    tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
 
1123
}
 
1124
 
 
1125
static void free_compare(DisasCompare *cmp)
 
1126
{
 
1127
    if (!cmp->g1) {
 
1128
        tcg_temp_free(cmp->c1);
 
1129
    }
 
1130
    if (!cmp->g2) {
 
1131
        tcg_temp_free(cmp->c2);
 
1132
    }
 
1133
}
 
1134
 
 
1135
static void gen_compare(DisasCompare *cmp, bool xcc, unsigned int cond,
 
1136
                        DisasContext *dc)
 
1137
{
 
1138
    static int subcc_cond[16] = {
 
1139
        TCG_COND_NEVER,
 
1140
        TCG_COND_EQ,
 
1141
        TCG_COND_LE,
 
1142
        TCG_COND_LT,
 
1143
        TCG_COND_LEU,
 
1144
        TCG_COND_LTU,
 
1145
        -1, /* neg */
 
1146
        -1, /* overflow */
 
1147
        TCG_COND_ALWAYS,
 
1148
        TCG_COND_NE,
 
1149
        TCG_COND_GT,
 
1150
        TCG_COND_GE,
 
1151
        TCG_COND_GTU,
 
1152
        TCG_COND_GEU,
 
1153
        -1, /* pos */
 
1154
        -1, /* no overflow */
 
1155
    };
 
1156
 
 
1157
    static int logic_cond[16] = {
 
1158
        TCG_COND_NEVER,
 
1159
        TCG_COND_EQ,     /* eq:  Z */
 
1160
        TCG_COND_LE,     /* le:  Z | (N ^ V) -> Z | N */
 
1161
        TCG_COND_LT,     /* lt:  N ^ V -> N */
 
1162
        TCG_COND_EQ,     /* leu: C | Z -> Z */
 
1163
        TCG_COND_NEVER,  /* ltu: C -> 0 */
 
1164
        TCG_COND_LT,     /* neg: N */
 
1165
        TCG_COND_NEVER,  /* vs:  V -> 0 */
 
1166
        TCG_COND_ALWAYS,
 
1167
        TCG_COND_NE,     /* ne:  !Z */
 
1168
        TCG_COND_GT,     /* gt:  !(Z | (N ^ V)) -> !(Z | N) */
 
1169
        TCG_COND_GE,     /* ge:  !(N ^ V) -> !N */
 
1170
        TCG_COND_NE,     /* gtu: !(C | Z) -> !Z */
 
1171
        TCG_COND_ALWAYS, /* geu: !C -> 1 */
 
1172
        TCG_COND_GE,     /* pos: !N */
 
1173
        TCG_COND_ALWAYS, /* vc:  !V -> 1 */
 
1174
    };
 
1175
 
 
1176
    TCGv_i32 r_src;
 
1177
    TCGv r_dst;
 
1178
 
 
1179
#ifdef TARGET_SPARC64
 
1180
    if (xcc) {
 
1181
        r_src = cpu_xcc;
 
1182
    } else {
 
1183
        r_src = cpu_psr;
 
1184
    }
 
1185
#else
 
1186
    r_src = cpu_psr;
 
1187
#endif
 
1188
 
 
1189
    switch (dc->cc_op) {
 
1190
    case CC_OP_LOGIC:
 
1191
        cmp->cond = logic_cond[cond];
 
1192
    do_compare_dst_0:
 
1193
        cmp->is_bool = false;
 
1194
        cmp->g2 = false;
 
1195
        cmp->c2 = tcg_const_tl(0);
 
1196
#ifdef TARGET_SPARC64
 
1197
        if (!xcc) {
 
1198
            cmp->g1 = false;
 
1199
            cmp->c1 = tcg_temp_new();
 
1200
            tcg_gen_ext32s_tl(cmp->c1, cpu_cc_dst);
 
1201
            break;
 
1202
        }
 
1203
#endif
 
1204
        cmp->g1 = true;
 
1205
        cmp->c1 = cpu_cc_dst;
 
1206
        break;
 
1207
 
 
1208
    case CC_OP_SUB:
 
1209
        switch (cond) {
 
1210
        case 6:  /* neg */
 
1211
        case 14: /* pos */
 
1212
            cmp->cond = (cond == 6 ? TCG_COND_LT : TCG_COND_GE);
 
1213
            goto do_compare_dst_0;
 
1214
 
 
1215
        case 7: /* overflow */
 
1216
        case 15: /* !overflow */
 
1217
            goto do_dynamic;
 
1218
 
 
1219
        default:
 
1220
            cmp->cond = subcc_cond[cond];
 
1221
            cmp->is_bool = false;
 
1222
#ifdef TARGET_SPARC64
 
1223
            if (!xcc) {
 
1224
                /* Note that sign-extension works for unsigned compares as
 
1225
                   long as both operands are sign-extended.  */
 
1226
                cmp->g1 = cmp->g2 = false;
 
1227
                cmp->c1 = tcg_temp_new();
 
1228
                cmp->c2 = tcg_temp_new();
 
1229
                tcg_gen_ext32s_tl(cmp->c1, cpu_cc_src);
 
1230
                tcg_gen_ext32s_tl(cmp->c2, cpu_cc_src2);
 
1231
                break;
 
1232
            }
 
1233
#endif
 
1234
            cmp->g1 = cmp->g2 = true;
 
1235
            cmp->c1 = cpu_cc_src;
 
1236
            cmp->c2 = cpu_cc_src2;
 
1237
            break;
 
1238
        }
 
1239
        break;
 
1240
 
 
1241
    default:
 
1242
    do_dynamic:
 
1243
        gen_helper_compute_psr(cpu_env);
 
1244
        dc->cc_op = CC_OP_FLAGS;
 
1245
        /* FALLTHRU */
 
1246
 
 
1247
    case CC_OP_FLAGS:
 
1248
        /* We're going to generate a boolean result.  */
 
1249
        cmp->cond = TCG_COND_NE;
 
1250
        cmp->is_bool = true;
 
1251
        cmp->g1 = cmp->g2 = false;
 
1252
        cmp->c1 = r_dst = tcg_temp_new();
 
1253
        cmp->c2 = tcg_const_tl(0);
 
1254
 
 
1255
        switch (cond) {
 
1256
        case 0x0:
 
1257
            gen_op_eval_bn(r_dst);
 
1258
            break;
 
1259
        case 0x1:
 
1260
            gen_op_eval_be(r_dst, r_src);
 
1261
            break;
 
1262
        case 0x2:
 
1263
            gen_op_eval_ble(r_dst, r_src);
 
1264
            break;
 
1265
        case 0x3:
 
1266
            gen_op_eval_bl(r_dst, r_src);
 
1267
            break;
 
1268
        case 0x4:
 
1269
            gen_op_eval_bleu(r_dst, r_src);
 
1270
            break;
 
1271
        case 0x5:
 
1272
            gen_op_eval_bcs(r_dst, r_src);
 
1273
            break;
 
1274
        case 0x6:
 
1275
            gen_op_eval_bneg(r_dst, r_src);
 
1276
            break;
 
1277
        case 0x7:
 
1278
            gen_op_eval_bvs(r_dst, r_src);
 
1279
            break;
 
1280
        case 0x8:
 
1281
            gen_op_eval_ba(r_dst);
 
1282
            break;
 
1283
        case 0x9:
 
1284
            gen_op_eval_bne(r_dst, r_src);
 
1285
            break;
 
1286
        case 0xa:
 
1287
            gen_op_eval_bg(r_dst, r_src);
 
1288
            break;
 
1289
        case 0xb:
 
1290
            gen_op_eval_bge(r_dst, r_src);
 
1291
            break;
 
1292
        case 0xc:
 
1293
            gen_op_eval_bgu(r_dst, r_src);
 
1294
            break;
 
1295
        case 0xd:
 
1296
            gen_op_eval_bcc(r_dst, r_src);
 
1297
            break;
 
1298
        case 0xe:
 
1299
            gen_op_eval_bpos(r_dst, r_src);
 
1300
            break;
 
1301
        case 0xf:
 
1302
            gen_op_eval_bvc(r_dst, r_src);
 
1303
            break;
 
1304
        }
 
1305
        break;
 
1306
    }
 
1307
}
 
1308
 
 
1309
static void gen_fcompare(DisasCompare *cmp, unsigned int cc, unsigned int cond)
 
1310
{
 
1311
    unsigned int offset;
 
1312
    TCGv r_dst;
 
1313
 
 
1314
    /* For now we still generate a straight boolean result.  */
 
1315
    cmp->cond = TCG_COND_NE;
 
1316
    cmp->is_bool = true;
 
1317
    cmp->g1 = cmp->g2 = false;
 
1318
    cmp->c1 = r_dst = tcg_temp_new();
 
1319
    cmp->c2 = tcg_const_tl(0);
 
1320
 
 
1321
    switch (cc) {
 
1322
    default:
 
1323
    case 0x0:
 
1324
        offset = 0;
 
1325
        break;
 
1326
    case 0x1:
 
1327
        offset = 32 - 10;
 
1328
        break;
 
1329
    case 0x2:
 
1330
        offset = 34 - 10;
 
1331
        break;
 
1332
    case 0x3:
 
1333
        offset = 36 - 10;
 
1334
        break;
 
1335
    }
 
1336
 
 
1337
    switch (cond) {
 
1338
    case 0x0:
 
1339
        gen_op_eval_bn(r_dst);
 
1340
        break;
 
1341
    case 0x1:
 
1342
        gen_op_eval_fbne(r_dst, cpu_fsr, offset);
 
1343
        break;
 
1344
    case 0x2:
 
1345
        gen_op_eval_fblg(r_dst, cpu_fsr, offset);
 
1346
        break;
 
1347
    case 0x3:
 
1348
        gen_op_eval_fbul(r_dst, cpu_fsr, offset);
 
1349
        break;
 
1350
    case 0x4:
 
1351
        gen_op_eval_fbl(r_dst, cpu_fsr, offset);
 
1352
        break;
 
1353
    case 0x5:
 
1354
        gen_op_eval_fbug(r_dst, cpu_fsr, offset);
 
1355
        break;
 
1356
    case 0x6:
 
1357
        gen_op_eval_fbg(r_dst, cpu_fsr, offset);
 
1358
        break;
 
1359
    case 0x7:
 
1360
        gen_op_eval_fbu(r_dst, cpu_fsr, offset);
 
1361
        break;
 
1362
    case 0x8:
 
1363
        gen_op_eval_ba(r_dst);
 
1364
        break;
 
1365
    case 0x9:
 
1366
        gen_op_eval_fbe(r_dst, cpu_fsr, offset);
 
1367
        break;
 
1368
    case 0xa:
 
1369
        gen_op_eval_fbue(r_dst, cpu_fsr, offset);
 
1370
        break;
 
1371
    case 0xb:
 
1372
        gen_op_eval_fbge(r_dst, cpu_fsr, offset);
 
1373
        break;
 
1374
    case 0xc:
 
1375
        gen_op_eval_fbuge(r_dst, cpu_fsr, offset);
 
1376
        break;
 
1377
    case 0xd:
 
1378
        gen_op_eval_fble(r_dst, cpu_fsr, offset);
 
1379
        break;
 
1380
    case 0xe:
 
1381
        gen_op_eval_fbule(r_dst, cpu_fsr, offset);
 
1382
        break;
 
1383
    case 0xf:
 
1384
        gen_op_eval_fbo(r_dst, cpu_fsr, offset);
 
1385
        break;
 
1386
    }
 
1387
}
 
1388
 
 
1389
static void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond,
 
1390
                     DisasContext *dc)
 
1391
{
 
1392
    DisasCompare cmp;
 
1393
    gen_compare(&cmp, cc, cond, dc);
 
1394
 
 
1395
    /* The interface is to return a boolean in r_dst.  */
 
1396
    if (cmp.is_bool) {
 
1397
        tcg_gen_mov_tl(r_dst, cmp.c1);
 
1398
    } else {
 
1399
        tcg_gen_setcond_tl(cmp.cond, r_dst, cmp.c1, cmp.c2);
 
1400
    }
 
1401
 
 
1402
    free_compare(&cmp);
 
1403
}
 
1404
 
 
1405
static void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
 
1406
{
 
1407
    DisasCompare cmp;
 
1408
    gen_fcompare(&cmp, cc, cond);
 
1409
 
 
1410
    /* The interface is to return a boolean in r_dst.  */
 
1411
    if (cmp.is_bool) {
 
1412
        tcg_gen_mov_tl(r_dst, cmp.c1);
 
1413
    } else {
 
1414
        tcg_gen_setcond_tl(cmp.cond, r_dst, cmp.c1, cmp.c2);
 
1415
    }
 
1416
 
 
1417
    free_compare(&cmp);
 
1418
}
 
1419
 
 
1420
#ifdef TARGET_SPARC64
 
1421
// Inverted logic
 
1422
static const int gen_tcg_cond_reg[8] = {
 
1423
    -1,
 
1424
    TCG_COND_NE,
 
1425
    TCG_COND_GT,
 
1426
    TCG_COND_GE,
 
1427
    -1,
 
1428
    TCG_COND_EQ,
 
1429
    TCG_COND_LE,
 
1430
    TCG_COND_LT,
 
1431
};
 
1432
 
 
1433
static void gen_compare_reg(DisasCompare *cmp, int cond, TCGv r_src)
 
1434
{
 
1435
    cmp->cond = tcg_invert_cond(gen_tcg_cond_reg[cond]);
 
1436
    cmp->is_bool = false;
 
1437
    cmp->g1 = true;
 
1438
    cmp->g2 = false;
 
1439
    cmp->c1 = r_src;
 
1440
    cmp->c2 = tcg_const_tl(0);
 
1441
}
 
1442
 
 
1443
static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
 
1444
{
 
1445
    DisasCompare cmp;
 
1446
    gen_compare_reg(&cmp, cond, r_src);
 
1447
 
 
1448
    /* The interface is to return a boolean in r_dst.  */
 
1449
    tcg_gen_setcond_tl(cmp.cond, r_dst, cmp.c1, cmp.c2);
 
1450
 
 
1451
    free_compare(&cmp);
 
1452
}
 
1453
#endif
 
1454
 
 
1455
static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc)
 
1456
{
 
1457
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
 
1458
    target_ulong target = dc->pc + offset;
 
1459
 
 
1460
#ifdef TARGET_SPARC64
 
1461
    if (unlikely(AM_CHECK(dc))) {
 
1462
        target &= 0xffffffffULL;
 
1463
    }
 
1464
#endif
 
1465
    if (cond == 0x0) {
 
1466
        /* unconditional not taken */
 
1467
        if (a) {
 
1468
            dc->pc = dc->npc + 4;
 
1469
            dc->npc = dc->pc + 4;
 
1470
        } else {
 
1471
            dc->pc = dc->npc;
 
1472
            dc->npc = dc->pc + 4;
 
1473
        }
 
1474
    } else if (cond == 0x8) {
 
1475
        /* unconditional taken */
 
1476
        if (a) {
 
1477
            dc->pc = target;
 
1478
            dc->npc = dc->pc + 4;
 
1479
        } else {
 
1480
            dc->pc = dc->npc;
 
1481
            dc->npc = target;
 
1482
            tcg_gen_mov_tl(cpu_pc, cpu_npc);
 
1483
        }
 
1484
    } else {
 
1485
        flush_cond(dc);
 
1486
        gen_cond(cpu_cond, cc, cond, dc);
 
1487
        if (a) {
 
1488
            gen_branch_a(dc, target);
 
1489
        } else {
 
1490
            gen_branch_n(dc, target);
 
1491
        }
 
1492
    }
 
1493
}
 
1494
 
 
1495
static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc)
 
1496
{
 
1497
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
 
1498
    target_ulong target = dc->pc + offset;
 
1499
 
 
1500
#ifdef TARGET_SPARC64
 
1501
    if (unlikely(AM_CHECK(dc))) {
 
1502
        target &= 0xffffffffULL;
 
1503
    }
 
1504
#endif
 
1505
    if (cond == 0x0) {
 
1506
        /* unconditional not taken */
 
1507
        if (a) {
 
1508
            dc->pc = dc->npc + 4;
 
1509
            dc->npc = dc->pc + 4;
 
1510
        } else {
 
1511
            dc->pc = dc->npc;
 
1512
            dc->npc = dc->pc + 4;
 
1513
        }
 
1514
    } else if (cond == 0x8) {
 
1515
        /* unconditional taken */
 
1516
        if (a) {
 
1517
            dc->pc = target;
 
1518
            dc->npc = dc->pc + 4;
 
1519
        } else {
 
1520
            dc->pc = dc->npc;
 
1521
            dc->npc = target;
 
1522
            tcg_gen_mov_tl(cpu_pc, cpu_npc);
 
1523
        }
 
1524
    } else {
 
1525
        flush_cond(dc);
 
1526
        gen_fcond(cpu_cond, cc, cond);
 
1527
        if (a) {
 
1528
            gen_branch_a(dc, target);
 
1529
        } else {
 
1530
            gen_branch_n(dc, target);
 
1531
        }
 
1532
    }
 
1533
}
 
1534
 
 
1535
#ifdef TARGET_SPARC64
 
1536
static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
 
1537
                          TCGv r_reg)
 
1538
{
 
1539
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
 
1540
    target_ulong target = dc->pc + offset;
 
1541
 
 
1542
    if (unlikely(AM_CHECK(dc))) {
 
1543
        target &= 0xffffffffULL;
 
1544
    }
 
1545
    flush_cond(dc);
 
1546
    gen_cond_reg(cpu_cond, cond, r_reg);
 
1547
    if (a) {
 
1548
        gen_branch_a(dc, target);
 
1549
    } else {
 
1550
        gen_branch_n(dc, target);
 
1551
    }
 
1552
}
 
1553
 
 
1554
static inline void gen_op_fcmps(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
 
1555
{
 
1556
    switch (fccno) {
 
1557
    case 0:
 
1558
        gen_helper_fcmps(cpu_fsr, cpu_env, r_rs1, r_rs2);
 
1559
        break;
 
1560
    case 1:
 
1561
        gen_helper_fcmps_fcc1(cpu_fsr, cpu_env, r_rs1, r_rs2);
 
1562
        break;
 
1563
    case 2:
 
1564
        gen_helper_fcmps_fcc2(cpu_fsr, cpu_env, r_rs1, r_rs2);
 
1565
        break;
 
1566
    case 3:
 
1567
        gen_helper_fcmps_fcc3(cpu_fsr, cpu_env, r_rs1, r_rs2);
 
1568
        break;
 
1569
    }
 
1570
}
 
1571
 
 
1572
static inline void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
 
1573
{
 
1574
    switch (fccno) {
 
1575
    case 0:
 
1576
        gen_helper_fcmpd(cpu_fsr, cpu_env, r_rs1, r_rs2);
 
1577
        break;
 
1578
    case 1:
 
1579
        gen_helper_fcmpd_fcc1(cpu_fsr, cpu_env, r_rs1, r_rs2);
 
1580
        break;
 
1581
    case 2:
 
1582
        gen_helper_fcmpd_fcc2(cpu_fsr, cpu_env, r_rs1, r_rs2);
 
1583
        break;
 
1584
    case 3:
 
1585
        gen_helper_fcmpd_fcc3(cpu_fsr, cpu_env, r_rs1, r_rs2);
 
1586
        break;
 
1587
    }
 
1588
}
 
1589
 
 
1590
static inline void gen_op_fcmpq(int fccno)
 
1591
{
 
1592
    switch (fccno) {
 
1593
    case 0:
 
1594
        gen_helper_fcmpq(cpu_fsr, cpu_env);
 
1595
        break;
 
1596
    case 1:
 
1597
        gen_helper_fcmpq_fcc1(cpu_fsr, cpu_env);
 
1598
        break;
 
1599
    case 2:
 
1600
        gen_helper_fcmpq_fcc2(cpu_fsr, cpu_env);
 
1601
        break;
 
1602
    case 3:
 
1603
        gen_helper_fcmpq_fcc3(cpu_fsr, cpu_env);
 
1604
        break;
 
1605
    }
 
1606
}
 
1607
 
 
1608
static inline void gen_op_fcmpes(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
 
1609
{
 
1610
    switch (fccno) {
 
1611
    case 0:
 
1612
        gen_helper_fcmpes(cpu_fsr, cpu_env, r_rs1, r_rs2);
 
1613
        break;
 
1614
    case 1:
 
1615
        gen_helper_fcmpes_fcc1(cpu_fsr, cpu_env, r_rs1, r_rs2);
 
1616
        break;
 
1617
    case 2:
 
1618
        gen_helper_fcmpes_fcc2(cpu_fsr, cpu_env, r_rs1, r_rs2);
 
1619
        break;
 
1620
    case 3:
 
1621
        gen_helper_fcmpes_fcc3(cpu_fsr, cpu_env, r_rs1, r_rs2);
 
1622
        break;
 
1623
    }
 
1624
}
 
1625
 
 
1626
static inline void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
 
1627
{
 
1628
    switch (fccno) {
 
1629
    case 0:
 
1630
        gen_helper_fcmped(cpu_fsr, cpu_env, r_rs1, r_rs2);
 
1631
        break;
 
1632
    case 1:
 
1633
        gen_helper_fcmped_fcc1(cpu_fsr, cpu_env, r_rs1, r_rs2);
 
1634
        break;
 
1635
    case 2:
 
1636
        gen_helper_fcmped_fcc2(cpu_fsr, cpu_env, r_rs1, r_rs2);
 
1637
        break;
 
1638
    case 3:
 
1639
        gen_helper_fcmped_fcc3(cpu_fsr, cpu_env, r_rs1, r_rs2);
 
1640
        break;
 
1641
    }
 
1642
}
 
1643
 
 
1644
static inline void gen_op_fcmpeq(int fccno)
 
1645
{
 
1646
    switch (fccno) {
 
1647
    case 0:
 
1648
        gen_helper_fcmpeq(cpu_fsr, cpu_env);
 
1649
        break;
 
1650
    case 1:
 
1651
        gen_helper_fcmpeq_fcc1(cpu_fsr, cpu_env);
 
1652
        break;
 
1653
    case 2:
 
1654
        gen_helper_fcmpeq_fcc2(cpu_fsr, cpu_env);
 
1655
        break;
 
1656
    case 3:
 
1657
        gen_helper_fcmpeq_fcc3(cpu_fsr, cpu_env);
 
1658
        break;
 
1659
    }
 
1660
}
 
1661
 
 
1662
#else
 
1663
 
 
1664
static inline void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2)
 
1665
{
 
1666
    gen_helper_fcmps(cpu_fsr, cpu_env, r_rs1, r_rs2);
 
1667
}
 
1668
 
 
1669
static inline void gen_op_fcmpd(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
 
1670
{
 
1671
    gen_helper_fcmpd(cpu_fsr, cpu_env, r_rs1, r_rs2);
 
1672
}
 
1673
 
 
1674
static inline void gen_op_fcmpq(int fccno)
 
1675
{
 
1676
    gen_helper_fcmpq(cpu_fsr, cpu_env);
 
1677
}
 
1678
 
 
1679
static inline void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2)
 
1680
{
 
1681
    gen_helper_fcmpes(cpu_fsr, cpu_env, r_rs1, r_rs2);
 
1682
}
 
1683
 
 
1684
static inline void gen_op_fcmped(int fccno, TCGv_i64 r_rs1, TCGv_i64 r_rs2)
 
1685
{
 
1686
    gen_helper_fcmped(cpu_fsr, cpu_env, r_rs1, r_rs2);
 
1687
}
 
1688
 
 
1689
static inline void gen_op_fcmpeq(int fccno)
 
1690
{
 
1691
    gen_helper_fcmpeq(cpu_fsr, cpu_env);
 
1692
}
 
1693
#endif
 
1694
 
 
1695
static void gen_op_fpexception_im(DisasContext *dc, int fsr_flags)
 
1696
{
 
1697
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_NMASK);
 
1698
    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
 
1699
    gen_exception(dc, TT_FP_EXCP);
 
1700
}
 
1701
 
 
1702
static int gen_trap_ifnofpu(DisasContext *dc)
 
1703
{
 
1704
#if !defined(CONFIG_USER_ONLY)
 
1705
    if (!dc->fpu_enabled) {
 
1706
        gen_exception(dc, TT_NFPU_INSN);
 
1707
        return 1;
 
1708
    }
 
1709
#endif
 
1710
    return 0;
 
1711
}
 
1712
 
 
1713
static inline void gen_op_clear_ieee_excp_and_FTT(void)
 
1714
{
 
1715
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_CEXC_NMASK);
 
1716
}
 
1717
 
 
1718
static inline void gen_fop_FF(DisasContext *dc, int rd, int rs,
 
1719
                              void (*gen)(TCGv_i32, TCGv_ptr, TCGv_i32))
 
1720
{
 
1721
    TCGv_i32 dst, src;
 
1722
 
 
1723
    src = gen_load_fpr_F(dc, rs);
 
1724
    dst = gen_dest_fpr_F(dc);
 
1725
 
 
1726
    gen(dst, cpu_env, src);
 
1727
    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
1728
 
 
1729
    gen_store_fpr_F(dc, rd, dst);
 
1730
}
 
1731
 
 
1732
static inline void gen_ne_fop_FF(DisasContext *dc, int rd, int rs,
 
1733
                                 void (*gen)(TCGv_i32, TCGv_i32))
 
1734
{
 
1735
    TCGv_i32 dst, src;
 
1736
 
 
1737
    src = gen_load_fpr_F(dc, rs);
 
1738
    dst = gen_dest_fpr_F(dc);
 
1739
 
 
1740
    gen(dst, src);
 
1741
 
 
1742
    gen_store_fpr_F(dc, rd, dst);
 
1743
}
 
1744
 
 
1745
static inline void gen_fop_FFF(DisasContext *dc, int rd, int rs1, int rs2,
 
1746
                        void (*gen)(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32))
 
1747
{
 
1748
    TCGv_i32 dst, src1, src2;
 
1749
 
 
1750
    src1 = gen_load_fpr_F(dc, rs1);
 
1751
    src2 = gen_load_fpr_F(dc, rs2);
 
1752
    dst = gen_dest_fpr_F(dc);
 
1753
 
 
1754
    gen(dst, cpu_env, src1, src2);
 
1755
    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
1756
 
 
1757
    gen_store_fpr_F(dc, rd, dst);
 
1758
}
 
1759
 
 
1760
#ifdef TARGET_SPARC64
 
1761
static inline void gen_ne_fop_FFF(DisasContext *dc, int rd, int rs1, int rs2,
 
1762
                                  void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32))
 
1763
{
 
1764
    TCGv_i32 dst, src1, src2;
 
1765
 
 
1766
    src1 = gen_load_fpr_F(dc, rs1);
 
1767
    src2 = gen_load_fpr_F(dc, rs2);
 
1768
    dst = gen_dest_fpr_F(dc);
 
1769
 
 
1770
    gen(dst, src1, src2);
 
1771
 
 
1772
    gen_store_fpr_F(dc, rd, dst);
 
1773
}
 
1774
#endif
 
1775
 
 
1776
static inline void gen_fop_DD(DisasContext *dc, int rd, int rs,
 
1777
                              void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i64))
 
1778
{
 
1779
    TCGv_i64 dst, src;
 
1780
 
 
1781
    src = gen_load_fpr_D(dc, rs);
 
1782
    dst = gen_dest_fpr_D(dc, rd);
 
1783
 
 
1784
    gen(dst, cpu_env, src);
 
1785
    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
1786
 
 
1787
    gen_store_fpr_D(dc, rd, dst);
 
1788
}
 
1789
 
 
1790
#ifdef TARGET_SPARC64
 
1791
static inline void gen_ne_fop_DD(DisasContext *dc, int rd, int rs,
 
1792
                                 void (*gen)(TCGv_i64, TCGv_i64))
 
1793
{
 
1794
    TCGv_i64 dst, src;
 
1795
 
 
1796
    src = gen_load_fpr_D(dc, rs);
 
1797
    dst = gen_dest_fpr_D(dc, rd);
 
1798
 
 
1799
    gen(dst, src);
 
1800
 
 
1801
    gen_store_fpr_D(dc, rd, dst);
 
1802
}
 
1803
#endif
 
1804
 
 
1805
static inline void gen_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2,
 
1806
                        void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64))
 
1807
{
 
1808
    TCGv_i64 dst, src1, src2;
 
1809
 
 
1810
    src1 = gen_load_fpr_D(dc, rs1);
 
1811
    src2 = gen_load_fpr_D(dc, rs2);
 
1812
    dst = gen_dest_fpr_D(dc, rd);
 
1813
 
 
1814
    gen(dst, cpu_env, src1, src2);
 
1815
    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
1816
 
 
1817
    gen_store_fpr_D(dc, rd, dst);
 
1818
}
 
1819
 
 
1820
#ifdef TARGET_SPARC64
 
1821
static inline void gen_ne_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2,
 
1822
                                  void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64))
 
1823
{
 
1824
    TCGv_i64 dst, src1, src2;
 
1825
 
 
1826
    src1 = gen_load_fpr_D(dc, rs1);
 
1827
    src2 = gen_load_fpr_D(dc, rs2);
 
1828
    dst = gen_dest_fpr_D(dc, rd);
 
1829
 
 
1830
    gen(dst, src1, src2);
 
1831
 
 
1832
    gen_store_fpr_D(dc, rd, dst);
 
1833
}
 
1834
 
 
1835
static inline void gen_gsr_fop_DDD(DisasContext *dc, int rd, int rs1, int rs2,
 
1836
                           void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64))
 
1837
{
 
1838
    TCGv_i64 dst, src1, src2;
 
1839
 
 
1840
    src1 = gen_load_fpr_D(dc, rs1);
 
1841
    src2 = gen_load_fpr_D(dc, rs2);
 
1842
    dst = gen_dest_fpr_D(dc, rd);
 
1843
 
 
1844
    gen(dst, cpu_gsr, src1, src2);
 
1845
 
 
1846
    gen_store_fpr_D(dc, rd, dst);
 
1847
}
 
1848
 
 
1849
static inline void gen_ne_fop_DDDD(DisasContext *dc, int rd, int rs1, int rs2,
 
1850
                           void (*gen)(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_i64))
 
1851
{
 
1852
    TCGv_i64 dst, src0, src1, src2;
 
1853
 
 
1854
    src1 = gen_load_fpr_D(dc, rs1);
 
1855
    src2 = gen_load_fpr_D(dc, rs2);
 
1856
    src0 = gen_load_fpr_D(dc, rd);
 
1857
    dst = gen_dest_fpr_D(dc, rd);
 
1858
 
 
1859
    gen(dst, src0, src1, src2);
 
1860
 
 
1861
    gen_store_fpr_D(dc, rd, dst);
 
1862
}
 
1863
#endif
 
1864
 
 
1865
static inline void gen_fop_QQ(DisasContext *dc, int rd, int rs,
 
1866
                              void (*gen)(TCGv_ptr))
 
1867
{
 
1868
    gen_op_load_fpr_QT1(QFPREG(rs));
 
1869
 
 
1870
    gen(cpu_env);
 
1871
    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
1872
 
 
1873
    gen_op_store_QT0_fpr(QFPREG(rd));
 
1874
    gen_update_fprs_dirty(dc, QFPREG(rd));
 
1875
}
 
1876
 
 
1877
#ifdef TARGET_SPARC64
 
1878
static inline void gen_ne_fop_QQ(DisasContext *dc, int rd, int rs,
 
1879
                                 void (*gen)(TCGv_ptr))
 
1880
{
 
1881
    gen_op_load_fpr_QT1(QFPREG(rs));
 
1882
 
 
1883
    gen(cpu_env);
 
1884
 
 
1885
    gen_op_store_QT0_fpr(QFPREG(rd));
 
1886
    gen_update_fprs_dirty(dc, QFPREG(rd));
 
1887
}
 
1888
#endif
 
1889
 
 
1890
static inline void gen_fop_QQQ(DisasContext *dc, int rd, int rs1, int rs2,
 
1891
                               void (*gen)(TCGv_ptr))
 
1892
{
 
1893
    gen_op_load_fpr_QT0(QFPREG(rs1));
 
1894
    gen_op_load_fpr_QT1(QFPREG(rs2));
 
1895
 
 
1896
    gen(cpu_env);
 
1897
    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
1898
 
 
1899
    gen_op_store_QT0_fpr(QFPREG(rd));
 
1900
    gen_update_fprs_dirty(dc, QFPREG(rd));
 
1901
}
 
1902
 
 
1903
static inline void gen_fop_DFF(DisasContext *dc, int rd, int rs1, int rs2,
 
1904
                        void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i32, TCGv_i32))
 
1905
{
 
1906
    TCGv_i64 dst;
 
1907
    TCGv_i32 src1, src2;
 
1908
 
 
1909
    src1 = gen_load_fpr_F(dc, rs1);
 
1910
    src2 = gen_load_fpr_F(dc, rs2);
 
1911
    dst = gen_dest_fpr_D(dc, rd);
 
1912
 
 
1913
    gen(dst, cpu_env, src1, src2);
 
1914
    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
1915
 
 
1916
    gen_store_fpr_D(dc, rd, dst);
 
1917
}
 
1918
 
 
1919
static inline void gen_fop_QDD(DisasContext *dc, int rd, int rs1, int rs2,
 
1920
                               void (*gen)(TCGv_ptr, TCGv_i64, TCGv_i64))
 
1921
{
 
1922
    TCGv_i64 src1, src2;
 
1923
 
 
1924
    src1 = gen_load_fpr_D(dc, rs1);
 
1925
    src2 = gen_load_fpr_D(dc, rs2);
 
1926
 
 
1927
    gen(cpu_env, src1, src2);
 
1928
    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
1929
 
 
1930
    gen_op_store_QT0_fpr(QFPREG(rd));
 
1931
    gen_update_fprs_dirty(dc, QFPREG(rd));
 
1932
}
 
1933
 
 
1934
#ifdef TARGET_SPARC64
 
1935
static inline void gen_fop_DF(DisasContext *dc, int rd, int rs,
 
1936
                              void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i32))
 
1937
{
 
1938
    TCGv_i64 dst;
 
1939
    TCGv_i32 src;
 
1940
 
 
1941
    src = gen_load_fpr_F(dc, rs);
 
1942
    dst = gen_dest_fpr_D(dc, rd);
 
1943
 
 
1944
    gen(dst, cpu_env, src);
 
1945
    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
1946
 
 
1947
    gen_store_fpr_D(dc, rd, dst);
 
1948
}
 
1949
#endif
 
1950
 
 
1951
static inline void gen_ne_fop_DF(DisasContext *dc, int rd, int rs,
 
1952
                                 void (*gen)(TCGv_i64, TCGv_ptr, TCGv_i32))
 
1953
{
 
1954
    TCGv_i64 dst;
 
1955
    TCGv_i32 src;
 
1956
 
 
1957
    src = gen_load_fpr_F(dc, rs);
 
1958
    dst = gen_dest_fpr_D(dc, rd);
 
1959
 
 
1960
    gen(dst, cpu_env, src);
 
1961
 
 
1962
    gen_store_fpr_D(dc, rd, dst);
 
1963
}
 
1964
 
 
1965
static inline void gen_fop_FD(DisasContext *dc, int rd, int rs,
 
1966
                              void (*gen)(TCGv_i32, TCGv_ptr, TCGv_i64))
 
1967
{
 
1968
    TCGv_i32 dst;
 
1969
    TCGv_i64 src;
 
1970
 
 
1971
    src = gen_load_fpr_D(dc, rs);
 
1972
    dst = gen_dest_fpr_F(dc);
 
1973
 
 
1974
    gen(dst, cpu_env, src);
 
1975
    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
1976
 
 
1977
    gen_store_fpr_F(dc, rd, dst);
 
1978
}
 
1979
 
 
1980
static inline void gen_fop_FQ(DisasContext *dc, int rd, int rs,
 
1981
                              void (*gen)(TCGv_i32, TCGv_ptr))
 
1982
{
 
1983
    TCGv_i32 dst;
 
1984
 
 
1985
    gen_op_load_fpr_QT1(QFPREG(rs));
 
1986
    dst = gen_dest_fpr_F(dc);
 
1987
 
 
1988
    gen(dst, cpu_env);
 
1989
    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
1990
 
 
1991
    gen_store_fpr_F(dc, rd, dst);
 
1992
}
 
1993
 
 
1994
static inline void gen_fop_DQ(DisasContext *dc, int rd, int rs,
 
1995
                              void (*gen)(TCGv_i64, TCGv_ptr))
 
1996
{
 
1997
    TCGv_i64 dst;
 
1998
 
 
1999
    gen_op_load_fpr_QT1(QFPREG(rs));
 
2000
    dst = gen_dest_fpr_D(dc, rd);
 
2001
 
 
2002
    gen(dst, cpu_env);
 
2003
    gen_helper_check_ieee_exceptions(cpu_fsr, cpu_env);
 
2004
 
 
2005
    gen_store_fpr_D(dc, rd, dst);
 
2006
}
 
2007
 
 
2008
static inline void gen_ne_fop_QF(DisasContext *dc, int rd, int rs,
 
2009
                                 void (*gen)(TCGv_ptr, TCGv_i32))
 
2010
{
 
2011
    TCGv_i32 src;
 
2012
 
 
2013
    src = gen_load_fpr_F(dc, rs);
 
2014
 
 
2015
    gen(cpu_env, src);
 
2016
 
 
2017
    gen_op_store_QT0_fpr(QFPREG(rd));
 
2018
    gen_update_fprs_dirty(dc, QFPREG(rd));
 
2019
}
 
2020
 
 
2021
static inline void gen_ne_fop_QD(DisasContext *dc, int rd, int rs,
 
2022
                                 void (*gen)(TCGv_ptr, TCGv_i64))
 
2023
{
 
2024
    TCGv_i64 src;
 
2025
 
 
2026
    src = gen_load_fpr_D(dc, rs);
 
2027
 
 
2028
    gen(cpu_env, src);
 
2029
 
 
2030
    gen_op_store_QT0_fpr(QFPREG(rd));
 
2031
    gen_update_fprs_dirty(dc, QFPREG(rd));
 
2032
}
 
2033
 
 
2034
static void gen_swap(DisasContext *dc, TCGv dst, TCGv src,
 
2035
                     TCGv addr, int mmu_idx, TCGMemOp memop)
 
2036
{
 
2037
    gen_address_mask(dc, addr);
 
2038
    tcg_gen_atomic_xchg_tl(dst, addr, src, mmu_idx, memop);
 
2039
}
 
2040
 
 
2041
static void gen_ldstub(DisasContext *dc, TCGv dst, TCGv addr, int mmu_idx)
 
2042
{
 
2043
    TCGv m1 = tcg_const_tl(0xff);
 
2044
    gen_address_mask(dc, addr);
 
2045
    tcg_gen_atomic_xchg_tl(dst, addr, m1, mmu_idx, MO_UB);
 
2046
    tcg_temp_free(m1);
 
2047
}
 
2048
 
 
2049
/* asi moves */
 
2050
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
 
2051
typedef enum {
 
2052
    GET_ASI_HELPER,
 
2053
    GET_ASI_EXCP,
 
2054
    GET_ASI_DIRECT,
 
2055
    GET_ASI_DTWINX,
 
2056
    GET_ASI_BLOCK,
 
2057
    GET_ASI_SHORT,
 
2058
    GET_ASI_BCOPY,
 
2059
    GET_ASI_BFILL,
 
2060
} ASIType;
 
2061
 
 
2062
typedef struct {
 
2063
    ASIType type;
 
2064
    int asi;
 
2065
    int mem_idx;
 
2066
    TCGMemOp memop;
 
2067
} DisasASI;
 
2068
 
 
2069
static DisasASI get_asi(DisasContext *dc, int insn, TCGMemOp memop)
 
2070
{
 
2071
    int asi = GET_FIELD(insn, 19, 26);
 
2072
    ASIType type = GET_ASI_HELPER;
 
2073
    int mem_idx = dc->mem_idx;
 
2074
 
 
2075
#ifndef TARGET_SPARC64
 
2076
    /* Before v9, all asis are immediate and privileged.  */
 
2077
    if (IS_IMM) {
 
2078
        gen_exception(dc, TT_ILL_INSN);
 
2079
        type = GET_ASI_EXCP;
 
2080
    } else if (supervisor(dc)
 
2081
               /* Note that LEON accepts ASI_USERDATA in user mode, for
 
2082
                  use with CASA.  Also note that previous versions of
 
2083
                  QEMU allowed (and old versions of gcc emitted) ASI_P
 
2084
                  for LEON, which is incorrect.  */
 
2085
               || (asi == ASI_USERDATA
 
2086
                   && (dc->def->features & CPU_FEATURE_CASA))) {
 
2087
        switch (asi) {
 
2088
        case ASI_USERDATA:   /* User data access */
 
2089
            mem_idx = MMU_USER_IDX;
 
2090
            type = GET_ASI_DIRECT;
 
2091
            break;
 
2092
        case ASI_KERNELDATA: /* Supervisor data access */
 
2093
            mem_idx = MMU_KERNEL_IDX;
 
2094
            type = GET_ASI_DIRECT;
 
2095
            break;
 
2096
        case ASI_M_BYPASS:    /* MMU passthrough */
 
2097
        case ASI_LEON_BYPASS: /* LEON MMU passthrough */
 
2098
            mem_idx = MMU_PHYS_IDX;
 
2099
            type = GET_ASI_DIRECT;
 
2100
            break;
 
2101
        case ASI_M_BCOPY: /* Block copy, sta access */
 
2102
            mem_idx = MMU_KERNEL_IDX;
 
2103
            type = GET_ASI_BCOPY;
 
2104
            break;
 
2105
        case ASI_M_BFILL: /* Block fill, stda access */
 
2106
            mem_idx = MMU_KERNEL_IDX;
 
2107
            type = GET_ASI_BFILL;
 
2108
            break;
 
2109
        }
 
2110
    } else {
 
2111
        gen_exception(dc, TT_PRIV_INSN);
 
2112
        type = GET_ASI_EXCP;
 
2113
    }
 
2114
#else
 
2115
    if (IS_IMM) {
 
2116
        asi = dc->asi;
 
2117
    }
 
2118
    /* With v9, all asis below 0x80 are privileged.  */
 
2119
    /* ??? We ought to check cpu_has_hypervisor, but we didn't copy
 
2120
       down that bit into DisasContext.  For the moment that's ok,
 
2121
       since the direct implementations below doesn't have any ASIs
 
2122
       in the restricted [0x30, 0x7f] range, and the check will be
 
2123
       done properly in the helper.  */
 
2124
    if (!supervisor(dc) && asi < 0x80) {
 
2125
        gen_exception(dc, TT_PRIV_ACT);
 
2126
        type = GET_ASI_EXCP;
 
2127
    } else {
 
2128
        switch (asi) {
 
2129
        case ASI_REAL:      /* Bypass */
 
2130
        case ASI_REAL_IO:   /* Bypass, non-cacheable */
 
2131
        case ASI_REAL_L:    /* Bypass LE */
 
2132
        case ASI_REAL_IO_L: /* Bypass, non-cacheable LE */
 
2133
        case ASI_TWINX_REAL:   /* Real address, twinx */
 
2134
        case ASI_TWINX_REAL_L: /* Real address, twinx, LE */
 
2135
        case ASI_QUAD_LDD_PHYS:
 
2136
        case ASI_QUAD_LDD_PHYS_L:
 
2137
            mem_idx = MMU_PHYS_IDX;
 
2138
            break;
 
2139
        case ASI_N:  /* Nucleus */
 
2140
        case ASI_NL: /* Nucleus LE */
 
2141
        case ASI_TWINX_N:
 
2142
        case ASI_TWINX_NL:
 
2143
        case ASI_NUCLEUS_QUAD_LDD:
 
2144
        case ASI_NUCLEUS_QUAD_LDD_L:
 
2145
            if (hypervisor(dc)) {
 
2146
                mem_idx = MMU_PHYS_IDX;
 
2147
            } else {
 
2148
                mem_idx = MMU_NUCLEUS_IDX;
 
2149
            }
 
2150
            break;
 
2151
        case ASI_AIUP:  /* As if user primary */
 
2152
        case ASI_AIUPL: /* As if user primary LE */
 
2153
        case ASI_TWINX_AIUP:
 
2154
        case ASI_TWINX_AIUP_L:
 
2155
        case ASI_BLK_AIUP_4V:
 
2156
        case ASI_BLK_AIUP_L_4V:
 
2157
        case ASI_BLK_AIUP:
 
2158
        case ASI_BLK_AIUPL:
 
2159
            mem_idx = MMU_USER_IDX;
 
2160
            break;
 
2161
        case ASI_AIUS:  /* As if user secondary */
 
2162
        case ASI_AIUSL: /* As if user secondary LE */
 
2163
        case ASI_TWINX_AIUS:
 
2164
        case ASI_TWINX_AIUS_L:
 
2165
        case ASI_BLK_AIUS_4V:
 
2166
        case ASI_BLK_AIUS_L_4V:
 
2167
        case ASI_BLK_AIUS:
 
2168
        case ASI_BLK_AIUSL:
 
2169
            mem_idx = MMU_USER_SECONDARY_IDX;
 
2170
            break;
 
2171
        case ASI_S:  /* Secondary */
 
2172
        case ASI_SL: /* Secondary LE */
 
2173
        case ASI_TWINX_S:
 
2174
        case ASI_TWINX_SL:
 
2175
        case ASI_BLK_COMMIT_S:
 
2176
        case ASI_BLK_S:
 
2177
        case ASI_BLK_SL:
 
2178
        case ASI_FL8_S:
 
2179
        case ASI_FL8_SL:
 
2180
        case ASI_FL16_S:
 
2181
        case ASI_FL16_SL:
 
2182
            if (mem_idx == MMU_USER_IDX) {
 
2183
                mem_idx = MMU_USER_SECONDARY_IDX;
 
2184
            } else if (mem_idx == MMU_KERNEL_IDX) {
 
2185
                mem_idx = MMU_KERNEL_SECONDARY_IDX;
 
2186
            }
 
2187
            break;
 
2188
        case ASI_P:  /* Primary */
 
2189
        case ASI_PL: /* Primary LE */
 
2190
        case ASI_TWINX_P:
 
2191
        case ASI_TWINX_PL:
 
2192
        case ASI_BLK_COMMIT_P:
 
2193
        case ASI_BLK_P:
 
2194
        case ASI_BLK_PL:
 
2195
        case ASI_FL8_P:
 
2196
        case ASI_FL8_PL:
 
2197
        case ASI_FL16_P:
 
2198
        case ASI_FL16_PL:
 
2199
            break;
 
2200
        }
 
2201
        switch (asi) {
 
2202
        case ASI_REAL:
 
2203
        case ASI_REAL_IO:
 
2204
        case ASI_REAL_L:
 
2205
        case ASI_REAL_IO_L:
 
2206
        case ASI_N:
 
2207
        case ASI_NL:
 
2208
        case ASI_AIUP:
 
2209
        case ASI_AIUPL:
 
2210
        case ASI_AIUS:
 
2211
        case ASI_AIUSL:
 
2212
        case ASI_S:
 
2213
        case ASI_SL:
 
2214
        case ASI_P:
 
2215
        case ASI_PL:
 
2216
            type = GET_ASI_DIRECT;
 
2217
            break;
 
2218
        case ASI_TWINX_REAL:
 
2219
        case ASI_TWINX_REAL_L:
 
2220
        case ASI_TWINX_N:
 
2221
        case ASI_TWINX_NL:
 
2222
        case ASI_TWINX_AIUP:
 
2223
        case ASI_TWINX_AIUP_L:
 
2224
        case ASI_TWINX_AIUS:
 
2225
        case ASI_TWINX_AIUS_L:
 
2226
        case ASI_TWINX_P:
 
2227
        case ASI_TWINX_PL:
 
2228
        case ASI_TWINX_S:
 
2229
        case ASI_TWINX_SL:
 
2230
        case ASI_QUAD_LDD_PHYS:
 
2231
        case ASI_QUAD_LDD_PHYS_L:
 
2232
        case ASI_NUCLEUS_QUAD_LDD:
 
2233
        case ASI_NUCLEUS_QUAD_LDD_L:
 
2234
            type = GET_ASI_DTWINX;
 
2235
            break;
 
2236
        case ASI_BLK_COMMIT_P:
 
2237
        case ASI_BLK_COMMIT_S:
 
2238
        case ASI_BLK_AIUP_4V:
 
2239
        case ASI_BLK_AIUP_L_4V:
 
2240
        case ASI_BLK_AIUP:
 
2241
        case ASI_BLK_AIUPL:
 
2242
        case ASI_BLK_AIUS_4V:
 
2243
        case ASI_BLK_AIUS_L_4V:
 
2244
        case ASI_BLK_AIUS:
 
2245
        case ASI_BLK_AIUSL:
 
2246
        case ASI_BLK_S:
 
2247
        case ASI_BLK_SL:
 
2248
        case ASI_BLK_P:
 
2249
        case ASI_BLK_PL:
 
2250
            type = GET_ASI_BLOCK;
 
2251
            break;
 
2252
        case ASI_FL8_S:
 
2253
        case ASI_FL8_SL:
 
2254
        case ASI_FL8_P:
 
2255
        case ASI_FL8_PL:
 
2256
            memop = MO_UB;
 
2257
            type = GET_ASI_SHORT;
 
2258
            break;
 
2259
        case ASI_FL16_S:
 
2260
        case ASI_FL16_SL:
 
2261
        case ASI_FL16_P:
 
2262
        case ASI_FL16_PL:
 
2263
            memop = MO_TEUW;
 
2264
            type = GET_ASI_SHORT;
 
2265
            break;
 
2266
        }
 
2267
        /* The little-endian asis all have bit 3 set.  */
 
2268
        if (asi & 8) {
 
2269
            memop ^= MO_BSWAP;
 
2270
        }
 
2271
    }
 
2272
#endif
 
2273
 
 
2274
    return (DisasASI){ type, asi, mem_idx, memop };
 
2275
}
 
2276
 
 
2277
static void gen_ld_asi(DisasContext *dc, TCGv dst, TCGv addr,
 
2278
                       int insn, TCGMemOp memop)
 
2279
{
 
2280
    DisasASI da = get_asi(dc, insn, memop);
 
2281
 
 
2282
    switch (da.type) {
 
2283
    case GET_ASI_EXCP:
 
2284
        break;
 
2285
    case GET_ASI_DTWINX: /* Reserved for ldda.  */
 
2286
        gen_exception(dc, TT_ILL_INSN);
 
2287
        break;
 
2288
    case GET_ASI_DIRECT:
 
2289
        gen_address_mask(dc, addr);
 
2290
        tcg_gen_qemu_ld_tl(dst, addr, da.mem_idx, da.memop);
 
2291
        break;
 
2292
    default:
 
2293
        {
 
2294
            TCGv_i32 r_asi = tcg_const_i32(da.asi);
 
2295
            TCGv_i32 r_mop = tcg_const_i32(memop);
 
2296
 
 
2297
            save_state(dc);
 
2298
#ifdef TARGET_SPARC64
 
2299
            gen_helper_ld_asi(dst, cpu_env, addr, r_asi, r_mop);
 
2300
#else
 
2301
            {
 
2302
                TCGv_i64 t64 = tcg_temp_new_i64();
 
2303
                gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_mop);
 
2304
                tcg_gen_trunc_i64_tl(dst, t64);
 
2305
                tcg_temp_free_i64(t64);
 
2306
            }
 
2307
#endif
 
2308
            tcg_temp_free_i32(r_mop);
 
2309
            tcg_temp_free_i32(r_asi);
 
2310
        }
 
2311
        break;
 
2312
    }
 
2313
}
 
2314
 
 
2315
static void gen_st_asi(DisasContext *dc, TCGv src, TCGv addr,
 
2316
                       int insn, TCGMemOp memop)
 
2317
{
 
2318
    DisasASI da = get_asi(dc, insn, memop);
 
2319
 
 
2320
    switch (da.type) {
 
2321
    case GET_ASI_EXCP:
 
2322
        break;
 
2323
    case GET_ASI_DTWINX: /* Reserved for stda.  */
 
2324
#ifndef TARGET_SPARC64
 
2325
        gen_exception(dc, TT_ILL_INSN);
 
2326
        break;
 
2327
#else
 
2328
        if (!(dc->def->features & CPU_FEATURE_HYPV)) {
 
2329
            /* Pre OpenSPARC CPUs don't have these */
 
2330
            gen_exception(dc, TT_ILL_INSN);
 
2331
            return;
 
2332
        }
 
2333
        /* in OpenSPARC T1+ CPUs TWINX ASIs in store instructions
 
2334
         * are ST_BLKINIT_ ASIs */
 
2335
        /* fall through */
 
2336
#endif
 
2337
    case GET_ASI_DIRECT:
 
2338
        gen_address_mask(dc, addr);
 
2339
        tcg_gen_qemu_st_tl(src, addr, da.mem_idx, da.memop);
 
2340
        break;
 
2341
#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
 
2342
    case GET_ASI_BCOPY:
 
2343
        /* Copy 32 bytes from the address in SRC to ADDR.  */
 
2344
        /* ??? The original qemu code suggests 4-byte alignment, dropping
 
2345
           the low bits, but the only place I can see this used is in the
 
2346
           Linux kernel with 32 byte alignment, which would make more sense
 
2347
           as a cacheline-style operation.  */
 
2348
        {
 
2349
            TCGv saddr = tcg_temp_new();
 
2350
            TCGv daddr = tcg_temp_new();
 
2351
            TCGv four = tcg_const_tl(4);
 
2352
            TCGv_i32 tmp = tcg_temp_new_i32();
 
2353
            int i;
 
2354
 
 
2355
            tcg_gen_andi_tl(saddr, src, -4);
 
2356
            tcg_gen_andi_tl(daddr, addr, -4);
 
2357
            for (i = 0; i < 32; i += 4) {
 
2358
                /* Since the loads and stores are paired, allow the
 
2359
                   copy to happen in the host endianness.  */
 
2360
                tcg_gen_qemu_ld_i32(tmp, saddr, da.mem_idx, MO_UL);
 
2361
                tcg_gen_qemu_st_i32(tmp, daddr, da.mem_idx, MO_UL);
 
2362
                tcg_gen_add_tl(saddr, saddr, four);
 
2363
                tcg_gen_add_tl(daddr, daddr, four);
 
2364
            }
 
2365
 
 
2366
            tcg_temp_free(saddr);
 
2367
            tcg_temp_free(daddr);
 
2368
            tcg_temp_free(four);
 
2369
            tcg_temp_free_i32(tmp);
 
2370
        }
 
2371
        break;
 
2372
#endif
 
2373
    default:
 
2374
        {
 
2375
            TCGv_i32 r_asi = tcg_const_i32(da.asi);
 
2376
            TCGv_i32 r_mop = tcg_const_i32(memop & MO_SIZE);
 
2377
 
 
2378
            save_state(dc);
 
2379
#ifdef TARGET_SPARC64
 
2380
            gen_helper_st_asi(cpu_env, addr, src, r_asi, r_mop);
 
2381
#else
 
2382
            {
 
2383
                TCGv_i64 t64 = tcg_temp_new_i64();
 
2384
                tcg_gen_extu_tl_i64(t64, src);
 
2385
                gen_helper_st_asi(cpu_env, addr, t64, r_asi, r_mop);
 
2386
                tcg_temp_free_i64(t64);
 
2387
            }
 
2388
#endif
 
2389
            tcg_temp_free_i32(r_mop);
 
2390
            tcg_temp_free_i32(r_asi);
 
2391
 
 
2392
            /* A write to a TLB register may alter page maps.  End the TB. */
 
2393
            dc->npc = DYNAMIC_PC;
 
2394
        }
 
2395
        break;
 
2396
    }
 
2397
}
 
2398
 
 
2399
static void gen_swap_asi(DisasContext *dc, TCGv dst, TCGv src,
 
2400
                         TCGv addr, int insn)
 
2401
{
 
2402
    DisasASI da = get_asi(dc, insn, MO_TEUL);
 
2403
 
 
2404
    switch (da.type) {
 
2405
    case GET_ASI_EXCP:
 
2406
        break;
 
2407
    case GET_ASI_DIRECT:
 
2408
        gen_swap(dc, dst, src, addr, da.mem_idx, da.memop);
 
2409
        break;
 
2410
    default:
 
2411
        /* ??? Should be DAE_invalid_asi.  */
 
2412
        gen_exception(dc, TT_DATA_ACCESS);
 
2413
        break;
 
2414
    }
 
2415
}
 
2416
 
 
2417
static void gen_cas_asi(DisasContext *dc, TCGv addr, TCGv cmpv,
 
2418
                        int insn, int rd)
 
2419
{
 
2420
    DisasASI da = get_asi(dc, insn, MO_TEUL);
 
2421
    TCGv oldv;
 
2422
 
 
2423
    switch (da.type) {
 
2424
    case GET_ASI_EXCP:
 
2425
        return;
 
2426
    case GET_ASI_DIRECT:
 
2427
        oldv = tcg_temp_new();
 
2428
        tcg_gen_atomic_cmpxchg_tl(oldv, addr, cmpv, gen_load_gpr(dc, rd),
 
2429
                                  da.mem_idx, da.memop);
 
2430
        gen_store_gpr(dc, rd, oldv);
 
2431
        tcg_temp_free(oldv);
 
2432
        break;
 
2433
    default:
 
2434
        /* ??? Should be DAE_invalid_asi.  */
 
2435
        gen_exception(dc, TT_DATA_ACCESS);
 
2436
        break;
 
2437
    }
 
2438
}
 
2439
 
 
2440
static void gen_ldstub_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn)
 
2441
{
 
2442
    DisasASI da = get_asi(dc, insn, MO_UB);
 
2443
 
 
2444
    switch (da.type) {
 
2445
    case GET_ASI_EXCP:
 
2446
        break;
 
2447
    case GET_ASI_DIRECT:
 
2448
        gen_ldstub(dc, dst, addr, da.mem_idx);
 
2449
        break;
 
2450
    default:
 
2451
        /* ??? In theory, this should be raise DAE_invalid_asi.
 
2452
           But the SS-20 roms do ldstuba [%l0] #ASI_M_CTL, %o1.  */
 
2453
        if (parallel_cpus) {
 
2454
            gen_helper_exit_atomic(cpu_env);
 
2455
        } else {
 
2456
            TCGv_i32 r_asi = tcg_const_i32(da.asi);
 
2457
            TCGv_i32 r_mop = tcg_const_i32(MO_UB);
 
2458
            TCGv_i64 s64, t64;
 
2459
 
 
2460
            save_state(dc);
 
2461
            t64 = tcg_temp_new_i64();
 
2462
            gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_mop);
 
2463
 
 
2464
            s64 = tcg_const_i64(0xff);
 
2465
            gen_helper_st_asi(cpu_env, addr, s64, r_asi, r_mop);
 
2466
            tcg_temp_free_i64(s64);
 
2467
            tcg_temp_free_i32(r_mop);
 
2468
            tcg_temp_free_i32(r_asi);
 
2469
 
 
2470
            tcg_gen_trunc_i64_tl(dst, t64);
 
2471
            tcg_temp_free_i64(t64);
 
2472
 
 
2473
            /* End the TB.  */
 
2474
            dc->npc = DYNAMIC_PC;
 
2475
        }
 
2476
        break;
 
2477
    }
 
2478
}
 
2479
#endif
 
2480
 
 
2481
#ifdef TARGET_SPARC64
 
2482
static void gen_ldf_asi(DisasContext *dc, TCGv addr,
 
2483
                        int insn, int size, int rd)
 
2484
{
 
2485
    DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL : MO_TEQ));
 
2486
    TCGv_i32 d32;
 
2487
    TCGv_i64 d64;
 
2488
 
 
2489
    switch (da.type) {
 
2490
    case GET_ASI_EXCP:
 
2491
        break;
 
2492
 
 
2493
    case GET_ASI_DIRECT:
 
2494
        gen_address_mask(dc, addr);
 
2495
        switch (size) {
 
2496
        case 4:
 
2497
            d32 = gen_dest_fpr_F(dc);
 
2498
            tcg_gen_qemu_ld_i32(d32, addr, da.mem_idx, da.memop);
 
2499
            gen_store_fpr_F(dc, rd, d32);
 
2500
            break;
 
2501
        case 8:
 
2502
            tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2], addr, da.mem_idx,
 
2503
                                da.memop | MO_ALIGN_4);
 
2504
            break;
 
2505
        case 16:
 
2506
            d64 = tcg_temp_new_i64();
 
2507
            tcg_gen_qemu_ld_i64(d64, addr, da.mem_idx, da.memop | MO_ALIGN_4);
 
2508
            tcg_gen_addi_tl(addr, addr, 8);
 
2509
            tcg_gen_qemu_ld_i64(cpu_fpr[rd/2+1], addr, da.mem_idx,
 
2510
                                da.memop | MO_ALIGN_4);
 
2511
            tcg_gen_mov_i64(cpu_fpr[rd / 2], d64);
 
2512
            tcg_temp_free_i64(d64);
 
2513
            break;
 
2514
        default:
 
2515
            g_assert_not_reached();
 
2516
        }
 
2517
        break;
 
2518
 
 
2519
    case GET_ASI_BLOCK:
 
2520
        /* Valid for lddfa on aligned registers only.  */
 
2521
        if (size == 8 && (rd & 7) == 0) {
 
2522
            TCGMemOp memop;
 
2523
            TCGv eight;
 
2524
            int i;
 
2525
 
 
2526
            gen_address_mask(dc, addr);
 
2527
 
 
2528
            /* The first operation checks required alignment.  */
 
2529
            memop = da.memop | MO_ALIGN_64;
 
2530
            eight = tcg_const_tl(8);
 
2531
            for (i = 0; ; ++i) {
 
2532
                tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2 + i], addr,
 
2533
                                    da.mem_idx, memop);
 
2534
                if (i == 7) {
 
2535
                    break;
 
2536
                }
 
2537
                tcg_gen_add_tl(addr, addr, eight);
 
2538
                memop = da.memop;
 
2539
            }
 
2540
            tcg_temp_free(eight);
 
2541
        } else {
 
2542
            gen_exception(dc, TT_ILL_INSN);
 
2543
        }
 
2544
        break;
 
2545
 
 
2546
    case GET_ASI_SHORT:
 
2547
        /* Valid for lddfa only.  */
 
2548
        if (size == 8) {
 
2549
            gen_address_mask(dc, addr);
 
2550
            tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2], addr, da.mem_idx, da.memop);
 
2551
        } else {
 
2552
            gen_exception(dc, TT_ILL_INSN);
 
2553
        }
 
2554
        break;
 
2555
 
 
2556
    default:
 
2557
        {
 
2558
            TCGv_i32 r_asi = tcg_const_i32(da.asi);
 
2559
            TCGv_i32 r_mop = tcg_const_i32(da.memop);
 
2560
 
 
2561
            save_state(dc);
 
2562
            /* According to the table in the UA2011 manual, the only
 
2563
               other asis that are valid for ldfa/lddfa/ldqfa are
 
2564
               the NO_FAULT asis.  We still need a helper for these,
 
2565
               but we can just use the integer asi helper for them.  */
 
2566
            switch (size) {
 
2567
            case 4:
 
2568
                d64 = tcg_temp_new_i64();
 
2569
                gen_helper_ld_asi(d64, cpu_env, addr, r_asi, r_mop);
 
2570
                d32 = gen_dest_fpr_F(dc);
 
2571
                tcg_gen_extrl_i64_i32(d32, d64);
 
2572
                tcg_temp_free_i64(d64);
 
2573
                gen_store_fpr_F(dc, rd, d32);
 
2574
                break;
 
2575
            case 8:
 
2576
                gen_helper_ld_asi(cpu_fpr[rd / 2], cpu_env, addr, r_asi, r_mop);
 
2577
                break;
 
2578
            case 16:
 
2579
                d64 = tcg_temp_new_i64();
 
2580
                gen_helper_ld_asi(d64, cpu_env, addr, r_asi, r_mop);
 
2581
                tcg_gen_addi_tl(addr, addr, 8);
 
2582
                gen_helper_ld_asi(cpu_fpr[rd/2+1], cpu_env, addr, r_asi, r_mop);
 
2583
                tcg_gen_mov_i64(cpu_fpr[rd / 2], d64);
 
2584
                tcg_temp_free_i64(d64);
 
2585
                break;
 
2586
            default:
 
2587
                g_assert_not_reached();
 
2588
            }
 
2589
            tcg_temp_free_i32(r_mop);
 
2590
            tcg_temp_free_i32(r_asi);
 
2591
        }
 
2592
        break;
 
2593
    }
 
2594
}
 
2595
 
 
2596
static void gen_stf_asi(DisasContext *dc, TCGv addr,
 
2597
                        int insn, int size, int rd)
 
2598
{
 
2599
    DisasASI da = get_asi(dc, insn, (size == 4 ? MO_TEUL : MO_TEQ));
 
2600
    TCGv_i32 d32;
 
2601
 
 
2602
    switch (da.type) {
 
2603
    case GET_ASI_EXCP:
 
2604
        break;
 
2605
 
 
2606
    case GET_ASI_DIRECT:
 
2607
        gen_address_mask(dc, addr);
 
2608
        switch (size) {
 
2609
        case 4:
 
2610
            d32 = gen_load_fpr_F(dc, rd);
 
2611
            tcg_gen_qemu_st_i32(d32, addr, da.mem_idx, da.memop);
 
2612
            break;
 
2613
        case 8:
 
2614
            tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da.mem_idx,
 
2615
                                da.memop | MO_ALIGN_4);
 
2616
            break;
 
2617
        case 16:
 
2618
            /* Only 4-byte alignment required.  However, it is legal for the
 
2619
               cpu to signal the alignment fault, and the OS trap handler is
 
2620
               required to fix it up.  Requiring 16-byte alignment here avoids
 
2621
               having to probe the second page before performing the first
 
2622
               write.  */
 
2623
            tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da.mem_idx,
 
2624
                                da.memop | MO_ALIGN_16);
 
2625
            tcg_gen_addi_tl(addr, addr, 8);
 
2626
            tcg_gen_qemu_st_i64(cpu_fpr[rd/2+1], addr, da.mem_idx, da.memop);
 
2627
            break;
 
2628
        default:
 
2629
            g_assert_not_reached();
 
2630
        }
 
2631
        break;
 
2632
 
 
2633
    case GET_ASI_BLOCK:
 
2634
        /* Valid for stdfa on aligned registers only.  */
 
2635
        if (size == 8 && (rd & 7) == 0) {
 
2636
            TCGMemOp memop;
 
2637
            TCGv eight;
 
2638
            int i;
 
2639
 
 
2640
            gen_address_mask(dc, addr);
 
2641
 
 
2642
            /* The first operation checks required alignment.  */
 
2643
            memop = da.memop | MO_ALIGN_64;
 
2644
            eight = tcg_const_tl(8);
 
2645
            for (i = 0; ; ++i) {
 
2646
                tcg_gen_qemu_st_i64(cpu_fpr[rd / 2 + i], addr,
 
2647
                                    da.mem_idx, memop);
 
2648
                if (i == 7) {
 
2649
                    break;
 
2650
                }
 
2651
                tcg_gen_add_tl(addr, addr, eight);
 
2652
                memop = da.memop;
 
2653
            }
 
2654
            tcg_temp_free(eight);
 
2655
        } else {
 
2656
            gen_exception(dc, TT_ILL_INSN);
 
2657
        }
 
2658
        break;
 
2659
 
 
2660
    case GET_ASI_SHORT:
 
2661
        /* Valid for stdfa only.  */
 
2662
        if (size == 8) {
 
2663
            gen_address_mask(dc, addr);
 
2664
            tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da.mem_idx, da.memop);
 
2665
        } else {
 
2666
            gen_exception(dc, TT_ILL_INSN);
 
2667
        }
 
2668
        break;
 
2669
 
 
2670
    default:
 
2671
        /* According to the table in the UA2011 manual, the only
 
2672
           other asis that are valid for ldfa/lddfa/ldqfa are
 
2673
           the PST* asis, which aren't currently handled.  */
 
2674
        gen_exception(dc, TT_ILL_INSN);
 
2675
        break;
 
2676
    }
 
2677
}
 
2678
 
 
2679
static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
 
2680
{
 
2681
    DisasASI da = get_asi(dc, insn, MO_TEQ);
 
2682
    TCGv_i64 hi = gen_dest_gpr(dc, rd);
 
2683
    TCGv_i64 lo = gen_dest_gpr(dc, rd + 1);
 
2684
 
 
2685
    switch (da.type) {
 
2686
    case GET_ASI_EXCP:
 
2687
        return;
 
2688
 
 
2689
    case GET_ASI_DTWINX:
 
2690
        gen_address_mask(dc, addr);
 
2691
        tcg_gen_qemu_ld_i64(hi, addr, da.mem_idx, da.memop | MO_ALIGN_16);
 
2692
        tcg_gen_addi_tl(addr, addr, 8);
 
2693
        tcg_gen_qemu_ld_i64(lo, addr, da.mem_idx, da.memop);
 
2694
        break;
 
2695
 
 
2696
    case GET_ASI_DIRECT:
 
2697
        {
 
2698
            TCGv_i64 tmp = tcg_temp_new_i64();
 
2699
 
 
2700
            gen_address_mask(dc, addr);
 
2701
            tcg_gen_qemu_ld_i64(tmp, addr, da.mem_idx, da.memop);
 
2702
 
 
2703
            /* Note that LE ldda acts as if each 32-bit register
 
2704
               result is byte swapped.  Having just performed one
 
2705
               64-bit bswap, we need now to swap the writebacks.  */
 
2706
            if ((da.memop & MO_BSWAP) == MO_TE) {
 
2707
                tcg_gen_extr32_i64(lo, hi, tmp);
 
2708
            } else {
 
2709
                tcg_gen_extr32_i64(hi, lo, tmp);
 
2710
            }
 
2711
            tcg_temp_free_i64(tmp);
 
2712
        }
 
2713
        break;
 
2714
 
 
2715
    default:
 
2716
        /* ??? In theory we've handled all of the ASIs that are valid
 
2717
           for ldda, and this should raise DAE_invalid_asi.  However,
 
2718
           real hardware allows others.  This can be seen with e.g.
 
2719
           FreeBSD 10.3 wrt ASI_IC_TAG.  */
 
2720
        {
 
2721
            TCGv_i32 r_asi = tcg_const_i32(da.asi);
 
2722
            TCGv_i32 r_mop = tcg_const_i32(da.memop);
 
2723
            TCGv_i64 tmp = tcg_temp_new_i64();
 
2724
 
 
2725
            save_state(dc);
 
2726
            gen_helper_ld_asi(tmp, cpu_env, addr, r_asi, r_mop);
 
2727
            tcg_temp_free_i32(r_asi);
 
2728
            tcg_temp_free_i32(r_mop);
 
2729
 
 
2730
            /* See above.  */
 
2731
            if ((da.memop & MO_BSWAP) == MO_TE) {
 
2732
                tcg_gen_extr32_i64(lo, hi, tmp);
 
2733
            } else {
 
2734
                tcg_gen_extr32_i64(hi, lo, tmp);
 
2735
            }
 
2736
            tcg_temp_free_i64(tmp);
 
2737
        }
 
2738
        break;
 
2739
    }
 
2740
 
 
2741
    gen_store_gpr(dc, rd, hi);
 
2742
    gen_store_gpr(dc, rd + 1, lo);
 
2743
}
 
2744
 
 
2745
static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
 
2746
                         int insn, int rd)
 
2747
{
 
2748
    DisasASI da = get_asi(dc, insn, MO_TEQ);
 
2749
    TCGv lo = gen_load_gpr(dc, rd + 1);
 
2750
 
 
2751
    switch (da.type) {
 
2752
    case GET_ASI_EXCP:
 
2753
        break;
 
2754
 
 
2755
    case GET_ASI_DTWINX:
 
2756
        gen_address_mask(dc, addr);
 
2757
        tcg_gen_qemu_st_i64(hi, addr, da.mem_idx, da.memop | MO_ALIGN_16);
 
2758
        tcg_gen_addi_tl(addr, addr, 8);
 
2759
        tcg_gen_qemu_st_i64(lo, addr, da.mem_idx, da.memop);
 
2760
        break;
 
2761
 
 
2762
    case GET_ASI_DIRECT:
 
2763
        {
 
2764
            TCGv_i64 t64 = tcg_temp_new_i64();
 
2765
 
 
2766
            /* Note that LE stda acts as if each 32-bit register result is
 
2767
               byte swapped.  We will perform one 64-bit LE store, so now
 
2768
               we must swap the order of the construction.  */
 
2769
            if ((da.memop & MO_BSWAP) == MO_TE) {
 
2770
                tcg_gen_concat32_i64(t64, lo, hi);
 
2771
            } else {
 
2772
                tcg_gen_concat32_i64(t64, hi, lo);
 
2773
            }
 
2774
            gen_address_mask(dc, addr);
 
2775
            tcg_gen_qemu_st_i64(t64, addr, da.mem_idx, da.memop);
 
2776
            tcg_temp_free_i64(t64);
 
2777
        }
 
2778
        break;
 
2779
 
 
2780
    default:
 
2781
        /* ??? In theory we've handled all of the ASIs that are valid
 
2782
           for stda, and this should raise DAE_invalid_asi.  */
 
2783
        {
 
2784
            TCGv_i32 r_asi = tcg_const_i32(da.asi);
 
2785
            TCGv_i32 r_mop = tcg_const_i32(da.memop);
 
2786
            TCGv_i64 t64 = tcg_temp_new_i64();
 
2787
 
 
2788
            /* See above.  */
 
2789
            if ((da.memop & MO_BSWAP) == MO_TE) {
 
2790
                tcg_gen_concat32_i64(t64, lo, hi);
 
2791
            } else {
 
2792
                tcg_gen_concat32_i64(t64, hi, lo);
 
2793
            }
 
2794
 
 
2795
            save_state(dc);
 
2796
            gen_helper_st_asi(cpu_env, addr, t64, r_asi, r_mop);
 
2797
            tcg_temp_free_i32(r_mop);
 
2798
            tcg_temp_free_i32(r_asi);
 
2799
            tcg_temp_free_i64(t64);
 
2800
        }
 
2801
        break;
 
2802
    }
 
2803
}
 
2804
 
 
2805
static void gen_casx_asi(DisasContext *dc, TCGv addr, TCGv cmpv,
 
2806
                         int insn, int rd)
 
2807
{
 
2808
    DisasASI da = get_asi(dc, insn, MO_TEQ);
 
2809
    TCGv oldv;
 
2810
 
 
2811
    switch (da.type) {
 
2812
    case GET_ASI_EXCP:
 
2813
        return;
 
2814
    case GET_ASI_DIRECT:
 
2815
        oldv = tcg_temp_new();
 
2816
        tcg_gen_atomic_cmpxchg_tl(oldv, addr, cmpv, gen_load_gpr(dc, rd),
 
2817
                                  da.mem_idx, da.memop);
 
2818
        gen_store_gpr(dc, rd, oldv);
 
2819
        tcg_temp_free(oldv);
 
2820
        break;
 
2821
    default:
 
2822
        /* ??? Should be DAE_invalid_asi.  */
 
2823
        gen_exception(dc, TT_DATA_ACCESS);
 
2824
        break;
 
2825
    }
 
2826
}
 
2827
 
 
2828
#elif !defined(CONFIG_USER_ONLY)
 
2829
static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
 
2830
{
 
2831
    /* ??? Work around an apparent bug in Ubuntu gcc 4.8.2-10ubuntu2+12,
 
2832
       whereby "rd + 1" elicits "error: array subscript is above array".
 
2833
       Since we have already asserted that rd is even, the semantics
 
2834
       are unchanged.  */
 
2835
    TCGv lo = gen_dest_gpr(dc, rd | 1);
 
2836
    TCGv hi = gen_dest_gpr(dc, rd);
 
2837
    TCGv_i64 t64 = tcg_temp_new_i64();
 
2838
    DisasASI da = get_asi(dc, insn, MO_TEQ);
 
2839
 
 
2840
    switch (da.type) {
 
2841
    case GET_ASI_EXCP:
 
2842
        tcg_temp_free_i64(t64);
 
2843
        return;
 
2844
    case GET_ASI_DIRECT:
 
2845
        gen_address_mask(dc, addr);
 
2846
        tcg_gen_qemu_ld_i64(t64, addr, da.mem_idx, da.memop);
 
2847
        break;
 
2848
    default:
 
2849
        {
 
2850
            TCGv_i32 r_asi = tcg_const_i32(da.asi);
 
2851
            TCGv_i32 r_mop = tcg_const_i32(MO_Q);
 
2852
 
 
2853
            save_state(dc);
 
2854
            gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_mop);
 
2855
            tcg_temp_free_i32(r_mop);
 
2856
            tcg_temp_free_i32(r_asi);
 
2857
        }
 
2858
        break;
 
2859
    }
 
2860
 
 
2861
    tcg_gen_extr_i64_i32(lo, hi, t64);
 
2862
    tcg_temp_free_i64(t64);
 
2863
    gen_store_gpr(dc, rd | 1, lo);
 
2864
    gen_store_gpr(dc, rd, hi);
 
2865
}
 
2866
 
 
2867
static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
 
2868
                         int insn, int rd)
 
2869
{
 
2870
    DisasASI da = get_asi(dc, insn, MO_TEQ);
 
2871
    TCGv lo = gen_load_gpr(dc, rd + 1);
 
2872
    TCGv_i64 t64 = tcg_temp_new_i64();
 
2873
 
 
2874
    tcg_gen_concat_tl_i64(t64, lo, hi);
 
2875
 
 
2876
    switch (da.type) {
 
2877
    case GET_ASI_EXCP:
 
2878
        break;
 
2879
    case GET_ASI_DIRECT:
 
2880
        gen_address_mask(dc, addr);
 
2881
        tcg_gen_qemu_st_i64(t64, addr, da.mem_idx, da.memop);
 
2882
        break;
 
2883
    case GET_ASI_BFILL:
 
2884
        /* Store 32 bytes of T64 to ADDR.  */
 
2885
        /* ??? The original qemu code suggests 8-byte alignment, dropping
 
2886
           the low bits, but the only place I can see this used is in the
 
2887
           Linux kernel with 32 byte alignment, which would make more sense
 
2888
           as a cacheline-style operation.  */
 
2889
        {
 
2890
            TCGv d_addr = tcg_temp_new();
 
2891
            TCGv eight = tcg_const_tl(8);
 
2892
            int i;
 
2893
 
 
2894
            tcg_gen_andi_tl(d_addr, addr, -8);
 
2895
            for (i = 0; i < 32; i += 8) {
 
2896
                tcg_gen_qemu_st_i64(t64, d_addr, da.mem_idx, da.memop);
 
2897
                tcg_gen_add_tl(d_addr, d_addr, eight);
 
2898
            }
 
2899
 
 
2900
            tcg_temp_free(d_addr);
 
2901
            tcg_temp_free(eight);
 
2902
        }
 
2903
        break;
 
2904
    default:
 
2905
        {
 
2906
            TCGv_i32 r_asi = tcg_const_i32(da.asi);
 
2907
            TCGv_i32 r_mop = tcg_const_i32(MO_Q);
 
2908
 
 
2909
            save_state(dc);
 
2910
            gen_helper_st_asi(cpu_env, addr, t64, r_asi, r_mop);
 
2911
            tcg_temp_free_i32(r_mop);
 
2912
            tcg_temp_free_i32(r_asi);
 
2913
        }
 
2914
        break;
 
2915
    }
 
2916
 
 
2917
    tcg_temp_free_i64(t64);
 
2918
}
 
2919
#endif
 
2920
 
 
2921
static TCGv get_src1(DisasContext *dc, unsigned int insn)
 
2922
{
 
2923
    unsigned int rs1 = GET_FIELD(insn, 13, 17);
 
2924
    return gen_load_gpr(dc, rs1);
 
2925
}
 
2926
 
 
2927
static TCGv get_src2(DisasContext *dc, unsigned int insn)
 
2928
{
 
2929
    if (IS_IMM) { /* immediate */
 
2930
        target_long simm = GET_FIELDs(insn, 19, 31);
 
2931
        TCGv t = get_temp_tl(dc);
 
2932
        tcg_gen_movi_tl(t, simm);
 
2933
        return t;
 
2934
    } else {      /* register */
 
2935
        unsigned int rs2 = GET_FIELD(insn, 27, 31);
 
2936
        return gen_load_gpr(dc, rs2);
 
2937
    }
 
2938
}
 
2939
 
 
2940
#ifdef TARGET_SPARC64
 
2941
static void gen_fmovs(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
 
2942
{
 
2943
    TCGv_i32 c32, zero, dst, s1, s2;
 
2944
 
 
2945
    /* We have two choices here: extend the 32 bit data and use movcond_i64,
 
2946
       or fold the comparison down to 32 bits and use movcond_i32.  Choose
 
2947
       the later.  */
 
2948
    c32 = tcg_temp_new_i32();
 
2949
    if (cmp->is_bool) {
 
2950
        tcg_gen_extrl_i64_i32(c32, cmp->c1);
 
2951
    } else {
 
2952
        TCGv_i64 c64 = tcg_temp_new_i64();
 
2953
        tcg_gen_setcond_i64(cmp->cond, c64, cmp->c1, cmp->c2);
 
2954
        tcg_gen_extrl_i64_i32(c32, c64);
 
2955
        tcg_temp_free_i64(c64);
 
2956
    }
 
2957
 
 
2958
    s1 = gen_load_fpr_F(dc, rs);
 
2959
    s2 = gen_load_fpr_F(dc, rd);
 
2960
    dst = gen_dest_fpr_F(dc);
 
2961
    zero = tcg_const_i32(0);
 
2962
 
 
2963
    tcg_gen_movcond_i32(TCG_COND_NE, dst, c32, zero, s1, s2);
 
2964
 
 
2965
    tcg_temp_free_i32(c32);
 
2966
    tcg_temp_free_i32(zero);
 
2967
    gen_store_fpr_F(dc, rd, dst);
 
2968
}
 
2969
 
 
2970
static void gen_fmovd(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
 
2971
{
 
2972
    TCGv_i64 dst = gen_dest_fpr_D(dc, rd);
 
2973
    tcg_gen_movcond_i64(cmp->cond, dst, cmp->c1, cmp->c2,
 
2974
                        gen_load_fpr_D(dc, rs),
 
2975
                        gen_load_fpr_D(dc, rd));
 
2976
    gen_store_fpr_D(dc, rd, dst);
 
2977
}
 
2978
 
 
2979
static void gen_fmovq(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
 
2980
{
 
2981
    int qd = QFPREG(rd);
 
2982
    int qs = QFPREG(rs);
 
2983
 
 
2984
    tcg_gen_movcond_i64(cmp->cond, cpu_fpr[qd / 2], cmp->c1, cmp->c2,
 
2985
                        cpu_fpr[qs / 2], cpu_fpr[qd / 2]);
 
2986
    tcg_gen_movcond_i64(cmp->cond, cpu_fpr[qd / 2 + 1], cmp->c1, cmp->c2,
 
2987
                        cpu_fpr[qs / 2 + 1], cpu_fpr[qd / 2 + 1]);
 
2988
 
 
2989
    gen_update_fprs_dirty(dc, qd);
 
2990
}
 
2991
 
 
2992
#ifndef CONFIG_USER_ONLY
 
2993
static inline void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_env cpu_env)
 
2994
{
 
2995
    TCGv_i32 r_tl = tcg_temp_new_i32();
 
2996
 
 
2997
    /* load env->tl into r_tl */
 
2998
    tcg_gen_ld_i32(r_tl, cpu_env, offsetof(CPUSPARCState, tl));
 
2999
 
 
3000
    /* tl = [0 ... MAXTL_MASK] where MAXTL_MASK must be power of 2 */
 
3001
    tcg_gen_andi_i32(r_tl, r_tl, MAXTL_MASK);
 
3002
 
 
3003
    /* calculate offset to current trap state from env->ts, reuse r_tl */
 
3004
    tcg_gen_muli_i32(r_tl, r_tl, sizeof (trap_state));
 
3005
    tcg_gen_addi_ptr(r_tsptr, cpu_env, offsetof(CPUSPARCState, ts));
 
3006
 
 
3007
    /* tsptr = env->ts[env->tl & MAXTL_MASK] */
 
3008
    {
 
3009
        TCGv_ptr r_tl_tmp = tcg_temp_new_ptr();
 
3010
        tcg_gen_ext_i32_ptr(r_tl_tmp, r_tl);
 
3011
        tcg_gen_add_ptr(r_tsptr, r_tsptr, r_tl_tmp);
 
3012
        tcg_temp_free_ptr(r_tl_tmp);
 
3013
    }
 
3014
 
 
3015
    tcg_temp_free_i32(r_tl);
 
3016
}
 
3017
#endif
 
3018
 
 
3019
static void gen_edge(DisasContext *dc, TCGv dst, TCGv s1, TCGv s2,
 
3020
                     int width, bool cc, bool left)
 
3021
{
 
3022
    TCGv lo1, lo2, t1, t2;
 
3023
    uint64_t amask, tabl, tabr;
 
3024
    int shift, imask, omask;
 
3025
 
 
3026
    if (cc) {
 
3027
        tcg_gen_mov_tl(cpu_cc_src, s1);
 
3028
        tcg_gen_mov_tl(cpu_cc_src2, s2);
 
3029
        tcg_gen_sub_tl(cpu_cc_dst, s1, s2);
 
3030
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUB);
 
3031
        dc->cc_op = CC_OP_SUB;
 
3032
    }
 
3033
 
 
3034
    /* Theory of operation: there are two tables, left and right (not to
 
3035
       be confused with the left and right versions of the opcode).  These
 
3036
       are indexed by the low 3 bits of the inputs.  To make things "easy",
 
3037
       these tables are loaded into two constants, TABL and TABR below.
 
3038
       The operation index = (input & imask) << shift calculates the index
 
3039
       into the constant, while val = (table >> index) & omask calculates
 
3040
       the value we're looking for.  */
 
3041
    switch (width) {
 
3042
    case 8:
 
3043
        imask = 0x7;
 
3044
        shift = 3;
 
3045
        omask = 0xff;
 
3046
        if (left) {
 
3047
            tabl = 0x80c0e0f0f8fcfeffULL;
 
3048
            tabr = 0xff7f3f1f0f070301ULL;
 
3049
        } else {
 
3050
            tabl = 0x0103070f1f3f7fffULL;
 
3051
            tabr = 0xfffefcf8f0e0c080ULL;
 
3052
        }
 
3053
        break;
 
3054
    case 16:
 
3055
        imask = 0x6;
 
3056
        shift = 1;
 
3057
        omask = 0xf;
 
3058
        if (left) {
 
3059
            tabl = 0x8cef;
 
3060
            tabr = 0xf731;
 
3061
        } else {
 
3062
            tabl = 0x137f;
 
3063
            tabr = 0xfec8;
 
3064
        }
 
3065
        break;
 
3066
    case 32:
 
3067
        imask = 0x4;
 
3068
        shift = 0;
 
3069
        omask = 0x3;
 
3070
        if (left) {
 
3071
            tabl = (2 << 2) | 3;
 
3072
            tabr = (3 << 2) | 1;
 
3073
        } else {
 
3074
            tabl = (1 << 2) | 3;
 
3075
            tabr = (3 << 2) | 2;
 
3076
        }
 
3077
        break;
 
3078
    default:
 
3079
        abort();
 
3080
    }
 
3081
 
 
3082
    lo1 = tcg_temp_new();
 
3083
    lo2 = tcg_temp_new();
 
3084
    tcg_gen_andi_tl(lo1, s1, imask);
 
3085
    tcg_gen_andi_tl(lo2, s2, imask);
 
3086
    tcg_gen_shli_tl(lo1, lo1, shift);
 
3087
    tcg_gen_shli_tl(lo2, lo2, shift);
 
3088
 
 
3089
    t1 = tcg_const_tl(tabl);
 
3090
    t2 = tcg_const_tl(tabr);
 
3091
    tcg_gen_shr_tl(lo1, t1, lo1);
 
3092
    tcg_gen_shr_tl(lo2, t2, lo2);
 
3093
    tcg_gen_andi_tl(dst, lo1, omask);
 
3094
    tcg_gen_andi_tl(lo2, lo2, omask);
 
3095
 
 
3096
    amask = -8;
 
3097
    if (AM_CHECK(dc)) {
 
3098
        amask &= 0xffffffffULL;
 
3099
    }
 
3100
    tcg_gen_andi_tl(s1, s1, amask);
 
3101
    tcg_gen_andi_tl(s2, s2, amask);
 
3102
 
 
3103
    /* We want to compute
 
3104
        dst = (s1 == s2 ? lo1 : lo1 & lo2).
 
3105
       We've already done dst = lo1, so this reduces to
 
3106
        dst &= (s1 == s2 ? -1 : lo2)
 
3107
       Which we perform by
 
3108
        lo2 |= -(s1 == s2)
 
3109
        dst &= lo2
 
3110
    */
 
3111
    tcg_gen_setcond_tl(TCG_COND_EQ, t1, s1, s2);
 
3112
    tcg_gen_neg_tl(t1, t1);
 
3113
    tcg_gen_or_tl(lo2, lo2, t1);
 
3114
    tcg_gen_and_tl(dst, dst, lo2);
 
3115
 
 
3116
    tcg_temp_free(lo1);
 
3117
    tcg_temp_free(lo2);
 
3118
    tcg_temp_free(t1);
 
3119
    tcg_temp_free(t2);
 
3120
}
 
3121
 
 
3122
static void gen_alignaddr(TCGv dst, TCGv s1, TCGv s2, bool left)
 
3123
{
 
3124
    TCGv tmp = tcg_temp_new();
 
3125
 
 
3126
    tcg_gen_add_tl(tmp, s1, s2);
 
3127
    tcg_gen_andi_tl(dst, tmp, -8);
 
3128
    if (left) {
 
3129
        tcg_gen_neg_tl(tmp, tmp);
 
3130
    }
 
3131
    tcg_gen_deposit_tl(cpu_gsr, cpu_gsr, tmp, 0, 3);
 
3132
 
 
3133
    tcg_temp_free(tmp);
 
3134
}
 
3135
 
 
3136
static void gen_faligndata(TCGv dst, TCGv gsr, TCGv s1, TCGv s2)
 
3137
{
 
3138
    TCGv t1, t2, shift;
 
3139
 
 
3140
    t1 = tcg_temp_new();
 
3141
    t2 = tcg_temp_new();
 
3142
    shift = tcg_temp_new();
 
3143
 
 
3144
    tcg_gen_andi_tl(shift, gsr, 7);
 
3145
    tcg_gen_shli_tl(shift, shift, 3);
 
3146
    tcg_gen_shl_tl(t1, s1, shift);
 
3147
 
 
3148
    /* A shift of 64 does not produce 0 in TCG.  Divide this into a
 
3149
       shift of (up to 63) followed by a constant shift of 1.  */
 
3150
    tcg_gen_xori_tl(shift, shift, 63);
 
3151
    tcg_gen_shr_tl(t2, s2, shift);
 
3152
    tcg_gen_shri_tl(t2, t2, 1);
 
3153
 
 
3154
    tcg_gen_or_tl(dst, t1, t2);
 
3155
 
 
3156
    tcg_temp_free(t1);
 
3157
    tcg_temp_free(t2);
 
3158
    tcg_temp_free(shift);
 
3159
}
 
3160
#endif
 
3161
 
 
3162
#define CHECK_IU_FEATURE(dc, FEATURE)                      \
 
3163
    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
 
3164
        goto illegal_insn;
 
3165
#define CHECK_FPU_FEATURE(dc, FEATURE)                     \
 
3166
    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
 
3167
        goto nfpu_insn;
 
3168
 
 
3169
/* before an instruction, dc->pc must be static */
 
3170
static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
 
3171
{
 
3172
    unsigned int opc, rs1, rs2, rd;
 
3173
    TCGv cpu_src1, cpu_src2;
 
3174
    TCGv_i32 cpu_src1_32, cpu_src2_32, cpu_dst_32;
 
3175
    TCGv_i64 cpu_src1_64, cpu_src2_64, cpu_dst_64;
 
3176
    target_long simm;
 
3177
 
 
3178
    opc = GET_FIELD(insn, 0, 1);
 
3179
    rd = GET_FIELD(insn, 2, 6);
 
3180
 
 
3181
    switch (opc) {
 
3182
    case 0:                     /* branches/sethi */
 
3183
        {
 
3184
            unsigned int xop = GET_FIELD(insn, 7, 9);
 
3185
            int32_t target;
 
3186
            switch (xop) {
 
3187
#ifdef TARGET_SPARC64
 
3188
            case 0x1:           /* V9 BPcc */
 
3189
                {
 
3190
                    int cc;
 
3191
 
 
3192
                    target = GET_FIELD_SP(insn, 0, 18);
 
3193
                    target = sign_extend(target, 19);
 
3194
                    target <<= 2;
 
3195
                    cc = GET_FIELD_SP(insn, 20, 21);
 
3196
                    if (cc == 0)
 
3197
                        do_branch(dc, target, insn, 0);
 
3198
                    else if (cc == 2)
 
3199
                        do_branch(dc, target, insn, 1);
 
3200
                    else
 
3201
                        goto illegal_insn;
 
3202
                    goto jmp_insn;
 
3203
                }
 
3204
            case 0x3:           /* V9 BPr */
 
3205
                {
 
3206
                    target = GET_FIELD_SP(insn, 0, 13) |
 
3207
                        (GET_FIELD_SP(insn, 20, 21) << 14);
 
3208
                    target = sign_extend(target, 16);
 
3209
                    target <<= 2;
 
3210
                    cpu_src1 = get_src1(dc, insn);
 
3211
                    do_branch_reg(dc, target, insn, cpu_src1);
 
3212
                    goto jmp_insn;
 
3213
                }
 
3214
            case 0x5:           /* V9 FBPcc */
 
3215
                {
 
3216
                    int cc = GET_FIELD_SP(insn, 20, 21);
 
3217
                    if (gen_trap_ifnofpu(dc)) {
 
3218
                        goto jmp_insn;
 
3219
                    }
 
3220
                    target = GET_FIELD_SP(insn, 0, 18);
 
3221
                    target = sign_extend(target, 19);
 
3222
                    target <<= 2;
 
3223
                    do_fbranch(dc, target, insn, cc);
 
3224
                    goto jmp_insn;
 
3225
                }
 
3226
#else
 
3227
            case 0x7:           /* CBN+x */
 
3228
                {
 
3229
                    goto ncp_insn;
 
3230
                }
 
3231
#endif
 
3232
            case 0x2:           /* BN+x */
 
3233
                {
 
3234
                    target = GET_FIELD(insn, 10, 31);
 
3235
                    target = sign_extend(target, 22);
 
3236
                    target <<= 2;
 
3237
                    do_branch(dc, target, insn, 0);
 
3238
                    goto jmp_insn;
 
3239
                }
 
3240
            case 0x6:           /* FBN+x */
 
3241
                {
 
3242
                    if (gen_trap_ifnofpu(dc)) {
 
3243
                        goto jmp_insn;
 
3244
                    }
 
3245
                    target = GET_FIELD(insn, 10, 31);
 
3246
                    target = sign_extend(target, 22);
 
3247
                    target <<= 2;
 
3248
                    do_fbranch(dc, target, insn, 0);
 
3249
                    goto jmp_insn;
 
3250
                }
 
3251
            case 0x4:           /* SETHI */
 
3252
                /* Special-case %g0 because that's the canonical nop.  */
 
3253
                if (rd) {
 
3254
                    uint32_t value = GET_FIELD(insn, 10, 31);
 
3255
                    TCGv t = gen_dest_gpr(dc, rd);
 
3256
                    tcg_gen_movi_tl(t, value << 10);
 
3257
                    gen_store_gpr(dc, rd, t);
 
3258
                }
 
3259
                break;
 
3260
            case 0x0:           /* UNIMPL */
 
3261
            default:
 
3262
                goto illegal_insn;
 
3263
            }
 
3264
            break;
 
3265
        }
 
3266
        break;
 
3267
    case 1:                     /*CALL*/
 
3268
        {
 
3269
            target_long target = GET_FIELDs(insn, 2, 31) << 2;
 
3270
            TCGv o7 = gen_dest_gpr(dc, 15);
 
3271
 
 
3272
            tcg_gen_movi_tl(o7, dc->pc);
 
3273
            gen_store_gpr(dc, 15, o7);
 
3274
            target += dc->pc;
 
3275
            gen_mov_pc_npc(dc);
 
3276
#ifdef TARGET_SPARC64
 
3277
            if (unlikely(AM_CHECK(dc))) {
 
3278
                target &= 0xffffffffULL;
 
3279
            }
 
3280
#endif
 
3281
            dc->npc = target;
 
3282
        }
 
3283
        goto jmp_insn;
 
3284
    case 2:                     /* FPU & Logical Operations */
 
3285
        {
 
3286
            unsigned int xop = GET_FIELD(insn, 7, 12);
 
3287
            TCGv cpu_dst = get_temp_tl(dc);
 
3288
            TCGv cpu_tmp0;
 
3289
 
 
3290
            if (xop == 0x3a) {  /* generate trap */
 
3291
                int cond = GET_FIELD(insn, 3, 6);
 
3292
                TCGv_i32 trap;
 
3293
                TCGLabel *l1 = NULL;
 
3294
                int mask;
 
3295
 
 
3296
                if (cond == 0) {
 
3297
                    /* Trap never.  */
 
3298
                    break;
 
3299
                }
 
3300
 
 
3301
                save_state(dc);
 
3302
 
 
3303
                if (cond != 8) {
 
3304
                    /* Conditional trap.  */
 
3305
                    DisasCompare cmp;
 
3306
#ifdef TARGET_SPARC64
 
3307
                    /* V9 icc/xcc */
 
3308
                    int cc = GET_FIELD_SP(insn, 11, 12);
 
3309
                    if (cc == 0) {
 
3310
                        gen_compare(&cmp, 0, cond, dc);
 
3311
                    } else if (cc == 2) {
 
3312
                        gen_compare(&cmp, 1, cond, dc);
 
3313
                    } else {
 
3314
                        goto illegal_insn;
 
3315
                    }
 
3316
#else
 
3317
                    gen_compare(&cmp, 0, cond, dc);
 
3318
#endif
 
3319
                    l1 = gen_new_label();
 
3320
                    tcg_gen_brcond_tl(tcg_invert_cond(cmp.cond),
 
3321
                                      cmp.c1, cmp.c2, l1);
 
3322
                    free_compare(&cmp);
 
3323
                }
 
3324
 
 
3325
                mask = ((dc->def->features & CPU_FEATURE_HYPV) && supervisor(dc)
 
3326
                        ? UA2005_HTRAP_MASK : V8_TRAP_MASK);
 
3327
 
 
3328
                /* Don't use the normal temporaries, as they may well have
 
3329
                   gone out of scope with the branch above.  While we're
 
3330
                   doing that we might as well pre-truncate to 32-bit.  */
 
3331
                trap = tcg_temp_new_i32();
 
3332
 
 
3333
                rs1 = GET_FIELD_SP(insn, 14, 18);
 
3334
                if (IS_IMM) {
 
3335
                    rs2 = GET_FIELD_SP(insn, 0, 7);
 
3336
                    if (rs1 == 0) {
 
3337
                        tcg_gen_movi_i32(trap, (rs2 & mask) + TT_TRAP);
 
3338
                        /* Signal that the trap value is fully constant.  */
 
3339
                        mask = 0;
 
3340
                    } else {
 
3341
                        TCGv t1 = gen_load_gpr(dc, rs1);
 
3342
                        tcg_gen_trunc_tl_i32(trap, t1);
 
3343
                        tcg_gen_addi_i32(trap, trap, rs2);
 
3344
                    }
 
3345
                } else {
 
3346
                    TCGv t1, t2;
 
3347
                    rs2 = GET_FIELD_SP(insn, 0, 4);
 
3348
                    t1 = gen_load_gpr(dc, rs1);
 
3349
                    t2 = gen_load_gpr(dc, rs2);
 
3350
                    tcg_gen_add_tl(t1, t1, t2);
 
3351
                    tcg_gen_trunc_tl_i32(trap, t1);
 
3352
                }
 
3353
                if (mask != 0) {
 
3354
                    tcg_gen_andi_i32(trap, trap, mask);
 
3355
                    tcg_gen_addi_i32(trap, trap, TT_TRAP);
 
3356
                }
 
3357
 
 
3358
                gen_helper_raise_exception(cpu_env, trap);
 
3359
                tcg_temp_free_i32(trap);
 
3360
 
 
3361
                if (cond == 8) {
 
3362
                    /* An unconditional trap ends the TB.  */
 
3363
                    dc->is_br = 1;
 
3364
                    goto jmp_insn;
 
3365
                } else {
 
3366
                    /* A conditional trap falls through to the next insn.  */
 
3367
                    gen_set_label(l1);
 
3368
                    break;
 
3369
                }
 
3370
            } else if (xop == 0x28) {
 
3371
                rs1 = GET_FIELD(insn, 13, 17);
 
3372
                switch(rs1) {
 
3373
                case 0: /* rdy */
 
3374
#ifndef TARGET_SPARC64
 
3375
                case 0x01 ... 0x0e: /* undefined in the SPARCv8
 
3376
                                       manual, rdy on the microSPARC
 
3377
                                       II */
 
3378
                case 0x0f:          /* stbar in the SPARCv8 manual,
 
3379
                                       rdy on the microSPARC II */
 
3380
                case 0x10 ... 0x1f: /* implementation-dependent in the
 
3381
                                       SPARCv8 manual, rdy on the
 
3382
                                       microSPARC II */
 
3383
                    /* Read Asr17 */
 
3384
                    if (rs1 == 0x11 && dc->def->features & CPU_FEATURE_ASR17) {
 
3385
                        TCGv t = gen_dest_gpr(dc, rd);
 
3386
                        /* Read Asr17 for a Leon3 monoprocessor */
 
3387
                        tcg_gen_movi_tl(t, (1 << 8) | (dc->def->nwindows - 1));
 
3388
                        gen_store_gpr(dc, rd, t);
 
3389
                        break;
 
3390
                    }
 
3391
#endif
 
3392
                    gen_store_gpr(dc, rd, cpu_y);
 
3393
                    break;
 
3394
#ifdef TARGET_SPARC64
 
3395
                case 0x2: /* V9 rdccr */
 
3396
                    update_psr(dc);
 
3397
                    gen_helper_rdccr(cpu_dst, cpu_env);
 
3398
                    gen_store_gpr(dc, rd, cpu_dst);
 
3399
                    break;
 
3400
                case 0x3: /* V9 rdasi */
 
3401
                    tcg_gen_movi_tl(cpu_dst, dc->asi);
 
3402
                    gen_store_gpr(dc, rd, cpu_dst);
 
3403
                    break;
 
3404
                case 0x4: /* V9 rdtick */
 
3405
                    {
 
3406
                        TCGv_ptr r_tickptr;
 
3407
                        TCGv_i32 r_const;
 
3408
 
 
3409
                        r_tickptr = tcg_temp_new_ptr();
 
3410
                        r_const = tcg_const_i32(dc->mem_idx);
 
3411
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
 
3412
                                       offsetof(CPUSPARCState, tick));
 
3413
                        gen_helper_tick_get_count(cpu_dst, cpu_env, r_tickptr,
 
3414
                                                  r_const);
 
3415
                        tcg_temp_free_ptr(r_tickptr);
 
3416
                        tcg_temp_free_i32(r_const);
 
3417
                        gen_store_gpr(dc, rd, cpu_dst);
 
3418
                    }
 
3419
                    break;
 
3420
                case 0x5: /* V9 rdpc */
 
3421
                    {
 
3422
                        TCGv t = gen_dest_gpr(dc, rd);
 
3423
                        if (unlikely(AM_CHECK(dc))) {
 
3424
                            tcg_gen_movi_tl(t, dc->pc & 0xffffffffULL);
 
3425
                        } else {
 
3426
                            tcg_gen_movi_tl(t, dc->pc);
 
3427
                        }
 
3428
                        gen_store_gpr(dc, rd, t);
 
3429
                    }
 
3430
                    break;
 
3431
                case 0x6: /* V9 rdfprs */
 
3432
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_fprs);
 
3433
                    gen_store_gpr(dc, rd, cpu_dst);
 
3434
                    break;
 
3435
                case 0xf: /* V9 membar */
 
3436
                    break; /* no effect */
 
3437
                case 0x13: /* Graphics Status */
 
3438
                    if (gen_trap_ifnofpu(dc)) {
 
3439
                        goto jmp_insn;
 
3440
                    }
 
3441
                    gen_store_gpr(dc, rd, cpu_gsr);
 
3442
                    break;
 
3443
                case 0x16: /* Softint */
 
3444
                    tcg_gen_ld32s_tl(cpu_dst, cpu_env,
 
3445
                                     offsetof(CPUSPARCState, softint));
 
3446
                    gen_store_gpr(dc, rd, cpu_dst);
 
3447
                    break;
 
3448
                case 0x17: /* Tick compare */
 
3449
                    gen_store_gpr(dc, rd, cpu_tick_cmpr);
 
3450
                    break;
 
3451
                case 0x18: /* System tick */
 
3452
                    {
 
3453
                        TCGv_ptr r_tickptr;
 
3454
                        TCGv_i32 r_const;
 
3455
 
 
3456
                        r_tickptr = tcg_temp_new_ptr();
 
3457
                        r_const = tcg_const_i32(dc->mem_idx);
 
3458
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
 
3459
                                       offsetof(CPUSPARCState, stick));
 
3460
                        gen_helper_tick_get_count(cpu_dst, cpu_env, r_tickptr,
 
3461
                                                  r_const);
 
3462
                        tcg_temp_free_ptr(r_tickptr);
 
3463
                        tcg_temp_free_i32(r_const);
 
3464
                        gen_store_gpr(dc, rd, cpu_dst);
 
3465
                    }
 
3466
                    break;
 
3467
                case 0x19: /* System tick compare */
 
3468
                    gen_store_gpr(dc, rd, cpu_stick_cmpr);
 
3469
                    break;
 
3470
                case 0x1a: /* UltraSPARC-T1 Strand status */
 
3471
                    /* XXX HYPV check maybe not enough, UA2005 & UA2007 describe
 
3472
                     * this ASR as impl. dep
 
3473
                     */
 
3474
                    CHECK_IU_FEATURE(dc, HYPV);
 
3475
                    {
 
3476
                        TCGv t = gen_dest_gpr(dc, rd);
 
3477
                        tcg_gen_movi_tl(t, 1UL);
 
3478
                        gen_store_gpr(dc, rd, t);
 
3479
                    }
 
3480
                    break;
 
3481
                case 0x10: /* Performance Control */
 
3482
                case 0x11: /* Performance Instrumentation Counter */
 
3483
                case 0x12: /* Dispatch Control */
 
3484
                case 0x14: /* Softint set, WO */
 
3485
                case 0x15: /* Softint clear, WO */
 
3486
#endif
 
3487
                default:
 
3488
                    goto illegal_insn;
 
3489
                }
 
3490
#if !defined(CONFIG_USER_ONLY)
 
3491
            } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
 
3492
#ifndef TARGET_SPARC64
 
3493
                if (!supervisor(dc)) {
 
3494
                    goto priv_insn;
 
3495
                }
 
3496
                update_psr(dc);
 
3497
                gen_helper_rdpsr(cpu_dst, cpu_env);
 
3498
#else
 
3499
                CHECK_IU_FEATURE(dc, HYPV);
 
3500
                if (!hypervisor(dc))
 
3501
                    goto priv_insn;
 
3502
                rs1 = GET_FIELD(insn, 13, 17);
 
3503
                switch (rs1) {
 
3504
                case 0: // hpstate
 
3505
                    tcg_gen_ld_i64(cpu_dst, cpu_env,
 
3506
                                   offsetof(CPUSPARCState, hpstate));
 
3507
                    break;
 
3508
                case 1: // htstate
 
3509
                    // gen_op_rdhtstate();
 
3510
                    break;
 
3511
                case 3: // hintp
 
3512
                    tcg_gen_mov_tl(cpu_dst, cpu_hintp);
 
3513
                    break;
 
3514
                case 5: // htba
 
3515
                    tcg_gen_mov_tl(cpu_dst, cpu_htba);
 
3516
                    break;
 
3517
                case 6: // hver
 
3518
                    tcg_gen_mov_tl(cpu_dst, cpu_hver);
 
3519
                    break;
 
3520
                case 31: // hstick_cmpr
 
3521
                    tcg_gen_mov_tl(cpu_dst, cpu_hstick_cmpr);
 
3522
                    break;
 
3523
                default:
 
3524
                    goto illegal_insn;
 
3525
                }
 
3526
#endif
 
3527
                gen_store_gpr(dc, rd, cpu_dst);
 
3528
                break;
 
3529
            } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
 
3530
                if (!supervisor(dc)) {
 
3531
                    goto priv_insn;
 
3532
                }
 
3533
                cpu_tmp0 = get_temp_tl(dc);
 
3534
#ifdef TARGET_SPARC64
 
3535
                rs1 = GET_FIELD(insn, 13, 17);
 
3536
                switch (rs1) {
 
3537
                case 0: // tpc
 
3538
                    {
 
3539
                        TCGv_ptr r_tsptr;
 
3540
 
 
3541
                        r_tsptr = tcg_temp_new_ptr();
 
3542
                        gen_load_trap_state_at_tl(r_tsptr, cpu_env);
 
3543
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
 
3544
                                      offsetof(trap_state, tpc));
 
3545
                        tcg_temp_free_ptr(r_tsptr);
 
3546
                    }
 
3547
                    break;
 
3548
                case 1: // tnpc
 
3549
                    {
 
3550
                        TCGv_ptr r_tsptr;
 
3551
 
 
3552
                        r_tsptr = tcg_temp_new_ptr();
 
3553
                        gen_load_trap_state_at_tl(r_tsptr, cpu_env);
 
3554
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
 
3555
                                      offsetof(trap_state, tnpc));
 
3556
                        tcg_temp_free_ptr(r_tsptr);
 
3557
                    }
 
3558
                    break;
 
3559
                case 2: // tstate
 
3560
                    {
 
3561
                        TCGv_ptr r_tsptr;
 
3562
 
 
3563
                        r_tsptr = tcg_temp_new_ptr();
 
3564
                        gen_load_trap_state_at_tl(r_tsptr, cpu_env);
 
3565
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
 
3566
                                      offsetof(trap_state, tstate));
 
3567
                        tcg_temp_free_ptr(r_tsptr);
 
3568
                    }
 
3569
                    break;
 
3570
                case 3: // tt
 
3571
                    {
 
3572
                        TCGv_ptr r_tsptr = tcg_temp_new_ptr();
 
3573
 
 
3574
                        gen_load_trap_state_at_tl(r_tsptr, cpu_env);
 
3575
                        tcg_gen_ld32s_tl(cpu_tmp0, r_tsptr,
 
3576
                                         offsetof(trap_state, tt));
 
3577
                        tcg_temp_free_ptr(r_tsptr);
 
3578
                    }
 
3579
                    break;
 
3580
                case 4: // tick
 
3581
                    {
 
3582
                        TCGv_ptr r_tickptr;
 
3583
                        TCGv_i32 r_const;
 
3584
 
 
3585
                        r_tickptr = tcg_temp_new_ptr();
 
3586
                        r_const = tcg_const_i32(dc->mem_idx);
 
3587
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
 
3588
                                       offsetof(CPUSPARCState, tick));
 
3589
                        gen_helper_tick_get_count(cpu_tmp0, cpu_env,
 
3590
                                                  r_tickptr, r_const);
 
3591
                        tcg_temp_free_ptr(r_tickptr);
 
3592
                        tcg_temp_free_i32(r_const);
 
3593
                    }
 
3594
                    break;
 
3595
                case 5: // tba
 
3596
                    tcg_gen_mov_tl(cpu_tmp0, cpu_tbr);
 
3597
                    break;
 
3598
                case 6: // pstate
 
3599
                    tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
 
3600
                                     offsetof(CPUSPARCState, pstate));
 
3601
                    break;
 
3602
                case 7: // tl
 
3603
                    tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
 
3604
                                     offsetof(CPUSPARCState, tl));
 
3605
                    break;
 
3606
                case 8: // pil
 
3607
                    tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
 
3608
                                     offsetof(CPUSPARCState, psrpil));
 
3609
                    break;
 
3610
                case 9: // cwp
 
3611
                    gen_helper_rdcwp(cpu_tmp0, cpu_env);
 
3612
                    break;
 
3613
                case 10: // cansave
 
3614
                    tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
 
3615
                                     offsetof(CPUSPARCState, cansave));
 
3616
                    break;
 
3617
                case 11: // canrestore
 
3618
                    tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
 
3619
                                     offsetof(CPUSPARCState, canrestore));
 
3620
                    break;
 
3621
                case 12: // cleanwin
 
3622
                    tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
 
3623
                                     offsetof(CPUSPARCState, cleanwin));
 
3624
                    break;
 
3625
                case 13: // otherwin
 
3626
                    tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
 
3627
                                     offsetof(CPUSPARCState, otherwin));
 
3628
                    break;
 
3629
                case 14: // wstate
 
3630
                    tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
 
3631
                                     offsetof(CPUSPARCState, wstate));
 
3632
                    break;
 
3633
                case 16: // UA2005 gl
 
3634
                    CHECK_IU_FEATURE(dc, GL);
 
3635
                    tcg_gen_ld32s_tl(cpu_tmp0, cpu_env,
 
3636
                                     offsetof(CPUSPARCState, gl));
 
3637
                    break;
 
3638
                case 26: // UA2005 strand status
 
3639
                    CHECK_IU_FEATURE(dc, HYPV);
 
3640
                    if (!hypervisor(dc))
 
3641
                        goto priv_insn;
 
3642
                    tcg_gen_mov_tl(cpu_tmp0, cpu_ssr);
 
3643
                    break;
 
3644
                case 31: // ver
 
3645
                    tcg_gen_mov_tl(cpu_tmp0, cpu_ver);
 
3646
                    break;
 
3647
                case 15: // fq
 
3648
                default:
 
3649
                    goto illegal_insn;
 
3650
                }
 
3651
#else
 
3652
                tcg_gen_ext_i32_tl(cpu_tmp0, cpu_wim);
 
3653
#endif
 
3654
                gen_store_gpr(dc, rd, cpu_tmp0);
 
3655
                break;
 
3656
            } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
 
3657
#ifdef TARGET_SPARC64
 
3658
                gen_helper_flushw(cpu_env);
 
3659
#else
 
3660
                if (!supervisor(dc))
 
3661
                    goto priv_insn;
 
3662
                gen_store_gpr(dc, rd, cpu_tbr);
 
3663
#endif
 
3664
                break;
 
3665
#endif
 
3666
            } else if (xop == 0x34) {   /* FPU Operations */
 
3667
                if (gen_trap_ifnofpu(dc)) {
 
3668
                    goto jmp_insn;
 
3669
                }
 
3670
                gen_op_clear_ieee_excp_and_FTT();
 
3671
                rs1 = GET_FIELD(insn, 13, 17);
 
3672
                rs2 = GET_FIELD(insn, 27, 31);
 
3673
                xop = GET_FIELD(insn, 18, 26);
 
3674
 
 
3675
                switch (xop) {
 
3676
                case 0x1: /* fmovs */
 
3677
                    cpu_src1_32 = gen_load_fpr_F(dc, rs2);
 
3678
                    gen_store_fpr_F(dc, rd, cpu_src1_32);
 
3679
                    break;
 
3680
                case 0x5: /* fnegs */
 
3681
                    gen_ne_fop_FF(dc, rd, rs2, gen_helper_fnegs);
 
3682
                    break;
 
3683
                case 0x9: /* fabss */
 
3684
                    gen_ne_fop_FF(dc, rd, rs2, gen_helper_fabss);
 
3685
                    break;
 
3686
                case 0x29: /* fsqrts */
 
3687
                    CHECK_FPU_FEATURE(dc, FSQRT);
 
3688
                    gen_fop_FF(dc, rd, rs2, gen_helper_fsqrts);
 
3689
                    break;
 
3690
                case 0x2a: /* fsqrtd */
 
3691
                    CHECK_FPU_FEATURE(dc, FSQRT);
 
3692
                    gen_fop_DD(dc, rd, rs2, gen_helper_fsqrtd);
 
3693
                    break;
 
3694
                case 0x2b: /* fsqrtq */
 
3695
                    CHECK_FPU_FEATURE(dc, FLOAT128);
 
3696
                    gen_fop_QQ(dc, rd, rs2, gen_helper_fsqrtq);
 
3697
                    break;
 
3698
                case 0x41: /* fadds */
 
3699
                    gen_fop_FFF(dc, rd, rs1, rs2, gen_helper_fadds);
 
3700
                    break;
 
3701
                case 0x42: /* faddd */
 
3702
                    gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_faddd);
 
3703
                    break;
 
3704
                case 0x43: /* faddq */
 
3705
                    CHECK_FPU_FEATURE(dc, FLOAT128);
 
3706
                    gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_faddq);
 
3707
                    break;
 
3708
                case 0x45: /* fsubs */
 
3709
                    gen_fop_FFF(dc, rd, rs1, rs2, gen_helper_fsubs);
 
3710
                    break;
 
3711
                case 0x46: /* fsubd */
 
3712
                    gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_fsubd);
 
3713
                    break;
 
3714
                case 0x47: /* fsubq */
 
3715
                    CHECK_FPU_FEATURE(dc, FLOAT128);
 
3716
                    gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_fsubq);
 
3717
                    break;
 
3718
                case 0x49: /* fmuls */
 
3719
                    CHECK_FPU_FEATURE(dc, FMUL);
 
3720
                    gen_fop_FFF(dc, rd, rs1, rs2, gen_helper_fmuls);
 
3721
                    break;
 
3722
                case 0x4a: /* fmuld */
 
3723
                    CHECK_FPU_FEATURE(dc, FMUL);
 
3724
                    gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmuld);
 
3725
                    break;
 
3726
                case 0x4b: /* fmulq */
 
3727
                    CHECK_FPU_FEATURE(dc, FLOAT128);
 
3728
                    CHECK_FPU_FEATURE(dc, FMUL);
 
3729
                    gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_fmulq);
 
3730
                    break;
 
3731
                case 0x4d: /* fdivs */
 
3732
                    gen_fop_FFF(dc, rd, rs1, rs2, gen_helper_fdivs);
 
3733
                    break;
 
3734
                case 0x4e: /* fdivd */
 
3735
                    gen_fop_DDD(dc, rd, rs1, rs2, gen_helper_fdivd);
 
3736
                    break;
 
3737
                case 0x4f: /* fdivq */
 
3738
                    CHECK_FPU_FEATURE(dc, FLOAT128);
 
3739
                    gen_fop_QQQ(dc, rd, rs1, rs2, gen_helper_fdivq);
 
3740
                    break;
 
3741
                case 0x69: /* fsmuld */
 
3742
                    CHECK_FPU_FEATURE(dc, FSMULD);
 
3743
                    gen_fop_DFF(dc, rd, rs1, rs2, gen_helper_fsmuld);
 
3744
                    break;
 
3745
                case 0x6e: /* fdmulq */
 
3746
                    CHECK_FPU_FEATURE(dc, FLOAT128);
 
3747
                    gen_fop_QDD(dc, rd, rs1, rs2, gen_helper_fdmulq);
 
3748
                    break;
 
3749
                case 0xc4: /* fitos */
 
3750
                    gen_fop_FF(dc, rd, rs2, gen_helper_fitos);
 
3751
                    break;
 
3752
                case 0xc6: /* fdtos */
 
3753
                    gen_fop_FD(dc, rd, rs2, gen_helper_fdtos);
 
3754
                    break;
 
3755
                case 0xc7: /* fqtos */
 
3756
                    CHECK_FPU_FEATURE(dc, FLOAT128);
 
3757
                    gen_fop_FQ(dc, rd, rs2, gen_helper_fqtos);
 
3758
                    break;
 
3759
                case 0xc8: /* fitod */
 
3760
                    gen_ne_fop_DF(dc, rd, rs2, gen_helper_fitod);
 
3761
                    break;
 
3762
                case 0xc9: /* fstod */
 
3763
                    gen_ne_fop_DF(dc, rd, rs2, gen_helper_fstod);
 
3764
                    break;
 
3765
                case 0xcb: /* fqtod */
 
3766
                    CHECK_FPU_FEATURE(dc, FLOAT128);
 
3767
                    gen_fop_DQ(dc, rd, rs2, gen_helper_fqtod);
 
3768
                    break;
 
3769
                case 0xcc: /* fitoq */
 
3770
                    CHECK_FPU_FEATURE(dc, FLOAT128);
 
3771
                    gen_ne_fop_QF(dc, rd, rs2, gen_helper_fitoq);
 
3772
                    break;
 
3773
                case 0xcd: /* fstoq */
 
3774
                    CHECK_FPU_FEATURE(dc, FLOAT128);
 
3775
                    gen_ne_fop_QF(dc, rd, rs2, gen_helper_fstoq);
 
3776
                    break;
 
3777
                case 0xce: /* fdtoq */
 
3778
                    CHECK_FPU_FEATURE(dc, FLOAT128);
 
3779
                    gen_ne_fop_QD(dc, rd, rs2, gen_helper_fdtoq);
 
3780
                    break;
 
3781
                case 0xd1: /* fstoi */
 
3782
                    gen_fop_FF(dc, rd, rs2, gen_helper_fstoi);
 
3783
                    break;
 
3784
                case 0xd2: /* fdtoi */
 
3785
                    gen_fop_FD(dc, rd, rs2, gen_helper_fdtoi);
 
3786
                    break;
 
3787
                case 0xd3: /* fqtoi */
 
3788
                    CHECK_FPU_FEATURE(dc, FLOAT128);
 
3789
                    gen_fop_FQ(dc, rd, rs2, gen_helper_fqtoi);
 
3790
                    break;
 
3791
#ifdef TARGET_SPARC64
 
3792
                case 0x2: /* V9 fmovd */
 
3793
                    cpu_src1_64 = gen_load_fpr_D(dc, rs2);
 
3794
                    gen_store_fpr_D(dc, rd, cpu_src1_64);
 
3795
                    break;
 
3796
                case 0x3: /* V9 fmovq */
 
3797
                    CHECK_FPU_FEATURE(dc, FLOAT128);
 
3798
                    gen_move_Q(dc, rd, rs2);
 
3799
                    break;
 
3800
                case 0x6: /* V9 fnegd */
 
3801
                    gen_ne_fop_DD(dc, rd, rs2, gen_helper_fnegd);
 
3802
                    break;
 
3803
                case 0x7: /* V9 fnegq */
 
3804
                    CHECK_FPU_FEATURE(dc, FLOAT128);
 
3805
                    gen_ne_fop_QQ(dc, rd, rs2, gen_helper_fnegq);
 
3806
                    break;
 
3807
                case 0xa: /* V9 fabsd */
 
3808
                    gen_ne_fop_DD(dc, rd, rs2, gen_helper_fabsd);
 
3809
                    break;
 
3810
                case 0xb: /* V9 fabsq */
 
3811
                    CHECK_FPU_FEATURE(dc, FLOAT128);
 
3812
                    gen_ne_fop_QQ(dc, rd, rs2, gen_helper_fabsq);
 
3813
                    break;
 
3814
                case 0x81: /* V9 fstox */
 
3815
                    gen_fop_DF(dc, rd, rs2, gen_helper_fstox);
 
3816
                    break;
 
3817
                case 0x82: /* V9 fdtox */
 
3818
                    gen_fop_DD(dc, rd, rs2, gen_helper_fdtox);
 
3819
                    break;
 
3820
                case 0x83: /* V9 fqtox */
 
3821
                    CHECK_FPU_FEATURE(dc, FLOAT128);
 
3822
                    gen_fop_DQ(dc, rd, rs2, gen_helper_fqtox);
 
3823
                    break;
 
3824
                case 0x84: /* V9 fxtos */
 
3825
                    gen_fop_FD(dc, rd, rs2, gen_helper_fxtos);
 
3826
                    break;
 
3827
                case 0x88: /* V9 fxtod */
 
3828
                    gen_fop_DD(dc, rd, rs2, gen_helper_fxtod);
 
3829
                    break;
 
3830
                case 0x8c: /* V9 fxtoq */
 
3831
                    CHECK_FPU_FEATURE(dc, FLOAT128);
 
3832
                    gen_ne_fop_QD(dc, rd, rs2, gen_helper_fxtoq);
 
3833
                    break;
 
3834
#endif
 
3835
                default:
 
3836
                    goto illegal_insn;
 
3837
                }
 
3838
            } else if (xop == 0x35) {   /* FPU Operations */
 
3839
#ifdef TARGET_SPARC64
 
3840
                int cond;
 
3841
#endif
 
3842
                if (gen_trap_ifnofpu(dc)) {
 
3843
                    goto jmp_insn;
 
3844
                }
 
3845
                gen_op_clear_ieee_excp_and_FTT();
 
3846
                rs1 = GET_FIELD(insn, 13, 17);
 
3847
                rs2 = GET_FIELD(insn, 27, 31);
 
3848
                xop = GET_FIELD(insn, 18, 26);
 
3849
 
 
3850
#ifdef TARGET_SPARC64
 
3851
#define FMOVR(sz)                                                  \
 
3852
                do {                                               \
 
3853
                    DisasCompare cmp;                              \
 
3854
                    cond = GET_FIELD_SP(insn, 10, 12);             \
 
3855
                    cpu_src1 = get_src1(dc, insn);                 \
 
3856
                    gen_compare_reg(&cmp, cond, cpu_src1);         \
 
3857
                    gen_fmov##sz(dc, &cmp, rd, rs2);               \
 
3858
                    free_compare(&cmp);                            \
 
3859
                } while (0)
 
3860
 
 
3861
                if ((xop & 0x11f) == 0x005) { /* V9 fmovsr */
 
3862
                    FMOVR(s);
 
3863
                    break;
 
3864
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
 
3865
                    FMOVR(d);
 
3866
                    break;
 
3867
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
 
3868
                    CHECK_FPU_FEATURE(dc, FLOAT128);
 
3869
                    FMOVR(q);
 
3870
                    break;
 
3871
                }
 
3872
#undef FMOVR
 
3873
#endif
 
3874
                switch (xop) {
 
3875
#ifdef TARGET_SPARC64
 
3876
#define FMOVCC(fcc, sz)                                                 \
 
3877
                    do {                                                \
 
3878
                        DisasCompare cmp;                               \
 
3879
                        cond = GET_FIELD_SP(insn, 14, 17);              \
 
3880
                        gen_fcompare(&cmp, fcc, cond);                  \
 
3881
                        gen_fmov##sz(dc, &cmp, rd, rs2);                \
 
3882
                        free_compare(&cmp);                             \
 
3883
                    } while (0)
 
3884
 
 
3885
                    case 0x001: /* V9 fmovscc %fcc0 */
 
3886
                        FMOVCC(0, s);
 
3887
                        break;
 
3888
                    case 0x002: /* V9 fmovdcc %fcc0 */
 
3889
                        FMOVCC(0, d);
 
3890
                        break;
 
3891
                    case 0x003: /* V9 fmovqcc %fcc0 */
 
3892
                        CHECK_FPU_FEATURE(dc, FLOAT128);
 
3893
                        FMOVCC(0, q);
 
3894
                        break;
 
3895
                    case 0x041: /* V9 fmovscc %fcc1 */
 
3896
                        FMOVCC(1, s);
 
3897
                        break;
 
3898
                    case 0x042: /* V9 fmovdcc %fcc1 */
 
3899
                        FMOVCC(1, d);
 
3900
                        break;
 
3901
                    case 0x043: /* V9 fmovqcc %fcc1 */
 
3902
                        CHECK_FPU_FEATURE(dc, FLOAT128);
 
3903
                        FMOVCC(1, q);
 
3904
                        break;
 
3905
                    case 0x081: /* V9 fmovscc %fcc2 */
 
3906
                        FMOVCC(2, s);
 
3907
                        break;
 
3908
                    case 0x082: /* V9 fmovdcc %fcc2 */
 
3909
                        FMOVCC(2, d);
 
3910
                        break;
 
3911
                    case 0x083: /* V9 fmovqcc %fcc2 */
 
3912
                        CHECK_FPU_FEATURE(dc, FLOAT128);
 
3913
                        FMOVCC(2, q);
 
3914
                        break;
 
3915
                    case 0x0c1: /* V9 fmovscc %fcc3 */
 
3916
                        FMOVCC(3, s);
 
3917
                        break;
 
3918
                    case 0x0c2: /* V9 fmovdcc %fcc3 */
 
3919
                        FMOVCC(3, d);
 
3920
                        break;
 
3921
                    case 0x0c3: /* V9 fmovqcc %fcc3 */
 
3922
                        CHECK_FPU_FEATURE(dc, FLOAT128);
 
3923
                        FMOVCC(3, q);
 
3924
                        break;
 
3925
#undef FMOVCC
 
3926
#define FMOVCC(xcc, sz)                                                 \
 
3927
                    do {                                                \
 
3928
                        DisasCompare cmp;                               \
 
3929
                        cond = GET_FIELD_SP(insn, 14, 17);              \
 
3930
                        gen_compare(&cmp, xcc, cond, dc);               \
 
3931
                        gen_fmov##sz(dc, &cmp, rd, rs2);                \
 
3932
                        free_compare(&cmp);                             \
 
3933
                    } while (0)
 
3934
 
 
3935
                    case 0x101: /* V9 fmovscc %icc */
 
3936
                        FMOVCC(0, s);
 
3937
                        break;
 
3938
                    case 0x102: /* V9 fmovdcc %icc */
 
3939
                        FMOVCC(0, d);
 
3940
                        break;
 
3941
                    case 0x103: /* V9 fmovqcc %icc */
 
3942
                        CHECK_FPU_FEATURE(dc, FLOAT128);
 
3943
                        FMOVCC(0, q);
 
3944
                        break;
 
3945
                    case 0x181: /* V9 fmovscc %xcc */
 
3946
                        FMOVCC(1, s);
 
3947
                        break;
 
3948
                    case 0x182: /* V9 fmovdcc %xcc */
 
3949
                        FMOVCC(1, d);
 
3950
                        break;
 
3951
                    case 0x183: /* V9 fmovqcc %xcc */
 
3952
                        CHECK_FPU_FEATURE(dc, FLOAT128);
 
3953
                        FMOVCC(1, q);
 
3954
                        break;
 
3955
#undef FMOVCC
 
3956
#endif
 
3957
                    case 0x51: /* fcmps, V9 %fcc */
 
3958
                        cpu_src1_32 = gen_load_fpr_F(dc, rs1);
 
3959
                        cpu_src2_32 = gen_load_fpr_F(dc, rs2);
 
3960
                        gen_op_fcmps(rd & 3, cpu_src1_32, cpu_src2_32);
 
3961
                        break;
 
3962
                    case 0x52: /* fcmpd, V9 %fcc */
 
3963
                        cpu_src1_64 = gen_load_fpr_D(dc, rs1);
 
3964
                        cpu_src2_64 = gen_load_fpr_D(dc, rs2);
 
3965
                        gen_op_fcmpd(rd & 3, cpu_src1_64, cpu_src2_64);
 
3966
                        break;
 
3967
                    case 0x53: /* fcmpq, V9 %fcc */
 
3968
                        CHECK_FPU_FEATURE(dc, FLOAT128);
 
3969
                        gen_op_load_fpr_QT0(QFPREG(rs1));
 
3970
                        gen_op_load_fpr_QT1(QFPREG(rs2));
 
3971
                        gen_op_fcmpq(rd & 3);
 
3972
                        break;
 
3973
                    case 0x55: /* fcmpes, V9 %fcc */
 
3974
                        cpu_src1_32 = gen_load_fpr_F(dc, rs1);
 
3975
                        cpu_src2_32 = gen_load_fpr_F(dc, rs2);
 
3976
                        gen_op_fcmpes(rd & 3, cpu_src1_32, cpu_src2_32);
 
3977
                        break;
 
3978
                    case 0x56: /* fcmped, V9 %fcc */
 
3979
                        cpu_src1_64 = gen_load_fpr_D(dc, rs1);
 
3980
                        cpu_src2_64 = gen_load_fpr_D(dc, rs2);
 
3981
                        gen_op_fcmped(rd & 3, cpu_src1_64, cpu_src2_64);
 
3982
                        break;
 
3983
                    case 0x57: /* fcmpeq, V9 %fcc */
 
3984
                        CHECK_FPU_FEATURE(dc, FLOAT128);
 
3985
                        gen_op_load_fpr_QT0(QFPREG(rs1));
 
3986
                        gen_op_load_fpr_QT1(QFPREG(rs2));
 
3987
                        gen_op_fcmpeq(rd & 3);
 
3988
                        break;
 
3989
                    default:
 
3990
                        goto illegal_insn;
 
3991
                }
 
3992
            } else if (xop == 0x2) {
 
3993
                TCGv dst = gen_dest_gpr(dc, rd);
 
3994
                rs1 = GET_FIELD(insn, 13, 17);
 
3995
                if (rs1 == 0) {
 
3996
                    /* clr/mov shortcut : or %g0, x, y -> mov x, y */
 
3997
                    if (IS_IMM) {       /* immediate */
 
3998
                        simm = GET_FIELDs(insn, 19, 31);
 
3999
                        tcg_gen_movi_tl(dst, simm);
 
4000
                        gen_store_gpr(dc, rd, dst);
 
4001
                    } else {            /* register */
 
4002
                        rs2 = GET_FIELD(insn, 27, 31);
 
4003
                        if (rs2 == 0) {
 
4004
                            tcg_gen_movi_tl(dst, 0);
 
4005
                            gen_store_gpr(dc, rd, dst);
 
4006
                        } else {
 
4007
                            cpu_src2 = gen_load_gpr(dc, rs2);
 
4008
                            gen_store_gpr(dc, rd, cpu_src2);
 
4009
                        }
 
4010
                    }
 
4011
                } else {
 
4012
                    cpu_src1 = get_src1(dc, insn);
 
4013
                    if (IS_IMM) {       /* immediate */
 
4014
                        simm = GET_FIELDs(insn, 19, 31);
 
4015
                        tcg_gen_ori_tl(dst, cpu_src1, simm);
 
4016
                        gen_store_gpr(dc, rd, dst);
 
4017
                    } else {            /* register */
 
4018
                        rs2 = GET_FIELD(insn, 27, 31);
 
4019
                        if (rs2 == 0) {
 
4020
                            /* mov shortcut:  or x, %g0, y -> mov x, y */
 
4021
                            gen_store_gpr(dc, rd, cpu_src1);
 
4022
                        } else {
 
4023
                            cpu_src2 = gen_load_gpr(dc, rs2);
 
4024
                            tcg_gen_or_tl(dst, cpu_src1, cpu_src2);
 
4025
                            gen_store_gpr(dc, rd, dst);
 
4026
                        }
 
4027
                    }
 
4028
                }
 
4029
#ifdef TARGET_SPARC64
 
4030
            } else if (xop == 0x25) { /* sll, V9 sllx */
 
4031
                cpu_src1 = get_src1(dc, insn);
 
4032
                if (IS_IMM) {   /* immediate */
 
4033
                    simm = GET_FIELDs(insn, 20, 31);
 
4034
                    if (insn & (1 << 12)) {
 
4035
                        tcg_gen_shli_i64(cpu_dst, cpu_src1, simm & 0x3f);
 
4036
                    } else {
 
4037
                        tcg_gen_shli_i64(cpu_dst, cpu_src1, simm & 0x1f);
 
4038
                    }
 
4039
                } else {                /* register */
 
4040
                    rs2 = GET_FIELD(insn, 27, 31);
 
4041
                    cpu_src2 = gen_load_gpr(dc, rs2);
 
4042
                    cpu_tmp0 = get_temp_tl(dc);
 
4043
                    if (insn & (1 << 12)) {
 
4044
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
 
4045
                    } else {
 
4046
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
 
4047
                    }
 
4048
                    tcg_gen_shl_i64(cpu_dst, cpu_src1, cpu_tmp0);
 
4049
                }
 
4050
                gen_store_gpr(dc, rd, cpu_dst);
 
4051
            } else if (xop == 0x26) { /* srl, V9 srlx */
 
4052
                cpu_src1 = get_src1(dc, insn);
 
4053
                if (IS_IMM) {   /* immediate */
 
4054
                    simm = GET_FIELDs(insn, 20, 31);
 
4055
                    if (insn & (1 << 12)) {
 
4056
                        tcg_gen_shri_i64(cpu_dst, cpu_src1, simm & 0x3f);
 
4057
                    } else {
 
4058
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
 
4059
                        tcg_gen_shri_i64(cpu_dst, cpu_dst, simm & 0x1f);
 
4060
                    }
 
4061
                } else {                /* register */
 
4062
                    rs2 = GET_FIELD(insn, 27, 31);
 
4063
                    cpu_src2 = gen_load_gpr(dc, rs2);
 
4064
                    cpu_tmp0 = get_temp_tl(dc);
 
4065
                    if (insn & (1 << 12)) {
 
4066
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
 
4067
                        tcg_gen_shr_i64(cpu_dst, cpu_src1, cpu_tmp0);
 
4068
                    } else {
 
4069
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
 
4070
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
 
4071
                        tcg_gen_shr_i64(cpu_dst, cpu_dst, cpu_tmp0);
 
4072
                    }
 
4073
                }
 
4074
                gen_store_gpr(dc, rd, cpu_dst);
 
4075
            } else if (xop == 0x27) { /* sra, V9 srax */
 
4076
                cpu_src1 = get_src1(dc, insn);
 
4077
                if (IS_IMM) {   /* immediate */
 
4078
                    simm = GET_FIELDs(insn, 20, 31);
 
4079
                    if (insn & (1 << 12)) {
 
4080
                        tcg_gen_sari_i64(cpu_dst, cpu_src1, simm & 0x3f);
 
4081
                    } else {
 
4082
                        tcg_gen_ext32s_i64(cpu_dst, cpu_src1);
 
4083
                        tcg_gen_sari_i64(cpu_dst, cpu_dst, simm & 0x1f);
 
4084
                    }
 
4085
                } else {                /* register */
 
4086
                    rs2 = GET_FIELD(insn, 27, 31);
 
4087
                    cpu_src2 = gen_load_gpr(dc, rs2);
 
4088
                    cpu_tmp0 = get_temp_tl(dc);
 
4089
                    if (insn & (1 << 12)) {
 
4090
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
 
4091
                        tcg_gen_sar_i64(cpu_dst, cpu_src1, cpu_tmp0);
 
4092
                    } else {
 
4093
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
 
4094
                        tcg_gen_ext32s_i64(cpu_dst, cpu_src1);
 
4095
                        tcg_gen_sar_i64(cpu_dst, cpu_dst, cpu_tmp0);
 
4096
                    }
 
4097
                }
 
4098
                gen_store_gpr(dc, rd, cpu_dst);
 
4099
#endif
 
4100
            } else if (xop < 0x36) {
 
4101
                if (xop < 0x20) {
 
4102
                    cpu_src1 = get_src1(dc, insn);
 
4103
                    cpu_src2 = get_src2(dc, insn);
 
4104
                    switch (xop & ~0x10) {
 
4105
                    case 0x0: /* add */
 
4106
                        if (xop & 0x10) {
 
4107
                            gen_op_add_cc(cpu_dst, cpu_src1, cpu_src2);
 
4108
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADD);
 
4109
                            dc->cc_op = CC_OP_ADD;
 
4110
                        } else {
 
4111
                            tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
 
4112
                        }
 
4113
                        break;
 
4114
                    case 0x1: /* and */
 
4115
                        tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_src2);
 
4116
                        if (xop & 0x10) {
 
4117
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
 
4118
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
 
4119
                            dc->cc_op = CC_OP_LOGIC;
 
4120
                        }
 
4121
                        break;
 
4122
                    case 0x2: /* or */
 
4123
                        tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
 
4124
                        if (xop & 0x10) {
 
4125
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
 
4126
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
 
4127
                            dc->cc_op = CC_OP_LOGIC;
 
4128
                        }
 
4129
                        break;
 
4130
                    case 0x3: /* xor */
 
4131
                        tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
 
4132
                        if (xop & 0x10) {
 
4133
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
 
4134
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
 
4135
                            dc->cc_op = CC_OP_LOGIC;
 
4136
                        }
 
4137
                        break;
 
4138
                    case 0x4: /* sub */
 
4139
                        if (xop & 0x10) {
 
4140
                            gen_op_sub_cc(cpu_dst, cpu_src1, cpu_src2);
 
4141
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUB);
 
4142
                            dc->cc_op = CC_OP_SUB;
 
4143
                        } else {
 
4144
                            tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_src2);
 
4145
                        }
 
4146
                        break;
 
4147
                    case 0x5: /* andn */
 
4148
                        tcg_gen_andc_tl(cpu_dst, cpu_src1, cpu_src2);
 
4149
                        if (xop & 0x10) {
 
4150
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
 
4151
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
 
4152
                            dc->cc_op = CC_OP_LOGIC;
 
4153
                        }
 
4154
                        break;
 
4155
                    case 0x6: /* orn */
 
4156
                        tcg_gen_orc_tl(cpu_dst, cpu_src1, cpu_src2);
 
4157
                        if (xop & 0x10) {
 
4158
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
 
4159
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
 
4160
                            dc->cc_op = CC_OP_LOGIC;
 
4161
                        }
 
4162
                        break;
 
4163
                    case 0x7: /* xorn */
 
4164
                        tcg_gen_eqv_tl(cpu_dst, cpu_src1, cpu_src2);
 
4165
                        if (xop & 0x10) {
 
4166
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
 
4167
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
 
4168
                            dc->cc_op = CC_OP_LOGIC;
 
4169
                        }
 
4170
                        break;
 
4171
                    case 0x8: /* addx, V9 addc */
 
4172
                        gen_op_addx_int(dc, cpu_dst, cpu_src1, cpu_src2,
 
4173
                                        (xop & 0x10));
 
4174
                        break;
 
4175
#ifdef TARGET_SPARC64
 
4176
                    case 0x9: /* V9 mulx */
 
4177
                        tcg_gen_mul_i64(cpu_dst, cpu_src1, cpu_src2);
 
4178
                        break;
 
4179
#endif
 
4180
                    case 0xa: /* umul */
 
4181
                        CHECK_IU_FEATURE(dc, MUL);
 
4182
                        gen_op_umul(cpu_dst, cpu_src1, cpu_src2);
 
4183
                        if (xop & 0x10) {
 
4184
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
 
4185
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
 
4186
                            dc->cc_op = CC_OP_LOGIC;
 
4187
                        }
 
4188
                        break;
 
4189
                    case 0xb: /* smul */
 
4190
                        CHECK_IU_FEATURE(dc, MUL);
 
4191
                        gen_op_smul(cpu_dst, cpu_src1, cpu_src2);
 
4192
                        if (xop & 0x10) {
 
4193
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
 
4194
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
 
4195
                            dc->cc_op = CC_OP_LOGIC;
 
4196
                        }
 
4197
                        break;
 
4198
                    case 0xc: /* subx, V9 subc */
 
4199
                        gen_op_subx_int(dc, cpu_dst, cpu_src1, cpu_src2,
 
4200
                                        (xop & 0x10));
 
4201
                        break;
 
4202
#ifdef TARGET_SPARC64
 
4203
                    case 0xd: /* V9 udivx */
 
4204
                        gen_helper_udivx(cpu_dst, cpu_env, cpu_src1, cpu_src2);
 
4205
                        break;
 
4206
#endif
 
4207
                    case 0xe: /* udiv */
 
4208
                        CHECK_IU_FEATURE(dc, DIV);
 
4209
                        if (xop & 0x10) {
 
4210
                            gen_helper_udiv_cc(cpu_dst, cpu_env, cpu_src1,
 
4211
                                               cpu_src2);
 
4212
                            dc->cc_op = CC_OP_DIV;
 
4213
                        } else {
 
4214
                            gen_helper_udiv(cpu_dst, cpu_env, cpu_src1,
 
4215
                                            cpu_src2);
 
4216
                        }
 
4217
                        break;
 
4218
                    case 0xf: /* sdiv */
 
4219
                        CHECK_IU_FEATURE(dc, DIV);
 
4220
                        if (xop & 0x10) {
 
4221
                            gen_helper_sdiv_cc(cpu_dst, cpu_env, cpu_src1,
 
4222
                                               cpu_src2);
 
4223
                            dc->cc_op = CC_OP_DIV;
 
4224
                        } else {
 
4225
                            gen_helper_sdiv(cpu_dst, cpu_env, cpu_src1,
 
4226
                                            cpu_src2);
 
4227
                        }
 
4228
                        break;
 
4229
                    default:
 
4230
                        goto illegal_insn;
 
4231
                    }
 
4232
                    gen_store_gpr(dc, rd, cpu_dst);
 
4233
                } else {
 
4234
                    cpu_src1 = get_src1(dc, insn);
 
4235
                    cpu_src2 = get_src2(dc, insn);
 
4236
                    switch (xop) {
 
4237
                    case 0x20: /* taddcc */
 
4238
                        gen_op_add_cc(cpu_dst, cpu_src1, cpu_src2);
 
4239
                        gen_store_gpr(dc, rd, cpu_dst);
 
4240
                        tcg_gen_movi_i32(cpu_cc_op, CC_OP_TADD);
 
4241
                        dc->cc_op = CC_OP_TADD;
 
4242
                        break;
 
4243
                    case 0x21: /* tsubcc */
 
4244
                        gen_op_sub_cc(cpu_dst, cpu_src1, cpu_src2);
 
4245
                        gen_store_gpr(dc, rd, cpu_dst);
 
4246
                        tcg_gen_movi_i32(cpu_cc_op, CC_OP_TSUB);
 
4247
                        dc->cc_op = CC_OP_TSUB;
 
4248
                        break;
 
4249
                    case 0x22: /* taddcctv */
 
4250
                        gen_helper_taddcctv(cpu_dst, cpu_env,
 
4251
                                            cpu_src1, cpu_src2);
 
4252
                        gen_store_gpr(dc, rd, cpu_dst);
 
4253
                        dc->cc_op = CC_OP_TADDTV;
 
4254
                        break;
 
4255
                    case 0x23: /* tsubcctv */
 
4256
                        gen_helper_tsubcctv(cpu_dst, cpu_env,
 
4257
                                            cpu_src1, cpu_src2);
 
4258
                        gen_store_gpr(dc, rd, cpu_dst);
 
4259
                        dc->cc_op = CC_OP_TSUBTV;
 
4260
                        break;
 
4261
                    case 0x24: /* mulscc */
 
4262
                        update_psr(dc);
 
4263
                        gen_op_mulscc(cpu_dst, cpu_src1, cpu_src2);
 
4264
                        gen_store_gpr(dc, rd, cpu_dst);
 
4265
                        tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADD);
 
4266
                        dc->cc_op = CC_OP_ADD;
 
4267
                        break;
 
4268
#ifndef TARGET_SPARC64
 
4269
                    case 0x25:  /* sll */
 
4270
                        if (IS_IMM) { /* immediate */
 
4271
                            simm = GET_FIELDs(insn, 20, 31);
 
4272
                            tcg_gen_shli_tl(cpu_dst, cpu_src1, simm & 0x1f);
 
4273
                        } else { /* register */
 
4274
                            cpu_tmp0 = get_temp_tl(dc);
 
4275
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
 
4276
                            tcg_gen_shl_tl(cpu_dst, cpu_src1, cpu_tmp0);
 
4277
                        }
 
4278
                        gen_store_gpr(dc, rd, cpu_dst);
 
4279
                        break;
 
4280
                    case 0x26:  /* srl */
 
4281
                        if (IS_IMM) { /* immediate */
 
4282
                            simm = GET_FIELDs(insn, 20, 31);
 
4283
                            tcg_gen_shri_tl(cpu_dst, cpu_src1, simm & 0x1f);
 
4284
                        } else { /* register */
 
4285
                            cpu_tmp0 = get_temp_tl(dc);
 
4286
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
 
4287
                            tcg_gen_shr_tl(cpu_dst, cpu_src1, cpu_tmp0);
 
4288
                        }
 
4289
                        gen_store_gpr(dc, rd, cpu_dst);
 
4290
                        break;
 
4291
                    case 0x27:  /* sra */
 
4292
                        if (IS_IMM) { /* immediate */
 
4293
                            simm = GET_FIELDs(insn, 20, 31);
 
4294
                            tcg_gen_sari_tl(cpu_dst, cpu_src1, simm & 0x1f);
 
4295
                        } else { /* register */
 
4296
                            cpu_tmp0 = get_temp_tl(dc);
 
4297
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
 
4298
                            tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0);
 
4299
                        }
 
4300
                        gen_store_gpr(dc, rd, cpu_dst);
 
4301
                        break;
 
4302
#endif
 
4303
                    case 0x30:
 
4304
                        {
 
4305
                            cpu_tmp0 = get_temp_tl(dc);
 
4306
                            switch(rd) {
 
4307
                            case 0: /* wry */
 
4308
                                tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
 
4309
                                tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
 
4310
                                break;
 
4311
#ifndef TARGET_SPARC64
 
4312
                            case 0x01 ... 0x0f: /* undefined in the
 
4313
                                                   SPARCv8 manual, nop
 
4314
                                                   on the microSPARC
 
4315
                                                   II */
 
4316
                            case 0x10 ... 0x1f: /* implementation-dependent
 
4317
                                                   in the SPARCv8
 
4318
                                                   manual, nop on the
 
4319
                                                   microSPARC II */
 
4320
                                if ((rd == 0x13) && (dc->def->features &
 
4321
                                                     CPU_FEATURE_POWERDOWN)) {
 
4322
                                    /* LEON3 power-down */
 
4323
                                    save_state(dc);
 
4324
                                    gen_helper_power_down(cpu_env);
 
4325
                                }
 
4326
                                break;
 
4327
#else
 
4328
                            case 0x2: /* V9 wrccr */
 
4329
                                tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
 
4330
                                gen_helper_wrccr(cpu_env, cpu_tmp0);
 
4331
                                tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS);
 
4332
                                dc->cc_op = CC_OP_FLAGS;
 
4333
                                break;
 
4334
                            case 0x3: /* V9 wrasi */
 
4335
                                tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
 
4336
                                tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xff);
 
4337
                                tcg_gen_st32_tl(cpu_tmp0, cpu_env,
 
4338
                                                offsetof(CPUSPARCState, asi));
 
4339
                                /* End TB to notice changed ASI.  */
 
4340
                                save_state(dc);
 
4341
                                gen_op_next_insn();
 
4342
                                tcg_gen_exit_tb(0);
 
4343
                                dc->is_br = 1;
 
4344
                                break;
 
4345
                            case 0x6: /* V9 wrfprs */
 
4346
                                tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
 
4347
                                tcg_gen_trunc_tl_i32(cpu_fprs, cpu_tmp0);
 
4348
                                dc->fprs_dirty = 0;
 
4349
                                save_state(dc);
 
4350
                                gen_op_next_insn();
 
4351
                                tcg_gen_exit_tb(0);
 
4352
                                dc->is_br = 1;
 
4353
                                break;
 
4354
                            case 0xf: /* V9 sir, nop if user */
 
4355
#if !defined(CONFIG_USER_ONLY)
 
4356
                                if (supervisor(dc)) {
 
4357
                                    ; // XXX
 
4358
                                }
 
4359
#endif
 
4360
                                break;
 
4361
                            case 0x13: /* Graphics Status */
 
4362
                                if (gen_trap_ifnofpu(dc)) {
 
4363
                                    goto jmp_insn;
 
4364
                                }
 
4365
                                tcg_gen_xor_tl(cpu_gsr, cpu_src1, cpu_src2);
 
4366
                                break;
 
4367
                            case 0x14: /* Softint set */
 
4368
                                if (!supervisor(dc))
 
4369
                                    goto illegal_insn;
 
4370
                                tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
 
4371
                                gen_helper_set_softint(cpu_env, cpu_tmp0);
 
4372
                                break;
 
4373
                            case 0x15: /* Softint clear */
 
4374
                                if (!supervisor(dc))
 
4375
                                    goto illegal_insn;
 
4376
                                tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
 
4377
                                gen_helper_clear_softint(cpu_env, cpu_tmp0);
 
4378
                                break;
 
4379
                            case 0x16: /* Softint write */
 
4380
                                if (!supervisor(dc))
 
4381
                                    goto illegal_insn;
 
4382
                                tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
 
4383
                                gen_helper_write_softint(cpu_env, cpu_tmp0);
 
4384
                                break;
 
4385
                            case 0x17: /* Tick compare */
 
4386
#if !defined(CONFIG_USER_ONLY)
 
4387
                                if (!supervisor(dc))
 
4388
                                    goto illegal_insn;
 
4389
#endif
 
4390
                                {
 
4391
                                    TCGv_ptr r_tickptr;
 
4392
 
 
4393
                                    tcg_gen_xor_tl(cpu_tick_cmpr, cpu_src1,
 
4394
                                                   cpu_src2);
 
4395
                                    r_tickptr = tcg_temp_new_ptr();
 
4396
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
 
4397
                                                   offsetof(CPUSPARCState, tick));
 
4398
                                    gen_helper_tick_set_limit(r_tickptr,
 
4399
                                                              cpu_tick_cmpr);
 
4400
                                    tcg_temp_free_ptr(r_tickptr);
 
4401
                                }
 
4402
                                break;
 
4403
                            case 0x18: /* System tick */
 
4404
#if !defined(CONFIG_USER_ONLY)
 
4405
                                if (!supervisor(dc))
 
4406
                                    goto illegal_insn;
 
4407
#endif
 
4408
                                {
 
4409
                                    TCGv_ptr r_tickptr;
 
4410
 
 
4411
                                    tcg_gen_xor_tl(cpu_tmp0, cpu_src1,
 
4412
                                                   cpu_src2);
 
4413
                                    r_tickptr = tcg_temp_new_ptr();
 
4414
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
 
4415
                                                   offsetof(CPUSPARCState, stick));
 
4416
                                    gen_helper_tick_set_count(r_tickptr,
 
4417
                                                              cpu_tmp0);
 
4418
                                    tcg_temp_free_ptr(r_tickptr);
 
4419
                                }
 
4420
                                break;
 
4421
                            case 0x19: /* System tick compare */
 
4422
#if !defined(CONFIG_USER_ONLY)
 
4423
                                if (!supervisor(dc))
 
4424
                                    goto illegal_insn;
 
4425
#endif
 
4426
                                {
 
4427
                                    TCGv_ptr r_tickptr;
 
4428
 
 
4429
                                    tcg_gen_xor_tl(cpu_stick_cmpr, cpu_src1,
 
4430
                                                   cpu_src2);
 
4431
                                    r_tickptr = tcg_temp_new_ptr();
 
4432
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
 
4433
                                                   offsetof(CPUSPARCState, stick));
 
4434
                                    gen_helper_tick_set_limit(r_tickptr,
 
4435
                                                              cpu_stick_cmpr);
 
4436
                                    tcg_temp_free_ptr(r_tickptr);
 
4437
                                }
 
4438
                                break;
 
4439
 
 
4440
                            case 0x10: /* Performance Control */
 
4441
                            case 0x11: /* Performance Instrumentation
 
4442
                                          Counter */
 
4443
                            case 0x12: /* Dispatch Control */
 
4444
#endif
 
4445
                            default:
 
4446
                                goto illegal_insn;
 
4447
                            }
 
4448
                        }
 
4449
                        break;
 
4450
#if !defined(CONFIG_USER_ONLY)
 
4451
                    case 0x31: /* wrpsr, V9 saved, restored */
 
4452
                        {
 
4453
                            if (!supervisor(dc))
 
4454
                                goto priv_insn;
 
4455
#ifdef TARGET_SPARC64
 
4456
                            switch (rd) {
 
4457
                            case 0:
 
4458
                                gen_helper_saved(cpu_env);
 
4459
                                break;
 
4460
                            case 1:
 
4461
                                gen_helper_restored(cpu_env);
 
4462
                                break;
 
4463
                            case 2: /* UA2005 allclean */
 
4464
                            case 3: /* UA2005 otherw */
 
4465
                            case 4: /* UA2005 normalw */
 
4466
                            case 5: /* UA2005 invalw */
 
4467
                                // XXX
 
4468
                            default:
 
4469
                                goto illegal_insn;
 
4470
                            }
 
4471
#else
 
4472
                            cpu_tmp0 = get_temp_tl(dc);
 
4473
                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
 
4474
                            gen_helper_wrpsr(cpu_env, cpu_tmp0);
 
4475
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS);
 
4476
                            dc->cc_op = CC_OP_FLAGS;
 
4477
                            save_state(dc);
 
4478
                            gen_op_next_insn();
 
4479
                            tcg_gen_exit_tb(0);
 
4480
                            dc->is_br = 1;
 
4481
#endif
 
4482
                        }
 
4483
                        break;
 
4484
                    case 0x32: /* wrwim, V9 wrpr */
 
4485
                        {
 
4486
                            if (!supervisor(dc))
 
4487
                                goto priv_insn;
 
4488
                            cpu_tmp0 = get_temp_tl(dc);
 
4489
                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
 
4490
#ifdef TARGET_SPARC64
 
4491
                            switch (rd) {
 
4492
                            case 0: // tpc
 
4493
                                {
 
4494
                                    TCGv_ptr r_tsptr;
 
4495
 
 
4496
                                    r_tsptr = tcg_temp_new_ptr();
 
4497
                                    gen_load_trap_state_at_tl(r_tsptr, cpu_env);
 
4498
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
 
4499
                                                  offsetof(trap_state, tpc));
 
4500
                                    tcg_temp_free_ptr(r_tsptr);
 
4501
                                }
 
4502
                                break;
 
4503
                            case 1: // tnpc
 
4504
                                {
 
4505
                                    TCGv_ptr r_tsptr;
 
4506
 
 
4507
                                    r_tsptr = tcg_temp_new_ptr();
 
4508
                                    gen_load_trap_state_at_tl(r_tsptr, cpu_env);
 
4509
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
 
4510
                                                  offsetof(trap_state, tnpc));
 
4511
                                    tcg_temp_free_ptr(r_tsptr);
 
4512
                                }
 
4513
                                break;
 
4514
                            case 2: // tstate
 
4515
                                {
 
4516
                                    TCGv_ptr r_tsptr;
 
4517
 
 
4518
                                    r_tsptr = tcg_temp_new_ptr();
 
4519
                                    gen_load_trap_state_at_tl(r_tsptr, cpu_env);
 
4520
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
 
4521
                                                  offsetof(trap_state,
 
4522
                                                           tstate));
 
4523
                                    tcg_temp_free_ptr(r_tsptr);
 
4524
                                }
 
4525
                                break;
 
4526
                            case 3: // tt
 
4527
                                {
 
4528
                                    TCGv_ptr r_tsptr;
 
4529
 
 
4530
                                    r_tsptr = tcg_temp_new_ptr();
 
4531
                                    gen_load_trap_state_at_tl(r_tsptr, cpu_env);
 
4532
                                    tcg_gen_st32_tl(cpu_tmp0, r_tsptr,
 
4533
                                                    offsetof(trap_state, tt));
 
4534
                                    tcg_temp_free_ptr(r_tsptr);
 
4535
                                }
 
4536
                                break;
 
4537
                            case 4: // tick
 
4538
                                {
 
4539
                                    TCGv_ptr r_tickptr;
 
4540
 
 
4541
                                    r_tickptr = tcg_temp_new_ptr();
 
4542
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
 
4543
                                                   offsetof(CPUSPARCState, tick));
 
4544
                                    gen_helper_tick_set_count(r_tickptr,
 
4545
                                                              cpu_tmp0);
 
4546
                                    tcg_temp_free_ptr(r_tickptr);
 
4547
                                }
 
4548
                                break;
 
4549
                            case 5: // tba
 
4550
                                tcg_gen_mov_tl(cpu_tbr, cpu_tmp0);
 
4551
                                break;
 
4552
                            case 6: // pstate
 
4553
                                save_state(dc);
 
4554
                                gen_helper_wrpstate(cpu_env, cpu_tmp0);
 
4555
                                dc->npc = DYNAMIC_PC;
 
4556
                                break;
 
4557
                            case 7: // tl
 
4558
                                save_state(dc);
 
4559
                                tcg_gen_st32_tl(cpu_tmp0, cpu_env,
 
4560
                                               offsetof(CPUSPARCState, tl));
 
4561
                                dc->npc = DYNAMIC_PC;
 
4562
                                break;
 
4563
                            case 8: // pil
 
4564
                                gen_helper_wrpil(cpu_env, cpu_tmp0);
 
4565
                                break;
 
4566
                            case 9: // cwp
 
4567
                                gen_helper_wrcwp(cpu_env, cpu_tmp0);
 
4568
                                break;
 
4569
                            case 10: // cansave
 
4570
                                tcg_gen_st32_tl(cpu_tmp0, cpu_env,
 
4571
                                                offsetof(CPUSPARCState,
 
4572
                                                         cansave));
 
4573
                                break;
 
4574
                            case 11: // canrestore
 
4575
                                tcg_gen_st32_tl(cpu_tmp0, cpu_env,
 
4576
                                                offsetof(CPUSPARCState,
 
4577
                                                         canrestore));
 
4578
                                break;
 
4579
                            case 12: // cleanwin
 
4580
                                tcg_gen_st32_tl(cpu_tmp0, cpu_env,
 
4581
                                                offsetof(CPUSPARCState,
 
4582
                                                         cleanwin));
 
4583
                                break;
 
4584
                            case 13: // otherwin
 
4585
                                tcg_gen_st32_tl(cpu_tmp0, cpu_env,
 
4586
                                                offsetof(CPUSPARCState,
 
4587
                                                         otherwin));
 
4588
                                break;
 
4589
                            case 14: // wstate
 
4590
                                tcg_gen_st32_tl(cpu_tmp0, cpu_env,
 
4591
                                                offsetof(CPUSPARCState,
 
4592
                                                         wstate));
 
4593
                                break;
 
4594
                            case 16: // UA2005 gl
 
4595
                                CHECK_IU_FEATURE(dc, GL);
 
4596
                                gen_helper_wrgl(cpu_env, cpu_tmp0);
 
4597
                                break;
 
4598
                            case 26: // UA2005 strand status
 
4599
                                CHECK_IU_FEATURE(dc, HYPV);
 
4600
                                if (!hypervisor(dc))
 
4601
                                    goto priv_insn;
 
4602
                                tcg_gen_mov_tl(cpu_ssr, cpu_tmp0);
 
4603
                                break;
 
4604
                            default:
 
4605
                                goto illegal_insn;
 
4606
                            }
 
4607
#else
 
4608
                            tcg_gen_trunc_tl_i32(cpu_wim, cpu_tmp0);
 
4609
                            if (dc->def->nwindows != 32) {
 
4610
                                tcg_gen_andi_tl(cpu_wim, cpu_wim,
 
4611
                                                (1 << dc->def->nwindows) - 1);
 
4612
                            }
 
4613
#endif
 
4614
                        }
 
4615
                        break;
 
4616
                    case 0x33: /* wrtbr, UA2005 wrhpr */
 
4617
                        {
 
4618
#ifndef TARGET_SPARC64
 
4619
                            if (!supervisor(dc))
 
4620
                                goto priv_insn;
 
4621
                            tcg_gen_xor_tl(cpu_tbr, cpu_src1, cpu_src2);
 
4622
#else
 
4623
                            CHECK_IU_FEATURE(dc, HYPV);
 
4624
                            if (!hypervisor(dc))
 
4625
                                goto priv_insn;
 
4626
                            cpu_tmp0 = get_temp_tl(dc);
 
4627
                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
 
4628
                            switch (rd) {
 
4629
                            case 0: // hpstate
 
4630
                                tcg_gen_st_i64(cpu_tmp0, cpu_env,
 
4631
                                               offsetof(CPUSPARCState,
 
4632
                                                        hpstate));
 
4633
                                save_state(dc);
 
4634
                                gen_op_next_insn();
 
4635
                                tcg_gen_exit_tb(0);
 
4636
                                dc->is_br = 1;
 
4637
                                break;
 
4638
                            case 1: // htstate
 
4639
                                // XXX gen_op_wrhtstate();
 
4640
                                break;
 
4641
                            case 3: // hintp
 
4642
                                tcg_gen_mov_tl(cpu_hintp, cpu_tmp0);
 
4643
                                break;
 
4644
                            case 5: // htba
 
4645
                                tcg_gen_mov_tl(cpu_htba, cpu_tmp0);
 
4646
                                break;
 
4647
                            case 31: // hstick_cmpr
 
4648
                                {
 
4649
                                    TCGv_ptr r_tickptr;
 
4650
 
 
4651
                                    tcg_gen_mov_tl(cpu_hstick_cmpr, cpu_tmp0);
 
4652
                                    r_tickptr = tcg_temp_new_ptr();
 
4653
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
 
4654
                                                   offsetof(CPUSPARCState, hstick));
 
4655
                                    gen_helper_tick_set_limit(r_tickptr,
 
4656
                                                              cpu_hstick_cmpr);
 
4657
                                    tcg_temp_free_ptr(r_tickptr);
 
4658
                                }
 
4659
                                break;
 
4660
                            case 6: // hver readonly
 
4661
                            default:
 
4662
                                goto illegal_insn;
 
4663
                            }
 
4664
#endif
 
4665
                        }
 
4666
                        break;
 
4667
#endif
 
4668
#ifdef TARGET_SPARC64
 
4669
                    case 0x2c: /* V9 movcc */
 
4670
                        {
 
4671
                            int cc = GET_FIELD_SP(insn, 11, 12);
 
4672
                            int cond = GET_FIELD_SP(insn, 14, 17);
 
4673
                            DisasCompare cmp;
 
4674
                            TCGv dst;
 
4675
 
 
4676
                            if (insn & (1 << 18)) {
 
4677
                                if (cc == 0) {
 
4678
                                    gen_compare(&cmp, 0, cond, dc);
 
4679
                                } else if (cc == 2) {
 
4680
                                    gen_compare(&cmp, 1, cond, dc);
 
4681
                                } else {
 
4682
                                    goto illegal_insn;
 
4683
                                }
 
4684
                            } else {
 
4685
                                gen_fcompare(&cmp, cc, cond);
 
4686
                            }
 
4687
 
 
4688
                            /* The get_src2 above loaded the normal 13-bit
 
4689
                               immediate field, not the 11-bit field we have
 
4690
                               in movcc.  But it did handle the reg case.  */
 
4691
                            if (IS_IMM) {
 
4692
                                simm = GET_FIELD_SPs(insn, 0, 10);
 
4693
                                tcg_gen_movi_tl(cpu_src2, simm);
 
4694
                            }
 
4695
 
 
4696
                            dst = gen_load_gpr(dc, rd);
 
4697
                            tcg_gen_movcond_tl(cmp.cond, dst,
 
4698
                                               cmp.c1, cmp.c2,
 
4699
                                               cpu_src2, dst);
 
4700
                            free_compare(&cmp);
 
4701
                            gen_store_gpr(dc, rd, dst);
 
4702
                            break;
 
4703
                        }
 
4704
                    case 0x2d: /* V9 sdivx */
 
4705
                        gen_helper_sdivx(cpu_dst, cpu_env, cpu_src1, cpu_src2);
 
4706
                        gen_store_gpr(dc, rd, cpu_dst);
 
4707
                        break;
 
4708
                    case 0x2e: /* V9 popc */
 
4709
                        tcg_gen_ctpop_tl(cpu_dst, cpu_src2);
 
4710
                        gen_store_gpr(dc, rd, cpu_dst);
 
4711
                        break;
 
4712
                    case 0x2f: /* V9 movr */
 
4713
                        {
 
4714
                            int cond = GET_FIELD_SP(insn, 10, 12);
 
4715
                            DisasCompare cmp;
 
4716
                            TCGv dst;
 
4717
 
 
4718
                            gen_compare_reg(&cmp, cond, cpu_src1);
 
4719
 
 
4720
                            /* The get_src2 above loaded the normal 13-bit
 
4721
                               immediate field, not the 10-bit field we have
 
4722
                               in movr.  But it did handle the reg case.  */
 
4723
                            if (IS_IMM) {
 
4724
                                simm = GET_FIELD_SPs(insn, 0, 9);
 
4725
                                tcg_gen_movi_tl(cpu_src2, simm);
 
4726
                            }
 
4727
 
 
4728
                            dst = gen_load_gpr(dc, rd);
 
4729
                            tcg_gen_movcond_tl(cmp.cond, dst,
 
4730
                                               cmp.c1, cmp.c2,
 
4731
                                               cpu_src2, dst);
 
4732
                            free_compare(&cmp);
 
4733
                            gen_store_gpr(dc, rd, dst);
 
4734
                            break;
 
4735
                        }
 
4736
#endif
 
4737
                    default:
 
4738
                        goto illegal_insn;
 
4739
                    }
 
4740
                }
 
4741
            } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
 
4742
#ifdef TARGET_SPARC64
 
4743
                int opf = GET_FIELD_SP(insn, 5, 13);
 
4744
                rs1 = GET_FIELD(insn, 13, 17);
 
4745
                rs2 = GET_FIELD(insn, 27, 31);
 
4746
                if (gen_trap_ifnofpu(dc)) {
 
4747
                    goto jmp_insn;
 
4748
                }
 
4749
 
 
4750
                switch (opf) {
 
4751
                case 0x000: /* VIS I edge8cc */
 
4752
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4753
                    cpu_src1 = gen_load_gpr(dc, rs1);
 
4754
                    cpu_src2 = gen_load_gpr(dc, rs2);
 
4755
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 1, 0);
 
4756
                    gen_store_gpr(dc, rd, cpu_dst);
 
4757
                    break;
 
4758
                case 0x001: /* VIS II edge8n */
 
4759
                    CHECK_FPU_FEATURE(dc, VIS2);
 
4760
                    cpu_src1 = gen_load_gpr(dc, rs1);
 
4761
                    cpu_src2 = gen_load_gpr(dc, rs2);
 
4762
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 0, 0);
 
4763
                    gen_store_gpr(dc, rd, cpu_dst);
 
4764
                    break;
 
4765
                case 0x002: /* VIS I edge8lcc */
 
4766
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4767
                    cpu_src1 = gen_load_gpr(dc, rs1);
 
4768
                    cpu_src2 = gen_load_gpr(dc, rs2);
 
4769
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 1, 1);
 
4770
                    gen_store_gpr(dc, rd, cpu_dst);
 
4771
                    break;
 
4772
                case 0x003: /* VIS II edge8ln */
 
4773
                    CHECK_FPU_FEATURE(dc, VIS2);
 
4774
                    cpu_src1 = gen_load_gpr(dc, rs1);
 
4775
                    cpu_src2 = gen_load_gpr(dc, rs2);
 
4776
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 8, 0, 1);
 
4777
                    gen_store_gpr(dc, rd, cpu_dst);
 
4778
                    break;
 
4779
                case 0x004: /* VIS I edge16cc */
 
4780
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4781
                    cpu_src1 = gen_load_gpr(dc, rs1);
 
4782
                    cpu_src2 = gen_load_gpr(dc, rs2);
 
4783
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 1, 0);
 
4784
                    gen_store_gpr(dc, rd, cpu_dst);
 
4785
                    break;
 
4786
                case 0x005: /* VIS II edge16n */
 
4787
                    CHECK_FPU_FEATURE(dc, VIS2);
 
4788
                    cpu_src1 = gen_load_gpr(dc, rs1);
 
4789
                    cpu_src2 = gen_load_gpr(dc, rs2);
 
4790
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 0, 0);
 
4791
                    gen_store_gpr(dc, rd, cpu_dst);
 
4792
                    break;
 
4793
                case 0x006: /* VIS I edge16lcc */
 
4794
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4795
                    cpu_src1 = gen_load_gpr(dc, rs1);
 
4796
                    cpu_src2 = gen_load_gpr(dc, rs2);
 
4797
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 1, 1);
 
4798
                    gen_store_gpr(dc, rd, cpu_dst);
 
4799
                    break;
 
4800
                case 0x007: /* VIS II edge16ln */
 
4801
                    CHECK_FPU_FEATURE(dc, VIS2);
 
4802
                    cpu_src1 = gen_load_gpr(dc, rs1);
 
4803
                    cpu_src2 = gen_load_gpr(dc, rs2);
 
4804
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 16, 0, 1);
 
4805
                    gen_store_gpr(dc, rd, cpu_dst);
 
4806
                    break;
 
4807
                case 0x008: /* VIS I edge32cc */
 
4808
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4809
                    cpu_src1 = gen_load_gpr(dc, rs1);
 
4810
                    cpu_src2 = gen_load_gpr(dc, rs2);
 
4811
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 1, 0);
 
4812
                    gen_store_gpr(dc, rd, cpu_dst);
 
4813
                    break;
 
4814
                case 0x009: /* VIS II edge32n */
 
4815
                    CHECK_FPU_FEATURE(dc, VIS2);
 
4816
                    cpu_src1 = gen_load_gpr(dc, rs1);
 
4817
                    cpu_src2 = gen_load_gpr(dc, rs2);
 
4818
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 0, 0);
 
4819
                    gen_store_gpr(dc, rd, cpu_dst);
 
4820
                    break;
 
4821
                case 0x00a: /* VIS I edge32lcc */
 
4822
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4823
                    cpu_src1 = gen_load_gpr(dc, rs1);
 
4824
                    cpu_src2 = gen_load_gpr(dc, rs2);
 
4825
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 1, 1);
 
4826
                    gen_store_gpr(dc, rd, cpu_dst);
 
4827
                    break;
 
4828
                case 0x00b: /* VIS II edge32ln */
 
4829
                    CHECK_FPU_FEATURE(dc, VIS2);
 
4830
                    cpu_src1 = gen_load_gpr(dc, rs1);
 
4831
                    cpu_src2 = gen_load_gpr(dc, rs2);
 
4832
                    gen_edge(dc, cpu_dst, cpu_src1, cpu_src2, 32, 0, 1);
 
4833
                    gen_store_gpr(dc, rd, cpu_dst);
 
4834
                    break;
 
4835
                case 0x010: /* VIS I array8 */
 
4836
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4837
                    cpu_src1 = gen_load_gpr(dc, rs1);
 
4838
                    cpu_src2 = gen_load_gpr(dc, rs2);
 
4839
                    gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
 
4840
                    gen_store_gpr(dc, rd, cpu_dst);
 
4841
                    break;
 
4842
                case 0x012: /* VIS I array16 */
 
4843
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4844
                    cpu_src1 = gen_load_gpr(dc, rs1);
 
4845
                    cpu_src2 = gen_load_gpr(dc, rs2);
 
4846
                    gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
 
4847
                    tcg_gen_shli_i64(cpu_dst, cpu_dst, 1);
 
4848
                    gen_store_gpr(dc, rd, cpu_dst);
 
4849
                    break;
 
4850
                case 0x014: /* VIS I array32 */
 
4851
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4852
                    cpu_src1 = gen_load_gpr(dc, rs1);
 
4853
                    cpu_src2 = gen_load_gpr(dc, rs2);
 
4854
                    gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
 
4855
                    tcg_gen_shli_i64(cpu_dst, cpu_dst, 2);
 
4856
                    gen_store_gpr(dc, rd, cpu_dst);
 
4857
                    break;
 
4858
                case 0x018: /* VIS I alignaddr */
 
4859
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4860
                    cpu_src1 = gen_load_gpr(dc, rs1);
 
4861
                    cpu_src2 = gen_load_gpr(dc, rs2);
 
4862
                    gen_alignaddr(cpu_dst, cpu_src1, cpu_src2, 0);
 
4863
                    gen_store_gpr(dc, rd, cpu_dst);
 
4864
                    break;
 
4865
                case 0x01a: /* VIS I alignaddrl */
 
4866
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4867
                    cpu_src1 = gen_load_gpr(dc, rs1);
 
4868
                    cpu_src2 = gen_load_gpr(dc, rs2);
 
4869
                    gen_alignaddr(cpu_dst, cpu_src1, cpu_src2, 1);
 
4870
                    gen_store_gpr(dc, rd, cpu_dst);
 
4871
                    break;
 
4872
                case 0x019: /* VIS II bmask */
 
4873
                    CHECK_FPU_FEATURE(dc, VIS2);
 
4874
                    cpu_src1 = gen_load_gpr(dc, rs1);
 
4875
                    cpu_src2 = gen_load_gpr(dc, rs2);
 
4876
                    tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
 
4877
                    tcg_gen_deposit_tl(cpu_gsr, cpu_gsr, cpu_dst, 32, 32);
 
4878
                    gen_store_gpr(dc, rd, cpu_dst);
 
4879
                    break;
 
4880
                case 0x020: /* VIS I fcmple16 */
 
4881
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4882
                    cpu_src1_64 = gen_load_fpr_D(dc, rs1);
 
4883
                    cpu_src2_64 = gen_load_fpr_D(dc, rs2);
 
4884
                    gen_helper_fcmple16(cpu_dst, cpu_src1_64, cpu_src2_64);
 
4885
                    gen_store_gpr(dc, rd, cpu_dst);
 
4886
                    break;
 
4887
                case 0x022: /* VIS I fcmpne16 */
 
4888
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4889
                    cpu_src1_64 = gen_load_fpr_D(dc, rs1);
 
4890
                    cpu_src2_64 = gen_load_fpr_D(dc, rs2);
 
4891
                    gen_helper_fcmpne16(cpu_dst, cpu_src1_64, cpu_src2_64);
 
4892
                    gen_store_gpr(dc, rd, cpu_dst);
 
4893
                    break;
 
4894
                case 0x024: /* VIS I fcmple32 */
 
4895
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4896
                    cpu_src1_64 = gen_load_fpr_D(dc, rs1);
 
4897
                    cpu_src2_64 = gen_load_fpr_D(dc, rs2);
 
4898
                    gen_helper_fcmple32(cpu_dst, cpu_src1_64, cpu_src2_64);
 
4899
                    gen_store_gpr(dc, rd, cpu_dst);
 
4900
                    break;
 
4901
                case 0x026: /* VIS I fcmpne32 */
 
4902
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4903
                    cpu_src1_64 = gen_load_fpr_D(dc, rs1);
 
4904
                    cpu_src2_64 = gen_load_fpr_D(dc, rs2);
 
4905
                    gen_helper_fcmpne32(cpu_dst, cpu_src1_64, cpu_src2_64);
 
4906
                    gen_store_gpr(dc, rd, cpu_dst);
 
4907
                    break;
 
4908
                case 0x028: /* VIS I fcmpgt16 */
 
4909
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4910
                    cpu_src1_64 = gen_load_fpr_D(dc, rs1);
 
4911
                    cpu_src2_64 = gen_load_fpr_D(dc, rs2);
 
4912
                    gen_helper_fcmpgt16(cpu_dst, cpu_src1_64, cpu_src2_64);
 
4913
                    gen_store_gpr(dc, rd, cpu_dst);
 
4914
                    break;
 
4915
                case 0x02a: /* VIS I fcmpeq16 */
 
4916
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4917
                    cpu_src1_64 = gen_load_fpr_D(dc, rs1);
 
4918
                    cpu_src2_64 = gen_load_fpr_D(dc, rs2);
 
4919
                    gen_helper_fcmpeq16(cpu_dst, cpu_src1_64, cpu_src2_64);
 
4920
                    gen_store_gpr(dc, rd, cpu_dst);
 
4921
                    break;
 
4922
                case 0x02c: /* VIS I fcmpgt32 */
 
4923
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4924
                    cpu_src1_64 = gen_load_fpr_D(dc, rs1);
 
4925
                    cpu_src2_64 = gen_load_fpr_D(dc, rs2);
 
4926
                    gen_helper_fcmpgt32(cpu_dst, cpu_src1_64, cpu_src2_64);
 
4927
                    gen_store_gpr(dc, rd, cpu_dst);
 
4928
                    break;
 
4929
                case 0x02e: /* VIS I fcmpeq32 */
 
4930
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4931
                    cpu_src1_64 = gen_load_fpr_D(dc, rs1);
 
4932
                    cpu_src2_64 = gen_load_fpr_D(dc, rs2);
 
4933
                    gen_helper_fcmpeq32(cpu_dst, cpu_src1_64, cpu_src2_64);
 
4934
                    gen_store_gpr(dc, rd, cpu_dst);
 
4935
                    break;
 
4936
                case 0x031: /* VIS I fmul8x16 */
 
4937
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4938
                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8x16);
 
4939
                    break;
 
4940
                case 0x033: /* VIS I fmul8x16au */
 
4941
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4942
                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8x16au);
 
4943
                    break;
 
4944
                case 0x035: /* VIS I fmul8x16al */
 
4945
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4946
                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8x16al);
 
4947
                    break;
 
4948
                case 0x036: /* VIS I fmul8sux16 */
 
4949
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4950
                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8sux16);
 
4951
                    break;
 
4952
                case 0x037: /* VIS I fmul8ulx16 */
 
4953
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4954
                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmul8ulx16);
 
4955
                    break;
 
4956
                case 0x038: /* VIS I fmuld8sux16 */
 
4957
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4958
                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmuld8sux16);
 
4959
                    break;
 
4960
                case 0x039: /* VIS I fmuld8ulx16 */
 
4961
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4962
                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fmuld8ulx16);
 
4963
                    break;
 
4964
                case 0x03a: /* VIS I fpack32 */
 
4965
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4966
                    gen_gsr_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpack32);
 
4967
                    break;
 
4968
                case 0x03b: /* VIS I fpack16 */
 
4969
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4970
                    cpu_src1_64 = gen_load_fpr_D(dc, rs2);
 
4971
                    cpu_dst_32 = gen_dest_fpr_F(dc);
 
4972
                    gen_helper_fpack16(cpu_dst_32, cpu_gsr, cpu_src1_64);
 
4973
                    gen_store_fpr_F(dc, rd, cpu_dst_32);
 
4974
                    break;
 
4975
                case 0x03d: /* VIS I fpackfix */
 
4976
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4977
                    cpu_src1_64 = gen_load_fpr_D(dc, rs2);
 
4978
                    cpu_dst_32 = gen_dest_fpr_F(dc);
 
4979
                    gen_helper_fpackfix(cpu_dst_32, cpu_gsr, cpu_src1_64);
 
4980
                    gen_store_fpr_F(dc, rd, cpu_dst_32);
 
4981
                    break;
 
4982
                case 0x03e: /* VIS I pdist */
 
4983
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4984
                    gen_ne_fop_DDDD(dc, rd, rs1, rs2, gen_helper_pdist);
 
4985
                    break;
 
4986
                case 0x048: /* VIS I faligndata */
 
4987
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4988
                    gen_gsr_fop_DDD(dc, rd, rs1, rs2, gen_faligndata);
 
4989
                    break;
 
4990
                case 0x04b: /* VIS I fpmerge */
 
4991
                    CHECK_FPU_FEATURE(dc, VIS1);
 
4992
                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpmerge);
 
4993
                    break;
 
4994
                case 0x04c: /* VIS II bshuffle */
 
4995
                    CHECK_FPU_FEATURE(dc, VIS2);
 
4996
                    gen_gsr_fop_DDD(dc, rd, rs1, rs2, gen_helper_bshuffle);
 
4997
                    break;
 
4998
                case 0x04d: /* VIS I fexpand */
 
4999
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5000
                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fexpand);
 
5001
                    break;
 
5002
                case 0x050: /* VIS I fpadd16 */
 
5003
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5004
                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpadd16);
 
5005
                    break;
 
5006
                case 0x051: /* VIS I fpadd16s */
 
5007
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5008
                    gen_ne_fop_FFF(dc, rd, rs1, rs2, gen_helper_fpadd16s);
 
5009
                    break;
 
5010
                case 0x052: /* VIS I fpadd32 */
 
5011
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5012
                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpadd32);
 
5013
                    break;
 
5014
                case 0x053: /* VIS I fpadd32s */
 
5015
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5016
                    gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_add_i32);
 
5017
                    break;
 
5018
                case 0x054: /* VIS I fpsub16 */
 
5019
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5020
                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpsub16);
 
5021
                    break;
 
5022
                case 0x055: /* VIS I fpsub16s */
 
5023
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5024
                    gen_ne_fop_FFF(dc, rd, rs1, rs2, gen_helper_fpsub16s);
 
5025
                    break;
 
5026
                case 0x056: /* VIS I fpsub32 */
 
5027
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5028
                    gen_ne_fop_DDD(dc, rd, rs1, rs2, gen_helper_fpsub32);
 
5029
                    break;
 
5030
                case 0x057: /* VIS I fpsub32s */
 
5031
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5032
                    gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_sub_i32);
 
5033
                    break;
 
5034
                case 0x060: /* VIS I fzero */
 
5035
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5036
                    cpu_dst_64 = gen_dest_fpr_D(dc, rd);
 
5037
                    tcg_gen_movi_i64(cpu_dst_64, 0);
 
5038
                    gen_store_fpr_D(dc, rd, cpu_dst_64);
 
5039
                    break;
 
5040
                case 0x061: /* VIS I fzeros */
 
5041
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5042
                    cpu_dst_32 = gen_dest_fpr_F(dc);
 
5043
                    tcg_gen_movi_i32(cpu_dst_32, 0);
 
5044
                    gen_store_fpr_F(dc, rd, cpu_dst_32);
 
5045
                    break;
 
5046
                case 0x062: /* VIS I fnor */
 
5047
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5048
                    gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_nor_i64);
 
5049
                    break;
 
5050
                case 0x063: /* VIS I fnors */
 
5051
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5052
                    gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_nor_i32);
 
5053
                    break;
 
5054
                case 0x064: /* VIS I fandnot2 */
 
5055
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5056
                    gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_andc_i64);
 
5057
                    break;
 
5058
                case 0x065: /* VIS I fandnot2s */
 
5059
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5060
                    gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_andc_i32);
 
5061
                    break;
 
5062
                case 0x066: /* VIS I fnot2 */
 
5063
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5064
                    gen_ne_fop_DD(dc, rd, rs2, tcg_gen_not_i64);
 
5065
                    break;
 
5066
                case 0x067: /* VIS I fnot2s */
 
5067
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5068
                    gen_ne_fop_FF(dc, rd, rs2, tcg_gen_not_i32);
 
5069
                    break;
 
5070
                case 0x068: /* VIS I fandnot1 */
 
5071
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5072
                    gen_ne_fop_DDD(dc, rd, rs2, rs1, tcg_gen_andc_i64);
 
5073
                    break;
 
5074
                case 0x069: /* VIS I fandnot1s */
 
5075
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5076
                    gen_ne_fop_FFF(dc, rd, rs2, rs1, tcg_gen_andc_i32);
 
5077
                    break;
 
5078
                case 0x06a: /* VIS I fnot1 */
 
5079
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5080
                    gen_ne_fop_DD(dc, rd, rs1, tcg_gen_not_i64);
 
5081
                    break;
 
5082
                case 0x06b: /* VIS I fnot1s */
 
5083
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5084
                    gen_ne_fop_FF(dc, rd, rs1, tcg_gen_not_i32);
 
5085
                    break;
 
5086
                case 0x06c: /* VIS I fxor */
 
5087
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5088
                    gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_xor_i64);
 
5089
                    break;
 
5090
                case 0x06d: /* VIS I fxors */
 
5091
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5092
                    gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_xor_i32);
 
5093
                    break;
 
5094
                case 0x06e: /* VIS I fnand */
 
5095
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5096
                    gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_nand_i64);
 
5097
                    break;
 
5098
                case 0x06f: /* VIS I fnands */
 
5099
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5100
                    gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_nand_i32);
 
5101
                    break;
 
5102
                case 0x070: /* VIS I fand */
 
5103
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5104
                    gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_and_i64);
 
5105
                    break;
 
5106
                case 0x071: /* VIS I fands */
 
5107
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5108
                    gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_and_i32);
 
5109
                    break;
 
5110
                case 0x072: /* VIS I fxnor */
 
5111
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5112
                    gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_eqv_i64);
 
5113
                    break;
 
5114
                case 0x073: /* VIS I fxnors */
 
5115
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5116
                    gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_eqv_i32);
 
5117
                    break;
 
5118
                case 0x074: /* VIS I fsrc1 */
 
5119
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5120
                    cpu_src1_64 = gen_load_fpr_D(dc, rs1);
 
5121
                    gen_store_fpr_D(dc, rd, cpu_src1_64);
 
5122
                    break;
 
5123
                case 0x075: /* VIS I fsrc1s */
 
5124
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5125
                    cpu_src1_32 = gen_load_fpr_F(dc, rs1);
 
5126
                    gen_store_fpr_F(dc, rd, cpu_src1_32);
 
5127
                    break;
 
5128
                case 0x076: /* VIS I fornot2 */
 
5129
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5130
                    gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_orc_i64);
 
5131
                    break;
 
5132
                case 0x077: /* VIS I fornot2s */
 
5133
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5134
                    gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_orc_i32);
 
5135
                    break;
 
5136
                case 0x078: /* VIS I fsrc2 */
 
5137
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5138
                    cpu_src1_64 = gen_load_fpr_D(dc, rs2);
 
5139
                    gen_store_fpr_D(dc, rd, cpu_src1_64);
 
5140
                    break;
 
5141
                case 0x079: /* VIS I fsrc2s */
 
5142
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5143
                    cpu_src1_32 = gen_load_fpr_F(dc, rs2);
 
5144
                    gen_store_fpr_F(dc, rd, cpu_src1_32);
 
5145
                    break;
 
5146
                case 0x07a: /* VIS I fornot1 */
 
5147
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5148
                    gen_ne_fop_DDD(dc, rd, rs2, rs1, tcg_gen_orc_i64);
 
5149
                    break;
 
5150
                case 0x07b: /* VIS I fornot1s */
 
5151
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5152
                    gen_ne_fop_FFF(dc, rd, rs2, rs1, tcg_gen_orc_i32);
 
5153
                    break;
 
5154
                case 0x07c: /* VIS I for */
 
5155
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5156
                    gen_ne_fop_DDD(dc, rd, rs1, rs2, tcg_gen_or_i64);
 
5157
                    break;
 
5158
                case 0x07d: /* VIS I fors */
 
5159
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5160
                    gen_ne_fop_FFF(dc, rd, rs1, rs2, tcg_gen_or_i32);
 
5161
                    break;
 
5162
                case 0x07e: /* VIS I fone */
 
5163
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5164
                    cpu_dst_64 = gen_dest_fpr_D(dc, rd);
 
5165
                    tcg_gen_movi_i64(cpu_dst_64, -1);
 
5166
                    gen_store_fpr_D(dc, rd, cpu_dst_64);
 
5167
                    break;
 
5168
                case 0x07f: /* VIS I fones */
 
5169
                    CHECK_FPU_FEATURE(dc, VIS1);
 
5170
                    cpu_dst_32 = gen_dest_fpr_F(dc);
 
5171
                    tcg_gen_movi_i32(cpu_dst_32, -1);
 
5172
                    gen_store_fpr_F(dc, rd, cpu_dst_32);
 
5173
                    break;
 
5174
                case 0x080: /* VIS I shutdown */
 
5175
                case 0x081: /* VIS II siam */
 
5176
                    // XXX
 
5177
                    goto illegal_insn;
 
5178
                default:
 
5179
                    goto illegal_insn;
 
5180
                }
 
5181
#else
 
5182
                goto ncp_insn;
 
5183
#endif
 
5184
            } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
 
5185
#ifdef TARGET_SPARC64
 
5186
                goto illegal_insn;
 
5187
#else
 
5188
                goto ncp_insn;
 
5189
#endif
 
5190
#ifdef TARGET_SPARC64
 
5191
            } else if (xop == 0x39) { /* V9 return */
 
5192
                save_state(dc);
 
5193
                cpu_src1 = get_src1(dc, insn);
 
5194
                cpu_tmp0 = get_temp_tl(dc);
 
5195
                if (IS_IMM) {   /* immediate */
 
5196
                    simm = GET_FIELDs(insn, 19, 31);
 
5197
                    tcg_gen_addi_tl(cpu_tmp0, cpu_src1, simm);
 
5198
                } else {                /* register */
 
5199
                    rs2 = GET_FIELD(insn, 27, 31);
 
5200
                    if (rs2) {
 
5201
                        cpu_src2 = gen_load_gpr(dc, rs2);
 
5202
                        tcg_gen_add_tl(cpu_tmp0, cpu_src1, cpu_src2);
 
5203
                    } else {
 
5204
                        tcg_gen_mov_tl(cpu_tmp0, cpu_src1);
 
5205
                    }
 
5206
                }
 
5207
                gen_helper_restore(cpu_env);
 
5208
                gen_mov_pc_npc(dc);
 
5209
                gen_check_align(cpu_tmp0, 3);
 
5210
                tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
 
5211
                dc->npc = DYNAMIC_PC;
 
5212
                goto jmp_insn;
 
5213
#endif
 
5214
            } else {
 
5215
                cpu_src1 = get_src1(dc, insn);
 
5216
                cpu_tmp0 = get_temp_tl(dc);
 
5217
                if (IS_IMM) {   /* immediate */
 
5218
                    simm = GET_FIELDs(insn, 19, 31);
 
5219
                    tcg_gen_addi_tl(cpu_tmp0, cpu_src1, simm);
 
5220
                } else {                /* register */
 
5221
                    rs2 = GET_FIELD(insn, 27, 31);
 
5222
                    if (rs2) {
 
5223
                        cpu_src2 = gen_load_gpr(dc, rs2);
 
5224
                        tcg_gen_add_tl(cpu_tmp0, cpu_src1, cpu_src2);
 
5225
                    } else {
 
5226
                        tcg_gen_mov_tl(cpu_tmp0, cpu_src1);
 
5227
                    }
 
5228
                }
 
5229
                switch (xop) {
 
5230
                case 0x38:      /* jmpl */
 
5231
                    {
 
5232
                        TCGv t = gen_dest_gpr(dc, rd);
 
5233
                        tcg_gen_movi_tl(t, dc->pc);
 
5234
                        gen_store_gpr(dc, rd, t);
 
5235
 
 
5236
                        gen_mov_pc_npc(dc);
 
5237
                        gen_check_align(cpu_tmp0, 3);
 
5238
                        gen_address_mask(dc, cpu_tmp0);
 
5239
                        tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
 
5240
                        dc->npc = DYNAMIC_PC;
 
5241
                    }
 
5242
                    goto jmp_insn;
 
5243
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
 
5244
                case 0x39:      /* rett, V9 return */
 
5245
                    {
 
5246
                        if (!supervisor(dc))
 
5247
                            goto priv_insn;
 
5248
                        gen_mov_pc_npc(dc);
 
5249
                        gen_check_align(cpu_tmp0, 3);
 
5250
                        tcg_gen_mov_tl(cpu_npc, cpu_tmp0);
 
5251
                        dc->npc = DYNAMIC_PC;
 
5252
                        gen_helper_rett(cpu_env);
 
5253
                    }
 
5254
                    goto jmp_insn;
 
5255
#endif
 
5256
                case 0x3b: /* flush */
 
5257
                    if (!((dc)->def->features & CPU_FEATURE_FLUSH))
 
5258
                        goto unimp_flush;
 
5259
                    /* nop */
 
5260
                    break;
 
5261
                case 0x3c:      /* save */
 
5262
                    gen_helper_save(cpu_env);
 
5263
                    gen_store_gpr(dc, rd, cpu_tmp0);
 
5264
                    break;
 
5265
                case 0x3d:      /* restore */
 
5266
                    gen_helper_restore(cpu_env);
 
5267
                    gen_store_gpr(dc, rd, cpu_tmp0);
 
5268
                    break;
 
5269
#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
 
5270
                case 0x3e:      /* V9 done/retry */
 
5271
                    {
 
5272
                        switch (rd) {
 
5273
                        case 0:
 
5274
                            if (!supervisor(dc))
 
5275
                                goto priv_insn;
 
5276
                            dc->npc = DYNAMIC_PC;
 
5277
                            dc->pc = DYNAMIC_PC;
 
5278
                            gen_helper_done(cpu_env);
 
5279
                            goto jmp_insn;
 
5280
                        case 1:
 
5281
                            if (!supervisor(dc))
 
5282
                                goto priv_insn;
 
5283
                            dc->npc = DYNAMIC_PC;
 
5284
                            dc->pc = DYNAMIC_PC;
 
5285
                            gen_helper_retry(cpu_env);
 
5286
                            goto jmp_insn;
 
5287
                        default:
 
5288
                            goto illegal_insn;
 
5289
                        }
 
5290
                    }
 
5291
                    break;
 
5292
#endif
 
5293
                default:
 
5294
                    goto illegal_insn;
 
5295
                }
 
5296
            }
 
5297
            break;
 
5298
        }
 
5299
        break;
 
5300
    case 3:                     /* load/store instructions */
 
5301
        {
 
5302
            unsigned int xop = GET_FIELD(insn, 7, 12);
 
5303
            /* ??? gen_address_mask prevents us from using a source
 
5304
               register directly.  Always generate a temporary.  */
 
5305
            TCGv cpu_addr = get_temp_tl(dc);
 
5306
 
 
5307
            tcg_gen_mov_tl(cpu_addr, get_src1(dc, insn));
 
5308
            if (xop == 0x3c || xop == 0x3e) {
 
5309
                /* V9 casa/casxa : no offset */
 
5310
            } else if (IS_IMM) {     /* immediate */
 
5311
                simm = GET_FIELDs(insn, 19, 31);
 
5312
                if (simm != 0) {
 
5313
                    tcg_gen_addi_tl(cpu_addr, cpu_addr, simm);
 
5314
                }
 
5315
            } else {            /* register */
 
5316
                rs2 = GET_FIELD(insn, 27, 31);
 
5317
                if (rs2 != 0) {
 
5318
                    tcg_gen_add_tl(cpu_addr, cpu_addr, gen_load_gpr(dc, rs2));
 
5319
                }
 
5320
            }
 
5321
            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
 
5322
                (xop > 0x17 && xop <= 0x1d ) ||
 
5323
                (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
 
5324
                TCGv cpu_val = gen_dest_gpr(dc, rd);
 
5325
 
 
5326
                switch (xop) {
 
5327
                case 0x0:       /* ld, V9 lduw, load unsigned word */
 
5328
                    gen_address_mask(dc, cpu_addr);
 
5329
                    tcg_gen_qemu_ld32u(cpu_val, cpu_addr, dc->mem_idx);
 
5330
                    break;
 
5331
                case 0x1:       /* ldub, load unsigned byte */
 
5332
                    gen_address_mask(dc, cpu_addr);
 
5333
                    tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx);
 
5334
                    break;
 
5335
                case 0x2:       /* lduh, load unsigned halfword */
 
5336
                    gen_address_mask(dc, cpu_addr);
 
5337
                    tcg_gen_qemu_ld16u(cpu_val, cpu_addr, dc->mem_idx);
 
5338
                    break;
 
5339
                case 0x3:       /* ldd, load double word */
 
5340
                    if (rd & 1)
 
5341
                        goto illegal_insn;
 
5342
                    else {
 
5343
                        TCGv_i64 t64;
 
5344
 
 
5345
                        gen_address_mask(dc, cpu_addr);
 
5346
                        t64 = tcg_temp_new_i64();
 
5347
                        tcg_gen_qemu_ld64(t64, cpu_addr, dc->mem_idx);
 
5348
                        tcg_gen_trunc_i64_tl(cpu_val, t64);
 
5349
                        tcg_gen_ext32u_tl(cpu_val, cpu_val);
 
5350
                        gen_store_gpr(dc, rd + 1, cpu_val);
 
5351
                        tcg_gen_shri_i64(t64, t64, 32);
 
5352
                        tcg_gen_trunc_i64_tl(cpu_val, t64);
 
5353
                        tcg_temp_free_i64(t64);
 
5354
                        tcg_gen_ext32u_tl(cpu_val, cpu_val);
 
5355
                    }
 
5356
                    break;
 
5357
                case 0x9:       /* ldsb, load signed byte */
 
5358
                    gen_address_mask(dc, cpu_addr);
 
5359
                    tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
 
5360
                    break;
 
5361
                case 0xa:       /* ldsh, load signed halfword */
 
5362
                    gen_address_mask(dc, cpu_addr);
 
5363
                    tcg_gen_qemu_ld16s(cpu_val, cpu_addr, dc->mem_idx);
 
5364
                    break;
 
5365
                case 0xd:       /* ldstub */
 
5366
                    gen_ldstub(dc, cpu_val, cpu_addr, dc->mem_idx);
 
5367
                    break;
 
5368
                case 0x0f:
 
5369
                    /* swap, swap register with memory. Also atomically */
 
5370
                    CHECK_IU_FEATURE(dc, SWAP);
 
5371
                    cpu_src1 = gen_load_gpr(dc, rd);
 
5372
                    gen_swap(dc, cpu_val, cpu_src1, cpu_addr,
 
5373
                             dc->mem_idx, MO_TEUL);
 
5374
                    break;
 
5375
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
 
5376
                case 0x10:      /* lda, V9 lduwa, load word alternate */
 
5377
                    gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEUL);
 
5378
                    break;
 
5379
                case 0x11:      /* lduba, load unsigned byte alternate */
 
5380
                    gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_UB);
 
5381
                    break;
 
5382
                case 0x12:      /* lduha, load unsigned halfword alternate */
 
5383
                    gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEUW);
 
5384
                    break;
 
5385
                case 0x13:      /* ldda, load double word alternate */
 
5386
                    if (rd & 1) {
 
5387
                        goto illegal_insn;
 
5388
                    }
 
5389
                    gen_ldda_asi(dc, cpu_addr, insn, rd);
 
5390
                    goto skip_move;
 
5391
                case 0x19:      /* ldsba, load signed byte alternate */
 
5392
                    gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_SB);
 
5393
                    break;
 
5394
                case 0x1a:      /* ldsha, load signed halfword alternate */
 
5395
                    gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TESW);
 
5396
                    break;
 
5397
                case 0x1d:      /* ldstuba -- XXX: should be atomically */
 
5398
                    gen_ldstub_asi(dc, cpu_val, cpu_addr, insn);
 
5399
                    break;
 
5400
                case 0x1f:      /* swapa, swap reg with alt. memory. Also
 
5401
                                   atomically */
 
5402
                    CHECK_IU_FEATURE(dc, SWAP);
 
5403
                    cpu_src1 = gen_load_gpr(dc, rd);
 
5404
                    gen_swap_asi(dc, cpu_val, cpu_src1, cpu_addr, insn);
 
5405
                    break;
 
5406
 
 
5407
#ifndef TARGET_SPARC64
 
5408
                case 0x30: /* ldc */
 
5409
                case 0x31: /* ldcsr */
 
5410
                case 0x33: /* lddc */
 
5411
                    goto ncp_insn;
 
5412
#endif
 
5413
#endif
 
5414
#ifdef TARGET_SPARC64
 
5415
                case 0x08: /* V9 ldsw */
 
5416
                    gen_address_mask(dc, cpu_addr);
 
5417
                    tcg_gen_qemu_ld32s(cpu_val, cpu_addr, dc->mem_idx);
 
5418
                    break;
 
5419
                case 0x0b: /* V9 ldx */
 
5420
                    gen_address_mask(dc, cpu_addr);
 
5421
                    tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx);
 
5422
                    break;
 
5423
                case 0x18: /* V9 ldswa */
 
5424
                    gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TESL);
 
5425
                    break;
 
5426
                case 0x1b: /* V9 ldxa */
 
5427
                    gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TEQ);
 
5428
                    break;
 
5429
                case 0x2d: /* V9 prefetch, no effect */
 
5430
                    goto skip_move;
 
5431
                case 0x30: /* V9 ldfa */
 
5432
                    if (gen_trap_ifnofpu(dc)) {
 
5433
                        goto jmp_insn;
 
5434
                    }
 
5435
                    gen_ldf_asi(dc, cpu_addr, insn, 4, rd);
 
5436
                    gen_update_fprs_dirty(dc, rd);
 
5437
                    goto skip_move;
 
5438
                case 0x33: /* V9 lddfa */
 
5439
                    if (gen_trap_ifnofpu(dc)) {
 
5440
                        goto jmp_insn;
 
5441
                    }
 
5442
                    gen_ldf_asi(dc, cpu_addr, insn, 8, DFPREG(rd));
 
5443
                    gen_update_fprs_dirty(dc, DFPREG(rd));
 
5444
                    goto skip_move;
 
5445
                case 0x3d: /* V9 prefetcha, no effect */
 
5446
                    goto skip_move;
 
5447
                case 0x32: /* V9 ldqfa */
 
5448
                    CHECK_FPU_FEATURE(dc, FLOAT128);
 
5449
                    if (gen_trap_ifnofpu(dc)) {
 
5450
                        goto jmp_insn;
 
5451
                    }
 
5452
                    gen_ldf_asi(dc, cpu_addr, insn, 16, QFPREG(rd));
 
5453
                    gen_update_fprs_dirty(dc, QFPREG(rd));
 
5454
                    goto skip_move;
 
5455
#endif
 
5456
                default:
 
5457
                    goto illegal_insn;
 
5458
                }
 
5459
                gen_store_gpr(dc, rd, cpu_val);
 
5460
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
 
5461
            skip_move: ;
 
5462
#endif
 
5463
            } else if (xop >= 0x20 && xop < 0x24) {
 
5464
                if (gen_trap_ifnofpu(dc)) {
 
5465
                    goto jmp_insn;
 
5466
                }
 
5467
                switch (xop) {
 
5468
                case 0x20:      /* ldf, load fpreg */
 
5469
                    gen_address_mask(dc, cpu_addr);
 
5470
                    cpu_dst_32 = gen_dest_fpr_F(dc);
 
5471
                    tcg_gen_qemu_ld_i32(cpu_dst_32, cpu_addr,
 
5472
                                        dc->mem_idx, MO_TEUL);
 
5473
                    gen_store_fpr_F(dc, rd, cpu_dst_32);
 
5474
                    break;
 
5475
                case 0x21:      /* ldfsr, V9 ldxfsr */
 
5476
#ifdef TARGET_SPARC64
 
5477
                    gen_address_mask(dc, cpu_addr);
 
5478
                    if (rd == 1) {
 
5479
                        TCGv_i64 t64 = tcg_temp_new_i64();
 
5480
                        tcg_gen_qemu_ld_i64(t64, cpu_addr,
 
5481
                                            dc->mem_idx, MO_TEQ);
 
5482
                        gen_helper_ldxfsr(cpu_fsr, cpu_env, cpu_fsr, t64);
 
5483
                        tcg_temp_free_i64(t64);
 
5484
                        break;
 
5485
                    }
 
5486
#endif
 
5487
                    cpu_dst_32 = get_temp_i32(dc);
 
5488
                    tcg_gen_qemu_ld_i32(cpu_dst_32, cpu_addr,
 
5489
                                        dc->mem_idx, MO_TEUL);
 
5490
                    gen_helper_ldfsr(cpu_fsr, cpu_env, cpu_fsr, cpu_dst_32);
 
5491
                    break;
 
5492
                case 0x22:      /* ldqf, load quad fpreg */
 
5493
                    CHECK_FPU_FEATURE(dc, FLOAT128);
 
5494
                    gen_address_mask(dc, cpu_addr);
 
5495
                    cpu_src1_64 = tcg_temp_new_i64();
 
5496
                    tcg_gen_qemu_ld_i64(cpu_src1_64, cpu_addr, dc->mem_idx,
 
5497
                                        MO_TEQ | MO_ALIGN_4);
 
5498
                    tcg_gen_addi_tl(cpu_addr, cpu_addr, 8);
 
5499
                    cpu_src2_64 = tcg_temp_new_i64();
 
5500
                    tcg_gen_qemu_ld_i64(cpu_src2_64, cpu_addr, dc->mem_idx,
 
5501
                                        MO_TEQ | MO_ALIGN_4);
 
5502
                    gen_store_fpr_Q(dc, rd, cpu_src1_64, cpu_src2_64);
 
5503
                    tcg_temp_free_i64(cpu_src1_64);
 
5504
                    tcg_temp_free_i64(cpu_src2_64);
 
5505
                    break;
 
5506
                case 0x23:      /* lddf, load double fpreg */
 
5507
                    gen_address_mask(dc, cpu_addr);
 
5508
                    cpu_dst_64 = gen_dest_fpr_D(dc, rd);
 
5509
                    tcg_gen_qemu_ld_i64(cpu_dst_64, cpu_addr, dc->mem_idx,
 
5510
                                        MO_TEQ | MO_ALIGN_4);
 
5511
                    gen_store_fpr_D(dc, rd, cpu_dst_64);
 
5512
                    break;
 
5513
                default:
 
5514
                    goto illegal_insn;
 
5515
                }
 
5516
            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) ||
 
5517
                       xop == 0xe || xop == 0x1e) {
 
5518
                TCGv cpu_val = gen_load_gpr(dc, rd);
 
5519
 
 
5520
                switch (xop) {
 
5521
                case 0x4: /* st, store word */
 
5522
                    gen_address_mask(dc, cpu_addr);
 
5523
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
 
5524
                    break;
 
5525
                case 0x5: /* stb, store byte */
 
5526
                    gen_address_mask(dc, cpu_addr);
 
5527
                    tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx);
 
5528
                    break;
 
5529
                case 0x6: /* sth, store halfword */
 
5530
                    gen_address_mask(dc, cpu_addr);
 
5531
                    tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx);
 
5532
                    break;
 
5533
                case 0x7: /* std, store double word */
 
5534
                    if (rd & 1)
 
5535
                        goto illegal_insn;
 
5536
                    else {
 
5537
                        TCGv_i64 t64;
 
5538
                        TCGv lo;
 
5539
 
 
5540
                        gen_address_mask(dc, cpu_addr);
 
5541
                        lo = gen_load_gpr(dc, rd + 1);
 
5542
                        t64 = tcg_temp_new_i64();
 
5543
                        tcg_gen_concat_tl_i64(t64, lo, cpu_val);
 
5544
                        tcg_gen_qemu_st64(t64, cpu_addr, dc->mem_idx);
 
5545
                        tcg_temp_free_i64(t64);
 
5546
                    }
 
5547
                    break;
 
5548
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
 
5549
                case 0x14: /* sta, V9 stwa, store word alternate */
 
5550
                    gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUL);
 
5551
                    break;
 
5552
                case 0x15: /* stba, store byte alternate */
 
5553
                    gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_UB);
 
5554
                    break;
 
5555
                case 0x16: /* stha, store halfword alternate */
 
5556
                    gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUW);
 
5557
                    break;
 
5558
                case 0x17: /* stda, store double word alternate */
 
5559
                    if (rd & 1) {
 
5560
                        goto illegal_insn;
 
5561
                    }
 
5562
                    gen_stda_asi(dc, cpu_val, cpu_addr, insn, rd);
 
5563
                    break;
 
5564
#endif
 
5565
#ifdef TARGET_SPARC64
 
5566
                case 0x0e: /* V9 stx */
 
5567
                    gen_address_mask(dc, cpu_addr);
 
5568
                    tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx);
 
5569
                    break;
 
5570
                case 0x1e: /* V9 stxa */
 
5571
                    gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEQ);
 
5572
                    break;
 
5573
#endif
 
5574
                default:
 
5575
                    goto illegal_insn;
 
5576
                }
 
5577
            } else if (xop > 0x23 && xop < 0x28) {
 
5578
                if (gen_trap_ifnofpu(dc)) {
 
5579
                    goto jmp_insn;
 
5580
                }
 
5581
                switch (xop) {
 
5582
                case 0x24: /* stf, store fpreg */
 
5583
                    gen_address_mask(dc, cpu_addr);
 
5584
                    cpu_src1_32 = gen_load_fpr_F(dc, rd);
 
5585
                    tcg_gen_qemu_st_i32(cpu_src1_32, cpu_addr,
 
5586
                                        dc->mem_idx, MO_TEUL);
 
5587
                    break;
 
5588
                case 0x25: /* stfsr, V9 stxfsr */
 
5589
                    {
 
5590
#ifdef TARGET_SPARC64
 
5591
                        gen_address_mask(dc, cpu_addr);
 
5592
                        if (rd == 1) {
 
5593
                            tcg_gen_qemu_st64(cpu_fsr, cpu_addr, dc->mem_idx);
 
5594
                            break;
 
5595
                        }
 
5596
#endif
 
5597
                        tcg_gen_qemu_st32(cpu_fsr, cpu_addr, dc->mem_idx);
 
5598
                    }
 
5599
                    break;
 
5600
                case 0x26:
 
5601
#ifdef TARGET_SPARC64
 
5602
                    /* V9 stqf, store quad fpreg */
 
5603
                    CHECK_FPU_FEATURE(dc, FLOAT128);
 
5604
                    gen_address_mask(dc, cpu_addr);
 
5605
                    /* ??? While stqf only requires 4-byte alignment, it is
 
5606
                       legal for the cpu to signal the unaligned exception.
 
5607
                       The OS trap handler is then required to fix it up.
 
5608
                       For qemu, this avoids having to probe the second page
 
5609
                       before performing the first write.  */
 
5610
                    cpu_src1_64 = gen_load_fpr_Q0(dc, rd);
 
5611
                    tcg_gen_qemu_st_i64(cpu_src1_64, cpu_addr,
 
5612
                                        dc->mem_idx, MO_TEQ | MO_ALIGN_16);
 
5613
                    tcg_gen_addi_tl(cpu_addr, cpu_addr, 8);
 
5614
                    cpu_src2_64 = gen_load_fpr_Q1(dc, rd);
 
5615
                    tcg_gen_qemu_st_i64(cpu_src1_64, cpu_addr,
 
5616
                                        dc->mem_idx, MO_TEQ);
 
5617
                    break;
 
5618
#else /* !TARGET_SPARC64 */
 
5619
                    /* stdfq, store floating point queue */
 
5620
#if defined(CONFIG_USER_ONLY)
 
5621
                    goto illegal_insn;
 
5622
#else
 
5623
                    if (!supervisor(dc))
 
5624
                        goto priv_insn;
 
5625
                    if (gen_trap_ifnofpu(dc)) {
 
5626
                        goto jmp_insn;
 
5627
                    }
 
5628
                    goto nfq_insn;
 
5629
#endif
 
5630
#endif
 
5631
                case 0x27: /* stdf, store double fpreg */
 
5632
                    gen_address_mask(dc, cpu_addr);
 
5633
                    cpu_src1_64 = gen_load_fpr_D(dc, rd);
 
5634
                    tcg_gen_qemu_st_i64(cpu_src1_64, cpu_addr, dc->mem_idx,
 
5635
                                        MO_TEQ | MO_ALIGN_4);
 
5636
                    break;
 
5637
                default:
 
5638
                    goto illegal_insn;
 
5639
                }
 
5640
            } else if (xop > 0x33 && xop < 0x3f) {
 
5641
                switch (xop) {
 
5642
#ifdef TARGET_SPARC64
 
5643
                case 0x34: /* V9 stfa */
 
5644
                    if (gen_trap_ifnofpu(dc)) {
 
5645
                        goto jmp_insn;
 
5646
                    }
 
5647
                    gen_stf_asi(dc, cpu_addr, insn, 4, rd);
 
5648
                    break;
 
5649
                case 0x36: /* V9 stqfa */
 
5650
                    {
 
5651
                        CHECK_FPU_FEATURE(dc, FLOAT128);
 
5652
                        if (gen_trap_ifnofpu(dc)) {
 
5653
                            goto jmp_insn;
 
5654
                        }
 
5655
                        gen_stf_asi(dc, cpu_addr, insn, 16, QFPREG(rd));
 
5656
                    }
 
5657
                    break;
 
5658
                case 0x37: /* V9 stdfa */
 
5659
                    if (gen_trap_ifnofpu(dc)) {
 
5660
                        goto jmp_insn;
 
5661
                    }
 
5662
                    gen_stf_asi(dc, cpu_addr, insn, 8, DFPREG(rd));
 
5663
                    break;
 
5664
                case 0x3e: /* V9 casxa */
 
5665
                    rs2 = GET_FIELD(insn, 27, 31);
 
5666
                    cpu_src2 = gen_load_gpr(dc, rs2);
 
5667
                    gen_casx_asi(dc, cpu_addr, cpu_src2, insn, rd);
 
5668
                    break;
 
5669
#else
 
5670
                case 0x34: /* stc */
 
5671
                case 0x35: /* stcsr */
 
5672
                case 0x36: /* stdcq */
 
5673
                case 0x37: /* stdc */
 
5674
                    goto ncp_insn;
 
5675
#endif
 
5676
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
 
5677
                case 0x3c: /* V9 or LEON3 casa */
 
5678
#ifndef TARGET_SPARC64
 
5679
                    CHECK_IU_FEATURE(dc, CASA);
 
5680
#endif
 
5681
                    rs2 = GET_FIELD(insn, 27, 31);
 
5682
                    cpu_src2 = gen_load_gpr(dc, rs2);
 
5683
                    gen_cas_asi(dc, cpu_addr, cpu_src2, insn, rd);
 
5684
                    break;
 
5685
#endif
 
5686
                default:
 
5687
                    goto illegal_insn;
 
5688
                }
 
5689
            } else {
 
5690
                goto illegal_insn;
 
5691
            }
 
5692
        }
 
5693
        break;
 
5694
    }
 
5695
    /* default case for non jump instructions */
 
5696
    if (dc->npc == DYNAMIC_PC) {
 
5697
        dc->pc = DYNAMIC_PC;
 
5698
        gen_op_next_insn();
 
5699
    } else if (dc->npc == JUMP_PC) {
 
5700
        /* we can do a static jump */
 
5701
        gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
 
5702
        dc->is_br = 1;
 
5703
    } else {
 
5704
        dc->pc = dc->npc;
 
5705
        dc->npc = dc->npc + 4;
 
5706
    }
 
5707
 jmp_insn:
 
5708
    goto egress;
 
5709
 illegal_insn:
 
5710
    gen_exception(dc, TT_ILL_INSN);
 
5711
    goto egress;
 
5712
 unimp_flush:
 
5713
    gen_exception(dc, TT_UNIMP_FLUSH);
 
5714
    goto egress;
 
5715
#if !defined(CONFIG_USER_ONLY)
 
5716
 priv_insn:
 
5717
    gen_exception(dc, TT_PRIV_INSN);
 
5718
    goto egress;
 
5719
#endif
 
5720
 nfpu_insn:
 
5721
    gen_op_fpexception_im(dc, FSR_FTT_UNIMPFPOP);
 
5722
    goto egress;
 
5723
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
 
5724
 nfq_insn:
 
5725
    gen_op_fpexception_im(dc, FSR_FTT_SEQ_ERROR);
 
5726
    goto egress;
 
5727
#endif
 
5728
#ifndef TARGET_SPARC64
 
5729
 ncp_insn:
 
5730
    gen_exception(dc, TT_NCP_INSN);
 
5731
    goto egress;
 
5732
#endif
 
5733
 egress:
 
5734
    if (dc->n_t32 != 0) {
 
5735
        int i;
 
5736
        for (i = dc->n_t32 - 1; i >= 0; --i) {
 
5737
            tcg_temp_free_i32(dc->t32[i]);
 
5738
        }
 
5739
        dc->n_t32 = 0;
 
5740
    }
 
5741
    if (dc->n_ttl != 0) {
 
5742
        int i;
 
5743
        for (i = dc->n_ttl - 1; i >= 0; --i) {
 
5744
            tcg_temp_free(dc->ttl[i]);
 
5745
        }
 
5746
        dc->n_ttl = 0;
 
5747
    }
 
5748
}
 
5749
 
 
5750
void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
 
5751
{
 
5752
    SPARCCPU *cpu = sparc_env_get_cpu(env);
 
5753
    CPUState *cs = CPU(cpu);
 
5754
    target_ulong pc_start, last_pc;
 
5755
    DisasContext dc1, *dc = &dc1;
 
5756
    int num_insns;
 
5757
    int max_insns;
 
5758
    unsigned int insn;
 
5759
 
 
5760
    memset(dc, 0, sizeof(DisasContext));
 
5761
    dc->tb = tb;
 
5762
    pc_start = tb->pc;
 
5763
    dc->pc = pc_start;
 
5764
    last_pc = dc->pc;
 
5765
    dc->npc = (target_ulong) tb->cs_base;
 
5766
    dc->cc_op = CC_OP_DYNAMIC;
 
5767
    dc->mem_idx = tb->flags & TB_FLAG_MMU_MASK;
 
5768
    dc->def = env->def;
 
5769
    dc->fpu_enabled = tb_fpu_enabled(tb->flags);
 
5770
    dc->address_mask_32bit = tb_am_enabled(tb->flags);
 
5771
    dc->singlestep = (cs->singlestep_enabled || singlestep);
 
5772
#ifndef CONFIG_USER_ONLY
 
5773
    dc->supervisor = (tb->flags & TB_FLAG_SUPER) != 0;
 
5774
#endif
 
5775
#ifdef TARGET_SPARC64
 
5776
    dc->fprs_dirty = 0;
 
5777
    dc->asi = (tb->flags >> TB_FLAG_ASI_SHIFT) & 0xff;
 
5778
#ifndef CONFIG_USER_ONLY
 
5779
    dc->hypervisor = (tb->flags & TB_FLAG_HYPER) != 0;
 
5780
#endif
 
5781
#endif
 
5782
 
 
5783
    num_insns = 0;
 
5784
    max_insns = tb->cflags & CF_COUNT_MASK;
 
5785
    if (max_insns == 0) {
 
5786
        max_insns = CF_COUNT_MASK;
 
5787
    }
 
5788
    if (max_insns > TCG_MAX_INSNS) {
 
5789
        max_insns = TCG_MAX_INSNS;
 
5790
    }
 
5791
 
 
5792
    gen_tb_start(tb);
 
5793
    do {
 
5794
        if (dc->npc & JUMP_PC) {
 
5795
            assert(dc->jump_pc[1] == dc->pc + 4);
 
5796
            tcg_gen_insn_start(dc->pc, dc->jump_pc[0] | JUMP_PC);
 
5797
        } else {
 
5798
            tcg_gen_insn_start(dc->pc, dc->npc);
 
5799
        }
 
5800
        num_insns++;
 
5801
        last_pc = dc->pc;
 
5802
 
 
5803
        if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) {
 
5804
            if (dc->pc != pc_start) {
 
5805
                save_state(dc);
 
5806
            }
 
5807
            gen_helper_debug(cpu_env);
 
5808
            tcg_gen_exit_tb(0);
 
5809
            dc->is_br = 1;
 
5810
            goto exit_gen_loop;
 
5811
        }
 
5812
 
 
5813
        if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
 
5814
            gen_io_start();
 
5815
        }
 
5816
 
 
5817
        insn = cpu_ldl_code(env, dc->pc);
 
5818
 
 
5819
        disas_sparc_insn(dc, insn);
 
5820
 
 
5821
        if (dc->is_br)
 
5822
            break;
 
5823
        /* if the next PC is different, we abort now */
 
5824
        if (dc->pc != (last_pc + 4))
 
5825
            break;
 
5826
        /* if we reach a page boundary, we stop generation so that the
 
5827
           PC of a TT_TFAULT exception is always in the right page */
 
5828
        if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
 
5829
            break;
 
5830
        /* if single step mode, we generate only one instruction and
 
5831
           generate an exception */
 
5832
        if (dc->singlestep) {
 
5833
            break;
 
5834
        }
 
5835
    } while (!tcg_op_buf_full() &&
 
5836
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32) &&
 
5837
             num_insns < max_insns);
 
5838
 
 
5839
 exit_gen_loop:
 
5840
    if (tb->cflags & CF_LAST_IO) {
 
5841
        gen_io_end();
 
5842
    }
 
5843
    if (!dc->is_br) {
 
5844
        if (dc->pc != DYNAMIC_PC &&
 
5845
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
 
5846
            /* static PC and NPC: we can use direct chaining */
 
5847
            gen_goto_tb(dc, 0, dc->pc, dc->npc);
 
5848
        } else {
 
5849
            if (dc->pc != DYNAMIC_PC) {
 
5850
                tcg_gen_movi_tl(cpu_pc, dc->pc);
 
5851
            }
 
5852
            save_npc(dc);
 
5853
            tcg_gen_exit_tb(0);
 
5854
        }
 
5855
    }
 
5856
    gen_tb_end(tb, num_insns);
 
5857
 
 
5858
    tb->size = last_pc + 4 - pc_start;
 
5859
    tb->icount = num_insns;
 
5860
 
 
5861
#ifdef DEBUG_DISAS
 
5862
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)
 
5863
        && qemu_log_in_addr_range(pc_start)) {
 
5864
        qemu_log_lock();
 
5865
        qemu_log("--------------\n");
 
5866
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
 
5867
        log_target_disas(cs, pc_start, last_pc + 4 - pc_start, 0);
 
5868
        qemu_log("\n");
 
5869
        qemu_log_unlock();
 
5870
    }
 
5871
#endif
 
5872
}
 
5873
 
 
5874
void gen_intermediate_code_init(CPUSPARCState *env)
 
5875
{
 
5876
    static int inited;
 
5877
    static const char gregnames[32][4] = {
 
5878
        "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
 
5879
        "o0", "o1", "o2", "o3", "o4", "o5", "o6", "o7",
 
5880
        "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
 
5881
        "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7",
 
5882
    };
 
5883
    static const char fregnames[32][4] = {
 
5884
        "f0", "f2", "f4", "f6", "f8", "f10", "f12", "f14",
 
5885
        "f16", "f18", "f20", "f22", "f24", "f26", "f28", "f30",
 
5886
        "f32", "f34", "f36", "f38", "f40", "f42", "f44", "f46",
 
5887
        "f48", "f50", "f52", "f54", "f56", "f58", "f60", "f62",
 
5888
    };
 
5889
 
 
5890
    static const struct { TCGv_i32 *ptr; int off; const char *name; } r32[] = {
 
5891
#ifdef TARGET_SPARC64
 
5892
        { &cpu_xcc, offsetof(CPUSPARCState, xcc), "xcc" },
 
5893
        { &cpu_fprs, offsetof(CPUSPARCState, fprs), "fprs" },
 
5894
#else
 
5895
        { &cpu_wim, offsetof(CPUSPARCState, wim), "wim" },
 
5896
#endif
 
5897
        { &cpu_cc_op, offsetof(CPUSPARCState, cc_op), "cc_op" },
 
5898
        { &cpu_psr, offsetof(CPUSPARCState, psr), "psr" },
 
5899
    };
 
5900
 
 
5901
    static const struct { TCGv *ptr; int off; const char *name; } rtl[] = {
 
5902
#ifdef TARGET_SPARC64
 
5903
        { &cpu_gsr, offsetof(CPUSPARCState, gsr), "gsr" },
 
5904
        { &cpu_tick_cmpr, offsetof(CPUSPARCState, tick_cmpr), "tick_cmpr" },
 
5905
        { &cpu_stick_cmpr, offsetof(CPUSPARCState, stick_cmpr), "stick_cmpr" },
 
5906
        { &cpu_hstick_cmpr, offsetof(CPUSPARCState, hstick_cmpr),
 
5907
          "hstick_cmpr" },
 
5908
        { &cpu_hintp, offsetof(CPUSPARCState, hintp), "hintp" },
 
5909
        { &cpu_htba, offsetof(CPUSPARCState, htba), "htba" },
 
5910
        { &cpu_hver, offsetof(CPUSPARCState, hver), "hver" },
 
5911
        { &cpu_ssr, offsetof(CPUSPARCState, ssr), "ssr" },
 
5912
        { &cpu_ver, offsetof(CPUSPARCState, version), "ver" },
 
5913
#endif
 
5914
        { &cpu_cond, offsetof(CPUSPARCState, cond), "cond" },
 
5915
        { &cpu_cc_src, offsetof(CPUSPARCState, cc_src), "cc_src" },
 
5916
        { &cpu_cc_src2, offsetof(CPUSPARCState, cc_src2), "cc_src2" },
 
5917
        { &cpu_cc_dst, offsetof(CPUSPARCState, cc_dst), "cc_dst" },
 
5918
        { &cpu_fsr, offsetof(CPUSPARCState, fsr), "fsr" },
 
5919
        { &cpu_pc, offsetof(CPUSPARCState, pc), "pc" },
 
5920
        { &cpu_npc, offsetof(CPUSPARCState, npc), "npc" },
 
5921
        { &cpu_y, offsetof(CPUSPARCState, y), "y" },
 
5922
#ifndef CONFIG_USER_ONLY
 
5923
        { &cpu_tbr, offsetof(CPUSPARCState, tbr), "tbr" },
 
5924
#endif
 
5925
    };
 
5926
 
 
5927
    unsigned int i;
 
5928
 
 
5929
    /* init various static tables */
 
5930
    if (inited) {
 
5931
        return;
 
5932
    }
 
5933
    inited = 1;
 
5934
 
 
5935
    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
 
5936
    tcg_ctx.tcg_env = cpu_env;
 
5937
 
 
5938
    cpu_regwptr = tcg_global_mem_new_ptr(cpu_env,
 
5939
                                         offsetof(CPUSPARCState, regwptr),
 
5940
                                         "regwptr");
 
5941
 
 
5942
    for (i = 0; i < ARRAY_SIZE(r32); ++i) {
 
5943
        *r32[i].ptr = tcg_global_mem_new_i32(cpu_env, r32[i].off, r32[i].name);
 
5944
    }
 
5945
 
 
5946
    for (i = 0; i < ARRAY_SIZE(rtl); ++i) {
 
5947
        *rtl[i].ptr = tcg_global_mem_new(cpu_env, rtl[i].off, rtl[i].name);
 
5948
    }
 
5949
 
 
5950
    TCGV_UNUSED(cpu_regs[0]);
 
5951
    for (i = 1; i < 8; ++i) {
 
5952
        cpu_regs[i] = tcg_global_mem_new(cpu_env,
 
5953
                                         offsetof(CPUSPARCState, gregs[i]),
 
5954
                                         gregnames[i]);
 
5955
    }
 
5956
 
 
5957
    for (i = 8; i < 32; ++i) {
 
5958
        cpu_regs[i] = tcg_global_mem_new(cpu_regwptr,
 
5959
                                         (i - 8) * sizeof(target_ulong),
 
5960
                                         gregnames[i]);
 
5961
    }
 
5962
 
 
5963
    for (i = 0; i < TARGET_DPREGS; i++) {
 
5964
        cpu_fpr[i] = tcg_global_mem_new_i64(cpu_env,
 
5965
                                            offsetof(CPUSPARCState, fpr[i]),
 
5966
                                            fregnames[i]);
 
5967
    }
 
5968
}
 
5969
 
 
5970
void restore_state_to_opc(CPUSPARCState *env, TranslationBlock *tb,
 
5971
                          target_ulong *data)
 
5972
{
 
5973
    target_ulong pc = data[0];
 
5974
    target_ulong npc = data[1];
 
5975
 
 
5976
    env->pc = pc;
 
5977
    if (npc == DYNAMIC_PC) {
 
5978
        /* dynamic NPC: already stored */
 
5979
    } else if (npc & JUMP_PC) {
 
5980
        /* jump PC: use 'cond' and the jump targets of the translation */
 
5981
        if (env->cond) {
 
5982
            env->npc = npc & ~3;
 
5983
        } else {
 
5984
            env->npc = pc + 4;
 
5985
        }
 
5986
    } else {
 
5987
        env->npc = npc;
 
5988
    }
 
5989
}