Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ fe987e23

History | View | Annotate | Download (190 kB)

1
/*
2
   SPARC translation
3

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

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

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

17
   You should have received a copy of the GNU Lesser General Public
18
   License along with this library; if not, see <http://www.gnu.org/licenses/>.
19
 */
20

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

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

    
33
#define GEN_HELPER 1
34
#include "helper.h"
35

    
36
#define DEBUG_DISAS
37

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

    
42
/* global register indexes */
43
static TCGv_ptr cpu_env, cpu_regwptr;
44
static TCGv cpu_cc_src, cpu_cc_src2, cpu_cc_dst;
45
static TCGv_i32 cpu_cc_op;
46
static TCGv_i32 cpu_psr;
47
static TCGv cpu_fsr, cpu_pc, cpu_npc, cpu_gregs[8];
48
static TCGv cpu_y;
49
#ifndef CONFIG_USER_ONLY
50
static TCGv cpu_tbr;
51
#endif
52
static TCGv cpu_cond, cpu_dst, cpu_addr, cpu_val;
53
#ifdef TARGET_SPARC64
54
static TCGv_i32 cpu_xcc, cpu_asi, cpu_fprs;
55
static TCGv cpu_gsr;
56
static TCGv cpu_tick_cmpr, cpu_stick_cmpr, cpu_hstick_cmpr;
57
static TCGv cpu_hintp, cpu_htba, cpu_hver, cpu_ssr, cpu_ver;
58
static TCGv_i32 cpu_softint;
59
#else
60
static TCGv cpu_wim;
61
#endif
62
/* local register indexes (only used inside old micro ops) */
63
static TCGv cpu_tmp0;
64
static TCGv_i32 cpu_tmp32;
65
static TCGv_i64 cpu_tmp64;
66
/* Floating point registers */
67
static TCGv_i32 cpu_fpr[TARGET_FPREGS];
68

    
69
static target_ulong gen_opc_npc[OPC_BUF_SIZE];
70
static target_ulong gen_opc_jump_pc[2];
71

    
72
#include "gen-icount.h"
73

    
74
typedef struct DisasContext {
75
    target_ulong pc;    /* current Program Counter: integer or DYNAMIC_PC */
76
    target_ulong npc;   /* next PC: integer or DYNAMIC_PC or JUMP_PC */
77
    target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
78
    int is_br;
79
    int mem_idx;
80
    int fpu_enabled;
81
    int address_mask_32bit;
82
    int singlestep;
83
    uint32_t cc_op;  /* current CC operation */
84
    struct TranslationBlock *tb;
85
    sparc_def_t *def;
86
} DisasContext;
87

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

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

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

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

    
107
#define UA2005_HTRAP_MASK 0xff
108
#define V8_TRAP_MASK 0x7f
109

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

    
116
#define IS_IMM (insn & (1<<13))
117

    
118
/* floating point registers moves */
119
static void gen_op_load_fpr_DT0(unsigned int src)
120
{
121
    tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, dt0) +
122
                   offsetof(CPU_DoubleU, l.upper));
123
    tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, dt0) +
124
                   offsetof(CPU_DoubleU, l.lower));
125
}
126

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

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

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

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

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

    
179
/* moves */
180
#ifdef CONFIG_USER_ONLY
181
#define supervisor(dc) 0
182
#ifdef TARGET_SPARC64
183
#define hypervisor(dc) 0
184
#endif
185
#else
186
#define supervisor(dc) (dc->mem_idx >= MMU_KERNEL_IDX)
187
#ifdef TARGET_SPARC64
188
#define hypervisor(dc) (dc->mem_idx == MMU_HYPV_IDX)
189
#else
190
#endif
191
#endif
192

    
193
#ifdef TARGET_SPARC64
194
#ifndef TARGET_ABI32
195
#define AM_CHECK(dc) ((dc)->address_mask_32bit)
196
#else
197
#define AM_CHECK(dc) (1)
198
#endif
199
#endif
200

    
201
static inline void gen_address_mask(DisasContext *dc, TCGv addr)
202
{
203
#ifdef TARGET_SPARC64
204
    if (AM_CHECK(dc))
205
        tcg_gen_andi_tl(addr, addr, 0xffffffffULL);
206
#endif
207
}
208

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

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

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

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

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

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

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

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

    
282
static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
283
{
284
    TCGv r_temp;
285
    TCGv_i32 r_const;
286
    int l1;
287

    
288
    l1 = gen_new_label();
289

    
290
    r_temp = tcg_temp_new();
291
    tcg_gen_xor_tl(r_temp, src1, src2);
292
    tcg_gen_not_tl(r_temp, r_temp);
293
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
294
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
295
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
296
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
297
    r_const = tcg_const_i32(TT_TOVF);
298
    gen_helper_raise_exception(r_const);
299
    tcg_temp_free_i32(r_const);
300
    gen_set_label(l1);
301
    tcg_temp_free(r_temp);
302
}
303

    
304
static inline void gen_tag_tv(TCGv src1, TCGv src2)
305
{
306
    int l1;
307
    TCGv_i32 r_const;
308

    
309
    l1 = gen_new_label();
310
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
311
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
312
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
313
    r_const = tcg_const_i32(TT_TOVF);
314
    gen_helper_raise_exception(r_const);
315
    tcg_temp_free_i32(r_const);
316
    gen_set_label(l1);
317
}
318

    
319
static inline void gen_op_addi_cc(TCGv dst, TCGv src1, target_long src2)
320
{
321
    tcg_gen_mov_tl(cpu_cc_src, src1);
322
    tcg_gen_movi_tl(cpu_cc_src2, src2);
323
    tcg_gen_addi_tl(cpu_cc_dst, cpu_cc_src, src2);
324
    tcg_gen_mov_tl(dst, cpu_cc_dst);
325
}
326

    
327
static inline void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2)
328
{
329
    tcg_gen_mov_tl(cpu_cc_src, src1);
330
    tcg_gen_mov_tl(cpu_cc_src2, src2);
331
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
332
    tcg_gen_mov_tl(dst, cpu_cc_dst);
333
}
334

    
335
static TCGv_i32 gen_add32_carry32(void)
336
{
337
    TCGv_i32 carry_32, cc_src1_32, cc_src2_32;
338

    
339
    /* Carry is computed from a previous add: (dst < src)  */
340
#if TARGET_LONG_BITS == 64
341
    cc_src1_32 = tcg_temp_new_i32();
342
    cc_src2_32 = tcg_temp_new_i32();
343
    tcg_gen_trunc_i64_i32(cc_src1_32, cpu_cc_dst);
344
    tcg_gen_trunc_i64_i32(cc_src2_32, cpu_cc_src);
345
#else
346
    cc_src1_32 = cpu_cc_dst;
347
    cc_src2_32 = cpu_cc_src;
348
#endif
349

    
350
    carry_32 = tcg_temp_new_i32();
351
    tcg_gen_setcond_i32(TCG_COND_LTU, carry_32, cc_src1_32, cc_src2_32);
352

    
353
#if TARGET_LONG_BITS == 64
354
    tcg_temp_free_i32(cc_src1_32);
355
    tcg_temp_free_i32(cc_src2_32);
356
#endif
357

    
358
    return carry_32;
359
}
360

    
361
static TCGv_i32 gen_sub32_carry32(void)
362
{
363
    TCGv_i32 carry_32, cc_src1_32, cc_src2_32;
364

    
365
    /* Carry is computed from a previous borrow: (src1 < src2)  */
366
#if TARGET_LONG_BITS == 64
367
    cc_src1_32 = tcg_temp_new_i32();
368
    cc_src2_32 = tcg_temp_new_i32();
369
    tcg_gen_trunc_i64_i32(cc_src1_32, cpu_cc_src);
370
    tcg_gen_trunc_i64_i32(cc_src2_32, cpu_cc_src2);
371
#else
372
    cc_src1_32 = cpu_cc_src;
373
    cc_src2_32 = cpu_cc_src2;
374
#endif
375

    
376
    carry_32 = tcg_temp_new_i32();
377
    tcg_gen_setcond_i32(TCG_COND_LTU, carry_32, cc_src1_32, cc_src2_32);
378

    
379
#if TARGET_LONG_BITS == 64
380
    tcg_temp_free_i32(cc_src1_32);
381
    tcg_temp_free_i32(cc_src2_32);
382
#endif
383

    
384
    return carry_32;
385
}
386

    
387
static void gen_op_addx_int(DisasContext *dc, TCGv dst, TCGv src1,
388
                            TCGv src2, int update_cc)
389
{
390
    TCGv_i32 carry_32;
391
    TCGv carry;
392

    
393
    switch (dc->cc_op) {
394
    case CC_OP_DIV:
395
    case CC_OP_LOGIC:
396
        /* Carry is known to be zero.  Fall back to plain ADD.  */
397
        if (update_cc) {
398
            gen_op_add_cc(dst, src1, src2);
399
        } else {
400
            tcg_gen_add_tl(dst, src1, src2);
401
        }
402
        return;
403

    
404
    case CC_OP_ADD:
405
    case CC_OP_TADD:
406
    case CC_OP_TADDTV:
407
#if TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 32
408
        {
409
            /* For 32-bit hosts, we can re-use the host's hardware carry
410
               generation by using an ADD2 opcode.  We discard the low
411
               part of the output.  Ideally we'd combine this operation
412
               with the add that generated the carry in the first place.  */
413
            TCGv dst_low = tcg_temp_new();
414
            tcg_gen_op6_i32(INDEX_op_add2_i32, dst_low, dst,
415
                            cpu_cc_src, src1, cpu_cc_src2, src2);
416
            tcg_temp_free(dst_low);
417
            goto add_done;
418
        }
419
#endif
420
        carry_32 = gen_add32_carry32();
421
        break;
422

    
423
    case CC_OP_SUB:
424
    case CC_OP_TSUB:
425
    case CC_OP_TSUBTV:
426
        carry_32 = gen_sub32_carry32();
427
        break;
428

    
429
    default:
430
        /* We need external help to produce the carry.  */
431
        carry_32 = tcg_temp_new_i32();
432
        gen_helper_compute_C_icc(carry_32);
433
        break;
434
    }
435

    
436
#if TARGET_LONG_BITS == 64
437
    carry = tcg_temp_new();
438
    tcg_gen_extu_i32_i64(carry, carry_32);
439
#else
440
    carry = carry_32;
441
#endif
442

    
443
    tcg_gen_add_tl(dst, src1, src2);
444
    tcg_gen_add_tl(dst, dst, carry);
445

    
446
    tcg_temp_free_i32(carry_32);
447
#if TARGET_LONG_BITS == 64
448
    tcg_temp_free(carry);
449
#endif
450

    
451
#if TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 32
452
 add_done:
453
#endif
454
    if (update_cc) {
455
        tcg_gen_mov_tl(cpu_cc_src, src1);
456
        tcg_gen_mov_tl(cpu_cc_src2, src2);
457
        tcg_gen_mov_tl(cpu_cc_dst, dst);
458
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADDX);
459
        dc->cc_op = CC_OP_ADDX;
460
    }
461
}
462

    
463
static inline void gen_op_tadd_cc(TCGv dst, TCGv src1, TCGv src2)
464
{
465
    tcg_gen_mov_tl(cpu_cc_src, src1);
466
    tcg_gen_mov_tl(cpu_cc_src2, src2);
467
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
468
    tcg_gen_mov_tl(dst, cpu_cc_dst);
469
}
470

    
471
static inline void gen_op_tadd_ccTV(TCGv dst, TCGv src1, TCGv src2)
472
{
473
    tcg_gen_mov_tl(cpu_cc_src, src1);
474
    tcg_gen_mov_tl(cpu_cc_src2, src2);
475
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
476
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
477
    gen_add_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
478
    tcg_gen_mov_tl(dst, cpu_cc_dst);
479
}
480

    
481
static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
482
{
483
    TCGv r_temp;
484
    TCGv_i32 r_const;
485
    int l1;
486

    
487
    l1 = gen_new_label();
488

    
489
    r_temp = tcg_temp_new();
490
    tcg_gen_xor_tl(r_temp, src1, src2);
491
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
492
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
493
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
494
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
495
    r_const = tcg_const_i32(TT_TOVF);
496
    gen_helper_raise_exception(r_const);
497
    tcg_temp_free_i32(r_const);
498
    gen_set_label(l1);
499
    tcg_temp_free(r_temp);
500
}
501

    
502
static inline void gen_op_subi_cc(TCGv dst, TCGv src1, target_long src2, DisasContext *dc)
503
{
504
    tcg_gen_mov_tl(cpu_cc_src, src1);
505
    tcg_gen_movi_tl(cpu_cc_src2, src2);
506
    if (src2 == 0) {
507
        tcg_gen_mov_tl(cpu_cc_dst, src1);
508
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
509
        dc->cc_op = CC_OP_LOGIC;
510
    } else {
511
        tcg_gen_subi_tl(cpu_cc_dst, cpu_cc_src, src2);
512
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUB);
513
        dc->cc_op = CC_OP_SUB;
514
    }
515
    tcg_gen_mov_tl(dst, cpu_cc_dst);
516
}
517

    
518
static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2)
519
{
520
    tcg_gen_mov_tl(cpu_cc_src, src1);
521
    tcg_gen_mov_tl(cpu_cc_src2, src2);
522
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
523
    tcg_gen_mov_tl(dst, cpu_cc_dst);
524
}
525

    
526
static void gen_op_subx_int(DisasContext *dc, TCGv dst, TCGv src1,
527
                            TCGv src2, int update_cc)
528
{
529
    TCGv_i32 carry_32;
530
    TCGv carry;
531

    
532
    switch (dc->cc_op) {
533
    case CC_OP_DIV:
534
    case CC_OP_LOGIC:
535
        /* Carry is known to be zero.  Fall back to plain SUB.  */
536
        if (update_cc) {
537
            gen_op_sub_cc(dst, src1, src2);
538
        } else {
539
            tcg_gen_sub_tl(dst, src1, src2);
540
        }
541
        return;
542

    
543
    case CC_OP_ADD:
544
    case CC_OP_TADD:
545
    case CC_OP_TADDTV:
546
        carry_32 = gen_add32_carry32();
547
        break;
548

    
549
    case CC_OP_SUB:
550
    case CC_OP_TSUB:
551
    case CC_OP_TSUBTV:
552
#if TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 32
553
        {
554
            /* For 32-bit hosts, we can re-use the host's hardware carry
555
               generation by using a SUB2 opcode.  We discard the low
556
               part of the output.  Ideally we'd combine this operation
557
               with the add that generated the carry in the first place.  */
558
            TCGv dst_low = tcg_temp_new();
559
            tcg_gen_op6_i32(INDEX_op_sub2_i32, dst_low, dst,
560
                            cpu_cc_src, src1, cpu_cc_src2, src2);
561
            tcg_temp_free(dst_low);
562
            goto sub_done;
563
        }
564
#endif
565
        carry_32 = gen_sub32_carry32();
566
        break;
567

    
568
    default:
569
        /* We need external help to produce the carry.  */
570
        carry_32 = tcg_temp_new_i32();
571
        gen_helper_compute_C_icc(carry_32);
572
        break;
573
    }
574

    
575
#if TARGET_LONG_BITS == 64
576
    carry = tcg_temp_new();
577
    tcg_gen_extu_i32_i64(carry, carry_32);
578
#else
579
    carry = carry_32;
580
#endif
581

    
582
    tcg_gen_sub_tl(dst, src1, src2);
583
    tcg_gen_sub_tl(dst, dst, carry);
584

    
585
    tcg_temp_free_i32(carry_32);
586
#if TARGET_LONG_BITS == 64
587
    tcg_temp_free(carry);
588
#endif
589

    
590
#if TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 32
591
 sub_done:
592
#endif
593
    if (update_cc) {
594
        tcg_gen_mov_tl(cpu_cc_src, src1);
595
        tcg_gen_mov_tl(cpu_cc_src2, src2);
596
        tcg_gen_mov_tl(cpu_cc_dst, dst);
597
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUBX);
598
        dc->cc_op = CC_OP_SUBX;
599
    }
600
}
601

    
602
static inline void gen_op_tsub_cc(TCGv dst, TCGv src1, TCGv src2)
603
{
604
    tcg_gen_mov_tl(cpu_cc_src, src1);
605
    tcg_gen_mov_tl(cpu_cc_src2, src2);
606
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
607
    tcg_gen_mov_tl(dst, cpu_cc_dst);
608
}
609

    
610
static inline void gen_op_tsub_ccTV(TCGv dst, TCGv src1, TCGv src2)
611
{
612
    tcg_gen_mov_tl(cpu_cc_src, src1);
613
    tcg_gen_mov_tl(cpu_cc_src2, src2);
614
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
615
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
616
    gen_sub_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
617
    tcg_gen_mov_tl(dst, cpu_cc_dst);
618
}
619

    
620
static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
621
{
622
    TCGv r_temp;
623
    int l1;
624

    
625
    l1 = gen_new_label();
626
    r_temp = tcg_temp_new();
627

    
628
    /* old op:
629
    if (!(env->y & 1))
630
        T1 = 0;
631
    */
632
    tcg_gen_andi_tl(cpu_cc_src, src1, 0xffffffff);
633
    tcg_gen_andi_tl(r_temp, cpu_y, 0x1);
634
    tcg_gen_andi_tl(cpu_cc_src2, src2, 0xffffffff);
635
    tcg_gen_brcondi_tl(TCG_COND_NE, r_temp, 0, l1);
636
    tcg_gen_movi_tl(cpu_cc_src2, 0);
637
    gen_set_label(l1);
638

    
639
    // b2 = T0 & 1;
640
    // env->y = (b2 << 31) | (env->y >> 1);
641
    tcg_gen_andi_tl(r_temp, cpu_cc_src, 0x1);
642
    tcg_gen_shli_tl(r_temp, r_temp, 31);
643
    tcg_gen_shri_tl(cpu_tmp0, cpu_y, 1);
644
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x7fffffff);
645
    tcg_gen_or_tl(cpu_tmp0, cpu_tmp0, r_temp);
646
    tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
647

    
648
    // b1 = N ^ V;
649
    gen_mov_reg_N(cpu_tmp0, cpu_psr);
650
    gen_mov_reg_V(r_temp, cpu_psr);
651
    tcg_gen_xor_tl(cpu_tmp0, cpu_tmp0, r_temp);
652
    tcg_temp_free(r_temp);
653

    
654
    // T0 = (b1 << 31) | (T0 >> 1);
655
    // src1 = T0;
656
    tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
657
    tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
658
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
659

    
660
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
661

    
662
    tcg_gen_mov_tl(dst, cpu_cc_dst);
663
}
664

    
665
static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
666
{
667
    TCGv_i64 r_temp, r_temp2;
668

    
669
    r_temp = tcg_temp_new_i64();
670
    r_temp2 = tcg_temp_new_i64();
671

    
672
    tcg_gen_extu_tl_i64(r_temp, src2);
673
    tcg_gen_extu_tl_i64(r_temp2, src1);
674
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
675

    
676
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
677
    tcg_gen_trunc_i64_tl(cpu_tmp0, r_temp);
678
    tcg_temp_free_i64(r_temp);
679
    tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
680
#ifdef TARGET_SPARC64
681
    tcg_gen_mov_i64(dst, r_temp2);
682
#else
683
    tcg_gen_trunc_i64_tl(dst, r_temp2);
684
#endif
685
    tcg_temp_free_i64(r_temp2);
686
}
687

    
688
static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
689
{
690
    TCGv_i64 r_temp, r_temp2;
691

    
692
    r_temp = tcg_temp_new_i64();
693
    r_temp2 = tcg_temp_new_i64();
694

    
695
    tcg_gen_ext_tl_i64(r_temp, src2);
696
    tcg_gen_ext_tl_i64(r_temp2, src1);
697
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
698

    
699
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
700
    tcg_gen_trunc_i64_tl(cpu_tmp0, r_temp);
701
    tcg_temp_free_i64(r_temp);
702
    tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
703
#ifdef TARGET_SPARC64
704
    tcg_gen_mov_i64(dst, r_temp2);
705
#else
706
    tcg_gen_trunc_i64_tl(dst, r_temp2);
707
#endif
708
    tcg_temp_free_i64(r_temp2);
709
}
710

    
711
#ifdef TARGET_SPARC64
712
static inline void gen_trap_ifdivzero_tl(TCGv divisor)
713
{
714
    TCGv_i32 r_const;
715
    int l1;
716

    
717
    l1 = gen_new_label();
718
    tcg_gen_brcondi_tl(TCG_COND_NE, divisor, 0, l1);
719
    r_const = tcg_const_i32(TT_DIV_ZERO);
720
    gen_helper_raise_exception(r_const);
721
    tcg_temp_free_i32(r_const);
722
    gen_set_label(l1);
723
}
724

    
725
static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
726
{
727
    int l1, l2;
728

    
729
    l1 = gen_new_label();
730
    l2 = gen_new_label();
731
    tcg_gen_mov_tl(cpu_cc_src, src1);
732
    tcg_gen_mov_tl(cpu_cc_src2, src2);
733
    gen_trap_ifdivzero_tl(cpu_cc_src2);
734
    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc_src, INT64_MIN, l1);
735
    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc_src2, -1, l1);
736
    tcg_gen_movi_i64(dst, INT64_MIN);
737
    tcg_gen_br(l2);
738
    gen_set_label(l1);
739
    tcg_gen_div_i64(dst, cpu_cc_src, cpu_cc_src2);
740
    gen_set_label(l2);
741
}
742
#endif
743

    
744
// 1
745
static inline void gen_op_eval_ba(TCGv dst)
746
{
747
    tcg_gen_movi_tl(dst, 1);
748
}
749

    
750
// Z
751
static inline void gen_op_eval_be(TCGv dst, TCGv_i32 src)
752
{
753
    gen_mov_reg_Z(dst, src);
754
}
755

    
756
// Z | (N ^ V)
757
static inline void gen_op_eval_ble(TCGv dst, TCGv_i32 src)
758
{
759
    gen_mov_reg_N(cpu_tmp0, src);
760
    gen_mov_reg_V(dst, src);
761
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
762
    gen_mov_reg_Z(cpu_tmp0, src);
763
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
764
}
765

    
766
// N ^ V
767
static inline void gen_op_eval_bl(TCGv dst, TCGv_i32 src)
768
{
769
    gen_mov_reg_V(cpu_tmp0, src);
770
    gen_mov_reg_N(dst, src);
771
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
772
}
773

    
774
// C | Z
775
static inline void gen_op_eval_bleu(TCGv dst, TCGv_i32 src)
776
{
777
    gen_mov_reg_Z(cpu_tmp0, src);
778
    gen_mov_reg_C(dst, src);
779
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
780
}
781

    
782
// C
783
static inline void gen_op_eval_bcs(TCGv dst, TCGv_i32 src)
784
{
785
    gen_mov_reg_C(dst, src);
786
}
787

    
788
// V
789
static inline void gen_op_eval_bvs(TCGv dst, TCGv_i32 src)
790
{
791
    gen_mov_reg_V(dst, src);
792
}
793

    
794
// 0
795
static inline void gen_op_eval_bn(TCGv dst)
796
{
797
    tcg_gen_movi_tl(dst, 0);
798
}
799

    
800
// N
801
static inline void gen_op_eval_bneg(TCGv dst, TCGv_i32 src)
802
{
803
    gen_mov_reg_N(dst, src);
804
}
805

    
806
// !Z
807
static inline void gen_op_eval_bne(TCGv dst, TCGv_i32 src)
808
{
809
    gen_mov_reg_Z(dst, src);
810
    tcg_gen_xori_tl(dst, dst, 0x1);
811
}
812

    
813
// !(Z | (N ^ V))
814
static inline void gen_op_eval_bg(TCGv dst, TCGv_i32 src)
815
{
816
    gen_mov_reg_N(cpu_tmp0, src);
817
    gen_mov_reg_V(dst, src);
818
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
819
    gen_mov_reg_Z(cpu_tmp0, src);
820
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
821
    tcg_gen_xori_tl(dst, dst, 0x1);
822
}
823

    
824
// !(N ^ V)
825
static inline void gen_op_eval_bge(TCGv dst, TCGv_i32 src)
826
{
827
    gen_mov_reg_V(cpu_tmp0, src);
828
    gen_mov_reg_N(dst, src);
829
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
830
    tcg_gen_xori_tl(dst, dst, 0x1);
831
}
832

    
833
// !(C | Z)
834
static inline void gen_op_eval_bgu(TCGv dst, TCGv_i32 src)
835
{
836
    gen_mov_reg_Z(cpu_tmp0, src);
837
    gen_mov_reg_C(dst, src);
838
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
839
    tcg_gen_xori_tl(dst, dst, 0x1);
840
}
841

    
842
// !C
843
static inline void gen_op_eval_bcc(TCGv dst, TCGv_i32 src)
844
{
845
    gen_mov_reg_C(dst, src);
846
    tcg_gen_xori_tl(dst, dst, 0x1);
847
}
848

    
849
// !N
850
static inline void gen_op_eval_bpos(TCGv dst, TCGv_i32 src)
851
{
852
    gen_mov_reg_N(dst, src);
853
    tcg_gen_xori_tl(dst, dst, 0x1);
854
}
855

    
856
// !V
857
static inline void gen_op_eval_bvc(TCGv dst, TCGv_i32 src)
858
{
859
    gen_mov_reg_V(dst, src);
860
    tcg_gen_xori_tl(dst, dst, 0x1);
861
}
862

    
863
/*
864
  FPSR bit field FCC1 | FCC0:
865
   0 =
866
   1 <
867
   2 >
868
   3 unordered
869
*/
870
static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src,
871
                                    unsigned int fcc_offset)
872
{
873
    tcg_gen_shri_tl(reg, src, FSR_FCC0_SHIFT + fcc_offset);
874
    tcg_gen_andi_tl(reg, reg, 0x1);
875
}
876

    
877
static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
878
                                    unsigned int fcc_offset)
879
{
880
    tcg_gen_shri_tl(reg, src, FSR_FCC1_SHIFT + fcc_offset);
881
    tcg_gen_andi_tl(reg, reg, 0x1);
882
}
883

    
884
// !0: FCC0 | FCC1
885
static inline void gen_op_eval_fbne(TCGv dst, TCGv src,
886
                                    unsigned int fcc_offset)
887
{
888
    gen_mov_reg_FCC0(dst, src, fcc_offset);
889
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
890
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
891
}
892

    
893
// 1 or 2: FCC0 ^ FCC1
894
static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
895
                                    unsigned int fcc_offset)
896
{
897
    gen_mov_reg_FCC0(dst, src, fcc_offset);
898
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
899
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
900
}
901

    
902
// 1 or 3: FCC0
903
static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
904
                                    unsigned int fcc_offset)
905
{
906
    gen_mov_reg_FCC0(dst, src, fcc_offset);
907
}
908

    
909
// 1: FCC0 & !FCC1
910
static inline void gen_op_eval_fbl(TCGv dst, TCGv src,
911
                                    unsigned int fcc_offset)
912
{
913
    gen_mov_reg_FCC0(dst, src, fcc_offset);
914
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
915
    tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
916
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
917
}
918

    
919
// 2 or 3: FCC1
920
static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
921
                                    unsigned int fcc_offset)
922
{
923
    gen_mov_reg_FCC1(dst, src, fcc_offset);
924
}
925

    
926
// 2: !FCC0 & FCC1
927
static inline void gen_op_eval_fbg(TCGv dst, TCGv src,
928
                                    unsigned int fcc_offset)
929
{
930
    gen_mov_reg_FCC0(dst, src, fcc_offset);
931
    tcg_gen_xori_tl(dst, dst, 0x1);
932
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
933
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
934
}
935

    
936
// 3: FCC0 & FCC1
937
static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
938
                                    unsigned int fcc_offset)
939
{
940
    gen_mov_reg_FCC0(dst, src, fcc_offset);
941
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
942
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
943
}
944

    
945
// 0: !(FCC0 | FCC1)
946
static inline void gen_op_eval_fbe(TCGv dst, TCGv src,
947
                                    unsigned int fcc_offset)
948
{
949
    gen_mov_reg_FCC0(dst, src, fcc_offset);
950
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
951
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
952
    tcg_gen_xori_tl(dst, dst, 0x1);
953
}
954

    
955
// 0 or 3: !(FCC0 ^ FCC1)
956
static inline void gen_op_eval_fbue(TCGv dst, TCGv src,
957
                                    unsigned int fcc_offset)
958
{
959
    gen_mov_reg_FCC0(dst, src, fcc_offset);
960
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
961
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
962
    tcg_gen_xori_tl(dst, dst, 0x1);
963
}
964

    
965
// 0 or 2: !FCC0
966
static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
967
                                    unsigned int fcc_offset)
968
{
969
    gen_mov_reg_FCC0(dst, src, fcc_offset);
970
    tcg_gen_xori_tl(dst, dst, 0x1);
971
}
972

    
973
// !1: !(FCC0 & !FCC1)
974
static inline void gen_op_eval_fbuge(TCGv dst, TCGv src,
975
                                    unsigned int fcc_offset)
976
{
977
    gen_mov_reg_FCC0(dst, src, fcc_offset);
978
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
979
    tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
980
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
981
    tcg_gen_xori_tl(dst, dst, 0x1);
982
}
983

    
984
// 0 or 1: !FCC1
985
static inline void gen_op_eval_fble(TCGv dst, TCGv src,
986
                                    unsigned int fcc_offset)
987
{
988
    gen_mov_reg_FCC1(dst, src, fcc_offset);
989
    tcg_gen_xori_tl(dst, dst, 0x1);
990
}
991

    
992
// !2: !(!FCC0 & FCC1)
993
static inline void gen_op_eval_fbule(TCGv dst, TCGv src,
994
                                    unsigned int fcc_offset)
995
{
996
    gen_mov_reg_FCC0(dst, src, fcc_offset);
997
    tcg_gen_xori_tl(dst, dst, 0x1);
998
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
999
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1000
    tcg_gen_xori_tl(dst, dst, 0x1);
1001
}
1002

    
1003
// !3: !(FCC0 & FCC1)
1004
static inline void gen_op_eval_fbo(TCGv dst, TCGv src,
1005
                                    unsigned int fcc_offset)
1006
{
1007
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1008
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1009
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1010
    tcg_gen_xori_tl(dst, dst, 0x1);
1011
}
1012

    
1013
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
1014
                               target_ulong pc2, TCGv r_cond)
1015
{
1016
    int l1;
1017

    
1018
    l1 = gen_new_label();
1019

    
1020
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
1021

    
1022
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
1023

    
1024
    gen_set_label(l1);
1025
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
1026
}
1027

    
1028
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
1029
                                target_ulong pc2, TCGv r_cond)
1030
{
1031
    int l1;
1032

    
1033
    l1 = gen_new_label();
1034

    
1035
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
1036

    
1037
    gen_goto_tb(dc, 0, pc2, pc1);
1038

    
1039
    gen_set_label(l1);
1040
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
1041
}
1042

    
1043
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
1044
                                      TCGv r_cond)
1045
{
1046
    int l1, l2;
1047

    
1048
    l1 = gen_new_label();
1049
    l2 = gen_new_label();
1050

    
1051
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
1052

    
1053
    tcg_gen_movi_tl(cpu_npc, npc1);
1054
    tcg_gen_br(l2);
1055

    
1056
    gen_set_label(l1);
1057
    tcg_gen_movi_tl(cpu_npc, npc2);
1058
    gen_set_label(l2);
1059
}
1060

    
1061
/* call this function before using the condition register as it may
1062
   have been set for a jump */
1063
static inline void flush_cond(DisasContext *dc, TCGv cond)
1064
{
1065
    if (dc->npc == JUMP_PC) {
1066
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1067
        dc->npc = DYNAMIC_PC;
1068
    }
1069
}
1070

    
1071
static inline void save_npc(DisasContext *dc, TCGv cond)
1072
{
1073
    if (dc->npc == JUMP_PC) {
1074
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1075
        dc->npc = DYNAMIC_PC;
1076
    } else if (dc->npc != DYNAMIC_PC) {
1077
        tcg_gen_movi_tl(cpu_npc, dc->npc);
1078
    }
1079
}
1080

    
1081
static inline void save_state(DisasContext *dc, TCGv cond)
1082
{
1083
    tcg_gen_movi_tl(cpu_pc, dc->pc);
1084
    /* flush pending conditional evaluations before exposing cpu state */
1085
    if (dc->cc_op != CC_OP_FLAGS) {
1086
        dc->cc_op = CC_OP_FLAGS;
1087
        gen_helper_compute_psr();
1088
    }
1089
    save_npc(dc, cond);
1090
}
1091

    
1092
static inline void gen_mov_pc_npc(DisasContext *dc, TCGv cond)
1093
{
1094
    if (dc->npc == JUMP_PC) {
1095
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1096
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1097
        dc->pc = DYNAMIC_PC;
1098
    } else if (dc->npc == DYNAMIC_PC) {
1099
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1100
        dc->pc = DYNAMIC_PC;
1101
    } else {
1102
        dc->pc = dc->npc;
1103
    }
1104
}
1105

    
1106
static inline void gen_op_next_insn(void)
1107
{
1108
    tcg_gen_mov_tl(cpu_pc, cpu_npc);
1109
    tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
1110
}
1111

    
1112
static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond,
1113
                            DisasContext *dc)
1114
{
1115
    TCGv_i32 r_src;
1116

    
1117
#ifdef TARGET_SPARC64
1118
    if (cc)
1119
        r_src = cpu_xcc;
1120
    else
1121
        r_src = cpu_psr;
1122
#else
1123
    r_src = cpu_psr;
1124
#endif
1125
    switch (dc->cc_op) {
1126
    case CC_OP_FLAGS:
1127
        break;
1128
    default:
1129
        gen_helper_compute_psr();
1130
        dc->cc_op = CC_OP_FLAGS;
1131
        break;
1132
    }
1133
    switch (cond) {
1134
    case 0x0:
1135
        gen_op_eval_bn(r_dst);
1136
        break;
1137
    case 0x1:
1138
        gen_op_eval_be(r_dst, r_src);
1139
        break;
1140
    case 0x2:
1141
        gen_op_eval_ble(r_dst, r_src);
1142
        break;
1143
    case 0x3:
1144
        gen_op_eval_bl(r_dst, r_src);
1145
        break;
1146
    case 0x4:
1147
        gen_op_eval_bleu(r_dst, r_src);
1148
        break;
1149
    case 0x5:
1150
        gen_op_eval_bcs(r_dst, r_src);
1151
        break;
1152
    case 0x6:
1153
        gen_op_eval_bneg(r_dst, r_src);
1154
        break;
1155
    case 0x7:
1156
        gen_op_eval_bvs(r_dst, r_src);
1157
        break;
1158
    case 0x8:
1159
        gen_op_eval_ba(r_dst);
1160
        break;
1161
    case 0x9:
1162
        gen_op_eval_bne(r_dst, r_src);
1163
        break;
1164
    case 0xa:
1165
        gen_op_eval_bg(r_dst, r_src);
1166
        break;
1167
    case 0xb:
1168
        gen_op_eval_bge(r_dst, r_src);
1169
        break;
1170
    case 0xc:
1171
        gen_op_eval_bgu(r_dst, r_src);
1172
        break;
1173
    case 0xd:
1174
        gen_op_eval_bcc(r_dst, r_src);
1175
        break;
1176
    case 0xe:
1177
        gen_op_eval_bpos(r_dst, r_src);
1178
        break;
1179
    case 0xf:
1180
        gen_op_eval_bvc(r_dst, r_src);
1181
        break;
1182
    }
1183
}
1184

    
1185
static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
1186
{
1187
    unsigned int offset;
1188

    
1189
    switch (cc) {
1190
    default:
1191
    case 0x0:
1192
        offset = 0;
1193
        break;
1194
    case 0x1:
1195
        offset = 32 - 10;
1196
        break;
1197
    case 0x2:
1198
        offset = 34 - 10;
1199
        break;
1200
    case 0x3:
1201
        offset = 36 - 10;
1202
        break;
1203
    }
1204

    
1205
    switch (cond) {
1206
    case 0x0:
1207
        gen_op_eval_bn(r_dst);
1208
        break;
1209
    case 0x1:
1210
        gen_op_eval_fbne(r_dst, cpu_fsr, offset);
1211
        break;
1212
    case 0x2:
1213
        gen_op_eval_fblg(r_dst, cpu_fsr, offset);
1214
        break;
1215
    case 0x3:
1216
        gen_op_eval_fbul(r_dst, cpu_fsr, offset);
1217
        break;
1218
    case 0x4:
1219
        gen_op_eval_fbl(r_dst, cpu_fsr, offset);
1220
        break;
1221
    case 0x5:
1222
        gen_op_eval_fbug(r_dst, cpu_fsr, offset);
1223
        break;
1224
    case 0x6:
1225
        gen_op_eval_fbg(r_dst, cpu_fsr, offset);
1226
        break;
1227
    case 0x7:
1228
        gen_op_eval_fbu(r_dst, cpu_fsr, offset);
1229
        break;
1230
    case 0x8:
1231
        gen_op_eval_ba(r_dst);
1232
        break;
1233
    case 0x9:
1234
        gen_op_eval_fbe(r_dst, cpu_fsr, offset);
1235
        break;
1236
    case 0xa:
1237
        gen_op_eval_fbue(r_dst, cpu_fsr, offset);
1238
        break;
1239
    case 0xb:
1240
        gen_op_eval_fbge(r_dst, cpu_fsr, offset);
1241
        break;
1242
    case 0xc:
1243
        gen_op_eval_fbuge(r_dst, cpu_fsr, offset);
1244
        break;
1245
    case 0xd:
1246
        gen_op_eval_fble(r_dst, cpu_fsr, offset);
1247
        break;
1248
    case 0xe:
1249
        gen_op_eval_fbule(r_dst, cpu_fsr, offset);
1250
        break;
1251
    case 0xf:
1252
        gen_op_eval_fbo(r_dst, cpu_fsr, offset);
1253
        break;
1254
    }
1255
}
1256

    
1257
#ifdef TARGET_SPARC64
1258
// Inverted logic
1259
static const int gen_tcg_cond_reg[8] = {
1260
    -1,
1261
    TCG_COND_NE,
1262
    TCG_COND_GT,
1263
    TCG_COND_GE,
1264
    -1,
1265
    TCG_COND_EQ,
1266
    TCG_COND_LE,
1267
    TCG_COND_LT,
1268
};
1269

    
1270
static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
1271
{
1272
    int l1;
1273

    
1274
    l1 = gen_new_label();
1275
    tcg_gen_movi_tl(r_dst, 0);
1276
    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], r_src, 0, l1);
1277
    tcg_gen_movi_tl(r_dst, 1);
1278
    gen_set_label(l1);
1279
}
1280
#endif
1281

    
1282
/* XXX: potentially incorrect if dynamic npc */
1283
static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1284
                      TCGv r_cond)
1285
{
1286
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1287
    target_ulong target = dc->pc + offset;
1288

    
1289
    if (cond == 0x0) {
1290
        /* unconditional not taken */
1291
        if (a) {
1292
            dc->pc = dc->npc + 4;
1293
            dc->npc = dc->pc + 4;
1294
        } else {
1295
            dc->pc = dc->npc;
1296
            dc->npc = dc->pc + 4;
1297
        }
1298
    } else if (cond == 0x8) {
1299
        /* unconditional taken */
1300
        if (a) {
1301
            dc->pc = target;
1302
            dc->npc = dc->pc + 4;
1303
        } else {
1304
            dc->pc = dc->npc;
1305
            dc->npc = target;
1306
            tcg_gen_mov_tl(cpu_pc, cpu_npc);
1307
        }
1308
    } else {
1309
        flush_cond(dc, r_cond);
1310
        gen_cond(r_cond, cc, cond, dc);
1311
        if (a) {
1312
            gen_branch_a(dc, target, dc->npc, r_cond);
1313
            dc->is_br = 1;
1314
        } else {
1315
            dc->pc = dc->npc;
1316
            dc->jump_pc[0] = target;
1317
            dc->jump_pc[1] = dc->npc + 4;
1318
            dc->npc = JUMP_PC;
1319
        }
1320
    }
1321
}
1322

    
1323
/* XXX: potentially incorrect if dynamic npc */
1324
static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1325
                      TCGv r_cond)
1326
{
1327
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1328
    target_ulong target = dc->pc + offset;
1329

    
1330
    if (cond == 0x0) {
1331
        /* unconditional not taken */
1332
        if (a) {
1333
            dc->pc = dc->npc + 4;
1334
            dc->npc = dc->pc + 4;
1335
        } else {
1336
            dc->pc = dc->npc;
1337
            dc->npc = dc->pc + 4;
1338
        }
1339
    } else if (cond == 0x8) {
1340
        /* unconditional taken */
1341
        if (a) {
1342
            dc->pc = target;
1343
            dc->npc = dc->pc + 4;
1344
        } else {
1345
            dc->pc = dc->npc;
1346
            dc->npc = target;
1347
            tcg_gen_mov_tl(cpu_pc, cpu_npc);
1348
        }
1349
    } else {
1350
        flush_cond(dc, r_cond);
1351
        gen_fcond(r_cond, cc, cond);
1352
        if (a) {
1353
            gen_branch_a(dc, target, dc->npc, r_cond);
1354
            dc->is_br = 1;
1355
        } else {
1356
            dc->pc = dc->npc;
1357
            dc->jump_pc[0] = target;
1358
            dc->jump_pc[1] = dc->npc + 4;
1359
            dc->npc = JUMP_PC;
1360
        }
1361
    }
1362
}
1363

    
1364
#ifdef TARGET_SPARC64
1365
/* XXX: potentially incorrect if dynamic npc */
1366
static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
1367
                          TCGv r_cond, TCGv r_reg)
1368
{
1369
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1370
    target_ulong target = dc->pc + offset;
1371

    
1372
    flush_cond(dc, r_cond);
1373
    gen_cond_reg(r_cond, cond, r_reg);
1374
    if (a) {
1375
        gen_branch_a(dc, target, dc->npc, r_cond);
1376
        dc->is_br = 1;
1377
    } else {
1378
        dc->pc = dc->npc;
1379
        dc->jump_pc[0] = target;
1380
        dc->jump_pc[1] = dc->npc + 4;
1381
        dc->npc = JUMP_PC;
1382
    }
1383
}
1384

    
1385
static inline void gen_op_fcmps(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
1386
{
1387
    switch (fccno) {
1388
    case 0:
1389
        gen_helper_fcmps(r_rs1, r_rs2);
1390
        break;
1391
    case 1:
1392
        gen_helper_fcmps_fcc1(r_rs1, r_rs2);
1393
        break;
1394
    case 2:
1395
        gen_helper_fcmps_fcc2(r_rs1, r_rs2);
1396
        break;
1397
    case 3:
1398
        gen_helper_fcmps_fcc3(r_rs1, r_rs2);
1399
        break;
1400
    }
1401
}
1402

    
1403
static inline void gen_op_fcmpd(int fccno)
1404
{
1405
    switch (fccno) {
1406
    case 0:
1407
        gen_helper_fcmpd();
1408
        break;
1409
    case 1:
1410
        gen_helper_fcmpd_fcc1();
1411
        break;
1412
    case 2:
1413
        gen_helper_fcmpd_fcc2();
1414
        break;
1415
    case 3:
1416
        gen_helper_fcmpd_fcc3();
1417
        break;
1418
    }
1419
}
1420

    
1421
static inline void gen_op_fcmpq(int fccno)
1422
{
1423
    switch (fccno) {
1424
    case 0:
1425
        gen_helper_fcmpq();
1426
        break;
1427
    case 1:
1428
        gen_helper_fcmpq_fcc1();
1429
        break;
1430
    case 2:
1431
        gen_helper_fcmpq_fcc2();
1432
        break;
1433
    case 3:
1434
        gen_helper_fcmpq_fcc3();
1435
        break;
1436
    }
1437
}
1438

    
1439
static inline void gen_op_fcmpes(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
1440
{
1441
    switch (fccno) {
1442
    case 0:
1443
        gen_helper_fcmpes(r_rs1, r_rs2);
1444
        break;
1445
    case 1:
1446
        gen_helper_fcmpes_fcc1(r_rs1, r_rs2);
1447
        break;
1448
    case 2:
1449
        gen_helper_fcmpes_fcc2(r_rs1, r_rs2);
1450
        break;
1451
    case 3:
1452
        gen_helper_fcmpes_fcc3(r_rs1, r_rs2);
1453
        break;
1454
    }
1455
}
1456

    
1457
static inline void gen_op_fcmped(int fccno)
1458
{
1459
    switch (fccno) {
1460
    case 0:
1461
        gen_helper_fcmped();
1462
        break;
1463
    case 1:
1464
        gen_helper_fcmped_fcc1();
1465
        break;
1466
    case 2:
1467
        gen_helper_fcmped_fcc2();
1468
        break;
1469
    case 3:
1470
        gen_helper_fcmped_fcc3();
1471
        break;
1472
    }
1473
}
1474

    
1475
static inline void gen_op_fcmpeq(int fccno)
1476
{
1477
    switch (fccno) {
1478
    case 0:
1479
        gen_helper_fcmpeq();
1480
        break;
1481
    case 1:
1482
        gen_helper_fcmpeq_fcc1();
1483
        break;
1484
    case 2:
1485
        gen_helper_fcmpeq_fcc2();
1486
        break;
1487
    case 3:
1488
        gen_helper_fcmpeq_fcc3();
1489
        break;
1490
    }
1491
}
1492

    
1493
#else
1494

    
1495
static inline void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2)
1496
{
1497
    gen_helper_fcmps(r_rs1, r_rs2);
1498
}
1499

    
1500
static inline void gen_op_fcmpd(int fccno)
1501
{
1502
    gen_helper_fcmpd();
1503
}
1504

    
1505
static inline void gen_op_fcmpq(int fccno)
1506
{
1507
    gen_helper_fcmpq();
1508
}
1509

    
1510
static inline void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2)
1511
{
1512
    gen_helper_fcmpes(r_rs1, r_rs2);
1513
}
1514

    
1515
static inline void gen_op_fcmped(int fccno)
1516
{
1517
    gen_helper_fcmped();
1518
}
1519

    
1520
static inline void gen_op_fcmpeq(int fccno)
1521
{
1522
    gen_helper_fcmpeq();
1523
}
1524
#endif
1525

    
1526
static inline void gen_op_fpexception_im(int fsr_flags)
1527
{
1528
    TCGv_i32 r_const;
1529

    
1530
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_NMASK);
1531
    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
1532
    r_const = tcg_const_i32(TT_FP_EXCP);
1533
    gen_helper_raise_exception(r_const);
1534
    tcg_temp_free_i32(r_const);
1535
}
1536

    
1537
static int gen_trap_ifnofpu(DisasContext *dc, TCGv r_cond)
1538
{
1539
#if !defined(CONFIG_USER_ONLY)
1540
    if (!dc->fpu_enabled) {
1541
        TCGv_i32 r_const;
1542

    
1543
        save_state(dc, r_cond);
1544
        r_const = tcg_const_i32(TT_NFPU_INSN);
1545
        gen_helper_raise_exception(r_const);
1546
        tcg_temp_free_i32(r_const);
1547
        dc->is_br = 1;
1548
        return 1;
1549
    }
1550
#endif
1551
    return 0;
1552
}
1553

    
1554
static inline void gen_op_clear_ieee_excp_and_FTT(void)
1555
{
1556
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_CEXC_NMASK);
1557
}
1558

    
1559
static inline void gen_clear_float_exceptions(void)
1560
{
1561
    gen_helper_clear_float_exceptions();
1562
}
1563

    
1564
/* asi moves */
1565
#ifdef TARGET_SPARC64
1566
static inline TCGv_i32 gen_get_asi(int insn, TCGv r_addr)
1567
{
1568
    int asi;
1569
    TCGv_i32 r_asi;
1570

    
1571
    if (IS_IMM) {
1572
        r_asi = tcg_temp_new_i32();
1573
        tcg_gen_mov_i32(r_asi, cpu_asi);
1574
    } else {
1575
        asi = GET_FIELD(insn, 19, 26);
1576
        r_asi = tcg_const_i32(asi);
1577
    }
1578
    return r_asi;
1579
}
1580

    
1581
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
1582
                              int sign)
1583
{
1584
    TCGv_i32 r_asi, r_size, r_sign;
1585

    
1586
    r_asi = gen_get_asi(insn, addr);
1587
    r_size = tcg_const_i32(size);
1588
    r_sign = tcg_const_i32(sign);
1589
    gen_helper_ld_asi(dst, addr, r_asi, r_size, r_sign);
1590
    tcg_temp_free_i32(r_sign);
1591
    tcg_temp_free_i32(r_size);
1592
    tcg_temp_free_i32(r_asi);
1593
}
1594

    
1595
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1596
{
1597
    TCGv_i32 r_asi, r_size;
1598

    
1599
    r_asi = gen_get_asi(insn, addr);
1600
    r_size = tcg_const_i32(size);
1601
    gen_helper_st_asi(addr, src, r_asi, r_size);
1602
    tcg_temp_free_i32(r_size);
1603
    tcg_temp_free_i32(r_asi);
1604
}
1605

    
1606
static inline void gen_ldf_asi(TCGv addr, int insn, int size, int rd)
1607
{
1608
    TCGv_i32 r_asi, r_size, r_rd;
1609

    
1610
    r_asi = gen_get_asi(insn, addr);
1611
    r_size = tcg_const_i32(size);
1612
    r_rd = tcg_const_i32(rd);
1613
    gen_helper_ldf_asi(addr, r_asi, r_size, r_rd);
1614
    tcg_temp_free_i32(r_rd);
1615
    tcg_temp_free_i32(r_size);
1616
    tcg_temp_free_i32(r_asi);
1617
}
1618

    
1619
static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
1620
{
1621
    TCGv_i32 r_asi, r_size, r_rd;
1622

    
1623
    r_asi = gen_get_asi(insn, addr);
1624
    r_size = tcg_const_i32(size);
1625
    r_rd = tcg_const_i32(rd);
1626
    gen_helper_stf_asi(addr, r_asi, r_size, r_rd);
1627
    tcg_temp_free_i32(r_rd);
1628
    tcg_temp_free_i32(r_size);
1629
    tcg_temp_free_i32(r_asi);
1630
}
1631

    
1632
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1633
{
1634
    TCGv_i32 r_asi, r_size, r_sign;
1635

    
1636
    r_asi = gen_get_asi(insn, addr);
1637
    r_size = tcg_const_i32(4);
1638
    r_sign = tcg_const_i32(0);
1639
    gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
1640
    tcg_temp_free_i32(r_sign);
1641
    gen_helper_st_asi(addr, dst, r_asi, r_size);
1642
    tcg_temp_free_i32(r_size);
1643
    tcg_temp_free_i32(r_asi);
1644
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1645
}
1646

    
1647
static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
1648
{
1649
    TCGv_i32 r_asi, r_rd;
1650

    
1651
    r_asi = gen_get_asi(insn, addr);
1652
    r_rd = tcg_const_i32(rd);
1653
    gen_helper_ldda_asi(addr, r_asi, r_rd);
1654
    tcg_temp_free_i32(r_rd);
1655
    tcg_temp_free_i32(r_asi);
1656
}
1657

    
1658
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1659
{
1660
    TCGv_i32 r_asi, r_size;
1661

    
1662
    gen_movl_reg_TN(rd + 1, cpu_tmp0);
1663
    tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, hi);
1664
    r_asi = gen_get_asi(insn, addr);
1665
    r_size = tcg_const_i32(8);
1666
    gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
1667
    tcg_temp_free_i32(r_size);
1668
    tcg_temp_free_i32(r_asi);
1669
}
1670

    
1671
static inline void gen_cas_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
1672
                               int rd)
1673
{
1674
    TCGv r_val1;
1675
    TCGv_i32 r_asi;
1676

    
1677
    r_val1 = tcg_temp_new();
1678
    gen_movl_reg_TN(rd, r_val1);
1679
    r_asi = gen_get_asi(insn, addr);
1680
    gen_helper_cas_asi(dst, addr, r_val1, val2, r_asi);
1681
    tcg_temp_free_i32(r_asi);
1682
    tcg_temp_free(r_val1);
1683
}
1684

    
1685
static inline void gen_casx_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
1686
                                int rd)
1687
{
1688
    TCGv_i32 r_asi;
1689

    
1690
    gen_movl_reg_TN(rd, cpu_tmp64);
1691
    r_asi = gen_get_asi(insn, addr);
1692
    gen_helper_casx_asi(dst, addr, cpu_tmp64, val2, r_asi);
1693
    tcg_temp_free_i32(r_asi);
1694
}
1695

    
1696
#elif !defined(CONFIG_USER_ONLY)
1697

    
1698
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
1699
                              int sign)
1700
{
1701
    TCGv_i32 r_asi, r_size, r_sign;
1702

    
1703
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1704
    r_size = tcg_const_i32(size);
1705
    r_sign = tcg_const_i32(sign);
1706
    gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
1707
    tcg_temp_free(r_sign);
1708
    tcg_temp_free(r_size);
1709
    tcg_temp_free(r_asi);
1710
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1711
}
1712

    
1713
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1714
{
1715
    TCGv_i32 r_asi, r_size;
1716

    
1717
    tcg_gen_extu_tl_i64(cpu_tmp64, src);
1718
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1719
    r_size = tcg_const_i32(size);
1720
    gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
1721
    tcg_temp_free(r_size);
1722
    tcg_temp_free(r_asi);
1723
}
1724

    
1725
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1726
{
1727
    TCGv_i32 r_asi, r_size, r_sign;
1728
    TCGv_i64 r_val;
1729

    
1730
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1731
    r_size = tcg_const_i32(4);
1732
    r_sign = tcg_const_i32(0);
1733
    gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
1734
    tcg_temp_free(r_sign);
1735
    r_val = tcg_temp_new_i64();
1736
    tcg_gen_extu_tl_i64(r_val, dst);
1737
    gen_helper_st_asi(addr, r_val, r_asi, r_size);
1738
    tcg_temp_free_i64(r_val);
1739
    tcg_temp_free(r_size);
1740
    tcg_temp_free(r_asi);
1741
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1742
}
1743

    
1744
static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
1745
{
1746
    TCGv_i32 r_asi, r_size, r_sign;
1747

    
1748
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1749
    r_size = tcg_const_i32(8);
1750
    r_sign = tcg_const_i32(0);
1751
    gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
1752
    tcg_temp_free(r_sign);
1753
    tcg_temp_free(r_size);
1754
    tcg_temp_free(r_asi);
1755
    tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
1756
    gen_movl_TN_reg(rd + 1, cpu_tmp0);
1757
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1758
    tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
1759
    gen_movl_TN_reg(rd, hi);
1760
}
1761

    
1762
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1763
{
1764
    TCGv_i32 r_asi, r_size;
1765

    
1766
    gen_movl_reg_TN(rd + 1, cpu_tmp0);
1767
    tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, hi);
1768
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1769
    r_size = tcg_const_i32(8);
1770
    gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
1771
    tcg_temp_free(r_size);
1772
    tcg_temp_free(r_asi);
1773
}
1774
#endif
1775

    
1776
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1777
static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
1778
{
1779
    TCGv_i64 r_val;
1780
    TCGv_i32 r_asi, r_size;
1781

    
1782
    gen_ld_asi(dst, addr, insn, 1, 0);
1783

    
1784
    r_val = tcg_const_i64(0xffULL);
1785
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1786
    r_size = tcg_const_i32(1);
1787
    gen_helper_st_asi(addr, r_val, r_asi, r_size);
1788
    tcg_temp_free_i32(r_size);
1789
    tcg_temp_free_i32(r_asi);
1790
    tcg_temp_free_i64(r_val);
1791
}
1792
#endif
1793

    
1794
static inline TCGv get_src1(unsigned int insn, TCGv def)
1795
{
1796
    TCGv r_rs1 = def;
1797
    unsigned int rs1;
1798

    
1799
    rs1 = GET_FIELD(insn, 13, 17);
1800
    if (rs1 == 0) {
1801
        tcg_gen_movi_tl(def, 0);
1802
    } else if (rs1 < 8) {
1803
        r_rs1 = cpu_gregs[rs1];
1804
    } else {
1805
        tcg_gen_ld_tl(def, cpu_regwptr, (rs1 - 8) * sizeof(target_ulong));
1806
    }
1807
    return r_rs1;
1808
}
1809

    
1810
static inline TCGv get_src2(unsigned int insn, TCGv def)
1811
{
1812
    TCGv r_rs2 = def;
1813

    
1814
    if (IS_IMM) { /* immediate */
1815
        target_long simm = GET_FIELDs(insn, 19, 31);
1816
        tcg_gen_movi_tl(def, simm);
1817
    } else { /* register */
1818
        unsigned int rs2 = GET_FIELD(insn, 27, 31);
1819
        if (rs2 == 0) {
1820
            tcg_gen_movi_tl(def, 0);
1821
        } else if (rs2 < 8) {
1822
            r_rs2 = cpu_gregs[rs2];
1823
        } else {
1824
            tcg_gen_ld_tl(def, cpu_regwptr, (rs2 - 8) * sizeof(target_ulong));
1825
        }
1826
    }
1827
    return r_rs2;
1828
}
1829

    
1830
#ifdef TARGET_SPARC64
1831
static inline void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_ptr cpu_env)
1832
{
1833
    TCGv_i32 r_tl = tcg_temp_new_i32();
1834

    
1835
    /* load env->tl into r_tl */
1836
    tcg_gen_ld_i32(r_tl, cpu_env, offsetof(CPUSPARCState, tl));
1837

    
1838
    /* tl = [0 ... MAXTL_MASK] where MAXTL_MASK must be power of 2 */
1839
    tcg_gen_andi_i32(r_tl, r_tl, MAXTL_MASK);
1840

    
1841
    /* calculate offset to current trap state from env->ts, reuse r_tl */
1842
    tcg_gen_muli_i32(r_tl, r_tl, sizeof (trap_state));
1843
    tcg_gen_addi_ptr(r_tsptr, cpu_env, offsetof(CPUState, ts));
1844

    
1845
    /* tsptr = env->ts[env->tl & MAXTL_MASK] */
1846
    {
1847
        TCGv_ptr r_tl_tmp = tcg_temp_new_ptr();
1848
        tcg_gen_ext_i32_ptr(r_tl_tmp, r_tl);
1849
        tcg_gen_add_ptr(r_tsptr, r_tsptr, r_tl_tmp);
1850
        tcg_temp_free_ptr(r_tl_tmp);
1851
    }
1852

    
1853
    tcg_temp_free_i32(r_tl);
1854
}
1855
#endif
1856

    
1857
#define CHECK_IU_FEATURE(dc, FEATURE)                      \
1858
    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
1859
        goto illegal_insn;
1860
#define CHECK_FPU_FEATURE(dc, FEATURE)                     \
1861
    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
1862
        goto nfpu_insn;
1863

    
1864
/* before an instruction, dc->pc must be static */
1865
static void disas_sparc_insn(DisasContext * dc)
1866
{
1867
    unsigned int insn, opc, rs1, rs2, rd;
1868
    TCGv cpu_src1, cpu_src2, cpu_tmp1, cpu_tmp2;
1869
    target_long simm;
1870

    
1871
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
1872
        tcg_gen_debug_insn_start(dc->pc);
1873
    insn = ldl_code(dc->pc);
1874
    opc = GET_FIELD(insn, 0, 1);
1875

    
1876
    rd = GET_FIELD(insn, 2, 6);
1877

    
1878
    cpu_tmp1 = cpu_src1 = tcg_temp_new();
1879
    cpu_tmp2 = cpu_src2 = tcg_temp_new();
1880

    
1881
    switch (opc) {
1882
    case 0:                     /* branches/sethi */
1883
        {
1884
            unsigned int xop = GET_FIELD(insn, 7, 9);
1885
            int32_t target;
1886
            switch (xop) {
1887
#ifdef TARGET_SPARC64
1888
            case 0x1:           /* V9 BPcc */
1889
                {
1890
                    int cc;
1891

    
1892
                    target = GET_FIELD_SP(insn, 0, 18);
1893
                    target = sign_extend(target, 18);
1894
                    target <<= 2;
1895
                    cc = GET_FIELD_SP(insn, 20, 21);
1896
                    if (cc == 0)
1897
                        do_branch(dc, target, insn, 0, cpu_cond);
1898
                    else if (cc == 2)
1899
                        do_branch(dc, target, insn, 1, cpu_cond);
1900
                    else
1901
                        goto illegal_insn;
1902
                    goto jmp_insn;
1903
                }
1904
            case 0x3:           /* V9 BPr */
1905
                {
1906
                    target = GET_FIELD_SP(insn, 0, 13) |
1907
                        (GET_FIELD_SP(insn, 20, 21) << 14);
1908
                    target = sign_extend(target, 16);
1909
                    target <<= 2;
1910
                    cpu_src1 = get_src1(insn, cpu_src1);
1911
                    do_branch_reg(dc, target, insn, cpu_cond, cpu_src1);
1912
                    goto jmp_insn;
1913
                }
1914
            case 0x5:           /* V9 FBPcc */
1915
                {
1916
                    int cc = GET_FIELD_SP(insn, 20, 21);
1917
                    if (gen_trap_ifnofpu(dc, cpu_cond))
1918
                        goto jmp_insn;
1919
                    target = GET_FIELD_SP(insn, 0, 18);
1920
                    target = sign_extend(target, 19);
1921
                    target <<= 2;
1922
                    do_fbranch(dc, target, insn, cc, cpu_cond);
1923
                    goto jmp_insn;
1924
                }
1925
#else
1926
            case 0x7:           /* CBN+x */
1927
                {
1928
                    goto ncp_insn;
1929
                }
1930
#endif
1931
            case 0x2:           /* BN+x */
1932
                {
1933
                    target = GET_FIELD(insn, 10, 31);
1934
                    target = sign_extend(target, 22);
1935
                    target <<= 2;
1936
                    do_branch(dc, target, insn, 0, cpu_cond);
1937
                    goto jmp_insn;
1938
                }
1939
            case 0x6:           /* FBN+x */
1940
                {
1941
                    if (gen_trap_ifnofpu(dc, cpu_cond))
1942
                        goto jmp_insn;
1943
                    target = GET_FIELD(insn, 10, 31);
1944
                    target = sign_extend(target, 22);
1945
                    target <<= 2;
1946
                    do_fbranch(dc, target, insn, 0, cpu_cond);
1947
                    goto jmp_insn;
1948
                }
1949
            case 0x4:           /* SETHI */
1950
                if (rd) { // nop
1951
                    uint32_t value = GET_FIELD(insn, 10, 31);
1952
                    TCGv r_const;
1953

    
1954
                    r_const = tcg_const_tl(value << 10);
1955
                    gen_movl_TN_reg(rd, r_const);
1956
                    tcg_temp_free(r_const);
1957
                }
1958
                break;
1959
            case 0x0:           /* UNIMPL */
1960
            default:
1961
                goto illegal_insn;
1962
            }
1963
            break;
1964
        }
1965
        break;
1966
    case 1:                     /*CALL*/
1967
        {
1968
            target_long target = GET_FIELDs(insn, 2, 31) << 2;
1969
            TCGv r_const;
1970

    
1971
            r_const = tcg_const_tl(dc->pc);
1972
            gen_movl_TN_reg(15, r_const);
1973
            tcg_temp_free(r_const);
1974
            target += dc->pc;
1975
            gen_mov_pc_npc(dc, cpu_cond);
1976
            dc->npc = target;
1977
        }
1978
        goto jmp_insn;
1979
    case 2:                     /* FPU & Logical Operations */
1980
        {
1981
            unsigned int xop = GET_FIELD(insn, 7, 12);
1982
            if (xop == 0x3a) {  /* generate trap */
1983
                int cond;
1984

    
1985
                cpu_src1 = get_src1(insn, cpu_src1);
1986
                if (IS_IMM) {
1987
                    rs2 = GET_FIELD(insn, 25, 31);
1988
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, rs2);
1989
                } else {
1990
                    rs2 = GET_FIELD(insn, 27, 31);
1991
                    if (rs2 != 0) {
1992
                        gen_movl_reg_TN(rs2, cpu_src2);
1993
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
1994
                    } else
1995
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
1996
                }
1997
                cond = GET_FIELD(insn, 3, 6);
1998
                if (cond == 0x8) {
1999
                    save_state(dc, cpu_cond);
2000
                    if ((dc->def->features & CPU_FEATURE_HYPV) &&
2001
                        supervisor(dc))
2002
                        tcg_gen_andi_tl(cpu_dst, cpu_dst, UA2005_HTRAP_MASK);
2003
                    else
2004
                        tcg_gen_andi_tl(cpu_dst, cpu_dst, V8_TRAP_MASK);
2005
                    tcg_gen_addi_tl(cpu_dst, cpu_dst, TT_TRAP);
2006
                    tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2007
                    gen_helper_raise_exception(cpu_tmp32);
2008
                } else if (cond != 0) {
2009
                    TCGv r_cond = tcg_temp_new();
2010
                    int l1;
2011
#ifdef TARGET_SPARC64
2012
                    /* V9 icc/xcc */
2013
                    int cc = GET_FIELD_SP(insn, 11, 12);
2014

    
2015
                    save_state(dc, cpu_cond);
2016
                    if (cc == 0)
2017
                        gen_cond(r_cond, 0, cond, dc);
2018
                    else if (cc == 2)
2019
                        gen_cond(r_cond, 1, cond, dc);
2020
                    else
2021
                        goto illegal_insn;
2022
#else
2023
                    save_state(dc, cpu_cond);
2024
                    gen_cond(r_cond, 0, cond, dc);
2025
#endif
2026
                    l1 = gen_new_label();
2027
                    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
2028

    
2029
                    if ((dc->def->features & CPU_FEATURE_HYPV) &&
2030
                        supervisor(dc))
2031
                        tcg_gen_andi_tl(cpu_dst, cpu_dst, UA2005_HTRAP_MASK);
2032
                    else
2033
                        tcg_gen_andi_tl(cpu_dst, cpu_dst, V8_TRAP_MASK);
2034
                    tcg_gen_addi_tl(cpu_dst, cpu_dst, TT_TRAP);
2035
                    tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2036
                    gen_helper_raise_exception(cpu_tmp32);
2037

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

    
2075
                        r_tickptr = tcg_temp_new_ptr();
2076
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2077
                                       offsetof(CPUState, tick));
2078
                        gen_helper_tick_get_count(cpu_dst, r_tickptr);
2079
                        tcg_temp_free_ptr(r_tickptr);
2080
                        gen_movl_TN_reg(rd, cpu_dst);
2081
                    }
2082
                    break;
2083
                case 0x5: /* V9 rdpc */
2084
                    {
2085
                        TCGv r_const;
2086

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

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

    
2182
                        r_tsptr = tcg_temp_new_ptr();
2183
                        gen_load_trap_state_at_tl(r_tsptr, cpu_env);
2184
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2185
                                      offsetof(trap_state, tpc));
2186
                        tcg_temp_free_ptr(r_tsptr);
2187
                    }
2188
                    break;
2189
                case 1: // tnpc
2190
                    {
2191
                        TCGv_ptr r_tsptr;
2192

    
2193
                        r_tsptr = tcg_temp_new_ptr();
2194
                        gen_load_trap_state_at_tl(r_tsptr, cpu_env);
2195
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2196
                                      offsetof(trap_state, tnpc));
2197
                        tcg_temp_free_ptr(r_tsptr);
2198
                    }
2199
                    break;
2200
                case 2: // tstate
2201
                    {
2202
                        TCGv_ptr r_tsptr;
2203

    
2204
                        r_tsptr = tcg_temp_new_ptr();
2205
                        gen_load_trap_state_at_tl(r_tsptr, cpu_env);
2206
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2207
                                      offsetof(trap_state, tstate));
2208
                        tcg_temp_free_ptr(r_tsptr);
2209
                    }
2210
                    break;
2211
                case 3: // tt
2212
                    {
2213
                        TCGv_ptr r_tsptr;
2214

    
2215
                        r_tsptr = tcg_temp_new_ptr();
2216
                        gen_load_trap_state_at_tl(r_tsptr, cpu_env);
2217
                        tcg_gen_ld_i32(cpu_tmp32, r_tsptr,
2218
                                       offsetof(trap_state, tt));
2219
                        tcg_temp_free_ptr(r_tsptr);
2220
                        tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2221
                    }
2222
                    break;
2223
                case 4: // tick
2224
                    {
2225
                        TCGv_ptr r_tickptr;
2226

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

    
2642
                    l1 = gen_new_label();
2643
                    cond = GET_FIELD_SP(insn, 14, 17);
2644
                    cpu_src1 = get_src1(insn, cpu_src1);
2645
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2646
                                       0, l1);
2647
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);
2648
                    gen_set_label(l1);
2649
                    break;
2650
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
2651
                    int l1;
2652

    
2653
                    l1 = gen_new_label();
2654
                    cond = GET_FIELD_SP(insn, 14, 17);
2655
                    cpu_src1 = get_src1(insn, cpu_src1);
2656
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2657
                                       0, l1);
2658
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)]);
2659
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], cpu_fpr[DFPREG(rs2) + 1]);
2660
                    gen_set_label(l1);
2661
                    break;
2662
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
2663
                    int l1;
2664

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

    
2835
                    case 0x101: /* V9 fmovscc %icc */
2836
                        FMOVSCC(0);
2837
                        break;
2838
                    case 0x102: /* V9 fmovdcc %icc */
2839
                        FMOVDCC(0);
2840
                    case 0x103: /* V9 fmovqcc %icc */
2841
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2842
                        FMOVQCC(0);
2843
                        break;
2844
                    case 0x181: /* V9 fmovscc %xcc */
2845
                        FMOVSCC(1);
2846
                        break;
2847
                    case 0x182: /* V9 fmovdcc %xcc */
2848
                        FMOVDCC(1);
2849
                        break;
2850
                    case 0x183: /* V9 fmovqcc %xcc */
2851
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2852
                        FMOVQCC(1);
2853
                        break;
2854
#undef FMOVSCC
2855
#undef FMOVDCC
2856
#undef FMOVQCC
2857
#endif
2858
                    case 0x51: /* fcmps, V9 %fcc */
2859
                        gen_op_fcmps(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]);
2860
                        break;
2861
                    case 0x52: /* fcmpd, V9 %fcc */
2862
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2863
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2864
                        gen_op_fcmpd(rd & 3);
2865
                        break;
2866
                    case 0x53: /* fcmpq, V9 %fcc */
2867
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2868
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2869
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2870
                        gen_op_fcmpq(rd & 3);
2871
                        break;
2872
                    case 0x55: /* fcmpes, V9 %fcc */
2873
                        gen_op_fcmpes(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]);
2874
                        break;
2875
                    case 0x56: /* fcmped, V9 %fcc */
2876
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2877
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2878
                        gen_op_fcmped(rd & 3);
2879
                        break;
2880
                    case 0x57: /* fcmpeq, V9 %fcc */
2881
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2882
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2883
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2884
                        gen_op_fcmpeq(rd & 3);
2885
                        break;
2886
                    default:
2887
                        goto illegal_insn;
2888
                }
2889
            } else if (xop == 0x2) {
2890
                // clr/mov shortcut
2891

    
2892
                rs1 = GET_FIELD(insn, 13, 17);
2893
                if (rs1 == 0) {
2894
                    // or %g0, x, y -> mov T0, x; mov y, T0
2895
                    if (IS_IMM) {       /* immediate */
2896
                        TCGv r_const;
2897

    
2898
                        simm = GET_FIELDs(insn, 19, 31);
2899
                        r_const = tcg_const_tl(simm);
2900
                        gen_movl_TN_reg(rd, r_const);
2901
                        tcg_temp_free(r_const);
2902
                    } else {            /* register */
2903
                        rs2 = GET_FIELD(insn, 27, 31);
2904
                        gen_movl_reg_TN(rs2, cpu_dst);
2905
                        gen_movl_TN_reg(rd, cpu_dst);
2906
                    }
2907
                } else {
2908
                    cpu_src1 = get_src1(insn, cpu_src1);
2909
                    if (IS_IMM) {       /* immediate */
2910
                        simm = GET_FIELDs(insn, 19, 31);
2911
                        tcg_gen_ori_tl(cpu_dst, cpu_src1, simm);
2912
                        gen_movl_TN_reg(rd, cpu_dst);
2913
                    } else {            /* register */
2914
                        // or x, %g0, y -> mov T1, x; mov y, T1
2915
                        rs2 = GET_FIELD(insn, 27, 31);
2916
                        if (rs2 != 0) {
2917
                            gen_movl_reg_TN(rs2, cpu_src2);
2918
                            tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
2919
                            gen_movl_TN_reg(rd, cpu_dst);
2920
                        } else
2921
                            gen_movl_TN_reg(rd, cpu_src1);
2922
                    }
2923
                }
2924
#ifdef TARGET_SPARC64
2925
            } else if (xop == 0x25) { /* sll, V9 sllx */
2926
                cpu_src1 = get_src1(insn, cpu_src1);
2927
                if (IS_IMM) {   /* immediate */
2928
                    simm = GET_FIELDs(insn, 20, 31);
2929
                    if (insn & (1 << 12)) {
2930
                        tcg_gen_shli_i64(cpu_dst, cpu_src1, simm & 0x3f);
2931
                    } else {
2932
                        tcg_gen_shli_i64(cpu_dst, cpu_src1, simm & 0x1f);
2933
                    }
2934
                } else {                /* register */
2935
                    rs2 = GET_FIELD(insn, 27, 31);
2936
                    gen_movl_reg_TN(rs2, cpu_src2);
2937
                    if (insn & (1 << 12)) {
2938
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2939
                    } else {
2940
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2941
                    }
2942
                    tcg_gen_shl_i64(cpu_dst, cpu_src1, cpu_tmp0);
2943
                }
2944
                gen_movl_TN_reg(rd, cpu_dst);
2945
            } else if (xop == 0x26) { /* srl, V9 srlx */
2946
                cpu_src1 = get_src1(insn, cpu_src1);
2947
                if (IS_IMM) {   /* immediate */
2948
                    simm = GET_FIELDs(insn, 20, 31);
2949
                    if (insn & (1 << 12)) {
2950
                        tcg_gen_shri_i64(cpu_dst, cpu_src1, simm & 0x3f);
2951
                    } else {
2952
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2953
                        tcg_gen_shri_i64(cpu_dst, cpu_dst, simm & 0x1f);
2954
                    }
2955
                } else {                /* register */
2956
                    rs2 = GET_FIELD(insn, 27, 31);
2957
                    gen_movl_reg_TN(rs2, cpu_src2);
2958
                    if (insn & (1 << 12)) {
2959
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2960
                        tcg_gen_shr_i64(cpu_dst, cpu_src1, cpu_tmp0);
2961
                    } else {
2962
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2963
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2964
                        tcg_gen_shr_i64(cpu_dst, cpu_dst, cpu_tmp0);
2965
                    }
2966
                }
2967
                gen_movl_TN_reg(rd, cpu_dst);
2968
            } else if (xop == 0x27) { /* sra, V9 srax */
2969
                cpu_src1 = get_src1(insn, cpu_src1);
2970
                if (IS_IMM) {   /* immediate */
2971
                    simm = GET_FIELDs(insn, 20, 31);
2972
                    if (insn & (1 << 12)) {
2973
                        tcg_gen_sari_i64(cpu_dst, cpu_src1, simm & 0x3f);
2974
                    } else {
2975
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2976
                        tcg_gen_ext32s_i64(cpu_dst, cpu_dst);
2977
                        tcg_gen_sari_i64(cpu_dst, cpu_dst, simm & 0x1f);
2978
                    }
2979
                } else {                /* register */
2980
                    rs2 = GET_FIELD(insn, 27, 31);
2981
                    gen_movl_reg_TN(rs2, cpu_src2);
2982
                    if (insn & (1 << 12)) {
2983
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2984
                        tcg_gen_sar_i64(cpu_dst, cpu_src1, cpu_tmp0);
2985
                    } else {
2986
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2987
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2988
                        tcg_gen_ext32s_i64(cpu_dst, cpu_dst);
2989
                        tcg_gen_sar_i64(cpu_dst, cpu_dst, cpu_tmp0);
2990
                    }
2991
                }
2992
                gen_movl_TN_reg(rd, cpu_dst);
2993
#endif
2994
            } else if (xop < 0x36) {
2995
                if (xop < 0x20) {
2996
                    cpu_src1 = get_src1(insn, cpu_src1);
2997
                    cpu_src2 = get_src2(insn, cpu_src2);
2998
                    switch (xop & ~0x10) {
2999
                    case 0x0: /* add */
3000
                        if (IS_IMM) {
3001
                            simm = GET_FIELDs(insn, 19, 31);
3002
                            if (xop & 0x10) {
3003
                                gen_op_addi_cc(cpu_dst, cpu_src1, simm);
3004
                                tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADD);
3005
                                dc->cc_op = CC_OP_ADD;
3006
                            } else {
3007
                                tcg_gen_addi_tl(cpu_dst, cpu_src1, simm);
3008
                            }
3009
                        } else {
3010
                            if (xop & 0x10) {
3011
                                gen_op_add_cc(cpu_dst, cpu_src1, cpu_src2);
3012
                                tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADD);
3013
                                dc->cc_op = CC_OP_ADD;
3014
                            } else {
3015
                                tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
3016
                            }
3017
                        }
3018
                        break;
3019
                    case 0x1: /* and */
3020
                        if (IS_IMM) {
3021
                            simm = GET_FIELDs(insn, 19, 31);
3022
                            tcg_gen_andi_tl(cpu_dst, cpu_src1, simm);
3023
                        } else {
3024
                            tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_src2);
3025
                        }
3026
                        if (xop & 0x10) {
3027
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3028
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
3029
                            dc->cc_op = CC_OP_LOGIC;
3030
                        }
3031
                        break;
3032
                    case 0x2: /* or */
3033
                        if (IS_IMM) {
3034
                            simm = GET_FIELDs(insn, 19, 31);
3035
                            tcg_gen_ori_tl(cpu_dst, cpu_src1, simm);
3036
                        } else {
3037
                            tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
3038
                        }
3039
                        if (xop & 0x10) {
3040
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3041
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
3042
                            dc->cc_op = CC_OP_LOGIC;
3043
                        }
3044
                        break;
3045
                    case 0x3: /* xor */
3046
                        if (IS_IMM) {
3047
                            simm = GET_FIELDs(insn, 19, 31);
3048
                            tcg_gen_xori_tl(cpu_dst, cpu_src1, simm);
3049
                        } else {
3050
                            tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3051
                        }
3052
                        if (xop & 0x10) {
3053
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3054
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
3055
                            dc->cc_op = CC_OP_LOGIC;
3056
                        }
3057
                        break;
3058
                    case 0x4: /* sub */
3059
                        if (IS_IMM) {
3060
                            simm = GET_FIELDs(insn, 19, 31);
3061
                            if (xop & 0x10) {
3062
                                gen_op_subi_cc(cpu_dst, cpu_src1, simm, dc);
3063
                            } else {
3064
                                tcg_gen_subi_tl(cpu_dst, cpu_src1, simm);
3065
                            }
3066
                        } else {
3067
                            if (xop & 0x10) {
3068
                                gen_op_sub_cc(cpu_dst, cpu_src1, cpu_src2);
3069
                                tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUB);
3070
                                dc->cc_op = CC_OP_SUB;
3071
                            } else {
3072
                                tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_src2);
3073
                            }
3074
                        }
3075
                        break;
3076
                    case 0x5: /* andn */
3077
                        if (IS_IMM) {
3078
                            simm = GET_FIELDs(insn, 19, 31);
3079
                            tcg_gen_andi_tl(cpu_dst, cpu_src1, ~simm);
3080
                        } else {
3081
                            tcg_gen_andc_tl(cpu_dst, cpu_src1, cpu_src2);
3082
                        }
3083
                        if (xop & 0x10) {
3084
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3085
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
3086
                            dc->cc_op = CC_OP_LOGIC;
3087
                        }
3088
                        break;
3089
                    case 0x6: /* orn */
3090
                        if (IS_IMM) {
3091
                            simm = GET_FIELDs(insn, 19, 31);
3092
                            tcg_gen_ori_tl(cpu_dst, cpu_src1, ~simm);
3093
                        } else {
3094
                            tcg_gen_orc_tl(cpu_dst, cpu_src1, cpu_src2);
3095
                        }
3096
                        if (xop & 0x10) {
3097
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3098
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
3099
                            dc->cc_op = CC_OP_LOGIC;
3100
                        }
3101
                        break;
3102
                    case 0x7: /* xorn */
3103
                        if (IS_IMM) {
3104
                            simm = GET_FIELDs(insn, 19, 31);
3105
                            tcg_gen_xori_tl(cpu_dst, cpu_src1, ~simm);
3106
                        } else {
3107
                            tcg_gen_not_tl(cpu_tmp0, cpu_src2);
3108
                            tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_tmp0);
3109
                        }
3110
                        if (xop & 0x10) {
3111
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3112
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
3113
                            dc->cc_op = CC_OP_LOGIC;
3114
                        }
3115
                        break;
3116
                    case 0x8: /* addx, V9 addc */
3117
                        gen_op_addx_int(dc, cpu_dst, cpu_src1, cpu_src2,
3118
                                        (xop & 0x10));
3119
                        break;
3120
#ifdef TARGET_SPARC64
3121
                    case 0x9: /* V9 mulx */
3122
                        if (IS_IMM) {
3123
                            simm = GET_FIELDs(insn, 19, 31);
3124
                            tcg_gen_muli_i64(cpu_dst, cpu_src1, simm);
3125
                        } else {
3126
                            tcg_gen_mul_i64(cpu_dst, cpu_src1, cpu_src2);
3127
                        }
3128
                        break;
3129
#endif
3130
                    case 0xa: /* umul */
3131
                        CHECK_IU_FEATURE(dc, MUL);
3132
                        gen_op_umul(cpu_dst, cpu_src1, cpu_src2);
3133
                        if (xop & 0x10) {
3134
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3135
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
3136
                            dc->cc_op = CC_OP_LOGIC;
3137
                        }
3138
                        break;
3139
                    case 0xb: /* smul */
3140
                        CHECK_IU_FEATURE(dc, MUL);
3141
                        gen_op_smul(cpu_dst, cpu_src1, cpu_src2);
3142
                        if (xop & 0x10) {
3143
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3144
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
3145
                            dc->cc_op = CC_OP_LOGIC;
3146
                        }
3147
                        break;
3148
                    case 0xc: /* subx, V9 subc */
3149
                        gen_op_subx_int(dc, cpu_dst, cpu_src1, cpu_src2,
3150
                                        (xop & 0x10));
3151
                        break;
3152
#ifdef TARGET_SPARC64
3153
                    case 0xd: /* V9 udivx */
3154
                        tcg_gen_mov_tl(cpu_cc_src, cpu_src1);
3155
                        tcg_gen_mov_tl(cpu_cc_src2, cpu_src2);
3156
                        gen_trap_ifdivzero_tl(cpu_cc_src2);
3157
                        tcg_gen_divu_i64(cpu_dst, cpu_cc_src, cpu_cc_src2);
3158
                        break;
3159
#endif
3160
                    case 0xe: /* udiv */
3161
                        CHECK_IU_FEATURE(dc, DIV);
3162
                        gen_helper_udiv(cpu_dst, cpu_src1, cpu_src2);
3163
                        if (xop & 0x10) {
3164
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3165
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_DIV);
3166
                            dc->cc_op = CC_OP_DIV;
3167
                        }
3168
                        break;
3169
                    case 0xf: /* sdiv */
3170
                        CHECK_IU_FEATURE(dc, DIV);
3171
                        gen_helper_sdiv(cpu_dst, cpu_src1, cpu_src2);
3172
                        if (xop & 0x10) {
3173
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3174
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_DIV);
3175
                            dc->cc_op = CC_OP_DIV;
3176
                        }
3177
                        break;
3178
                    default:
3179
                        goto illegal_insn;
3180
                    }
3181
                    gen_movl_TN_reg(rd, cpu_dst);
3182
                } else {
3183
                    cpu_src1 = get_src1(insn, cpu_src1);
3184
                    cpu_src2 = get_src2(insn, cpu_src2);
3185
                    switch (xop) {
3186
                    case 0x20: /* taddcc */
3187
                        gen_op_tadd_cc(cpu_dst, cpu_src1, cpu_src2);
3188
                        gen_movl_TN_reg(rd, cpu_dst);
3189
                        tcg_gen_movi_i32(cpu_cc_op, CC_OP_TADD);
3190
                        dc->cc_op = CC_OP_TADD;
3191
                        break;
3192
                    case 0x21: /* tsubcc */
3193
                        gen_op_tsub_cc(cpu_dst, cpu_src1, cpu_src2);
3194
                        gen_movl_TN_reg(rd, cpu_dst);
3195
                        tcg_gen_movi_i32(cpu_cc_op, CC_OP_TSUB);
3196
                        dc->cc_op = CC_OP_TSUB;
3197
                        break;
3198
                    case 0x22: /* taddcctv */
3199
                        save_state(dc, cpu_cond);
3200
                        gen_op_tadd_ccTV(cpu_dst, cpu_src1, cpu_src2);
3201
                        gen_movl_TN_reg(rd, cpu_dst);
3202
                        tcg_gen_movi_i32(cpu_cc_op, CC_OP_TADDTV);
3203
                        dc->cc_op = CC_OP_TADDTV;
3204
                        break;
3205
                    case 0x23: /* tsubcctv */
3206
                        save_state(dc, cpu_cond);
3207
                        gen_op_tsub_ccTV(cpu_dst, cpu_src1, cpu_src2);
3208
                        gen_movl_TN_reg(rd, cpu_dst);
3209
                        tcg_gen_movi_i32(cpu_cc_op, CC_OP_TSUBTV);
3210
                        dc->cc_op = CC_OP_TSUBTV;
3211
                        break;
3212
                    case 0x24: /* mulscc */
3213
                        gen_helper_compute_psr();
3214
                        gen_op_mulscc(cpu_dst, cpu_src1, cpu_src2);
3215
                        gen_movl_TN_reg(rd, cpu_dst);
3216
                        tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADD);
3217
                        dc->cc_op = CC_OP_ADD;
3218
                        break;
3219
#ifndef TARGET_SPARC64
3220
                    case 0x25:  /* sll */
3221
                        if (IS_IMM) { /* immediate */
3222
                            simm = GET_FIELDs(insn, 20, 31);
3223
                            tcg_gen_shli_tl(cpu_dst, cpu_src1, simm & 0x1f);
3224
                        } else { /* register */
3225
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3226
                            tcg_gen_shl_tl(cpu_dst, cpu_src1, cpu_tmp0);
3227
                        }
3228
                        gen_movl_TN_reg(rd, cpu_dst);
3229
                        break;
3230
                    case 0x26:  /* srl */
3231
                        if (IS_IMM) { /* immediate */
3232
                            simm = GET_FIELDs(insn, 20, 31);
3233
                            tcg_gen_shri_tl(cpu_dst, cpu_src1, simm & 0x1f);
3234
                        } else { /* register */
3235
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3236
                            tcg_gen_shr_tl(cpu_dst, cpu_src1, cpu_tmp0);
3237
                        }
3238
                        gen_movl_TN_reg(rd, cpu_dst);
3239
                        break;
3240
                    case 0x27:  /* sra */
3241
                        if (IS_IMM) { /* immediate */
3242
                            simm = GET_FIELDs(insn, 20, 31);
3243
                            tcg_gen_sari_tl(cpu_dst, cpu_src1, simm & 0x1f);
3244
                        } else { /* register */
3245
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3246
                            tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0);
3247
                        }
3248
                        gen_movl_TN_reg(rd, cpu_dst);
3249
                        break;
3250
#endif
3251
                    case 0x30:
3252
                        {
3253
                            switch(rd) {
3254
                            case 0: /* wry */
3255
                                tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
3256
                                tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
3257
                                break;
3258
#ifndef TARGET_SPARC64
3259
                            case 0x01 ... 0x0f: /* undefined in the
3260
                                                   SPARCv8 manual, nop
3261
                                                   on the microSPARC
3262
                                                   II */
3263
                            case 0x10 ... 0x1f: /* implementation-dependent
3264
                                                   in the SPARCv8
3265
                                                   manual, nop on the
3266
                                                   microSPARC II */
3267
                                break;
3268
#else
3269
                            case 0x2: /* V9 wrccr */
3270
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3271
                                gen_helper_wrccr(cpu_dst);
3272
                                tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS);
3273
                                dc->cc_op = CC_OP_FLAGS;
3274
                                break;
3275
                            case 0x3: /* V9 wrasi */
3276
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3277
                                tcg_gen_andi_tl(cpu_dst, cpu_dst, 0xff);
3278
                                tcg_gen_trunc_tl_i32(cpu_asi, cpu_dst);
3279
                                break;
3280
                            case 0x6: /* V9 wrfprs */
3281
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3282
                                tcg_gen_trunc_tl_i32(cpu_fprs, cpu_dst);
3283
                                save_state(dc, cpu_cond);
3284
                                gen_op_next_insn();
3285
                                tcg_gen_exit_tb(0);
3286
                                dc->is_br = 1;
3287
                                break;
3288
                            case 0xf: /* V9 sir, nop if user */
3289
#if !defined(CONFIG_USER_ONLY)
3290
                                if (supervisor(dc)) {
3291
                                    ; // XXX
3292
                                }
3293
#endif
3294
                                break;
3295
                            case 0x13: /* Graphics Status */
3296
                                if (gen_trap_ifnofpu(dc, cpu_cond))
3297
                                    goto jmp_insn;
3298
                                tcg_gen_xor_tl(cpu_gsr, cpu_src1, cpu_src2);
3299
                                break;
3300
                            case 0x14: /* Softint set */
3301
                                if (!supervisor(dc))
3302
                                    goto illegal_insn;
3303
                                tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2);
3304
                                gen_helper_set_softint(cpu_tmp64);
3305
                                break;
3306
                            case 0x15: /* Softint clear */
3307
                                if (!supervisor(dc))
3308
                                    goto illegal_insn;
3309
                                tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2);
3310
                                gen_helper_clear_softint(cpu_tmp64);
3311
                                break;
3312
                            case 0x16: /* Softint write */
3313
                                if (!supervisor(dc))
3314
                                    goto illegal_insn;
3315
                                tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2);
3316
                                gen_helper_write_softint(cpu_tmp64);
3317
                                break;
3318
                            case 0x17: /* Tick compare */
3319
#if !defined(CONFIG_USER_ONLY)
3320
                                if (!supervisor(dc))
3321
                                    goto illegal_insn;
3322
#endif
3323
                                {
3324
                                    TCGv_ptr r_tickptr;
3325

    
3326
                                    tcg_gen_xor_tl(cpu_tick_cmpr, cpu_src1,
3327
                                                   cpu_src2);
3328
                                    r_tickptr = tcg_temp_new_ptr();
3329
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3330
                                                   offsetof(CPUState, tick));
3331
                                    gen_helper_tick_set_limit(r_tickptr,
3332
                                                              cpu_tick_cmpr);
3333
                                    tcg_temp_free_ptr(r_tickptr);
3334
                                }
3335
                                break;
3336
                            case 0x18: /* System tick */
3337
#if !defined(CONFIG_USER_ONLY)
3338
                                if (!supervisor(dc))
3339
                                    goto illegal_insn;
3340
#endif
3341
                                {
3342
                                    TCGv_ptr r_tickptr;
3343

    
3344
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
3345
                                                   cpu_src2);
3346
                                    r_tickptr = tcg_temp_new_ptr();
3347
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3348
                                                   offsetof(CPUState, stick));
3349
                                    gen_helper_tick_set_count(r_tickptr,
3350
                                                              cpu_dst);
3351
                                    tcg_temp_free_ptr(r_tickptr);
3352
                                }
3353
                                break;
3354
                            case 0x19: /* System tick compare */
3355
#if !defined(CONFIG_USER_ONLY)
3356
                                if (!supervisor(dc))
3357
                                    goto illegal_insn;
3358
#endif
3359
                                {
3360
                                    TCGv_ptr r_tickptr;
3361

    
3362
                                    tcg_gen_xor_tl(cpu_stick_cmpr, cpu_src1,
3363
                                                   cpu_src2);
3364
                                    r_tickptr = tcg_temp_new_ptr();
3365
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3366
                                                   offsetof(CPUState, stick));
3367
                                    gen_helper_tick_set_limit(r_tickptr,
3368
                                                              cpu_stick_cmpr);
3369
                                    tcg_temp_free_ptr(r_tickptr);
3370
                                }
3371
                                break;
3372

    
3373
                            case 0x10: /* Performance Control */
3374
                            case 0x11: /* Performance Instrumentation
3375
                                          Counter */
3376
                            case 0x12: /* Dispatch Control */
3377
#endif
3378
                            default:
3379
                                goto illegal_insn;
3380
                            }
3381
                        }
3382
                        break;
3383
#if !defined(CONFIG_USER_ONLY)
3384
                    case 0x31: /* wrpsr, V9 saved, restored */
3385
                        {
3386
                            if (!supervisor(dc))
3387
                                goto priv_insn;
3388
#ifdef TARGET_SPARC64
3389
                            switch (rd) {
3390
                            case 0:
3391
                                gen_helper_saved();
3392
                                break;
3393
                            case 1:
3394
                                gen_helper_restored();
3395
                                break;
3396
                            case 2: /* UA2005 allclean */
3397
                            case 3: /* UA2005 otherw */
3398
                            case 4: /* UA2005 normalw */
3399
                            case 5: /* UA2005 invalw */
3400
                                // XXX
3401
                            default:
3402
                                goto illegal_insn;
3403
                            }
3404
#else
3405
                            tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3406
                            gen_helper_wrpsr(cpu_dst);
3407
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS);
3408
                            dc->cc_op = CC_OP_FLAGS;
3409
                            save_state(dc, cpu_cond);
3410
                            gen_op_next_insn();
3411
                            tcg_gen_exit_tb(0);
3412
                            dc->is_br = 1;
3413
#endif
3414
                        }
3415
                        break;
3416
                    case 0x32: /* wrwim, V9 wrpr */
3417
                        {
3418
                            if (!supervisor(dc))
3419
                                goto priv_insn;
3420
                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
3421
#ifdef TARGET_SPARC64
3422
                            switch (rd) {
3423
                            case 0: // tpc
3424
                                {
3425
                                    TCGv_ptr r_tsptr;
3426

    
3427
                                    r_tsptr = tcg_temp_new_ptr();
3428
                                    gen_load_trap_state_at_tl(r_tsptr, cpu_env);
3429
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3430
                                                  offsetof(trap_state, tpc));
3431
                                    tcg_temp_free_ptr(r_tsptr);
3432
                                }
3433
                                break;
3434
                            case 1: // tnpc
3435
                                {
3436
                                    TCGv_ptr r_tsptr;
3437

    
3438
                                    r_tsptr = tcg_temp_new_ptr();
3439
                                    gen_load_trap_state_at_tl(r_tsptr, cpu_env);
3440
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3441
                                                  offsetof(trap_state, tnpc));
3442
                                    tcg_temp_free_ptr(r_tsptr);
3443
                                }
3444
                                break;
3445
                            case 2: // tstate
3446
                                {
3447
                                    TCGv_ptr r_tsptr;
3448

    
3449
                                    r_tsptr = tcg_temp_new_ptr();
3450
                                    gen_load_trap_state_at_tl(r_tsptr, cpu_env);
3451
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3452
                                                  offsetof(trap_state,
3453
                                                           tstate));
3454
                                    tcg_temp_free_ptr(r_tsptr);
3455
                                }
3456
                                break;
3457
                            case 3: // tt
3458
                                {
3459
                                    TCGv_ptr r_tsptr;
3460

    
3461
                                    r_tsptr = tcg_temp_new_ptr();
3462
                                    gen_load_trap_state_at_tl(r_tsptr, cpu_env);
3463
                                    tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3464
                                    tcg_gen_st_i32(cpu_tmp32, r_tsptr,
3465
                                                   offsetof(trap_state, tt));
3466
                                    tcg_temp_free_ptr(r_tsptr);
3467
                                }
3468
                                break;
3469
                            case 4: // tick
3470
                                {
3471
                                    TCGv_ptr r_tickptr;
3472

    
3473
                                    r_tickptr = tcg_temp_new_ptr();
3474
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3475
                                                   offsetof(CPUState, tick));
3476
                                    gen_helper_tick_set_count(r_tickptr,
3477
                                                              cpu_tmp0);
3478
                                    tcg_temp_free_ptr(r_tickptr);
3479
                                }
3480
                                break;
3481
                            case 5: // tba
3482
                                tcg_gen_mov_tl(cpu_tbr, cpu_tmp0);
3483
                                break;
3484
                            case 6: // pstate
3485
                                save_state(dc, cpu_cond);
3486
                                gen_helper_wrpstate(cpu_tmp0);
3487
                                dc->npc = DYNAMIC_PC;
3488
                                break;
3489
                            case 7: // tl
3490
                                save_state(dc, cpu_cond);
3491
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3492
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3493
                                               offsetof(CPUSPARCState, tl));
3494
                                dc->npc = DYNAMIC_PC;
3495
                                break;
3496
                            case 8: // pil
3497
                                gen_helper_wrpil(cpu_tmp0);
3498
                                break;
3499
                            case 9: // cwp
3500
                                gen_helper_wrcwp(cpu_tmp0);
3501
                                break;
3502
                            case 10: // cansave
3503
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3504
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3505
                                               offsetof(CPUSPARCState,
3506
                                                        cansave));
3507
                                break;
3508
                            case 11: // canrestore
3509
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3510
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3511
                                               offsetof(CPUSPARCState,
3512
                                                        canrestore));
3513
                                break;
3514
                            case 12: // cleanwin
3515
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3516
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3517
                                               offsetof(CPUSPARCState,
3518
                                                        cleanwin));
3519
                                break;
3520
                            case 13: // otherwin
3521
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3522
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3523
                                               offsetof(CPUSPARCState,
3524
                                                        otherwin));
3525
                                break;
3526
                            case 14: // wstate
3527
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3528
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3529
                                               offsetof(CPUSPARCState,
3530
                                                        wstate));
3531
                                break;
3532
                            case 16: // UA2005 gl
3533
                                CHECK_IU_FEATURE(dc, GL);
3534
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3535
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3536
                                               offsetof(CPUSPARCState, gl));
3537
                                break;
3538
                            case 26: // UA2005 strand status
3539
                                CHECK_IU_FEATURE(dc, HYPV);
3540
                                if (!hypervisor(dc))
3541
                                    goto priv_insn;
3542
                                tcg_gen_mov_tl(cpu_ssr, cpu_tmp0);
3543
                                break;
3544
                            default:
3545
                                goto illegal_insn;
3546
                            }
3547
#else
3548
                            tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3549
                            if (dc->def->nwindows != 32)
3550
                                tcg_gen_andi_tl(cpu_tmp32, cpu_tmp32,
3551
                                                (1 << dc->def->nwindows) - 1);
3552
                            tcg_gen_mov_i32(cpu_wim, cpu_tmp32);
3553
#endif
3554
                        }
3555
                        break;
3556
                    case 0x33: /* wrtbr, UA2005 wrhpr */
3557
                        {
3558
#ifndef TARGET_SPARC64
3559
                            if (!supervisor(dc))
3560
                                goto priv_insn;
3561
                            tcg_gen_xor_tl(cpu_tbr, cpu_src1, cpu_src2);
3562
#else
3563
                            CHECK_IU_FEATURE(dc, HYPV);
3564
                            if (!hypervisor(dc))
3565
                                goto priv_insn;
3566
                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
3567
                            switch (rd) {
3568
                            case 0: // hpstate
3569
                                // XXX gen_op_wrhpstate();
3570
                                save_state(dc, cpu_cond);
3571
                                gen_op_next_insn();
3572
                                tcg_gen_exit_tb(0);
3573
                                dc->is_br = 1;
3574
                                break;
3575
                            case 1: // htstate
3576
                                // XXX gen_op_wrhtstate();
3577
                                break;
3578
                            case 3: // hintp
3579
                                tcg_gen_mov_tl(cpu_hintp, cpu_tmp0);
3580
                                break;
3581
                            case 5: // htba
3582
                                tcg_gen_mov_tl(cpu_htba, cpu_tmp0);
3583
                                break;
3584
                            case 31: // hstick_cmpr
3585
                                {
3586
                                    TCGv_ptr r_tickptr;
3587

    
3588
                                    tcg_gen_mov_tl(cpu_hstick_cmpr, cpu_tmp0);
3589
                                    r_tickptr = tcg_temp_new_ptr();
3590
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3591
                                                   offsetof(CPUState, hstick));
3592
                                    gen_helper_tick_set_limit(r_tickptr,
3593
                                                              cpu_hstick_cmpr);
3594
                                    tcg_temp_free_ptr(r_tickptr);
3595
                                }
3596
                                break;
3597
                            case 6: // hver readonly
3598
                            default:
3599
                                goto illegal_insn;
3600
                            }
3601
#endif
3602
                        }
3603
                        break;
3604
#endif
3605
#ifdef TARGET_SPARC64
3606
                    case 0x2c: /* V9 movcc */
3607
                        {
3608
                            int cc = GET_FIELD_SP(insn, 11, 12);
3609
                            int cond = GET_FIELD_SP(insn, 14, 17);
3610
                            TCGv r_cond;
3611
                            int l1;
3612

    
3613
                            r_cond = tcg_temp_new();
3614
                            if (insn & (1 << 18)) {
3615
                                if (cc == 0)
3616
                                    gen_cond(r_cond, 0, cond, dc);
3617
                                else if (cc == 2)
3618
                                    gen_cond(r_cond, 1, cond, dc);
3619
                                else
3620
                                    goto illegal_insn;
3621
                            } else {
3622
                                gen_fcond(r_cond, cc, cond);
3623
                            }
3624

    
3625
                            l1 = gen_new_label();
3626

    
3627
                            tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
3628
                            if (IS_IMM) {       /* immediate */
3629
                                TCGv r_const;
3630

    
3631
                                simm = GET_FIELD_SPs(insn, 0, 10);
3632
                                r_const = tcg_const_tl(simm);
3633
                                gen_movl_TN_reg(rd, r_const);
3634
                                tcg_temp_free(r_const);
3635
                            } else {
3636
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3637
                                gen_movl_reg_TN(rs2, cpu_tmp0);
3638
                                gen_movl_TN_reg(rd, cpu_tmp0);
3639
                            }
3640
                            gen_set_label(l1);
3641
                            tcg_temp_free(r_cond);
3642
                            break;
3643
                        }
3644
                    case 0x2d: /* V9 sdivx */
3645
                        gen_op_sdivx(cpu_dst, cpu_src1, cpu_src2);
3646
                        gen_movl_TN_reg(rd, cpu_dst);
3647
                        break;
3648
                    case 0x2e: /* V9 popc */
3649
                        {
3650
                            cpu_src2 = get_src2(insn, cpu_src2);
3651
                            gen_helper_popc(cpu_dst, cpu_src2);
3652
                            gen_movl_TN_reg(rd, cpu_dst);
3653
                        }
3654
                    case 0x2f: /* V9 movr */
3655
                        {
3656
                            int cond = GET_FIELD_SP(insn, 10, 12);
3657
                            int l1;
3658

    
3659
                            cpu_src1 = get_src1(insn, cpu_src1);
3660

    
3661
                            l1 = gen_new_label();
3662

    
3663
                            tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond],
3664
                                              cpu_src1, 0, l1);
3665
                            if (IS_IMM) {       /* immediate */
3666
                                TCGv r_const;
3667

    
3668
                                simm = GET_FIELD_SPs(insn, 0, 9);
3669
                                r_const = tcg_const_tl(simm);
3670
                                gen_movl_TN_reg(rd, r_const);
3671
                                tcg_temp_free(r_const);
3672
                            } else {
3673
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3674
                                gen_movl_reg_TN(rs2, cpu_tmp0);
3675
                                gen_movl_TN_reg(rd, cpu_tmp0);
3676
                            }
3677
                            gen_set_label(l1);
3678
                            break;
3679
                        }
3680
#endif
3681
                    default:
3682
                        goto illegal_insn;
3683
                    }
3684
                }
3685
            } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
3686
#ifdef TARGET_SPARC64
3687
                int opf = GET_FIELD_SP(insn, 5, 13);
3688
                rs1 = GET_FIELD(insn, 13, 17);
3689
                rs2 = GET_FIELD(insn, 27, 31);
3690
                if (gen_trap_ifnofpu(dc, cpu_cond))
3691
                    goto jmp_insn;
3692

    
3693
                switch (opf) {
3694
                case 0x000: /* VIS I edge8cc */
3695
                case 0x001: /* VIS II edge8n */
3696
                case 0x002: /* VIS I edge8lcc */
3697
                case 0x003: /* VIS II edge8ln */
3698
                case 0x004: /* VIS I edge16cc */
3699
                case 0x005: /* VIS II edge16n */
3700
                case 0x006: /* VIS I edge16lcc */
3701
                case 0x007: /* VIS II edge16ln */
3702
                case 0x008: /* VIS I edge32cc */
3703
                case 0x009: /* VIS II edge32n */
3704
                case 0x00a: /* VIS I edge32lcc */
3705
                case 0x00b: /* VIS II edge32ln */
3706
                    // XXX
3707
                    goto illegal_insn;
3708
                case 0x010: /* VIS I array8 */
3709
                    CHECK_FPU_FEATURE(dc, VIS1);
3710
                    cpu_src1 = get_src1(insn, cpu_src1);
3711
                    gen_movl_reg_TN(rs2, cpu_src2);
3712
                    gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
3713
                    gen_movl_TN_reg(rd, cpu_dst);
3714
                    break;
3715
                case 0x012: /* VIS I array16 */
3716
                    CHECK_FPU_FEATURE(dc, VIS1);
3717
                    cpu_src1 = get_src1(insn, cpu_src1);
3718
                    gen_movl_reg_TN(rs2, cpu_src2);
3719
                    gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
3720
                    tcg_gen_shli_i64(cpu_dst, cpu_dst, 1);
3721
                    gen_movl_TN_reg(rd, cpu_dst);
3722
                    break;
3723
                case 0x014: /* VIS I array32 */
3724
                    CHECK_FPU_FEATURE(dc, VIS1);
3725
                    cpu_src1 = get_src1(insn, cpu_src1);
3726
                    gen_movl_reg_TN(rs2, cpu_src2);
3727
                    gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
3728
                    tcg_gen_shli_i64(cpu_dst, cpu_dst, 2);
3729
                    gen_movl_TN_reg(rd, cpu_dst);
3730
                    break;
3731
                case 0x018: /* VIS I alignaddr */
3732
                    CHECK_FPU_FEATURE(dc, VIS1);
3733
                    cpu_src1 = get_src1(insn, cpu_src1);
3734
                    gen_movl_reg_TN(rs2, cpu_src2);
3735
                    gen_helper_alignaddr(cpu_dst, cpu_src1, cpu_src2);
3736
                    gen_movl_TN_reg(rd, cpu_dst);
3737
                    break;
3738
                case 0x019: /* VIS II bmask */
3739
                case 0x01a: /* VIS I alignaddrl */
3740
                    // XXX
3741
                    goto illegal_insn;
3742
                case 0x020: /* VIS I fcmple16 */
3743
                    CHECK_FPU_FEATURE(dc, VIS1);
3744
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3745
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3746
                    gen_helper_fcmple16();
3747
                    gen_op_store_DT0_fpr(DFPREG(rd));
3748
                    break;
3749
                case 0x022: /* VIS I fcmpne16 */
3750
                    CHECK_FPU_FEATURE(dc, VIS1);
3751
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3752
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3753
                    gen_helper_fcmpne16();
3754
                    gen_op_store_DT0_fpr(DFPREG(rd));
3755
                    break;
3756
                case 0x024: /* VIS I fcmple32 */
3757
                    CHECK_FPU_FEATURE(dc, VIS1);
3758
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3759
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3760
                    gen_helper_fcmple32();
3761
                    gen_op_store_DT0_fpr(DFPREG(rd));
3762
                    break;
3763
                case 0x026: /* VIS I fcmpne32 */
3764
                    CHECK_FPU_FEATURE(dc, VIS1);
3765
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3766
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3767
                    gen_helper_fcmpne32();
3768
                    gen_op_store_DT0_fpr(DFPREG(rd));
3769
                    break;
3770
                case 0x028: /* VIS I fcmpgt16 */
3771
                    CHECK_FPU_FEATURE(dc, VIS1);
3772
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3773
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3774
                    gen_helper_fcmpgt16();
3775
                    gen_op_store_DT0_fpr(DFPREG(rd));
3776
                    break;
3777
                case 0x02a: /* VIS I fcmpeq16 */
3778
                    CHECK_FPU_FEATURE(dc, VIS1);
3779
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3780
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3781
                    gen_helper_fcmpeq16();
3782
                    gen_op_store_DT0_fpr(DFPREG(rd));
3783
                    break;
3784
                case 0x02c: /* VIS I fcmpgt32 */
3785
                    CHECK_FPU_FEATURE(dc, VIS1);
3786
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3787
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3788
                    gen_helper_fcmpgt32();
3789
                    gen_op_store_DT0_fpr(DFPREG(rd));
3790
                    break;
3791
                case 0x02e: /* VIS I fcmpeq32 */
3792
                    CHECK_FPU_FEATURE(dc, VIS1);
3793
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3794
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3795
                    gen_helper_fcmpeq32();
3796
                    gen_op_store_DT0_fpr(DFPREG(rd));
3797
                    break;
3798
                case 0x031: /* VIS I fmul8x16 */
3799
                    CHECK_FPU_FEATURE(dc, VIS1);
3800
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3801
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3802
                    gen_helper_fmul8x16();
3803
                    gen_op_store_DT0_fpr(DFPREG(rd));
3804
                    break;
3805
                case 0x033: /* VIS I fmul8x16au */
3806
                    CHECK_FPU_FEATURE(dc, VIS1);
3807
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3808
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3809
                    gen_helper_fmul8x16au();
3810
                    gen_op_store_DT0_fpr(DFPREG(rd));
3811
                    break;
3812
                case 0x035: /* VIS I fmul8x16al */
3813
                    CHECK_FPU_FEATURE(dc, VIS1);
3814
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3815
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3816
                    gen_helper_fmul8x16al();
3817
                    gen_op_store_DT0_fpr(DFPREG(rd));
3818
                    break;
3819
                case 0x036: /* VIS I fmul8sux16 */
3820
                    CHECK_FPU_FEATURE(dc, VIS1);
3821
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3822
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3823
                    gen_helper_fmul8sux16();
3824
                    gen_op_store_DT0_fpr(DFPREG(rd));
3825
                    break;
3826
                case 0x037: /* VIS I fmul8ulx16 */
3827
                    CHECK_FPU_FEATURE(dc, VIS1);
3828
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3829
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3830
                    gen_helper_fmul8ulx16();
3831
                    gen_op_store_DT0_fpr(DFPREG(rd));
3832
                    break;
3833
                case 0x038: /* VIS I fmuld8sux16 */
3834
                    CHECK_FPU_FEATURE(dc, VIS1);
3835
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3836
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3837
                    gen_helper_fmuld8sux16();
3838
                    gen_op_store_DT0_fpr(DFPREG(rd));
3839
                    break;
3840
                case 0x039: /* VIS I fmuld8ulx16 */
3841
                    CHECK_FPU_FEATURE(dc, VIS1);
3842
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3843
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3844
                    gen_helper_fmuld8ulx16();
3845
                    gen_op_store_DT0_fpr(DFPREG(rd));
3846
                    break;
3847
                case 0x03a: /* VIS I fpack32 */
3848
                case 0x03b: /* VIS I fpack16 */
3849
                case 0x03d: /* VIS I fpackfix */
3850
                case 0x03e: /* VIS I pdist */
3851
                    // XXX
3852
                    goto illegal_insn;
3853
                case 0x048: /* VIS I faligndata */
3854
                    CHECK_FPU_FEATURE(dc, VIS1);
3855
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3856
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3857
                    gen_helper_faligndata();
3858
                    gen_op_store_DT0_fpr(DFPREG(rd));
3859
                    break;
3860
                case 0x04b: /* VIS I fpmerge */
3861
                    CHECK_FPU_FEATURE(dc, VIS1);
3862
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3863
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3864
                    gen_helper_fpmerge();
3865
                    gen_op_store_DT0_fpr(DFPREG(rd));
3866
                    break;
3867
                case 0x04c: /* VIS II bshuffle */
3868
                    // XXX
3869
                    goto illegal_insn;
3870
                case 0x04d: /* VIS I fexpand */
3871
                    CHECK_FPU_FEATURE(dc, VIS1);
3872
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3873
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3874
                    gen_helper_fexpand();
3875
                    gen_op_store_DT0_fpr(DFPREG(rd));
3876
                    break;
3877
                case 0x050: /* VIS I fpadd16 */
3878
                    CHECK_FPU_FEATURE(dc, VIS1);
3879
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3880
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3881
                    gen_helper_fpadd16();
3882
                    gen_op_store_DT0_fpr(DFPREG(rd));
3883
                    break;
3884
                case 0x051: /* VIS I fpadd16s */
3885
                    CHECK_FPU_FEATURE(dc, VIS1);
3886
                    gen_helper_fpadd16s(cpu_fpr[rd],
3887
                                        cpu_fpr[rs1], cpu_fpr[rs2]);
3888
                    break;
3889
                case 0x052: /* VIS I fpadd32 */
3890
                    CHECK_FPU_FEATURE(dc, VIS1);
3891
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3892
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3893
                    gen_helper_fpadd32();
3894
                    gen_op_store_DT0_fpr(DFPREG(rd));
3895
                    break;
3896
                case 0x053: /* VIS I fpadd32s */
3897
                    CHECK_FPU_FEATURE(dc, VIS1);
3898
                    gen_helper_fpadd32s(cpu_fpr[rd],
3899
                                        cpu_fpr[rs1], cpu_fpr[rs2]);
3900
                    break;
3901
                case 0x054: /* VIS I fpsub16 */
3902
                    CHECK_FPU_FEATURE(dc, VIS1);
3903
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3904
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3905
                    gen_helper_fpsub16();
3906
                    gen_op_store_DT0_fpr(DFPREG(rd));
3907
                    break;
3908
                case 0x055: /* VIS I fpsub16s */
3909
                    CHECK_FPU_FEATURE(dc, VIS1);
3910
                    gen_helper_fpsub16s(cpu_fpr[rd],
3911
                                        cpu_fpr[rs1], cpu_fpr[rs2]);
3912
                    break;
3913
                case 0x056: /* VIS I fpsub32 */
3914
                    CHECK_FPU_FEATURE(dc, VIS1);
3915
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3916
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3917
                    gen_helper_fpsub32();
3918
                    gen_op_store_DT0_fpr(DFPREG(rd));
3919
                    break;
3920
                case 0x057: /* VIS I fpsub32s */
3921
                    CHECK_FPU_FEATURE(dc, VIS1);
3922
                    gen_helper_fpsub32s(cpu_fpr[rd],
3923
                                        cpu_fpr[rs1], cpu_fpr[rs2]);
3924
                    break;
3925
                case 0x060: /* VIS I fzero */
3926
                    CHECK_FPU_FEATURE(dc, VIS1);
3927
                    tcg_gen_movi_i32(cpu_fpr[DFPREG(rd)], 0);
3928
                    tcg_gen_movi_i32(cpu_fpr[DFPREG(rd) + 1], 0);
3929
                    break;
3930
                case 0x061: /* VIS I fzeros */
3931
                    CHECK_FPU_FEATURE(dc, VIS1);
3932
                    tcg_gen_movi_i32(cpu_fpr[rd], 0);
3933
                    break;
3934
                case 0x062: /* VIS I fnor */
3935
                    CHECK_FPU_FEATURE(dc, VIS1);
3936
                    tcg_gen_nor_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1)],
3937
                                    cpu_fpr[DFPREG(rs2)]);
3938
                    tcg_gen_nor_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1) + 1],
3939
                                    cpu_fpr[DFPREG(rs2) + 1]);
3940
                    break;
3941
                case 0x063: /* VIS I fnors */
3942
                    CHECK_FPU_FEATURE(dc, VIS1);
3943
                    tcg_gen_nor_i32(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
3944
                    break;
3945
                case 0x064: /* VIS I fandnot2 */
3946
                    CHECK_FPU_FEATURE(dc, VIS1);
3947
                    tcg_gen_andc_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
3948
                                     cpu_fpr[DFPREG(rs2)]);
3949
                    tcg_gen_andc_i32(cpu_fpr[DFPREG(rd) + 1],
3950
                                     cpu_fpr[DFPREG(rs1) + 1],
3951
                                     cpu_fpr[DFPREG(rs2) + 1]);
3952
                    break;
3953
                case 0x065: /* VIS I fandnot2s */
3954
                    CHECK_FPU_FEATURE(dc, VIS1);
3955
                    tcg_gen_andc_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
3956
                    break;
3957
                case 0x066: /* VIS I fnot2 */
3958
                    CHECK_FPU_FEATURE(dc, VIS1);
3959
                    tcg_gen_not_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)]);
3960
                    tcg_gen_not_i32(cpu_fpr[DFPREG(rd) + 1],
3961
                                    cpu_fpr[DFPREG(rs2) + 1]);
3962
                    break;
3963
                case 0x067: /* VIS I fnot2s */
3964
                    CHECK_FPU_FEATURE(dc, VIS1);
3965
                    tcg_gen_not_i32(cpu_fpr[rd], cpu_fpr[rs2]);
3966
                    break;
3967
                case 0x068: /* VIS I fandnot1 */
3968
                    CHECK_FPU_FEATURE(dc, VIS1);
3969
                    tcg_gen_andc_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)],
3970
                                     cpu_fpr[DFPREG(rs1)]);
3971
                    tcg_gen_andc_i32(cpu_fpr[DFPREG(rd) + 1],
3972
                                     cpu_fpr[DFPREG(rs2) + 1],
3973
                                     cpu_fpr[DFPREG(rs1) + 1]);
3974
                    break;
3975
                case 0x069: /* VIS I fandnot1s */
3976
                    CHECK_FPU_FEATURE(dc, VIS1);
3977
                    tcg_gen_andc_i32(cpu_fpr[rd], cpu_fpr[rs2], cpu_fpr[rs1]);
3978
                    break;
3979
                case 0x06a: /* VIS I fnot1 */
3980
                    CHECK_FPU_FEATURE(dc, VIS1);
3981
                    tcg_gen_not_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)]);
3982
                    tcg_gen_not_i32(cpu_fpr[DFPREG(rd) + 1],
3983
                                    cpu_fpr[DFPREG(rs1) + 1]);
3984
                    break;
3985
                case 0x06b: /* VIS I fnot1s */
3986
                    CHECK_FPU_FEATURE(dc, VIS1);
3987
                    tcg_gen_not_i32(cpu_fpr[rd], cpu_fpr[rs1]);
3988
                    break;
3989
                case 0x06c: /* VIS I fxor */
3990
                    CHECK_FPU_FEATURE(dc, VIS1);
3991
                    tcg_gen_xor_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
3992
                                    cpu_fpr[DFPREG(rs2)]);
3993
                    tcg_gen_xor_i32(cpu_fpr[DFPREG(rd) + 1],
3994
                                    cpu_fpr[DFPREG(rs1) + 1],
3995
                                    cpu_fpr[DFPREG(rs2) + 1]);
3996
                    break;
3997
                case 0x06d: /* VIS I fxors */
3998
                    CHECK_FPU_FEATURE(dc, VIS1);
3999
                    tcg_gen_xor_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
4000
                    break;
4001
                case 0x06e: /* VIS I fnand */
4002
                    CHECK_FPU_FEATURE(dc, VIS1);
4003
                    tcg_gen_nand_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1)],
4004
                                     cpu_fpr[DFPREG(rs2)]);
4005
                    tcg_gen_nand_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1) + 1],
4006
                                     cpu_fpr[DFPREG(rs2) + 1]);
4007
                    break;
4008
                case 0x06f: /* VIS I fnands */
4009
                    CHECK_FPU_FEATURE(dc, VIS1);
4010
                    tcg_gen_nand_i32(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
4011
                    break;
4012
                case 0x070: /* VIS I fand */
4013
                    CHECK_FPU_FEATURE(dc, VIS1);
4014
                    tcg_gen_and_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
4015
                                    cpu_fpr[DFPREG(rs2)]);
4016
                    tcg_gen_and_i32(cpu_fpr[DFPREG(rd) + 1],
4017
                                    cpu_fpr[DFPREG(rs1) + 1],
4018
                                    cpu_fpr[DFPREG(rs2) + 1]);
4019
                    break;
4020
                case 0x071: /* VIS I fands */
4021
                    CHECK_FPU_FEATURE(dc, VIS1);
4022
                    tcg_gen_and_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
4023
                    break;
4024
                case 0x072: /* VIS I fxnor */
4025
                    CHECK_FPU_FEATURE(dc, VIS1);
4026
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs2)], -1);
4027
                    tcg_gen_xor_i32(cpu_fpr[DFPREG(rd)], cpu_tmp32,
4028
                                    cpu_fpr[DFPREG(rs1)]);
4029
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs2) + 1], -1);
4030
                    tcg_gen_xor_i32(cpu_fpr[DFPREG(rd) + 1], cpu_tmp32,
4031
                                    cpu_fpr[DFPREG(rs1) + 1]);
4032
                    break;
4033
                case 0x073: /* VIS I fxnors */
4034
                    CHECK_FPU_FEATURE(dc, VIS1);
4035
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[rs2], -1);
4036
                    tcg_gen_xor_i32(cpu_fpr[rd], cpu_tmp32, cpu_fpr[rs1]);
4037
                    break;
4038
                case 0x074: /* VIS I fsrc1 */
4039
                    CHECK_FPU_FEATURE(dc, VIS1);
4040
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)]);
4041
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1],
4042
                                    cpu_fpr[DFPREG(rs1) + 1]);
4043
                    break;
4044
                case 0x075: /* VIS I fsrc1s */
4045
                    CHECK_FPU_FEATURE(dc, VIS1);
4046
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs1]);
4047
                    break;
4048
                case 0x076: /* VIS I fornot2 */
4049
                    CHECK_FPU_FEATURE(dc, VIS1);
4050
                    tcg_gen_orc_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
4051
                                    cpu_fpr[DFPREG(rs2)]);
4052
                    tcg_gen_orc_i32(cpu_fpr[DFPREG(rd) + 1],
4053
                                    cpu_fpr[DFPREG(rs1) + 1],
4054
                                    cpu_fpr[DFPREG(rs2) + 1]);
4055
                    break;
4056
                case 0x077: /* VIS I fornot2s */
4057
                    CHECK_FPU_FEATURE(dc, VIS1);
4058
                    tcg_gen_orc_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
4059
                    break;
4060
                case 0x078: /* VIS I fsrc2 */
4061
                    CHECK_FPU_FEATURE(dc, VIS1);
4062
                    gen_op_load_fpr_DT0(DFPREG(rs2));
4063
                    gen_op_store_DT0_fpr(DFPREG(rd));
4064
                    break;
4065
                case 0x079: /* VIS I fsrc2s */
4066
                    CHECK_FPU_FEATURE(dc, VIS1);
4067
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);
4068
                    break;
4069
                case 0x07a: /* VIS I fornot1 */
4070
                    CHECK_FPU_FEATURE(dc, VIS1);
4071
                    tcg_gen_orc_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)],
4072
                                    cpu_fpr[DFPREG(rs1)]);
4073
                    tcg_gen_orc_i32(cpu_fpr[DFPREG(rd) + 1],
4074
                                    cpu_fpr[DFPREG(rs2) + 1],
4075
                                    cpu_fpr[DFPREG(rs1) + 1]);
4076
                    break;
4077
                case 0x07b: /* VIS I fornot1s */
4078
                    CHECK_FPU_FEATURE(dc, VIS1);
4079
                    tcg_gen_orc_i32(cpu_fpr[rd], cpu_fpr[rs2], cpu_fpr[rs1]);
4080
                    break;
4081
                case 0x07c: /* VIS I for */
4082
                    CHECK_FPU_FEATURE(dc, VIS1);
4083
                    tcg_gen_or_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
4084
                                   cpu_fpr[DFPREG(rs2)]);
4085
                    tcg_gen_or_i32(cpu_fpr[DFPREG(rd) + 1],
4086
                                   cpu_fpr[DFPREG(rs1) + 1],
4087
                                   cpu_fpr[DFPREG(rs2) + 1]);
4088
                    break;
4089
                case 0x07d: /* VIS I fors */
4090
                    CHECK_FPU_FEATURE(dc, VIS1);
4091
                    tcg_gen_or_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
4092
                    break;
4093
                case 0x07e: /* VIS I fone */
4094
                    CHECK_FPU_FEATURE(dc, VIS1);
4095
                    tcg_gen_movi_i32(cpu_fpr[DFPREG(rd)], -1);
4096
                    tcg_gen_movi_i32(cpu_fpr[DFPREG(rd) + 1], -1);
4097
                    break;
4098
                case 0x07f: /* VIS I fones */
4099
                    CHECK_FPU_FEATURE(dc, VIS1);
4100
                    tcg_gen_movi_i32(cpu_fpr[rd], -1);
4101
                    break;
4102
                case 0x080: /* VIS I shutdown */
4103
                case 0x081: /* VIS II siam */
4104
                    // XXX
4105
                    goto illegal_insn;
4106
                default:
4107
                    goto illegal_insn;
4108
                }
4109
#else
4110
                goto ncp_insn;
4111
#endif
4112
            } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
4113
#ifdef TARGET_SPARC64
4114
                goto illegal_insn;
4115
#else
4116
                goto ncp_insn;
4117
#endif
4118
#ifdef TARGET_SPARC64
4119
            } else if (xop == 0x39) { /* V9 return */
4120
                TCGv_i32 r_const;
4121

    
4122
                save_state(dc, cpu_cond);
4123
                cpu_src1 = get_src1(insn, cpu_src1);
4124
                if (IS_IMM) {   /* immediate */
4125
                    simm = GET_FIELDs(insn, 19, 31);
4126
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, simm);
4127
                } else {                /* register */
4128
                    rs2 = GET_FIELD(insn, 27, 31);
4129
                    if (rs2) {
4130
                        gen_movl_reg_TN(rs2, cpu_src2);
4131
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
4132
                    } else
4133
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
4134
                }
4135
                gen_helper_restore();
4136
                gen_mov_pc_npc(dc, cpu_cond);
4137
                r_const = tcg_const_i32(3);
4138
                gen_helper_check_align(cpu_dst, r_const);
4139
                tcg_temp_free_i32(r_const);
4140
                tcg_gen_mov_tl(cpu_npc, cpu_dst);
4141
                dc->npc = DYNAMIC_PC;
4142
                goto jmp_insn;
4143
#endif
4144
            } else {
4145
                cpu_src1 = get_src1(insn, cpu_src1);
4146
                if (IS_IMM) {   /* immediate */
4147
                    simm = GET_FIELDs(insn, 19, 31);
4148
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, simm);
4149
                } else {                /* register */
4150
                    rs2 = GET_FIELD(insn, 27, 31);
4151
                    if (rs2) {
4152
                        gen_movl_reg_TN(rs2, cpu_src2);
4153
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
4154
                    } else
4155
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
4156
                }
4157
                switch (xop) {
4158
                case 0x38:      /* jmpl */
4159
                    {
4160
                        TCGv r_pc;
4161
                        TCGv_i32 r_const;
4162

    
4163
                        r_pc = tcg_const_tl(dc->pc);
4164
                        gen_movl_TN_reg(rd, r_pc);
4165
                        tcg_temp_free(r_pc);
4166
                        gen_mov_pc_npc(dc, cpu_cond);
4167
                        r_const = tcg_const_i32(3);
4168
                        gen_helper_check_align(cpu_dst, r_const);
4169
                        tcg_temp_free_i32(r_const);
4170
                        tcg_gen_mov_tl(cpu_npc, cpu_dst);
4171
                        dc->npc = DYNAMIC_PC;
4172
                    }
4173
                    goto jmp_insn;
4174
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
4175
                case 0x39:      /* rett, V9 return */
4176
                    {
4177
                        TCGv_i32 r_const;
4178

    
4179
                        if (!supervisor(dc))
4180
                            goto priv_insn;
4181
                        gen_mov_pc_npc(dc, cpu_cond);
4182
                        r_const = tcg_const_i32(3);
4183
                        gen_helper_check_align(cpu_dst, r_const);
4184
                        tcg_temp_free_i32(r_const);
4185
                        tcg_gen_mov_tl(cpu_npc, cpu_dst);
4186
                        dc->npc = DYNAMIC_PC;
4187
                        gen_helper_rett();
4188
                    }
4189
                    goto jmp_insn;
4190
#endif
4191
                case 0x3b: /* flush */
4192
                    if (!((dc)->def->features & CPU_FEATURE_FLUSH))
4193
                        goto unimp_flush;
4194
                    gen_helper_flush(cpu_dst);
4195
                    break;
4196
                case 0x3c:      /* save */
4197
                    save_state(dc, cpu_cond);
4198
                    gen_helper_save();
4199
                    gen_movl_TN_reg(rd, cpu_dst);
4200
                    break;
4201
                case 0x3d:      /* restore */
4202
                    save_state(dc, cpu_cond);
4203
                    gen_helper_restore();
4204
                    gen_movl_TN_reg(rd, cpu_dst);
4205
                    break;
4206
#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
4207
                case 0x3e:      /* V9 done/retry */
4208
                    {
4209
                        switch (rd) {
4210
                        case 0:
4211
                            if (!supervisor(dc))
4212
                                goto priv_insn;
4213
                            dc->npc = DYNAMIC_PC;
4214
                            dc->pc = DYNAMIC_PC;
4215
                            gen_helper_done();
4216
                            goto jmp_insn;
4217
                        case 1:
4218
                            if (!supervisor(dc))
4219
                                goto priv_insn;
4220
                            dc->npc = DYNAMIC_PC;
4221
                            dc->pc = DYNAMIC_PC;
4222
                            gen_helper_retry();
4223
                            goto jmp_insn;
4224
                        default:
4225
                            goto illegal_insn;
4226
                        }
4227
                    }
4228
                    break;
4229
#endif
4230
                default:
4231
                    goto illegal_insn;
4232
                }
4233
            }
4234
            break;
4235
        }
4236
        break;
4237
    case 3:                     /* load/store instructions */
4238
        {
4239
            unsigned int xop = GET_FIELD(insn, 7, 12);
4240

    
4241
            /* flush pending conditional evaluations before exposing
4242
               cpu state */
4243
            if (dc->cc_op != CC_OP_FLAGS) {
4244
                dc->cc_op = CC_OP_FLAGS;
4245
                gen_helper_compute_psr();
4246
            }
4247
            cpu_src1 = get_src1(insn, cpu_src1);
4248
            if (xop == 0x3c || xop == 0x3e) { // V9 casa/casxa
4249
                rs2 = GET_FIELD(insn, 27, 31);
4250
                gen_movl_reg_TN(rs2, cpu_src2);
4251
                tcg_gen_mov_tl(cpu_addr, cpu_src1);
4252
            } else if (IS_IMM) {     /* immediate */
4253
                simm = GET_FIELDs(insn, 19, 31);
4254
                tcg_gen_addi_tl(cpu_addr, cpu_src1, simm);
4255
            } else {            /* register */
4256
                rs2 = GET_FIELD(insn, 27, 31);
4257
                if (rs2 != 0) {
4258
                    gen_movl_reg_TN(rs2, cpu_src2);
4259
                    tcg_gen_add_tl(cpu_addr, cpu_src1, cpu_src2);
4260
                } else
4261
                    tcg_gen_mov_tl(cpu_addr, cpu_src1);
4262
            }
4263
            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
4264
                (xop > 0x17 && xop <= 0x1d ) ||
4265
                (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
4266
                switch (xop) {
4267
                case 0x0:       /* ld, V9 lduw, load unsigned word */
4268
                    gen_address_mask(dc, cpu_addr);
4269
                    tcg_gen_qemu_ld32u(cpu_val, cpu_addr, dc->mem_idx);
4270
                    break;
4271
                case 0x1:       /* ldub, load unsigned byte */
4272
                    gen_address_mask(dc, cpu_addr);
4273
                    tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx);
4274
                    break;
4275
                case 0x2:       /* lduh, load unsigned halfword */
4276
                    gen_address_mask(dc, cpu_addr);
4277
                    tcg_gen_qemu_ld16u(cpu_val, cpu_addr, dc->mem_idx);
4278
                    break;
4279
                case 0x3:       /* ldd, load double word */
4280
                    if (rd & 1)
4281
                        goto illegal_insn;
4282
                    else {
4283
                        TCGv_i32 r_const;
4284

    
4285
                        save_state(dc, cpu_cond);
4286
                        r_const = tcg_const_i32(7);
4287
                        gen_helper_check_align(cpu_addr, r_const); // XXX remove
4288
                        tcg_temp_free_i32(r_const);
4289
                        gen_address_mask(dc, cpu_addr);
4290
                        tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
4291
                        tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
4292
                        tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffffULL);
4293
                        gen_movl_TN_reg(rd + 1, cpu_tmp0);
4294
                        tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
4295
                        tcg_gen_trunc_i64_tl(cpu_val, cpu_tmp64);
4296
                        tcg_gen_andi_tl(cpu_val, cpu_val, 0xffffffffULL);
4297
                    }
4298
                    break;
4299
                case 0x9:       /* ldsb, load signed byte */
4300
                    gen_address_mask(dc, cpu_addr);
4301
                    tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
4302
                    break;
4303
                case 0xa:       /* ldsh, load signed halfword */
4304
                    gen_address_mask(dc, cpu_addr);
4305
                    tcg_gen_qemu_ld16s(cpu_val, cpu_addr, dc->mem_idx);
4306
                    break;
4307
                case 0xd:       /* ldstub -- XXX: should be atomically */
4308
                    {
4309
                        TCGv r_const;
4310

    
4311
                        gen_address_mask(dc, cpu_addr);
4312
                        tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
4313
                        r_const = tcg_const_tl(0xff);
4314
                        tcg_gen_qemu_st8(r_const, cpu_addr, dc->mem_idx);
4315
                        tcg_temp_free(r_const);
4316
                    }
4317
                    break;
4318
                case 0x0f:      /* swap, swap register with memory. Also
4319
                                   atomically */
4320
                    CHECK_IU_FEATURE(dc, SWAP);
4321
                    gen_movl_reg_TN(rd, cpu_val);
4322
                    gen_address_mask(dc, cpu_addr);
4323
                    tcg_gen_qemu_ld32u(cpu_tmp0, cpu_addr, dc->mem_idx);
4324
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
4325
                    tcg_gen_mov_tl(cpu_val, cpu_tmp0);
4326
                    break;
4327
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4328
                case 0x10:      /* lda, V9 lduwa, load word alternate */
4329
#ifndef TARGET_SPARC64
4330
                    if (IS_IMM)
4331
                        goto illegal_insn;
4332
                    if (!supervisor(dc))
4333
                        goto priv_insn;
4334
#endif
4335
                    save_state(dc, cpu_cond);
4336
                    gen_ld_asi(cpu_val, cpu_addr, insn, 4, 0);
4337
                    break;
4338
                case 0x11:      /* lduba, load unsigned byte alternate */
4339
#ifndef TARGET_SPARC64
4340
                    if (IS_IMM)
4341
                        goto illegal_insn;
4342
                    if (!supervisor(dc))
4343
                        goto priv_insn;
4344
#endif
4345
                    save_state(dc, cpu_cond);
4346
                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 0);
4347
                    break;
4348
                case 0x12:      /* lduha, load unsigned halfword alternate */
4349
#ifndef TARGET_SPARC64
4350
                    if (IS_IMM)
4351
                        goto illegal_insn;
4352
                    if (!supervisor(dc))
4353
                        goto priv_insn;
4354
#endif
4355
                    save_state(dc, cpu_cond);
4356
                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 0);
4357
                    break;
4358
                case 0x13:      /* ldda, load double word alternate */
4359
#ifndef TARGET_SPARC64
4360
                    if (IS_IMM)
4361
                        goto illegal_insn;
4362
                    if (!supervisor(dc))
4363
                        goto priv_insn;
4364
#endif
4365
                    if (rd & 1)
4366
                        goto illegal_insn;
4367
                    save_state(dc, cpu_cond);
4368
                    gen_ldda_asi(cpu_val, cpu_addr, insn, rd);
4369
                    goto skip_move;
4370
                case 0x19:      /* ldsba, load signed byte alternate */
4371
#ifndef TARGET_SPARC64
4372
                    if (IS_IMM)
4373
                        goto illegal_insn;
4374
                    if (!supervisor(dc))
4375
                        goto priv_insn;
4376
#endif
4377
                    save_state(dc, cpu_cond);
4378
                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 1);
4379
                    break;
4380
                case 0x1a:      /* ldsha, load signed halfword alternate */
4381
#ifndef TARGET_SPARC64
4382
                    if (IS_IMM)
4383
                        goto illegal_insn;
4384
                    if (!supervisor(dc))
4385
                        goto priv_insn;
4386
#endif
4387
                    save_state(dc, cpu_cond);
4388
                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 1);
4389
                    break;
4390
                case 0x1d:      /* ldstuba -- XXX: should be atomically */
4391
#ifndef TARGET_SPARC64
4392
                    if (IS_IMM)
4393
                        goto illegal_insn;
4394
                    if (!supervisor(dc))
4395
                        goto priv_insn;
4396
#endif
4397
                    save_state(dc, cpu_cond);
4398
                    gen_ldstub_asi(cpu_val, cpu_addr, insn);
4399
                    break;
4400
                case 0x1f:      /* swapa, swap reg with alt. memory. Also
4401
                                   atomically */
4402
                    CHECK_IU_FEATURE(dc, SWAP);
4403
#ifndef TARGET_SPARC64
4404
                    if (IS_IMM)
4405
                        goto illegal_insn;
4406
                    if (!supervisor(dc))
4407
                        goto priv_insn;
4408
#endif
4409
                    save_state(dc, cpu_cond);
4410
                    gen_movl_reg_TN(rd, cpu_val);
4411
                    gen_swap_asi(cpu_val, cpu_addr, insn);
4412
                    break;
4413

    
4414
#ifndef TARGET_SPARC64
4415
                case 0x30: /* ldc */
4416
                case 0x31: /* ldcsr */
4417
                case 0x33: /* lddc */
4418
                    goto ncp_insn;
4419
#endif
4420
#endif
4421
#ifdef TARGET_SPARC64
4422
                case 0x08: /* V9 ldsw */
4423
                    gen_address_mask(dc, cpu_addr);
4424
                    tcg_gen_qemu_ld32s(cpu_val, cpu_addr, dc->mem_idx);
4425
                    break;
4426
                case 0x0b: /* V9 ldx */
4427
                    gen_address_mask(dc, cpu_addr);
4428
                    tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx);
4429
                    break;
4430
                case 0x18: /* V9 ldswa */
4431
                    save_state(dc, cpu_cond);
4432
                    gen_ld_asi(cpu_val, cpu_addr, insn, 4, 1);
4433
                    break;
4434
                case 0x1b: /* V9 ldxa */
4435
                    save_state(dc, cpu_cond);
4436
                    gen_ld_asi(cpu_val, cpu_addr, insn, 8, 0);
4437
                    break;
4438
                case 0x2d: /* V9 prefetch, no effect */
4439
                    goto skip_move;
4440
                case 0x30: /* V9 ldfa */
4441
                    save_state(dc, cpu_cond);
4442
                    gen_ldf_asi(cpu_addr, insn, 4, rd);
4443
                    goto skip_move;
4444
                case 0x33: /* V9 lddfa */
4445
                    save_state(dc, cpu_cond);
4446
                    gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd));
4447
                    goto skip_move;
4448
                case 0x3d: /* V9 prefetcha, no effect */
4449
                    goto skip_move;
4450
                case 0x32: /* V9 ldqfa */
4451
                    CHECK_FPU_FEATURE(dc, FLOAT128);
4452
                    save_state(dc, cpu_cond);
4453
                    gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd));
4454
                    goto skip_move;
4455
#endif
4456
                default:
4457
                    goto illegal_insn;
4458
                }
4459
                gen_movl_TN_reg(rd, cpu_val);
4460
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4461
            skip_move: ;
4462
#endif
4463
            } else if (xop >= 0x20 && xop < 0x24) {
4464
                if (gen_trap_ifnofpu(dc, cpu_cond))
4465
                    goto jmp_insn;
4466
                save_state(dc, cpu_cond);
4467
                switch (xop) {
4468
                case 0x20:      /* ldf, load fpreg */
4469
                    gen_address_mask(dc, cpu_addr);
4470
                    tcg_gen_qemu_ld32u(cpu_tmp0, cpu_addr, dc->mem_idx);
4471
                    tcg_gen_trunc_tl_i32(cpu_fpr[rd], cpu_tmp0);
4472
                    break;
4473
                case 0x21:      /* ldfsr, V9 ldxfsr */
4474
#ifdef TARGET_SPARC64
4475
                    gen_address_mask(dc, cpu_addr);
4476
                    if (rd == 1) {
4477
                        tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
4478
                        gen_helper_ldxfsr(cpu_tmp64);
4479
                    } else {
4480
                        tcg_gen_qemu_ld32u(cpu_tmp0, cpu_addr, dc->mem_idx);
4481
                        tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
4482
                        gen_helper_ldfsr(cpu_tmp32);
4483
                    }
4484
#else
4485
                    {
4486
                        tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
4487
                        gen_helper_ldfsr(cpu_tmp32);
4488
                    }
4489
#endif
4490
                    break;
4491
                case 0x22:      /* ldqf, load quad fpreg */
4492
                    {
4493
                        TCGv_i32 r_const;
4494

    
4495
                        CHECK_FPU_FEATURE(dc, FLOAT128);
4496
                        r_const = tcg_const_i32(dc->mem_idx);
4497
                        gen_address_mask(dc, cpu_addr);
4498
                        gen_helper_ldqf(cpu_addr, r_const);
4499
                        tcg_temp_free_i32(r_const);
4500
                        gen_op_store_QT0_fpr(QFPREG(rd));
4501
                    }
4502
                    break;
4503
                case 0x23:      /* lddf, load double fpreg */
4504
                    {
4505
                        TCGv_i32 r_const;
4506

    
4507
                        r_const = tcg_const_i32(dc->mem_idx);
4508
                        gen_address_mask(dc, cpu_addr);
4509
                        gen_helper_lddf(cpu_addr, r_const);
4510
                        tcg_temp_free_i32(r_const);
4511
                        gen_op_store_DT0_fpr(DFPREG(rd));
4512
                    }
4513
                    break;
4514
                default:
4515
                    goto illegal_insn;
4516
                }
4517
            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) ||
4518
                       xop == 0xe || xop == 0x1e) {
4519
                gen_movl_reg_TN(rd, cpu_val);
4520
                switch (xop) {
4521
                case 0x4: /* st, store word */
4522
                    gen_address_mask(dc, cpu_addr);
4523
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
4524
                    break;
4525
                case 0x5: /* stb, store byte */
4526
                    gen_address_mask(dc, cpu_addr);
4527
                    tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx);
4528
                    break;
4529
                case 0x6: /* sth, store halfword */
4530
                    gen_address_mask(dc, cpu_addr);
4531
                    tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx);
4532
                    break;
4533
                case 0x7: /* std, store double word */
4534
                    if (rd & 1)
4535
                        goto illegal_insn;
4536
                    else {
4537
                        TCGv_i32 r_const;
4538

    
4539
                        save_state(dc, cpu_cond);
4540
                        gen_address_mask(dc, cpu_addr);
4541
                        r_const = tcg_const_i32(7);
4542
                        gen_helper_check_align(cpu_addr, r_const); // XXX remove
4543
                        tcg_temp_free_i32(r_const);
4544
                        gen_movl_reg_TN(rd + 1, cpu_tmp0);
4545
                        tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, cpu_val);
4546
                        tcg_gen_qemu_st64(cpu_tmp64, cpu_addr, dc->mem_idx);
4547
                    }
4548
                    break;
4549
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4550
                case 0x14: /* sta, V9 stwa, store word alternate */
4551
#ifndef TARGET_SPARC64
4552
                    if (IS_IMM)
4553
                        goto illegal_insn;
4554
                    if (!supervisor(dc))
4555
                        goto priv_insn;
4556
#endif
4557
                    save_state(dc, cpu_cond);
4558
                    gen_st_asi(cpu_val, cpu_addr, insn, 4);
4559
                    dc->npc = DYNAMIC_PC;
4560
                    break;
4561
                case 0x15: /* stba, store byte alternate */
4562
#ifndef TARGET_SPARC64
4563
                    if (IS_IMM)
4564
                        goto illegal_insn;
4565
                    if (!supervisor(dc))
4566
                        goto priv_insn;
4567
#endif
4568
                    save_state(dc, cpu_cond);
4569
                    gen_st_asi(cpu_val, cpu_addr, insn, 1);
4570
                    dc->npc = DYNAMIC_PC;
4571
                    break;
4572
                case 0x16: /* stha, store halfword alternate */
4573
#ifndef TARGET_SPARC64
4574
                    if (IS_IMM)
4575
                        goto illegal_insn;
4576
                    if (!supervisor(dc))
4577
                        goto priv_insn;
4578
#endif
4579
                    save_state(dc, cpu_cond);
4580
                    gen_st_asi(cpu_val, cpu_addr, insn, 2);
4581
                    dc->npc = DYNAMIC_PC;
4582
                    break;
4583
                case 0x17: /* stda, store double word alternate */
4584
#ifndef TARGET_SPARC64
4585
                    if (IS_IMM)
4586
                        goto illegal_insn;
4587
                    if (!supervisor(dc))
4588
                        goto priv_insn;
4589
#endif
4590
                    if (rd & 1)
4591
                        goto illegal_insn;
4592
                    else {
4593
                        save_state(dc, cpu_cond);
4594
                        gen_stda_asi(cpu_val, cpu_addr, insn, rd);
4595
                    }
4596
                    break;
4597
#endif
4598
#ifdef TARGET_SPARC64
4599
                case 0x0e: /* V9 stx */
4600
                    gen_address_mask(dc, cpu_addr);
4601
                    tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx);
4602
                    break;
4603
                case 0x1e: /* V9 stxa */
4604
                    save_state(dc, cpu_cond);
4605
                    gen_st_asi(cpu_val, cpu_addr, insn, 8);
4606
                    dc->npc = DYNAMIC_PC;
4607
                    break;
4608
#endif
4609
                default:
4610
                    goto illegal_insn;
4611
                }
4612
            } else if (xop > 0x23 && xop < 0x28) {
4613
                if (gen_trap_ifnofpu(dc, cpu_cond))
4614
                    goto jmp_insn;
4615
                save_state(dc, cpu_cond);
4616
                switch (xop) {
4617
                case 0x24: /* stf, store fpreg */
4618
                    gen_address_mask(dc, cpu_addr);
4619
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_fpr[rd]);
4620
                    tcg_gen_qemu_st32(cpu_tmp0, cpu_addr, dc->mem_idx);
4621
                    break;
4622
                case 0x25: /* stfsr, V9 stxfsr */
4623
#ifdef TARGET_SPARC64
4624
                    gen_address_mask(dc, cpu_addr);
4625
                    tcg_gen_ld_i64(cpu_tmp64, cpu_env, offsetof(CPUState, fsr));
4626
                    if (rd == 1)
4627
                        tcg_gen_qemu_st64(cpu_tmp64, cpu_addr, dc->mem_idx);
4628
                    else
4629
                        tcg_gen_qemu_st32(cpu_tmp64, cpu_addr, dc->mem_idx);
4630
#else
4631
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUState, fsr));
4632
                    tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx);
4633
#endif
4634
                    break;
4635
                case 0x26:
4636
#ifdef TARGET_SPARC64
4637
                    /* V9 stqf, store quad fpreg */
4638
                    {
4639
                        TCGv_i32 r_const;
4640

    
4641
                        CHECK_FPU_FEATURE(dc, FLOAT128);
4642
                        gen_op_load_fpr_QT0(QFPREG(rd));
4643
                        r_const = tcg_const_i32(dc->mem_idx);
4644
                        gen_address_mask(dc, cpu_addr);
4645
                        gen_helper_stqf(cpu_addr, r_const);
4646
                        tcg_temp_free_i32(r_const);
4647
                    }
4648
                    break;
4649
#else /* !TARGET_SPARC64 */
4650
                    /* stdfq, store floating point queue */
4651
#if defined(CONFIG_USER_ONLY)
4652
                    goto illegal_insn;
4653
#else
4654
                    if (!supervisor(dc))
4655
                        goto priv_insn;
4656
                    if (gen_trap_ifnofpu(dc, cpu_cond))
4657
                        goto jmp_insn;
4658
                    goto nfq_insn;
4659
#endif
4660
#endif
4661
                case 0x27: /* stdf, store double fpreg */
4662
                    {
4663
                        TCGv_i32 r_const;
4664

    
4665
                        gen_op_load_fpr_DT0(DFPREG(rd));
4666
                        r_const = tcg_const_i32(dc->mem_idx);
4667
                        gen_address_mask(dc, cpu_addr);
4668
                        gen_helper_stdf(cpu_addr, r_const);
4669
                        tcg_temp_free_i32(r_const);
4670
                    }
4671
                    break;
4672
                default:
4673
                    goto illegal_insn;
4674
                }
4675
            } else if (xop > 0x33 && xop < 0x3f) {
4676
                save_state(dc, cpu_cond);
4677
                switch (xop) {
4678
#ifdef TARGET_SPARC64
4679
                case 0x34: /* V9 stfa */
4680
                    gen_stf_asi(cpu_addr, insn, 4, rd);
4681
                    break;
4682
                case 0x36: /* V9 stqfa */
4683
                    {
4684
                        TCGv_i32 r_const;
4685

    
4686
                        CHECK_FPU_FEATURE(dc, FLOAT128);
4687
                        r_const = tcg_const_i32(7);
4688
                        gen_helper_check_align(cpu_addr, r_const);
4689
                        tcg_temp_free_i32(r_const);
4690
                        gen_op_load_fpr_QT0(QFPREG(rd));
4691
                        gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd));
4692
                    }
4693
                    break;
4694
                case 0x37: /* V9 stdfa */
4695
                    gen_op_load_fpr_DT0(DFPREG(rd));
4696
                    gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
4697
                    break;
4698
                case 0x3c: /* V9 casa */
4699
                    gen_cas_asi(cpu_val, cpu_addr, cpu_src2, insn, rd);
4700
                    gen_movl_TN_reg(rd, cpu_val);
4701
                    break;
4702
                case 0x3e: /* V9 casxa */
4703
                    gen_casx_asi(cpu_val, cpu_addr, cpu_src2, insn, rd);
4704
                    gen_movl_TN_reg(rd, cpu_val);
4705
                    break;
4706
#else
4707
                case 0x34: /* stc */
4708
                case 0x35: /* stcsr */
4709
                case 0x36: /* stdcq */
4710
                case 0x37: /* stdc */
4711
                    goto ncp_insn;
4712
#endif
4713
                default:
4714
                    goto illegal_insn;
4715
                }
4716
            } else
4717
                goto illegal_insn;
4718
        }
4719
        break;
4720
    }
4721
    /* default case for non jump instructions */
4722
    if (dc->npc == DYNAMIC_PC) {
4723
        dc->pc = DYNAMIC_PC;
4724
        gen_op_next_insn();
4725
    } else if (dc->npc == JUMP_PC) {
4726
        /* we can do a static jump */
4727
        gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
4728
        dc->is_br = 1;
4729
    } else {
4730
        dc->pc = dc->npc;
4731
        dc->npc = dc->npc + 4;
4732
    }
4733
 jmp_insn:
4734
    goto egress;
4735
 illegal_insn:
4736
    {
4737
        TCGv_i32 r_const;
4738

    
4739
        save_state(dc, cpu_cond);
4740
        r_const = tcg_const_i32(TT_ILL_INSN);
4741
        gen_helper_raise_exception(r_const);
4742
        tcg_temp_free_i32(r_const);
4743
        dc->is_br = 1;
4744
    }
4745
    goto egress;
4746
 unimp_flush:
4747
    {
4748
        TCGv_i32 r_const;
4749

    
4750
        save_state(dc, cpu_cond);
4751
        r_const = tcg_const_i32(TT_UNIMP_FLUSH);
4752
        gen_helper_raise_exception(r_const);
4753
        tcg_temp_free_i32(r_const);
4754
        dc->is_br = 1;
4755
    }
4756
    goto egress;
4757
#if !defined(CONFIG_USER_ONLY)
4758
 priv_insn:
4759
    {
4760
        TCGv_i32 r_const;
4761

    
4762
        save_state(dc, cpu_cond);
4763
        r_const = tcg_const_i32(TT_PRIV_INSN);
4764
        gen_helper_raise_exception(r_const);
4765
        tcg_temp_free_i32(r_const);
4766
        dc->is_br = 1;
4767
    }
4768
    goto egress;
4769
#endif
4770
 nfpu_insn:
4771
    save_state(dc, cpu_cond);
4772
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
4773
    dc->is_br = 1;
4774
    goto egress;
4775
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
4776
 nfq_insn:
4777
    save_state(dc, cpu_cond);
4778
    gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
4779
    dc->is_br = 1;
4780
    goto egress;
4781
#endif
4782
#ifndef TARGET_SPARC64
4783
 ncp_insn:
4784
    {
4785
        TCGv r_const;
4786

    
4787
        save_state(dc, cpu_cond);
4788
        r_const = tcg_const_i32(TT_NCP_INSN);
4789
        gen_helper_raise_exception(r_const);
4790
        tcg_temp_free(r_const);
4791
        dc->is_br = 1;
4792
    }
4793
    goto egress;
4794
#endif
4795
 egress:
4796
    tcg_temp_free(cpu_tmp1);
4797
    tcg_temp_free(cpu_tmp2);
4798
}
4799

    
4800
static inline void gen_intermediate_code_internal(TranslationBlock * tb,
4801
                                                  int spc, CPUSPARCState *env)
4802
{
4803
    target_ulong pc_start, last_pc;
4804
    uint16_t *gen_opc_end;
4805
    DisasContext dc1, *dc = &dc1;
4806
    CPUBreakpoint *bp;
4807
    int j, lj = -1;
4808
    int num_insns;
4809
    int max_insns;
4810

    
4811
    memset(dc, 0, sizeof(DisasContext));
4812
    dc->tb = tb;
4813
    pc_start = tb->pc;
4814
    dc->pc = pc_start;
4815
    last_pc = dc->pc;
4816
    dc->npc = (target_ulong) tb->cs_base;
4817
    dc->cc_op = CC_OP_DYNAMIC;
4818
    dc->mem_idx = cpu_mmu_index(env);
4819
    dc->def = env->def;
4820
    if ((dc->def->features & CPU_FEATURE_FLOAT))
4821
        dc->fpu_enabled = cpu_fpu_enabled(env);
4822
    else
4823
        dc->fpu_enabled = 0;
4824
#ifdef TARGET_SPARC64
4825
    dc->address_mask_32bit = env->pstate & PS_AM;
4826
#endif
4827
    dc->singlestep = (env->singlestep_enabled || singlestep);
4828
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4829

    
4830
    cpu_tmp0 = tcg_temp_new();
4831
    cpu_tmp32 = tcg_temp_new_i32();
4832
    cpu_tmp64 = tcg_temp_new_i64();
4833

    
4834
    cpu_dst = tcg_temp_local_new();
4835

    
4836
    // loads and stores
4837
    cpu_val = tcg_temp_local_new();
4838
    cpu_addr = tcg_temp_local_new();
4839

    
4840
    num_insns = 0;
4841
    max_insns = tb->cflags & CF_COUNT_MASK;
4842
    if (max_insns == 0)
4843
        max_insns = CF_COUNT_MASK;
4844
    gen_icount_start();
4845
    do {
4846
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
4847
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
4848
                if (bp->pc == dc->pc) {
4849
                    if (dc->pc != pc_start)
4850
                        save_state(dc, cpu_cond);
4851
                    gen_helper_debug();
4852
                    tcg_gen_exit_tb(0);
4853
                    dc->is_br = 1;
4854
                    goto exit_gen_loop;
4855
                }
4856
            }
4857
        }
4858
        if (spc) {
4859
            qemu_log("Search PC...\n");
4860
            j = gen_opc_ptr - gen_opc_buf;
4861
            if (lj < j) {
4862
                lj++;
4863
                while (lj < j)
4864
                    gen_opc_instr_start[lj++] = 0;
4865
                gen_opc_pc[lj] = dc->pc;
4866
                gen_opc_npc[lj] = dc->npc;
4867
                gen_opc_instr_start[lj] = 1;
4868
                gen_opc_icount[lj] = num_insns;
4869
            }
4870
        }
4871
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
4872
            gen_io_start();
4873
        last_pc = dc->pc;
4874
        disas_sparc_insn(dc);
4875
        num_insns++;
4876

    
4877
        if (dc->is_br)
4878
            break;
4879
        /* if the next PC is different, we abort now */
4880
        if (dc->pc != (last_pc + 4))
4881
            break;
4882