Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ 25517f99

History | View | Annotate | Download (186.8 kB)

1
/*
2
   SPARC translation
3

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

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

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

17
   You should have received a copy of the GNU Lesser General Public
18
   License along with this library; if not, write to the Free Software
19
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
20
 */
21

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

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

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

    
37
#define DEBUG_DISAS
38

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

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

    
70
#include "gen-icount.h"
71

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

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

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

    
93
#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
94
#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
95

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

    
104
#define UA2005_HTRAP_MASK 0xff
105
#define V8_TRAP_MASK 0x7f
106

    
107
static int sign_extend(int x, int len)
108
{
109
    len = 32 - len;
110
    return (x << len) >> len;
111
}
112

    
113
#define IS_IMM (insn & (1<<13))
114

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

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

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

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

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

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

    
176
/* moves */
177
#ifdef CONFIG_USER_ONLY
178
#define supervisor(dc) 0
179
#ifdef TARGET_SPARC64
180
#define hypervisor(dc) 0
181
#endif
182
#else
183
#define supervisor(dc) (dc->mem_idx >= 1)
184
#ifdef TARGET_SPARC64
185
#define hypervisor(dc) (dc->mem_idx == 2)
186
#else
187
#endif
188
#endif
189

    
190
#ifdef TARGET_SPARC64
191
#ifndef TARGET_ABI32
192
#define AM_CHECK(dc) ((dc)->address_mask_32bit)
193
#else
194
#define AM_CHECK(dc) (1)
195
#endif
196
#endif
197

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

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

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

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

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

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

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

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

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

    
278
static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
279
{
280
    TCGv r_temp;
281
    TCGv_i32 r_const;
282
    int l1;
283

    
284
    l1 = gen_new_label();
285

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

    
300
static inline void gen_tag_tv(TCGv src1, TCGv src2)
301
{
302
    int l1;
303
    TCGv_i32 r_const;
304

    
305
    l1 = gen_new_label();
306
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
307
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
308
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
309
    r_const = tcg_const_i32(TT_TOVF);
310
    gen_helper_raise_exception(r_const);
311
    tcg_temp_free_i32(r_const);
312
    gen_set_label(l1);
313
}
314

    
315
static inline void gen_op_addi_cc(TCGv dst, TCGv src1, target_long src2)
316
{
317
    tcg_gen_mov_tl(cpu_cc_src, src1);
318
    tcg_gen_movi_tl(cpu_cc_src2, src2);
319
    tcg_gen_addi_tl(cpu_cc_dst, cpu_cc_src, src2);
320
    tcg_gen_mov_tl(dst, cpu_cc_dst);
321
}
322

    
323
static inline void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2)
324
{
325
    tcg_gen_mov_tl(cpu_cc_src, src1);
326
    tcg_gen_mov_tl(cpu_cc_src2, src2);
327
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
328
    tcg_gen_mov_tl(dst, cpu_cc_dst);
329
}
330

    
331
static inline void gen_op_addxi_cc(TCGv dst, TCGv src1, target_long src2)
332
{
333
    tcg_gen_mov_tl(cpu_cc_src, src1);
334
    tcg_gen_movi_tl(cpu_cc_src2, src2);
335
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
336
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_tmp0);
337
    tcg_gen_addi_tl(cpu_cc_dst, cpu_cc_dst, src2);
338
    tcg_gen_mov_tl(dst, cpu_cc_dst);
339
}
340

    
341
static inline void gen_op_addx_cc(TCGv dst, TCGv src1, TCGv src2)
342
{
343
    tcg_gen_mov_tl(cpu_cc_src, src1);
344
    tcg_gen_mov_tl(cpu_cc_src2, src2);
345
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
346
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_tmp0);
347
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_dst, cpu_cc_src2);
348
    tcg_gen_mov_tl(dst, cpu_cc_dst);
349
}
350

    
351
static inline void gen_op_tadd_cc(TCGv dst, TCGv src1, TCGv src2)
352
{
353
    tcg_gen_mov_tl(cpu_cc_src, src1);
354
    tcg_gen_mov_tl(cpu_cc_src2, src2);
355
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
356
    tcg_gen_mov_tl(dst, cpu_cc_dst);
357
}
358

    
359
static inline void gen_op_tadd_ccTV(TCGv dst, TCGv src1, TCGv src2)
360
{
361
    tcg_gen_mov_tl(cpu_cc_src, src1);
362
    tcg_gen_mov_tl(cpu_cc_src2, src2);
363
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
364
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
365
    gen_add_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
366
    tcg_gen_mov_tl(dst, cpu_cc_dst);
367
}
368

    
369
static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
370
{
371
    TCGv r_temp;
372
    TCGv_i32 r_const;
373
    int l1;
374

    
375
    l1 = gen_new_label();
376

    
377
    r_temp = tcg_temp_new();
378
    tcg_gen_xor_tl(r_temp, src1, src2);
379
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
380
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
381
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
382
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
383
    r_const = tcg_const_i32(TT_TOVF);
384
    gen_helper_raise_exception(r_const);
385
    tcg_temp_free_i32(r_const);
386
    gen_set_label(l1);
387
    tcg_temp_free(r_temp);
388
}
389

    
390
static inline void gen_op_subi_cc(TCGv dst, TCGv src1, target_long src2, DisasContext *dc)
391
{
392
    tcg_gen_mov_tl(cpu_cc_src, src1);
393
    tcg_gen_movi_tl(cpu_cc_src2, src2);
394
    if (src2 == 0) {
395
        tcg_gen_mov_tl(cpu_cc_dst, src1);
396
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
397
        dc->cc_op = CC_OP_LOGIC;
398
    } else {
399
        tcg_gen_subi_tl(cpu_cc_dst, cpu_cc_src, src2);
400
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUB);
401
        dc->cc_op = CC_OP_SUB;
402
    }
403
    tcg_gen_mov_tl(dst, cpu_cc_dst);
404
}
405

    
406
static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2)
407
{
408
    tcg_gen_mov_tl(cpu_cc_src, src1);
409
    tcg_gen_mov_tl(cpu_cc_src2, src2);
410
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
411
    tcg_gen_mov_tl(dst, cpu_cc_dst);
412
}
413

    
414
static inline void gen_op_subxi_cc(TCGv dst, TCGv src1, target_long src2)
415
{
416
    tcg_gen_mov_tl(cpu_cc_src, src1);
417
    tcg_gen_movi_tl(cpu_cc_src2, src2);
418
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
419
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_tmp0);
420
    tcg_gen_subi_tl(cpu_cc_dst, cpu_cc_dst, src2);
421
    tcg_gen_mov_tl(dst, cpu_cc_dst);
422
}
423

    
424
static inline void gen_op_subx_cc(TCGv dst, TCGv src1, TCGv src2)
425
{
426
    tcg_gen_mov_tl(cpu_cc_src, src1);
427
    tcg_gen_mov_tl(cpu_cc_src2, src2);
428
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
429
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_tmp0);
430
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_dst, cpu_cc_src2);
431
    tcg_gen_mov_tl(dst, cpu_cc_dst);
432
}
433

    
434
static inline void gen_op_tsub_cc(TCGv dst, TCGv src1, TCGv src2)
435
{
436
    tcg_gen_mov_tl(cpu_cc_src, src1);
437
    tcg_gen_mov_tl(cpu_cc_src2, src2);
438
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
439
    tcg_gen_mov_tl(dst, cpu_cc_dst);
440
}
441

    
442
static inline void gen_op_tsub_ccTV(TCGv dst, TCGv src1, TCGv src2)
443
{
444
    tcg_gen_mov_tl(cpu_cc_src, src1);
445
    tcg_gen_mov_tl(cpu_cc_src2, src2);
446
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
447
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
448
    gen_sub_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
449
    tcg_gen_mov_tl(dst, cpu_cc_dst);
450
}
451

    
452
static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
453
{
454
    TCGv r_temp;
455
    int l1;
456

    
457
    l1 = gen_new_label();
458
    r_temp = tcg_temp_new();
459

    
460
    /* old op:
461
    if (!(env->y & 1))
462
        T1 = 0;
463
    */
464
    tcg_gen_andi_tl(cpu_cc_src, src1, 0xffffffff);
465
    tcg_gen_andi_tl(r_temp, cpu_y, 0x1);
466
    tcg_gen_andi_tl(cpu_cc_src2, src2, 0xffffffff);
467
    tcg_gen_brcondi_tl(TCG_COND_NE, r_temp, 0, l1);
468
    tcg_gen_movi_tl(cpu_cc_src2, 0);
469
    gen_set_label(l1);
470

    
471
    // b2 = T0 & 1;
472
    // env->y = (b2 << 31) | (env->y >> 1);
473
    tcg_gen_andi_tl(r_temp, cpu_cc_src, 0x1);
474
    tcg_gen_shli_tl(r_temp, r_temp, 31);
475
    tcg_gen_shri_tl(cpu_tmp0, cpu_y, 1);
476
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x7fffffff);
477
    tcg_gen_or_tl(cpu_tmp0, cpu_tmp0, r_temp);
478
    tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
479

    
480
    // b1 = N ^ V;
481
    gen_mov_reg_N(cpu_tmp0, cpu_psr);
482
    gen_mov_reg_V(r_temp, cpu_psr);
483
    tcg_gen_xor_tl(cpu_tmp0, cpu_tmp0, r_temp);
484
    tcg_temp_free(r_temp);
485

    
486
    // T0 = (b1 << 31) | (T0 >> 1);
487
    // src1 = T0;
488
    tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
489
    tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
490
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
491

    
492
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
493

    
494
    tcg_gen_mov_tl(dst, cpu_cc_dst);
495
}
496

    
497
static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
498
{
499
    TCGv_i64 r_temp, r_temp2;
500

    
501
    r_temp = tcg_temp_new_i64();
502
    r_temp2 = tcg_temp_new_i64();
503

    
504
    tcg_gen_extu_tl_i64(r_temp, src2);
505
    tcg_gen_extu_tl_i64(r_temp2, src1);
506
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
507

    
508
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
509
    tcg_gen_trunc_i64_tl(cpu_tmp0, r_temp);
510
    tcg_temp_free_i64(r_temp);
511
    tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
512
#ifdef TARGET_SPARC64
513
    tcg_gen_mov_i64(dst, r_temp2);
514
#else
515
    tcg_gen_trunc_i64_tl(dst, r_temp2);
516
#endif
517
    tcg_temp_free_i64(r_temp2);
518
}
519

    
520
static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
521
{
522
    TCGv_i64 r_temp, r_temp2;
523

    
524
    r_temp = tcg_temp_new_i64();
525
    r_temp2 = tcg_temp_new_i64();
526

    
527
    tcg_gen_ext_tl_i64(r_temp, src2);
528
    tcg_gen_ext_tl_i64(r_temp2, src1);
529
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
530

    
531
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
532
    tcg_gen_trunc_i64_tl(cpu_tmp0, r_temp);
533
    tcg_temp_free_i64(r_temp);
534
    tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
535
#ifdef TARGET_SPARC64
536
    tcg_gen_mov_i64(dst, r_temp2);
537
#else
538
    tcg_gen_trunc_i64_tl(dst, r_temp2);
539
#endif
540
    tcg_temp_free_i64(r_temp2);
541
}
542

    
543
#ifdef TARGET_SPARC64
544
static inline void gen_trap_ifdivzero_tl(TCGv divisor)
545
{
546
    TCGv_i32 r_const;
547
    int l1;
548

    
549
    l1 = gen_new_label();
550
    tcg_gen_brcondi_tl(TCG_COND_NE, divisor, 0, l1);
551
    r_const = tcg_const_i32(TT_DIV_ZERO);
552
    gen_helper_raise_exception(r_const);
553
    tcg_temp_free_i32(r_const);
554
    gen_set_label(l1);
555
}
556

    
557
static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
558
{
559
    int l1, l2;
560

    
561
    l1 = gen_new_label();
562
    l2 = gen_new_label();
563
    tcg_gen_mov_tl(cpu_cc_src, src1);
564
    tcg_gen_mov_tl(cpu_cc_src2, src2);
565
    gen_trap_ifdivzero_tl(cpu_cc_src2);
566
    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc_src, INT64_MIN, l1);
567
    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc_src2, -1, l1);
568
    tcg_gen_movi_i64(dst, INT64_MIN);
569
    tcg_gen_br(l2);
570
    gen_set_label(l1);
571
    tcg_gen_div_i64(dst, cpu_cc_src, cpu_cc_src2);
572
    gen_set_label(l2);
573
}
574
#endif
575

    
576
// 1
577
static inline void gen_op_eval_ba(TCGv dst)
578
{
579
    tcg_gen_movi_tl(dst, 1);
580
}
581

    
582
// Z
583
static inline void gen_op_eval_be(TCGv dst, TCGv_i32 src)
584
{
585
    gen_mov_reg_Z(dst, src);
586
}
587

    
588
// Z | (N ^ V)
589
static inline void gen_op_eval_ble(TCGv dst, TCGv_i32 src)
590
{
591
    gen_mov_reg_N(cpu_tmp0, src);
592
    gen_mov_reg_V(dst, src);
593
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
594
    gen_mov_reg_Z(cpu_tmp0, src);
595
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
596
}
597

    
598
// N ^ V
599
static inline void gen_op_eval_bl(TCGv dst, TCGv_i32 src)
600
{
601
    gen_mov_reg_V(cpu_tmp0, src);
602
    gen_mov_reg_N(dst, src);
603
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
604
}
605

    
606
// C | Z
607
static inline void gen_op_eval_bleu(TCGv dst, TCGv_i32 src)
608
{
609
    gen_mov_reg_Z(cpu_tmp0, src);
610
    gen_mov_reg_C(dst, src);
611
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
612
}
613

    
614
// C
615
static inline void gen_op_eval_bcs(TCGv dst, TCGv_i32 src)
616
{
617
    gen_mov_reg_C(dst, src);
618
}
619

    
620
// V
621
static inline void gen_op_eval_bvs(TCGv dst, TCGv_i32 src)
622
{
623
    gen_mov_reg_V(dst, src);
624
}
625

    
626
// 0
627
static inline void gen_op_eval_bn(TCGv dst)
628
{
629
    tcg_gen_movi_tl(dst, 0);
630
}
631

    
632
// N
633
static inline void gen_op_eval_bneg(TCGv dst, TCGv_i32 src)
634
{
635
    gen_mov_reg_N(dst, src);
636
}
637

    
638
// !Z
639
static inline void gen_op_eval_bne(TCGv dst, TCGv_i32 src)
640
{
641
    gen_mov_reg_Z(dst, src);
642
    tcg_gen_xori_tl(dst, dst, 0x1);
643
}
644

    
645
// !(Z | (N ^ V))
646
static inline void gen_op_eval_bg(TCGv dst, TCGv_i32 src)
647
{
648
    gen_mov_reg_N(cpu_tmp0, src);
649
    gen_mov_reg_V(dst, src);
650
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
651
    gen_mov_reg_Z(cpu_tmp0, src);
652
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
653
    tcg_gen_xori_tl(dst, dst, 0x1);
654
}
655

    
656
// !(N ^ V)
657
static inline void gen_op_eval_bge(TCGv dst, TCGv_i32 src)
658
{
659
    gen_mov_reg_V(cpu_tmp0, src);
660
    gen_mov_reg_N(dst, src);
661
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
662
    tcg_gen_xori_tl(dst, dst, 0x1);
663
}
664

    
665
// !(C | Z)
666
static inline void gen_op_eval_bgu(TCGv dst, TCGv_i32 src)
667
{
668
    gen_mov_reg_Z(cpu_tmp0, src);
669
    gen_mov_reg_C(dst, src);
670
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
671
    tcg_gen_xori_tl(dst, dst, 0x1);
672
}
673

    
674
// !C
675
static inline void gen_op_eval_bcc(TCGv dst, TCGv_i32 src)
676
{
677
    gen_mov_reg_C(dst, src);
678
    tcg_gen_xori_tl(dst, dst, 0x1);
679
}
680

    
681
// !N
682
static inline void gen_op_eval_bpos(TCGv dst, TCGv_i32 src)
683
{
684
    gen_mov_reg_N(dst, src);
685
    tcg_gen_xori_tl(dst, dst, 0x1);
686
}
687

    
688
// !V
689
static inline void gen_op_eval_bvc(TCGv dst, TCGv_i32 src)
690
{
691
    gen_mov_reg_V(dst, src);
692
    tcg_gen_xori_tl(dst, dst, 0x1);
693
}
694

    
695
/*
696
  FPSR bit field FCC1 | FCC0:
697
   0 =
698
   1 <
699
   2 >
700
   3 unordered
701
*/
702
static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src,
703
                                    unsigned int fcc_offset)
704
{
705
    tcg_gen_shri_tl(reg, src, FSR_FCC0_SHIFT + fcc_offset);
706
    tcg_gen_andi_tl(reg, reg, 0x1);
707
}
708

    
709
static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
710
                                    unsigned int fcc_offset)
711
{
712
    tcg_gen_shri_tl(reg, src, FSR_FCC1_SHIFT + fcc_offset);
713
    tcg_gen_andi_tl(reg, reg, 0x1);
714
}
715

    
716
// !0: FCC0 | FCC1
717
static inline void gen_op_eval_fbne(TCGv dst, TCGv src,
718
                                    unsigned int fcc_offset)
719
{
720
    gen_mov_reg_FCC0(dst, src, fcc_offset);
721
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
722
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
723
}
724

    
725
// 1 or 2: FCC0 ^ FCC1
726
static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
727
                                    unsigned int fcc_offset)
728
{
729
    gen_mov_reg_FCC0(dst, src, fcc_offset);
730
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
731
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
732
}
733

    
734
// 1 or 3: FCC0
735
static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
736
                                    unsigned int fcc_offset)
737
{
738
    gen_mov_reg_FCC0(dst, src, fcc_offset);
739
}
740

    
741
// 1: FCC0 & !FCC1
742
static inline void gen_op_eval_fbl(TCGv dst, TCGv src,
743
                                    unsigned int fcc_offset)
744
{
745
    gen_mov_reg_FCC0(dst, src, fcc_offset);
746
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
747
    tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
748
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
749
}
750

    
751
// 2 or 3: FCC1
752
static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
753
                                    unsigned int fcc_offset)
754
{
755
    gen_mov_reg_FCC1(dst, src, fcc_offset);
756
}
757

    
758
// 2: !FCC0 & FCC1
759
static inline void gen_op_eval_fbg(TCGv dst, TCGv src,
760
                                    unsigned int fcc_offset)
761
{
762
    gen_mov_reg_FCC0(dst, src, fcc_offset);
763
    tcg_gen_xori_tl(dst, dst, 0x1);
764
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
765
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
766
}
767

    
768
// 3: FCC0 & FCC1
769
static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
770
                                    unsigned int fcc_offset)
771
{
772
    gen_mov_reg_FCC0(dst, src, fcc_offset);
773
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
774
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
775
}
776

    
777
// 0: !(FCC0 | FCC1)
778
static inline void gen_op_eval_fbe(TCGv dst, TCGv src,
779
                                    unsigned int fcc_offset)
780
{
781
    gen_mov_reg_FCC0(dst, src, fcc_offset);
782
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
783
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
784
    tcg_gen_xori_tl(dst, dst, 0x1);
785
}
786

    
787
// 0 or 3: !(FCC0 ^ FCC1)
788
static inline void gen_op_eval_fbue(TCGv dst, TCGv src,
789
                                    unsigned int fcc_offset)
790
{
791
    gen_mov_reg_FCC0(dst, src, fcc_offset);
792
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
793
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
794
    tcg_gen_xori_tl(dst, dst, 0x1);
795
}
796

    
797
// 0 or 2: !FCC0
798
static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
799
                                    unsigned int fcc_offset)
800
{
801
    gen_mov_reg_FCC0(dst, src, fcc_offset);
802
    tcg_gen_xori_tl(dst, dst, 0x1);
803
}
804

    
805
// !1: !(FCC0 & !FCC1)
806
static inline void gen_op_eval_fbuge(TCGv dst, TCGv src,
807
                                    unsigned int fcc_offset)
808
{
809
    gen_mov_reg_FCC0(dst, src, fcc_offset);
810
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
811
    tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
812
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
813
    tcg_gen_xori_tl(dst, dst, 0x1);
814
}
815

    
816
// 0 or 1: !FCC1
817
static inline void gen_op_eval_fble(TCGv dst, TCGv src,
818
                                    unsigned int fcc_offset)
819
{
820
    gen_mov_reg_FCC1(dst, src, fcc_offset);
821
    tcg_gen_xori_tl(dst, dst, 0x1);
822
}
823

    
824
// !2: !(!FCC0 & FCC1)
825
static inline void gen_op_eval_fbule(TCGv dst, TCGv src,
826
                                    unsigned int fcc_offset)
827
{
828
    gen_mov_reg_FCC0(dst, src, fcc_offset);
829
    tcg_gen_xori_tl(dst, dst, 0x1);
830
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
831
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
832
    tcg_gen_xori_tl(dst, dst, 0x1);
833
}
834

    
835
// !3: !(FCC0 & FCC1)
836
static inline void gen_op_eval_fbo(TCGv dst, TCGv src,
837
                                    unsigned int fcc_offset)
838
{
839
    gen_mov_reg_FCC0(dst, src, fcc_offset);
840
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
841
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
842
    tcg_gen_xori_tl(dst, dst, 0x1);
843
}
844

    
845
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
846
                               target_ulong pc2, TCGv r_cond)
847
{
848
    int l1;
849

    
850
    l1 = gen_new_label();
851

    
852
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
853

    
854
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
855

    
856
    gen_set_label(l1);
857
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
858
}
859

    
860
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
861
                                target_ulong pc2, TCGv r_cond)
862
{
863
    int l1;
864

    
865
    l1 = gen_new_label();
866

    
867
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
868

    
869
    gen_goto_tb(dc, 0, pc2, pc1);
870

    
871
    gen_set_label(l1);
872
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
873
}
874

    
875
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
876
                                      TCGv r_cond)
877
{
878
    int l1, l2;
879

    
880
    l1 = gen_new_label();
881
    l2 = gen_new_label();
882

    
883
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
884

    
885
    tcg_gen_movi_tl(cpu_npc, npc1);
886
    tcg_gen_br(l2);
887

    
888
    gen_set_label(l1);
889
    tcg_gen_movi_tl(cpu_npc, npc2);
890
    gen_set_label(l2);
891
}
892

    
893
/* call this function before using the condition register as it may
894
   have been set for a jump */
895
static inline void flush_cond(DisasContext *dc, TCGv cond)
896
{
897
    if (dc->npc == JUMP_PC) {
898
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
899
        dc->npc = DYNAMIC_PC;
900
    }
901
}
902

    
903
static inline void save_npc(DisasContext *dc, TCGv cond)
904
{
905
    if (dc->npc == JUMP_PC) {
906
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
907
        dc->npc = DYNAMIC_PC;
908
    } else if (dc->npc != DYNAMIC_PC) {
909
        tcg_gen_movi_tl(cpu_npc, dc->npc);
910
    }
911
}
912

    
913
static inline void save_state(DisasContext *dc, TCGv cond)
914
{
915
    tcg_gen_movi_tl(cpu_pc, dc->pc);
916
    save_npc(dc, cond);
917
}
918

    
919
static inline void gen_mov_pc_npc(DisasContext *dc, TCGv cond)
920
{
921
    if (dc->npc == JUMP_PC) {
922
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
923
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
924
        dc->pc = DYNAMIC_PC;
925
    } else if (dc->npc == DYNAMIC_PC) {
926
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
927
        dc->pc = DYNAMIC_PC;
928
    } else {
929
        dc->pc = dc->npc;
930
    }
931
}
932

    
933
static inline void gen_op_next_insn(void)
934
{
935
    tcg_gen_mov_tl(cpu_pc, cpu_npc);
936
    tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
937
}
938

    
939
static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond,
940
                            DisasContext *dc)
941
{
942
    TCGv_i32 r_src;
943

    
944
#ifdef TARGET_SPARC64
945
    if (cc)
946
        r_src = cpu_xcc;
947
    else
948
        r_src = cpu_psr;
949
#else
950
    r_src = cpu_psr;
951
#endif
952
    switch (dc->cc_op) {
953
    case CC_OP_FLAGS:
954
        break;
955
    default:
956
        gen_helper_compute_psr();
957
        dc->cc_op = CC_OP_FLAGS;
958
        break;
959
    }
960
    switch (cond) {
961
    case 0x0:
962
        gen_op_eval_bn(r_dst);
963
        break;
964
    case 0x1:
965
        gen_op_eval_be(r_dst, r_src);
966
        break;
967
    case 0x2:
968
        gen_op_eval_ble(r_dst, r_src);
969
        break;
970
    case 0x3:
971
        gen_op_eval_bl(r_dst, r_src);
972
        break;
973
    case 0x4:
974
        gen_op_eval_bleu(r_dst, r_src);
975
        break;
976
    case 0x5:
977
        gen_op_eval_bcs(r_dst, r_src);
978
        break;
979
    case 0x6:
980
        gen_op_eval_bneg(r_dst, r_src);
981
        break;
982
    case 0x7:
983
        gen_op_eval_bvs(r_dst, r_src);
984
        break;
985
    case 0x8:
986
        gen_op_eval_ba(r_dst);
987
        break;
988
    case 0x9:
989
        gen_op_eval_bne(r_dst, r_src);
990
        break;
991
    case 0xa:
992
        gen_op_eval_bg(r_dst, r_src);
993
        break;
994
    case 0xb:
995
        gen_op_eval_bge(r_dst, r_src);
996
        break;
997
    case 0xc:
998
        gen_op_eval_bgu(r_dst, r_src);
999
        break;
1000
    case 0xd:
1001
        gen_op_eval_bcc(r_dst, r_src);
1002
        break;
1003
    case 0xe:
1004
        gen_op_eval_bpos(r_dst, r_src);
1005
        break;
1006
    case 0xf:
1007
        gen_op_eval_bvc(r_dst, r_src);
1008
        break;
1009
    }
1010
}
1011

    
1012
static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
1013
{
1014
    unsigned int offset;
1015

    
1016
    switch (cc) {
1017
    default:
1018
    case 0x0:
1019
        offset = 0;
1020
        break;
1021
    case 0x1:
1022
        offset = 32 - 10;
1023
        break;
1024
    case 0x2:
1025
        offset = 34 - 10;
1026
        break;
1027
    case 0x3:
1028
        offset = 36 - 10;
1029
        break;
1030
    }
1031

    
1032
    switch (cond) {
1033
    case 0x0:
1034
        gen_op_eval_bn(r_dst);
1035
        break;
1036
    case 0x1:
1037
        gen_op_eval_fbne(r_dst, cpu_fsr, offset);
1038
        break;
1039
    case 0x2:
1040
        gen_op_eval_fblg(r_dst, cpu_fsr, offset);
1041
        break;
1042
    case 0x3:
1043
        gen_op_eval_fbul(r_dst, cpu_fsr, offset);
1044
        break;
1045
    case 0x4:
1046
        gen_op_eval_fbl(r_dst, cpu_fsr, offset);
1047
        break;
1048
    case 0x5:
1049
        gen_op_eval_fbug(r_dst, cpu_fsr, offset);
1050
        break;
1051
    case 0x6:
1052
        gen_op_eval_fbg(r_dst, cpu_fsr, offset);
1053
        break;
1054
    case 0x7:
1055
        gen_op_eval_fbu(r_dst, cpu_fsr, offset);
1056
        break;
1057
    case 0x8:
1058
        gen_op_eval_ba(r_dst);
1059
        break;
1060
    case 0x9:
1061
        gen_op_eval_fbe(r_dst, cpu_fsr, offset);
1062
        break;
1063
    case 0xa:
1064
        gen_op_eval_fbue(r_dst, cpu_fsr, offset);
1065
        break;
1066
    case 0xb:
1067
        gen_op_eval_fbge(r_dst, cpu_fsr, offset);
1068
        break;
1069
    case 0xc:
1070
        gen_op_eval_fbuge(r_dst, cpu_fsr, offset);
1071
        break;
1072
    case 0xd:
1073
        gen_op_eval_fble(r_dst, cpu_fsr, offset);
1074
        break;
1075
    case 0xe:
1076
        gen_op_eval_fbule(r_dst, cpu_fsr, offset);
1077
        break;
1078
    case 0xf:
1079
        gen_op_eval_fbo(r_dst, cpu_fsr, offset);
1080
        break;
1081
    }
1082
}
1083

    
1084
#ifdef TARGET_SPARC64
1085
// Inverted logic
1086
static const int gen_tcg_cond_reg[8] = {
1087
    -1,
1088
    TCG_COND_NE,
1089
    TCG_COND_GT,
1090
    TCG_COND_GE,
1091
    -1,
1092
    TCG_COND_EQ,
1093
    TCG_COND_LE,
1094
    TCG_COND_LT,
1095
};
1096

    
1097
static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
1098
{
1099
    int l1;
1100

    
1101
    l1 = gen_new_label();
1102
    tcg_gen_movi_tl(r_dst, 0);
1103
    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], r_src, 0, l1);
1104
    tcg_gen_movi_tl(r_dst, 1);
1105
    gen_set_label(l1);
1106
}
1107
#endif
1108

    
1109
/* XXX: potentially incorrect if dynamic npc */
1110
static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1111
                      TCGv r_cond)
1112
{
1113
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1114
    target_ulong target = dc->pc + offset;
1115

    
1116
    if (cond == 0x0) {
1117
        /* unconditional not taken */
1118
        if (a) {
1119
            dc->pc = dc->npc + 4;
1120
            dc->npc = dc->pc + 4;
1121
        } else {
1122
            dc->pc = dc->npc;
1123
            dc->npc = dc->pc + 4;
1124
        }
1125
    } else if (cond == 0x8) {
1126
        /* unconditional taken */
1127
        if (a) {
1128
            dc->pc = target;
1129
            dc->npc = dc->pc + 4;
1130
        } else {
1131
            dc->pc = dc->npc;
1132
            dc->npc = target;
1133
        }
1134
    } else {
1135
        flush_cond(dc, r_cond);
1136
        gen_cond(r_cond, cc, cond, dc);
1137
        if (a) {
1138
            gen_branch_a(dc, target, dc->npc, r_cond);
1139
            dc->is_br = 1;
1140
        } else {
1141
            dc->pc = dc->npc;
1142
            dc->jump_pc[0] = target;
1143
            dc->jump_pc[1] = dc->npc + 4;
1144
            dc->npc = JUMP_PC;
1145
        }
1146
    }
1147
}
1148

    
1149
/* XXX: potentially incorrect if dynamic npc */
1150
static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1151
                      TCGv r_cond)
1152
{
1153
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1154
    target_ulong target = dc->pc + offset;
1155

    
1156
    if (cond == 0x0) {
1157
        /* unconditional not taken */
1158
        if (a) {
1159
            dc->pc = dc->npc + 4;
1160
            dc->npc = dc->pc + 4;
1161
        } else {
1162
            dc->pc = dc->npc;
1163
            dc->npc = dc->pc + 4;
1164
        }
1165
    } else if (cond == 0x8) {
1166
        /* unconditional taken */
1167
        if (a) {
1168
            dc->pc = target;
1169
            dc->npc = dc->pc + 4;
1170
        } else {
1171
            dc->pc = dc->npc;
1172
            dc->npc = target;
1173
        }
1174
    } else {
1175
        flush_cond(dc, r_cond);
1176
        gen_fcond(r_cond, cc, cond);
1177
        if (a) {
1178
            gen_branch_a(dc, target, dc->npc, r_cond);
1179
            dc->is_br = 1;
1180
        } else {
1181
            dc->pc = dc->npc;
1182
            dc->jump_pc[0] = target;
1183
            dc->jump_pc[1] = dc->npc + 4;
1184
            dc->npc = JUMP_PC;
1185
        }
1186
    }
1187
}
1188

    
1189
#ifdef TARGET_SPARC64
1190
/* XXX: potentially incorrect if dynamic npc */
1191
static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
1192
                          TCGv r_cond, TCGv r_reg)
1193
{
1194
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1195
    target_ulong target = dc->pc + offset;
1196

    
1197
    flush_cond(dc, r_cond);
1198
    gen_cond_reg(r_cond, cond, r_reg);
1199
    if (a) {
1200
        gen_branch_a(dc, target, dc->npc, r_cond);
1201
        dc->is_br = 1;
1202
    } else {
1203
        dc->pc = dc->npc;
1204
        dc->jump_pc[0] = target;
1205
        dc->jump_pc[1] = dc->npc + 4;
1206
        dc->npc = JUMP_PC;
1207
    }
1208
}
1209

    
1210
static inline void gen_op_fcmps(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
1211
{
1212
    switch (fccno) {
1213
    case 0:
1214
        gen_helper_fcmps(r_rs1, r_rs2);
1215
        break;
1216
    case 1:
1217
        gen_helper_fcmps_fcc1(r_rs1, r_rs2);
1218
        break;
1219
    case 2:
1220
        gen_helper_fcmps_fcc2(r_rs1, r_rs2);
1221
        break;
1222
    case 3:
1223
        gen_helper_fcmps_fcc3(r_rs1, r_rs2);
1224
        break;
1225
    }
1226
}
1227

    
1228
static inline void gen_op_fcmpd(int fccno)
1229
{
1230
    switch (fccno) {
1231
    case 0:
1232
        gen_helper_fcmpd();
1233
        break;
1234
    case 1:
1235
        gen_helper_fcmpd_fcc1();
1236
        break;
1237
    case 2:
1238
        gen_helper_fcmpd_fcc2();
1239
        break;
1240
    case 3:
1241
        gen_helper_fcmpd_fcc3();
1242
        break;
1243
    }
1244
}
1245

    
1246
static inline void gen_op_fcmpq(int fccno)
1247
{
1248
    switch (fccno) {
1249
    case 0:
1250
        gen_helper_fcmpq();
1251
        break;
1252
    case 1:
1253
        gen_helper_fcmpq_fcc1();
1254
        break;
1255
    case 2:
1256
        gen_helper_fcmpq_fcc2();
1257
        break;
1258
    case 3:
1259
        gen_helper_fcmpq_fcc3();
1260
        break;
1261
    }
1262
}
1263

    
1264
static inline void gen_op_fcmpes(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
1265
{
1266
    switch (fccno) {
1267
    case 0:
1268
        gen_helper_fcmpes(r_rs1, r_rs2);
1269
        break;
1270
    case 1:
1271
        gen_helper_fcmpes_fcc1(r_rs1, r_rs2);
1272
        break;
1273
    case 2:
1274
        gen_helper_fcmpes_fcc2(r_rs1, r_rs2);
1275
        break;
1276
    case 3:
1277
        gen_helper_fcmpes_fcc3(r_rs1, r_rs2);
1278
        break;
1279
    }
1280
}
1281

    
1282
static inline void gen_op_fcmped(int fccno)
1283
{
1284
    switch (fccno) {
1285
    case 0:
1286
        gen_helper_fcmped();
1287
        break;
1288
    case 1:
1289
        gen_helper_fcmped_fcc1();
1290
        break;
1291
    case 2:
1292
        gen_helper_fcmped_fcc2();
1293
        break;
1294
    case 3:
1295
        gen_helper_fcmped_fcc3();
1296
        break;
1297
    }
1298
}
1299

    
1300
static inline void gen_op_fcmpeq(int fccno)
1301
{
1302
    switch (fccno) {
1303
    case 0:
1304
        gen_helper_fcmpeq();
1305
        break;
1306
    case 1:
1307
        gen_helper_fcmpeq_fcc1();
1308
        break;
1309
    case 2:
1310
        gen_helper_fcmpeq_fcc2();
1311
        break;
1312
    case 3:
1313
        gen_helper_fcmpeq_fcc3();
1314
        break;
1315
    }
1316
}
1317

    
1318
#else
1319

    
1320
static inline void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2)
1321
{
1322
    gen_helper_fcmps(r_rs1, r_rs2);
1323
}
1324

    
1325
static inline void gen_op_fcmpd(int fccno)
1326
{
1327
    gen_helper_fcmpd();
1328
}
1329

    
1330
static inline void gen_op_fcmpq(int fccno)
1331
{
1332
    gen_helper_fcmpq();
1333
}
1334

    
1335
static inline void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2)
1336
{
1337
    gen_helper_fcmpes(r_rs1, r_rs2);
1338
}
1339

    
1340
static inline void gen_op_fcmped(int fccno)
1341
{
1342
    gen_helper_fcmped();
1343
}
1344

    
1345
static inline void gen_op_fcmpeq(int fccno)
1346
{
1347
    gen_helper_fcmpeq();
1348
}
1349
#endif
1350

    
1351
static inline void gen_op_fpexception_im(int fsr_flags)
1352
{
1353
    TCGv_i32 r_const;
1354

    
1355
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_NMASK);
1356
    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
1357
    r_const = tcg_const_i32(TT_FP_EXCP);
1358
    gen_helper_raise_exception(r_const);
1359
    tcg_temp_free_i32(r_const);
1360
}
1361

    
1362
static int gen_trap_ifnofpu(DisasContext *dc, TCGv r_cond)
1363
{
1364
#if !defined(CONFIG_USER_ONLY)
1365
    if (!dc->fpu_enabled) {
1366
        TCGv_i32 r_const;
1367

    
1368
        save_state(dc, r_cond);
1369
        r_const = tcg_const_i32(TT_NFPU_INSN);
1370
        gen_helper_raise_exception(r_const);
1371
        tcg_temp_free_i32(r_const);
1372
        dc->is_br = 1;
1373
        return 1;
1374
    }
1375
#endif
1376
    return 0;
1377
}
1378

    
1379
static inline void gen_op_clear_ieee_excp_and_FTT(void)
1380
{
1381
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_CEXC_NMASK);
1382
}
1383

    
1384
static inline void gen_clear_float_exceptions(void)
1385
{
1386
    gen_helper_clear_float_exceptions();
1387
}
1388

    
1389
/* asi moves */
1390
#ifdef TARGET_SPARC64
1391
static inline TCGv_i32 gen_get_asi(int insn, TCGv r_addr)
1392
{
1393
    int asi;
1394
    TCGv_i32 r_asi;
1395

    
1396
    if (IS_IMM) {
1397
        r_asi = tcg_temp_new_i32();
1398
        tcg_gen_mov_i32(r_asi, cpu_asi);
1399
    } else {
1400
        asi = GET_FIELD(insn, 19, 26);
1401
        r_asi = tcg_const_i32(asi);
1402
    }
1403
    return r_asi;
1404
}
1405

    
1406
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
1407
                              int sign)
1408
{
1409
    TCGv_i32 r_asi, r_size, r_sign;
1410

    
1411
    r_asi = gen_get_asi(insn, addr);
1412
    r_size = tcg_const_i32(size);
1413
    r_sign = tcg_const_i32(sign);
1414
    gen_helper_ld_asi(dst, addr, r_asi, r_size, r_sign);
1415
    tcg_temp_free_i32(r_sign);
1416
    tcg_temp_free_i32(r_size);
1417
    tcg_temp_free_i32(r_asi);
1418
}
1419

    
1420
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1421
{
1422
    TCGv_i32 r_asi, r_size;
1423

    
1424
    r_asi = gen_get_asi(insn, addr);
1425
    r_size = tcg_const_i32(size);
1426
    gen_helper_st_asi(addr, src, r_asi, r_size);
1427
    tcg_temp_free_i32(r_size);
1428
    tcg_temp_free_i32(r_asi);
1429
}
1430

    
1431
static inline void gen_ldf_asi(TCGv addr, int insn, int size, int rd)
1432
{
1433
    TCGv_i32 r_asi, r_size, r_rd;
1434

    
1435
    r_asi = gen_get_asi(insn, addr);
1436
    r_size = tcg_const_i32(size);
1437
    r_rd = tcg_const_i32(rd);
1438
    gen_helper_ldf_asi(addr, r_asi, r_size, r_rd);
1439
    tcg_temp_free_i32(r_rd);
1440
    tcg_temp_free_i32(r_size);
1441
    tcg_temp_free_i32(r_asi);
1442
}
1443

    
1444
static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
1445
{
1446
    TCGv_i32 r_asi, r_size, r_rd;
1447

    
1448
    r_asi = gen_get_asi(insn, addr);
1449
    r_size = tcg_const_i32(size);
1450
    r_rd = tcg_const_i32(rd);
1451
    gen_helper_stf_asi(addr, r_asi, r_size, r_rd);
1452
    tcg_temp_free_i32(r_rd);
1453
    tcg_temp_free_i32(r_size);
1454
    tcg_temp_free_i32(r_asi);
1455
}
1456

    
1457
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1458
{
1459
    TCGv_i32 r_asi, r_size, r_sign;
1460

    
1461
    r_asi = gen_get_asi(insn, addr);
1462
    r_size = tcg_const_i32(4);
1463
    r_sign = tcg_const_i32(0);
1464
    gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
1465
    tcg_temp_free_i32(r_sign);
1466
    gen_helper_st_asi(addr, dst, r_asi, r_size);
1467
    tcg_temp_free_i32(r_size);
1468
    tcg_temp_free_i32(r_asi);
1469
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1470
}
1471

    
1472
static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
1473
{
1474
    TCGv_i32 r_asi, r_rd;
1475

    
1476
    r_asi = gen_get_asi(insn, addr);
1477
    r_rd = tcg_const_i32(rd);
1478
    gen_helper_ldda_asi(addr, r_asi, r_rd);
1479
    tcg_temp_free_i32(r_rd);
1480
    tcg_temp_free_i32(r_asi);
1481
}
1482

    
1483
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1484
{
1485
    TCGv_i32 r_asi, r_size;
1486

    
1487
    gen_movl_reg_TN(rd + 1, cpu_tmp0);
1488
    tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, hi);
1489
    r_asi = gen_get_asi(insn, addr);
1490
    r_size = tcg_const_i32(8);
1491
    gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
1492
    tcg_temp_free_i32(r_size);
1493
    tcg_temp_free_i32(r_asi);
1494
}
1495

    
1496
static inline void gen_cas_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
1497
                               int rd)
1498
{
1499
    TCGv r_val1;
1500
    TCGv_i32 r_asi;
1501

    
1502
    r_val1 = tcg_temp_new();
1503
    gen_movl_reg_TN(rd, r_val1);
1504
    r_asi = gen_get_asi(insn, addr);
1505
    gen_helper_cas_asi(dst, addr, r_val1, val2, r_asi);
1506
    tcg_temp_free_i32(r_asi);
1507
    tcg_temp_free(r_val1);
1508
}
1509

    
1510
static inline void gen_casx_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
1511
                                int rd)
1512
{
1513
    TCGv_i32 r_asi;
1514

    
1515
    gen_movl_reg_TN(rd, cpu_tmp64);
1516
    r_asi = gen_get_asi(insn, addr);
1517
    gen_helper_casx_asi(dst, addr, cpu_tmp64, val2, r_asi);
1518
    tcg_temp_free_i32(r_asi);
1519
}
1520

    
1521
#elif !defined(CONFIG_USER_ONLY)
1522

    
1523
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
1524
                              int sign)
1525
{
1526
    TCGv_i32 r_asi, r_size, r_sign;
1527

    
1528
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1529
    r_size = tcg_const_i32(size);
1530
    r_sign = tcg_const_i32(sign);
1531
    gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
1532
    tcg_temp_free(r_sign);
1533
    tcg_temp_free(r_size);
1534
    tcg_temp_free(r_asi);
1535
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1536
}
1537

    
1538
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1539
{
1540
    TCGv_i32 r_asi, r_size;
1541

    
1542
    tcg_gen_extu_tl_i64(cpu_tmp64, src);
1543
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1544
    r_size = tcg_const_i32(size);
1545
    gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
1546
    tcg_temp_free(r_size);
1547
    tcg_temp_free(r_asi);
1548
}
1549

    
1550
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1551
{
1552
    TCGv_i32 r_asi, r_size, r_sign;
1553
    TCGv_i64 r_val;
1554

    
1555
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1556
    r_size = tcg_const_i32(4);
1557
    r_sign = tcg_const_i32(0);
1558
    gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
1559
    tcg_temp_free(r_sign);
1560
    r_val = tcg_temp_new_i64();
1561
    tcg_gen_extu_tl_i64(r_val, dst);
1562
    gen_helper_st_asi(addr, r_val, r_asi, r_size);
1563
    tcg_temp_free_i64(r_val);
1564
    tcg_temp_free(r_size);
1565
    tcg_temp_free(r_asi);
1566
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1567
}
1568

    
1569
static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
1570
{
1571
    TCGv_i32 r_asi, r_size, r_sign;
1572

    
1573
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1574
    r_size = tcg_const_i32(8);
1575
    r_sign = tcg_const_i32(0);
1576
    gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
1577
    tcg_temp_free(r_sign);
1578
    tcg_temp_free(r_size);
1579
    tcg_temp_free(r_asi);
1580
    tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
1581
    gen_movl_TN_reg(rd + 1, cpu_tmp0);
1582
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1583
    tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
1584
    gen_movl_TN_reg(rd, hi);
1585
}
1586

    
1587
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1588
{
1589
    TCGv_i32 r_asi, r_size;
1590

    
1591
    gen_movl_reg_TN(rd + 1, cpu_tmp0);
1592
    tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, hi);
1593
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1594
    r_size = tcg_const_i32(8);
1595
    gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
1596
    tcg_temp_free(r_size);
1597
    tcg_temp_free(r_asi);
1598
}
1599
#endif
1600

    
1601
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1602
static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
1603
{
1604
    TCGv_i64 r_val;
1605
    TCGv_i32 r_asi, r_size;
1606

    
1607
    gen_ld_asi(dst, addr, insn, 1, 0);
1608

    
1609
    r_val = tcg_const_i64(0xffULL);
1610
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1611
    r_size = tcg_const_i32(1);
1612
    gen_helper_st_asi(addr, r_val, r_asi, r_size);
1613
    tcg_temp_free_i32(r_size);
1614
    tcg_temp_free_i32(r_asi);
1615
    tcg_temp_free_i64(r_val);
1616
}
1617
#endif
1618

    
1619
static inline TCGv get_src1(unsigned int insn, TCGv def)
1620
{
1621
    TCGv r_rs1 = def;
1622
    unsigned int rs1;
1623

    
1624
    rs1 = GET_FIELD(insn, 13, 17);
1625
    if (rs1 == 0)
1626
        r_rs1 = tcg_const_tl(0); // XXX how to free?
1627
    else if (rs1 < 8)
1628
        r_rs1 = cpu_gregs[rs1];
1629
    else
1630
        tcg_gen_ld_tl(def, cpu_regwptr, (rs1 - 8) * sizeof(target_ulong));
1631
    return r_rs1;
1632
}
1633

    
1634
static inline TCGv get_src2(unsigned int insn, TCGv def)
1635
{
1636
    TCGv r_rs2 = def;
1637

    
1638
    if (IS_IMM) { /* immediate */
1639
        target_long simm;
1640

    
1641
        simm = GET_FIELDs(insn, 19, 31);
1642
        r_rs2 = tcg_const_tl(simm); // XXX how to free?
1643
    } else { /* register */
1644
        unsigned int rs2;
1645

    
1646
        rs2 = GET_FIELD(insn, 27, 31);
1647
        if (rs2 == 0)
1648
            r_rs2 = tcg_const_tl(0); // XXX how to free?
1649
        else if (rs2 < 8)
1650
            r_rs2 = cpu_gregs[rs2];
1651
        else
1652
            tcg_gen_ld_tl(def, cpu_regwptr, (rs2 - 8) * sizeof(target_ulong));
1653
    }
1654
    return r_rs2;
1655
}
1656

    
1657
#define CHECK_IU_FEATURE(dc, FEATURE)                      \
1658
    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
1659
        goto illegal_insn;
1660
#define CHECK_FPU_FEATURE(dc, FEATURE)                     \
1661
    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
1662
        goto nfpu_insn;
1663

    
1664
/* before an instruction, dc->pc must be static */
1665
static void disas_sparc_insn(DisasContext * dc)
1666
{
1667
    unsigned int insn, opc, rs1, rs2, rd;
1668
    target_long simm;
1669

    
1670
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
1671
        tcg_gen_debug_insn_start(dc->pc);
1672
    insn = ldl_code(dc->pc);
1673
    opc = GET_FIELD(insn, 0, 1);
1674

    
1675
    rd = GET_FIELD(insn, 2, 6);
1676

    
1677
    cpu_src1 = tcg_temp_new(); // const
1678
    cpu_src2 = tcg_temp_new(); // const
1679

    
1680
    switch (opc) {
1681
    case 0:                     /* branches/sethi */
1682
        {
1683
            unsigned int xop = GET_FIELD(insn, 7, 9);
1684
            int32_t target;
1685
            switch (xop) {
1686
#ifdef TARGET_SPARC64
1687
            case 0x1:           /* V9 BPcc */
1688
                {
1689
                    int cc;
1690

    
1691
                    target = GET_FIELD_SP(insn, 0, 18);
1692
                    target = sign_extend(target, 18);
1693
                    target <<= 2;
1694
                    cc = GET_FIELD_SP(insn, 20, 21);
1695
                    if (cc == 0)
1696
                        do_branch(dc, target, insn, 0, cpu_cond);
1697
                    else if (cc == 2)
1698
                        do_branch(dc, target, insn, 1, cpu_cond);
1699
                    else
1700
                        goto illegal_insn;
1701
                    goto jmp_insn;
1702
                }
1703
            case 0x3:           /* V9 BPr */
1704
                {
1705
                    target = GET_FIELD_SP(insn, 0, 13) |
1706
                        (GET_FIELD_SP(insn, 20, 21) << 14);
1707
                    target = sign_extend(target, 16);
1708
                    target <<= 2;
1709
                    cpu_src1 = get_src1(insn, cpu_src1);
1710
                    do_branch_reg(dc, target, insn, cpu_cond, cpu_src1);
1711
                    goto jmp_insn;
1712
                }
1713
            case 0x5:           /* V9 FBPcc */
1714
                {
1715
                    int cc = GET_FIELD_SP(insn, 20, 21);
1716
                    if (gen_trap_ifnofpu(dc, cpu_cond))
1717
                        goto jmp_insn;
1718
                    target = GET_FIELD_SP(insn, 0, 18);
1719
                    target = sign_extend(target, 19);
1720
                    target <<= 2;
1721
                    do_fbranch(dc, target, insn, cc, cpu_cond);
1722
                    goto jmp_insn;
1723
                }
1724
#else
1725
            case 0x7:           /* CBN+x */
1726
                {
1727
                    goto ncp_insn;
1728
                }
1729
#endif
1730
            case 0x2:           /* BN+x */
1731
                {
1732
                    target = GET_FIELD(insn, 10, 31);
1733
                    target = sign_extend(target, 22);
1734
                    target <<= 2;
1735
                    do_branch(dc, target, insn, 0, cpu_cond);
1736
                    goto jmp_insn;
1737
                }
1738
            case 0x6:           /* FBN+x */
1739
                {
1740
                    if (gen_trap_ifnofpu(dc, cpu_cond))
1741
                        goto jmp_insn;
1742
                    target = GET_FIELD(insn, 10, 31);
1743
                    target = sign_extend(target, 22);
1744
                    target <<= 2;
1745
                    do_fbranch(dc, target, insn, 0, cpu_cond);
1746
                    goto jmp_insn;
1747
                }
1748
            case 0x4:           /* SETHI */
1749
                if (rd) { // nop
1750
                    uint32_t value = GET_FIELD(insn, 10, 31);
1751
                    TCGv r_const;
1752

    
1753
                    r_const = tcg_const_tl(value << 10);
1754
                    gen_movl_TN_reg(rd, r_const);
1755
                    tcg_temp_free(r_const);
1756
                }
1757
                break;
1758
            case 0x0:           /* UNIMPL */
1759
            default:
1760
                goto illegal_insn;
1761
            }
1762
            break;
1763
        }
1764
        break;
1765
    case 1:                     /*CALL*/
1766
        {
1767
            target_long target = GET_FIELDs(insn, 2, 31) << 2;
1768
            TCGv r_const;
1769

    
1770
            r_const = tcg_const_tl(dc->pc);
1771
            gen_movl_TN_reg(15, r_const);
1772
            tcg_temp_free(r_const);
1773
            target += dc->pc;
1774
            gen_mov_pc_npc(dc, cpu_cond);
1775
            dc->npc = target;
1776
        }
1777
        goto jmp_insn;
1778
    case 2:                     /* FPU & Logical Operations */
1779
        {
1780
            unsigned int xop = GET_FIELD(insn, 7, 12);
1781
            if (xop == 0x3a) {  /* generate trap */
1782
                int cond;
1783

    
1784
                cpu_src1 = get_src1(insn, cpu_src1);
1785
                if (IS_IMM) {
1786
                    rs2 = GET_FIELD(insn, 25, 31);
1787
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, rs2);
1788
                } else {
1789
                    rs2 = GET_FIELD(insn, 27, 31);
1790
                    if (rs2 != 0) {
1791
                        gen_movl_reg_TN(rs2, cpu_src2);
1792
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
1793
                    } else
1794
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
1795
                }
1796
                cond = GET_FIELD(insn, 3, 6);
1797
                if (cond == 0x8) {
1798
                    save_state(dc, cpu_cond);
1799
                    if ((dc->def->features & CPU_FEATURE_HYPV) &&
1800
                        supervisor(dc))
1801
                        tcg_gen_andi_tl(cpu_dst, cpu_dst, UA2005_HTRAP_MASK);
1802
                    else
1803
                        tcg_gen_andi_tl(cpu_dst, cpu_dst, V8_TRAP_MASK);
1804
                    tcg_gen_addi_tl(cpu_dst, cpu_dst, TT_TRAP);
1805
                    tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
1806
                    gen_helper_raise_exception(cpu_tmp32);
1807
                } else if (cond != 0) {
1808
                    TCGv r_cond = tcg_temp_new();
1809
                    int l1;
1810
#ifdef TARGET_SPARC64
1811
                    /* V9 icc/xcc */
1812
                    int cc = GET_FIELD_SP(insn, 11, 12);
1813

    
1814
                    save_state(dc, cpu_cond);
1815
                    if (cc == 0)
1816
                        gen_cond(r_cond, 0, cond, dc);
1817
                    else if (cc == 2)
1818
                        gen_cond(r_cond, 1, cond, dc);
1819
                    else
1820
                        goto illegal_insn;
1821
#else
1822
                    save_state(dc, cpu_cond);
1823
                    gen_cond(r_cond, 0, cond, dc);
1824
#endif
1825
                    l1 = gen_new_label();
1826
                    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
1827

    
1828
                    if ((dc->def->features & CPU_FEATURE_HYPV) &&
1829
                        supervisor(dc))
1830
                        tcg_gen_andi_tl(cpu_dst, cpu_dst, UA2005_HTRAP_MASK);
1831
                    else
1832
                        tcg_gen_andi_tl(cpu_dst, cpu_dst, V8_TRAP_MASK);
1833
                    tcg_gen_addi_tl(cpu_dst, cpu_dst, TT_TRAP);
1834
                    tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
1835
                    gen_helper_raise_exception(cpu_tmp32);
1836

    
1837
                    gen_set_label(l1);
1838
                    tcg_temp_free(r_cond);
1839
                }
1840
                gen_op_next_insn();
1841
                tcg_gen_exit_tb(0);
1842
                dc->is_br = 1;
1843
                goto jmp_insn;
1844
            } else if (xop == 0x28) {
1845
                rs1 = GET_FIELD(insn, 13, 17);
1846
                switch(rs1) {
1847
                case 0: /* rdy */
1848
#ifndef TARGET_SPARC64
1849
                case 0x01 ... 0x0e: /* undefined in the SPARCv8
1850
                                       manual, rdy on the microSPARC
1851
                                       II */
1852
                case 0x0f:          /* stbar in the SPARCv8 manual,
1853
                                       rdy on the microSPARC II */
1854
                case 0x10 ... 0x1f: /* implementation-dependent in the
1855
                                       SPARCv8 manual, rdy on the
1856
                                       microSPARC II */
1857
#endif
1858
                    gen_movl_TN_reg(rd, cpu_y);
1859
                    break;
1860
#ifdef TARGET_SPARC64
1861
                case 0x2: /* V9 rdccr */
1862
                    gen_helper_compute_psr();
1863
                    gen_helper_rdccr(cpu_dst);
1864
                    gen_movl_TN_reg(rd, cpu_dst);
1865
                    break;
1866
                case 0x3: /* V9 rdasi */
1867
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_asi);
1868
                    gen_movl_TN_reg(rd, cpu_dst);
1869
                    break;
1870
                case 0x4: /* V9 rdtick */
1871
                    {
1872
                        TCGv_ptr r_tickptr;
1873

    
1874
                        r_tickptr = tcg_temp_new_ptr();
1875
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
1876
                                       offsetof(CPUState, tick));
1877
                        gen_helper_tick_get_count(cpu_dst, r_tickptr);
1878
                        tcg_temp_free_ptr(r_tickptr);
1879
                        gen_movl_TN_reg(rd, cpu_dst);
1880
                    }
1881
                    break;
1882
                case 0x5: /* V9 rdpc */
1883
                    {
1884
                        TCGv r_const;
1885

    
1886
                        r_const = tcg_const_tl(dc->pc);
1887
                        gen_movl_TN_reg(rd, r_const);
1888
                        tcg_temp_free(r_const);
1889
                    }
1890
                    break;
1891
                case 0x6: /* V9 rdfprs */
1892
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_fprs);
1893
                    gen_movl_TN_reg(rd, cpu_dst);
1894
                    break;
1895
                case 0xf: /* V9 membar */
1896
                    break; /* no effect */
1897
                case 0x13: /* Graphics Status */
1898
                    if (gen_trap_ifnofpu(dc, cpu_cond))
1899
                        goto jmp_insn;
1900
                    gen_movl_TN_reg(rd, cpu_gsr);
1901
                    break;
1902
                case 0x16: /* Softint */
1903
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_softint);
1904
                    gen_movl_TN_reg(rd, cpu_dst);
1905
                    break;
1906
                case 0x17: /* Tick compare */
1907
                    gen_movl_TN_reg(rd, cpu_tick_cmpr);
1908
                    break;
1909
                case 0x18: /* System tick */
1910
                    {
1911
                        TCGv_ptr r_tickptr;
1912

    
1913
                        r_tickptr = tcg_temp_new_ptr();
1914
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
1915
                                       offsetof(CPUState, stick));
1916
                        gen_helper_tick_get_count(cpu_dst, r_tickptr);
1917
                        tcg_temp_free_ptr(r_tickptr);
1918
                        gen_movl_TN_reg(rd, cpu_dst);
1919
                    }
1920
                    break;
1921
                case 0x19: /* System tick compare */
1922
                    gen_movl_TN_reg(rd, cpu_stick_cmpr);
1923
                    break;
1924
                case 0x10: /* Performance Control */
1925
                case 0x11: /* Performance Instrumentation Counter */
1926
                case 0x12: /* Dispatch Control */
1927
                case 0x14: /* Softint set, WO */
1928
                case 0x15: /* Softint clear, WO */
1929
#endif
1930
                default:
1931
                    goto illegal_insn;
1932
                }
1933
#if !defined(CONFIG_USER_ONLY)
1934
            } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
1935
#ifndef TARGET_SPARC64
1936
                if (!supervisor(dc))
1937
                    goto priv_insn;
1938
                gen_helper_compute_psr();
1939
                dc->cc_op = CC_OP_FLAGS;
1940
                gen_helper_rdpsr(cpu_dst);
1941
#else
1942
                CHECK_IU_FEATURE(dc, HYPV);
1943
                if (!hypervisor(dc))
1944
                    goto priv_insn;
1945
                rs1 = GET_FIELD(insn, 13, 17);
1946
                switch (rs1) {
1947
                case 0: // hpstate
1948
                    // gen_op_rdhpstate();
1949
                    break;
1950
                case 1: // htstate
1951
                    // gen_op_rdhtstate();
1952
                    break;
1953
                case 3: // hintp
1954
                    tcg_gen_mov_tl(cpu_dst, cpu_hintp);
1955
                    break;
1956
                case 5: // htba
1957
                    tcg_gen_mov_tl(cpu_dst, cpu_htba);
1958
                    break;
1959
                case 6: // hver
1960
                    tcg_gen_mov_tl(cpu_dst, cpu_hver);
1961
                    break;
1962
                case 31: // hstick_cmpr
1963
                    tcg_gen_mov_tl(cpu_dst, cpu_hstick_cmpr);
1964
                    break;
1965
                default:
1966
                    goto illegal_insn;
1967
                }
1968
#endif
1969
                gen_movl_TN_reg(rd, cpu_dst);
1970
                break;
1971
            } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
1972
                if (!supervisor(dc))
1973
                    goto priv_insn;
1974
#ifdef TARGET_SPARC64
1975
                rs1 = GET_FIELD(insn, 13, 17);
1976
                switch (rs1) {
1977
                case 0: // tpc
1978
                    {
1979
                        TCGv_ptr r_tsptr;
1980

    
1981
                        r_tsptr = tcg_temp_new_ptr();
1982
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
1983
                                       offsetof(CPUState, tsptr));
1984
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
1985
                                      offsetof(trap_state, tpc));
1986
                        tcg_temp_free_ptr(r_tsptr);
1987
                    }
1988
                    break;
1989
                case 1: // tnpc
1990
                    {
1991
                        TCGv_ptr r_tsptr;
1992

    
1993
                        r_tsptr = tcg_temp_new_ptr();
1994
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
1995
                                       offsetof(CPUState, tsptr));
1996
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
1997
                                      offsetof(trap_state, tnpc));
1998
                        tcg_temp_free_ptr(r_tsptr);
1999
                    }
2000
                    break;
2001
                case 2: // tstate
2002
                    {
2003
                        TCGv_ptr r_tsptr;
2004

    
2005
                        r_tsptr = tcg_temp_new_ptr();
2006
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2007
                                       offsetof(CPUState, tsptr));
2008
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2009
                                      offsetof(trap_state, tstate));
2010
                        tcg_temp_free_ptr(r_tsptr);
2011
                    }
2012
                    break;
2013
                case 3: // tt
2014
                    {
2015
                        TCGv_ptr r_tsptr;
2016

    
2017
                        r_tsptr = tcg_temp_new_ptr();
2018
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2019
                                       offsetof(CPUState, tsptr));
2020
                        tcg_gen_ld_i32(cpu_tmp32, r_tsptr,
2021
                                       offsetof(trap_state, tt));
2022
                        tcg_temp_free_ptr(r_tsptr);
2023
                        tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2024
                    }
2025
                    break;
2026
                case 4: // tick
2027
                    {
2028
                        TCGv_ptr r_tickptr;
2029

    
2030
                        r_tickptr = tcg_temp_new_ptr();
2031
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2032
                                       offsetof(CPUState, tick));
2033
                        gen_helper_tick_get_count(cpu_tmp0, r_tickptr);
2034
                        gen_movl_TN_reg(rd, cpu_tmp0);
2035
                        tcg_temp_free_ptr(r_tickptr);
2036
                    }
2037
                    break;
2038
                case 5: // tba
2039
                    tcg_gen_mov_tl(cpu_tmp0, cpu_tbr);
2040
                    break;
2041
                case 6: // pstate
2042
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2043
                                   offsetof(CPUSPARCState, pstate));
2044
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2045
                    break;
2046
                case 7: // tl
2047
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2048
                                   offsetof(CPUSPARCState, tl));
2049
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2050
                    break;
2051
                case 8: // pil
2052
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2053
                                   offsetof(CPUSPARCState, psrpil));
2054
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2055
                    break;
2056
                case 9: // cwp
2057
                    gen_helper_rdcwp(cpu_tmp0);
2058
                    break;
2059
                case 10: // cansave
2060
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2061
                                   offsetof(CPUSPARCState, cansave));
2062
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2063
                    break;
2064
                case 11: // canrestore
2065
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2066
                                   offsetof(CPUSPARCState, canrestore));
2067
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2068
                    break;
2069
                case 12: // cleanwin
2070
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2071
                                   offsetof(CPUSPARCState, cleanwin));
2072
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2073
                    break;
2074
                case 13: // otherwin
2075
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2076
                                   offsetof(CPUSPARCState, otherwin));
2077
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2078
                    break;
2079
                case 14: // wstate
2080
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2081
                                   offsetof(CPUSPARCState, wstate));
2082
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2083
                    break;
2084
                case 16: // UA2005 gl
2085
                    CHECK_IU_FEATURE(dc, GL);
2086
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2087
                                   offsetof(CPUSPARCState, gl));
2088
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2089
                    break;
2090
                case 26: // UA2005 strand status
2091
                    CHECK_IU_FEATURE(dc, HYPV);
2092
                    if (!hypervisor(dc))
2093
                        goto priv_insn;
2094
                    tcg_gen_mov_tl(cpu_tmp0, cpu_ssr);
2095
                    break;
2096
                case 31: // ver
2097
                    tcg_gen_mov_tl(cpu_tmp0, cpu_ver);
2098
                    break;
2099
                case 15: // fq
2100
                default:
2101
                    goto illegal_insn;
2102
                }
2103
#else
2104
                tcg_gen_ext_i32_tl(cpu_tmp0, cpu_wim);
2105
#endif
2106
                gen_movl_TN_reg(rd, cpu_tmp0);
2107
                break;
2108
            } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
2109
#ifdef TARGET_SPARC64
2110
                save_state(dc, cpu_cond);
2111
                gen_helper_flushw();
2112
#else
2113
                if (!supervisor(dc))
2114
                    goto priv_insn;
2115
                gen_movl_TN_reg(rd, cpu_tbr);
2116
#endif
2117
                break;
2118
#endif
2119
            } else if (xop == 0x34) {   /* FPU Operations */
2120
                if (gen_trap_ifnofpu(dc, cpu_cond))
2121
                    goto jmp_insn;
2122
                gen_op_clear_ieee_excp_and_FTT();
2123
                rs1 = GET_FIELD(insn, 13, 17);
2124
                rs2 = GET_FIELD(insn, 27, 31);
2125
                xop = GET_FIELD(insn, 18, 26);
2126
                switch (xop) {
2127
                case 0x1: /* fmovs */
2128
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);
2129
                    break;
2130
                case 0x5: /* fnegs */
2131
                    gen_helper_fnegs(cpu_fpr[rd], cpu_fpr[rs2]);
2132
                    break;
2133
                case 0x9: /* fabss */
2134
                    gen_helper_fabss(cpu_fpr[rd], cpu_fpr[rs2]);
2135
                    break;
2136
                case 0x29: /* fsqrts */
2137
                    CHECK_FPU_FEATURE(dc, FSQRT);
2138
                    gen_clear_float_exceptions();
2139
                    gen_helper_fsqrts(cpu_tmp32, cpu_fpr[rs2]);
2140
                    gen_helper_check_ieee_exceptions();
2141
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2142
                    break;
2143
                case 0x2a: /* fsqrtd */
2144
                    CHECK_FPU_FEATURE(dc, FSQRT);
2145
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2146
                    gen_clear_float_exceptions();
2147
                    gen_helper_fsqrtd();
2148
                    gen_helper_check_ieee_exceptions();
2149
                    gen_op_store_DT0_fpr(DFPREG(rd));
2150
                    break;
2151
                case 0x2b: /* fsqrtq */
2152
                    CHECK_FPU_FEATURE(dc, FLOAT128);
2153
                    gen_op_load_fpr_QT1(QFPREG(rs2));
2154
                    gen_clear_float_exceptions();
2155
                    gen_helper_fsqrtq();
2156
                    gen_helper_check_ieee_exceptions();
2157
                    gen_op_store_QT0_fpr(QFPREG(rd));
2158
                    break;
2159
                case 0x41: /* fadds */
2160
                    gen_clear_float_exceptions();
2161
                    gen_helper_fadds(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
2162
                    gen_helper_check_ieee_exceptions();
2163
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2164
                    break;
2165
                case 0x42: /* faddd */
2166
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2167
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2168
                    gen_clear_float_exceptions();
2169
                    gen_helper_faddd();
2170
                    gen_helper_check_ieee_exceptions();
2171
                    gen_op_store_DT0_fpr(DFPREG(rd));
2172
                    break;
2173
                case 0x43: /* faddq */
2174
                    CHECK_FPU_FEATURE(dc, FLOAT128);
2175
                    gen_op_load_fpr_QT0(QFPREG(rs1));
2176
                    gen_op_load_fpr_QT1(QFPREG(rs2));
2177
                    gen_clear_float_exceptions();
2178
                    gen_helper_faddq();
2179
                    gen_helper_check_ieee_exceptions();
2180
                    gen_op_store_QT0_fpr(QFPREG(rd));
2181
                    break;
2182
                case 0x45: /* fsubs */
2183
                    gen_clear_float_exceptions();
2184
                    gen_helper_fsubs(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
2185
                    gen_helper_check_ieee_exceptions();
2186
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2187
                    break;
2188
                case 0x46: /* fsubd */
2189
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2190
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2191
                    gen_clear_float_exceptions();
2192
                    gen_helper_fsubd();
2193
                    gen_helper_check_ieee_exceptions();
2194
                    gen_op_store_DT0_fpr(DFPREG(rd));
2195
                    break;
2196
                case 0x47: /* fsubq */
2197
                    CHECK_FPU_FEATURE(dc, FLOAT128);
2198
                    gen_op_load_fpr_QT0(QFPREG(rs1));
2199
                    gen_op_load_fpr_QT1(QFPREG(rs2));
2200
                    gen_clear_float_exceptions();
2201
                    gen_helper_fsubq();
2202
                    gen_helper_check_ieee_exceptions();
2203
                    gen_op_store_QT0_fpr(QFPREG(rd));
2204
                    break;
2205
                case 0x49: /* fmuls */
2206
                    CHECK_FPU_FEATURE(dc, FMUL);
2207
                    gen_clear_float_exceptions();
2208
                    gen_helper_fmuls(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
2209
                    gen_helper_check_ieee_exceptions();
2210
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2211
                    break;
2212
                case 0x4a: /* fmuld */
2213
                    CHECK_FPU_FEATURE(dc, FMUL);
2214
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2215
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2216
                    gen_clear_float_exceptions();
2217
                    gen_helper_fmuld();
2218
                    gen_helper_check_ieee_exceptions();
2219
                    gen_op_store_DT0_fpr(DFPREG(rd));
2220
                    break;
2221
                case 0x4b: /* fmulq */
2222
                    CHECK_FPU_FEATURE(dc, FLOAT128);
2223
                    CHECK_FPU_FEATURE(dc, FMUL);
2224
                    gen_op_load_fpr_QT0(QFPREG(rs1));
2225
                    gen_op_load_fpr_QT1(QFPREG(rs2));
2226
                    gen_clear_float_exceptions();
2227
                    gen_helper_fmulq();
2228
                    gen_helper_check_ieee_exceptions();
2229
                    gen_op_store_QT0_fpr(QFPREG(rd));
2230
                    break;
2231
                case 0x4d: /* fdivs */
2232
                    gen_clear_float_exceptions();
2233
                    gen_helper_fdivs(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
2234
                    gen_helper_check_ieee_exceptions();
2235
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2236
                    break;
2237
                case 0x4e: /* fdivd */
2238
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2239
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2240
                    gen_clear_float_exceptions();
2241
                    gen_helper_fdivd();
2242
                    gen_helper_check_ieee_exceptions();
2243
                    gen_op_store_DT0_fpr(DFPREG(rd));
2244
                    break;
2245
                case 0x4f: /* fdivq */
2246
                    CHECK_FPU_FEATURE(dc, FLOAT128);
2247
                    gen_op_load_fpr_QT0(QFPREG(rs1));
2248
                    gen_op_load_fpr_QT1(QFPREG(rs2));
2249
                    gen_clear_float_exceptions();
2250
                    gen_helper_fdivq();
2251
                    gen_helper_check_ieee_exceptions();
2252
                    gen_op_store_QT0_fpr(QFPREG(rd));
2253
                    break;
2254
                case 0x69: /* fsmuld */
2255
                    CHECK_FPU_FEATURE(dc, FSMULD);
2256
                    gen_clear_float_exceptions();
2257
                    gen_helper_fsmuld(cpu_fpr[rs1], cpu_fpr[rs2]);
2258
                    gen_helper_check_ieee_exceptions();
2259
                    gen_op_store_DT0_fpr(DFPREG(rd));
2260
                    break;
2261
                case 0x6e: /* fdmulq */
2262
                    CHECK_FPU_FEATURE(dc, FLOAT128);
2263
                    gen_op_load_fpr_DT0(DFPREG(rs1));
2264
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2265
                    gen_clear_float_exceptions();
2266
                    gen_helper_fdmulq();
2267
                    gen_helper_check_ieee_exceptions();
2268
                    gen_op_store_QT0_fpr(QFPREG(rd));
2269
                    break;
2270
                case 0xc4: /* fitos */
2271
                    gen_clear_float_exceptions();
2272
                    gen_helper_fitos(cpu_tmp32, cpu_fpr[rs2]);
2273
                    gen_helper_check_ieee_exceptions();
2274
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2275
                    break;
2276
                case 0xc6: /* fdtos */
2277
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2278
                    gen_clear_float_exceptions();
2279
                    gen_helper_fdtos(cpu_tmp32);
2280
                    gen_helper_check_ieee_exceptions();
2281
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2282
                    break;
2283
                case 0xc7: /* fqtos */
2284
                    CHECK_FPU_FEATURE(dc, FLOAT128);
2285
                    gen_op_load_fpr_QT1(QFPREG(rs2));
2286
                    gen_clear_float_exceptions();
2287
                    gen_helper_fqtos(cpu_tmp32);
2288
                    gen_helper_check_ieee_exceptions();
2289
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2290
                    break;
2291
                case 0xc8: /* fitod */
2292
                    gen_helper_fitod(cpu_fpr[rs2]);
2293
                    gen_op_store_DT0_fpr(DFPREG(rd));
2294
                    break;
2295
                case 0xc9: /* fstod */
2296
                    gen_helper_fstod(cpu_fpr[rs2]);
2297
                    gen_op_store_DT0_fpr(DFPREG(rd));
2298
                    break;
2299
                case 0xcb: /* fqtod */
2300
                    CHECK_FPU_FEATURE(dc, FLOAT128);
2301
                    gen_op_load_fpr_QT1(QFPREG(rs2));
2302
                    gen_clear_float_exceptions();
2303
                    gen_helper_fqtod();
2304
                    gen_helper_check_ieee_exceptions();
2305
                    gen_op_store_DT0_fpr(DFPREG(rd));
2306
                    break;
2307
                case 0xcc: /* fitoq */
2308
                    CHECK_FPU_FEATURE(dc, FLOAT128);
2309
                    gen_helper_fitoq(cpu_fpr[rs2]);
2310
                    gen_op_store_QT0_fpr(QFPREG(rd));
2311
                    break;
2312
                case 0xcd: /* fstoq */
2313
                    CHECK_FPU_FEATURE(dc, FLOAT128);
2314
                    gen_helper_fstoq(cpu_fpr[rs2]);
2315
                    gen_op_store_QT0_fpr(QFPREG(rd));
2316
                    break;
2317
                case 0xce: /* fdtoq */
2318
                    CHECK_FPU_FEATURE(dc, FLOAT128);
2319
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2320
                    gen_helper_fdtoq();
2321
                    gen_op_store_QT0_fpr(QFPREG(rd));
2322
                    break;
2323
                case 0xd1: /* fstoi */
2324
                    gen_clear_float_exceptions();
2325
                    gen_helper_fstoi(cpu_tmp32, cpu_fpr[rs2]);
2326
                    gen_helper_check_ieee_exceptions();
2327
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2328
                    break;
2329
                case 0xd2: /* fdtoi */
2330
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2331
                    gen_clear_float_exceptions();
2332
                    gen_helper_fdtoi(cpu_tmp32);
2333
                    gen_helper_check_ieee_exceptions();
2334
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2335
                    break;
2336
                case 0xd3: /* fqtoi */
2337
                    CHECK_FPU_FEATURE(dc, FLOAT128);
2338
                    gen_op_load_fpr_QT1(QFPREG(rs2));
2339
                    gen_clear_float_exceptions();
2340
                    gen_helper_fqtoi(cpu_tmp32);
2341
                    gen_helper_check_ieee_exceptions();
2342
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2343
                    break;
2344
#ifdef TARGET_SPARC64
2345
                case 0x2: /* V9 fmovd */
2346
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)]);
2347
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1],
2348
                                    cpu_fpr[DFPREG(rs2) + 1]);
2349
                    break;
2350
                case 0x3: /* V9 fmovq */
2351
                    CHECK_FPU_FEATURE(dc, FLOAT128);
2352
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], cpu_fpr[QFPREG(rs2)]);
2353
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1],
2354
                                    cpu_fpr[QFPREG(rs2) + 1]);
2355
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2],
2356
                                    cpu_fpr[QFPREG(rs2) + 2]);
2357
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3],
2358
                                    cpu_fpr[QFPREG(rs2) + 3]);
2359
                    break;
2360
                case 0x6: /* V9 fnegd */
2361
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2362
                    gen_helper_fnegd();
2363
                    gen_op_store_DT0_fpr(DFPREG(rd));
2364
                    break;
2365
                case 0x7: /* V9 fnegq */
2366
                    CHECK_FPU_FEATURE(dc, FLOAT128);
2367
                    gen_op_load_fpr_QT1(QFPREG(rs2));
2368
                    gen_helper_fnegq();
2369
                    gen_op_store_QT0_fpr(QFPREG(rd));
2370
                    break;
2371
                case 0xa: /* V9 fabsd */
2372
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2373
                    gen_helper_fabsd();
2374
                    gen_op_store_DT0_fpr(DFPREG(rd));
2375
                    break;
2376
                case 0xb: /* V9 fabsq */
2377
                    CHECK_FPU_FEATURE(dc, FLOAT128);
2378
                    gen_op_load_fpr_QT1(QFPREG(rs2));
2379
                    gen_helper_fabsq();
2380
                    gen_op_store_QT0_fpr(QFPREG(rd));
2381
                    break;
2382
                case 0x81: /* V9 fstox */
2383
                    gen_clear_float_exceptions();
2384
                    gen_helper_fstox(cpu_fpr[rs2]);
2385
                    gen_helper_check_ieee_exceptions();
2386
                    gen_op_store_DT0_fpr(DFPREG(rd));
2387
                    break;
2388
                case 0x82: /* V9 fdtox */
2389
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2390
                    gen_clear_float_exceptions();
2391
                    gen_helper_fdtox();
2392
                    gen_helper_check_ieee_exceptions();
2393
                    gen_op_store_DT0_fpr(DFPREG(rd));
2394
                    break;
2395
                case 0x83: /* V9 fqtox */
2396
                    CHECK_FPU_FEATURE(dc, FLOAT128);
2397
                    gen_op_load_fpr_QT1(QFPREG(rs2));
2398
                    gen_clear_float_exceptions();
2399
                    gen_helper_fqtox();
2400
                    gen_helper_check_ieee_exceptions();
2401
                    gen_op_store_DT0_fpr(DFPREG(rd));
2402
                    break;
2403
                case 0x84: /* V9 fxtos */
2404
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2405
                    gen_clear_float_exceptions();
2406
                    gen_helper_fxtos(cpu_tmp32);
2407
                    gen_helper_check_ieee_exceptions();
2408
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2409
                    break;
2410
                case 0x88: /* V9 fxtod */
2411
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2412
                    gen_clear_float_exceptions();
2413
                    gen_helper_fxtod();
2414
                    gen_helper_check_ieee_exceptions();
2415
                    gen_op_store_DT0_fpr(DFPREG(rd));
2416
                    break;
2417
                case 0x8c: /* V9 fxtoq */
2418
                    CHECK_FPU_FEATURE(dc, FLOAT128);
2419
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2420
                    gen_clear_float_exceptions();
2421
                    gen_helper_fxtoq();
2422
                    gen_helper_check_ieee_exceptions();
2423
                    gen_op_store_QT0_fpr(QFPREG(rd));
2424
                    break;
2425
#endif
2426
                default:
2427
                    goto illegal_insn;
2428
                }
2429
            } else if (xop == 0x35) {   /* FPU Operations */
2430
#ifdef TARGET_SPARC64
2431
                int cond;
2432
#endif
2433
                if (gen_trap_ifnofpu(dc, cpu_cond))
2434
                    goto jmp_insn;
2435
                gen_op_clear_ieee_excp_and_FTT();
2436
                rs1 = GET_FIELD(insn, 13, 17);
2437
                rs2 = GET_FIELD(insn, 27, 31);
2438
                xop = GET_FIELD(insn, 18, 26);
2439
#ifdef TARGET_SPARC64
2440
                if ((xop & 0x11f) == 0x005) { // V9 fmovsr
2441
                    int l1;
2442

    
2443
                    l1 = gen_new_label();
2444
                    cond = GET_FIELD_SP(insn, 14, 17);
2445
                    cpu_src1 = get_src1(insn, cpu_src1);
2446
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2447
                                       0, l1);
2448
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);
2449
                    gen_set_label(l1);
2450
                    break;
2451
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
2452
                    int l1;
2453

    
2454
                    l1 = gen_new_label();
2455
                    cond = GET_FIELD_SP(insn, 14, 17);
2456
                    cpu_src1 = get_src1(insn, cpu_src1);
2457
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2458
                                       0, l1);
2459
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)]);
2460
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], cpu_fpr[DFPREG(rs2) + 1]);
2461
                    gen_set_label(l1);
2462
                    break;
2463
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
2464
                    int l1;
2465

    
2466
                    CHECK_FPU_FEATURE(dc, FLOAT128);
2467
                    l1 = gen_new_label();
2468
                    cond = GET_FIELD_SP(insn, 14, 17);
2469
                    cpu_src1 = get_src1(insn, cpu_src1);
2470
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2471
                                       0, l1);
2472
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], cpu_fpr[QFPREG(rs2)]);
2473
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], cpu_fpr[QFPREG(rs2) + 1]);
2474
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], cpu_fpr[QFPREG(rs2) + 2]);
2475
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], cpu_fpr[QFPREG(rs2) + 3]);
2476
                    gen_set_label(l1);
2477
                    break;
2478
                }
2479
#endif
2480
                switch (xop) {
2481
#ifdef TARGET_SPARC64
2482
#define FMOVSCC(fcc)                                                    \
2483
                    {                                                   \
2484
                        TCGv r_cond;                                    \
2485
                        int l1;                                         \
2486
                                                                        \
2487
                        l1 = gen_new_label();                           \
2488
                        r_cond = tcg_temp_new();                        \
2489
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2490
                        gen_fcond(r_cond, fcc, cond);                   \
2491
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2492
                                           0, l1);                      \
2493
                        tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);     \
2494
                        gen_set_label(l1);                              \
2495
                        tcg_temp_free(r_cond);                          \
2496
                    }
2497
#define FMOVDCC(fcc)                                                    \
2498
                    {                                                   \
2499
                        TCGv r_cond;                                    \
2500
                        int l1;                                         \
2501
                                                                        \
2502
                        l1 = gen_new_label();                           \
2503
                        r_cond = tcg_temp_new();                        \
2504
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2505
                        gen_fcond(r_cond, fcc, cond);                   \
2506
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2507
                                           0, l1);                      \
2508
                        tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)],            \
2509
                                        cpu_fpr[DFPREG(rs2)]);          \
2510
                        tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1],        \
2511
                                        cpu_fpr[DFPREG(rs2) + 1]);      \
2512
                        gen_set_label(l1);                              \
2513
                        tcg_temp_free(r_cond);                          \
2514
                    }
2515
#define FMOVQCC(fcc)                                                    \
2516
                    {                                                   \
2517
                        TCGv r_cond;                                    \
2518
                        int l1;                                         \
2519
                                                                        \
2520
                        l1 = gen_new_label();                           \
2521
                        r_cond = tcg_temp_new();                        \
2522
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2523
                        gen_fcond(r_cond, fcc, cond);                   \
2524
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2525
                                           0, l1);                      \
2526
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)],            \
2527
                                        cpu_fpr[QFPREG(rs2)]);          \
2528
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1],        \
2529
                                        cpu_fpr[QFPREG(rs2) + 1]);      \
2530
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2],        \
2531
                                        cpu_fpr[QFPREG(rs2) + 2]);      \
2532
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3],        \
2533
                                        cpu_fpr[QFPREG(rs2) + 3]);      \
2534
                        gen_set_label(l1);                              \
2535
                        tcg_temp_free(r_cond);                          \
2536
                    }
2537
                    case 0x001: /* V9 fmovscc %fcc0 */
2538
                        FMOVSCC(0);
2539
                        break;
2540
                    case 0x002: /* V9 fmovdcc %fcc0 */
2541
                        FMOVDCC(0);
2542
                        break;
2543
                    case 0x003: /* V9 fmovqcc %fcc0 */
2544
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2545
                        FMOVQCC(0);
2546
                        break;
2547
                    case 0x041: /* V9 fmovscc %fcc1 */
2548
                        FMOVSCC(1);
2549
                        break;
2550
                    case 0x042: /* V9 fmovdcc %fcc1 */
2551
                        FMOVDCC(1);
2552
                        break;
2553
                    case 0x043: /* V9 fmovqcc %fcc1 */
2554
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2555
                        FMOVQCC(1);
2556
                        break;
2557
                    case 0x081: /* V9 fmovscc %fcc2 */
2558
                        FMOVSCC(2);
2559
                        break;
2560
                    case 0x082: /* V9 fmovdcc %fcc2 */
2561
                        FMOVDCC(2);
2562
                        break;
2563
                    case 0x083: /* V9 fmovqcc %fcc2 */
2564
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2565
                        FMOVQCC(2);
2566
                        break;
2567
                    case 0x0c1: /* V9 fmovscc %fcc3 */
2568
                        FMOVSCC(3);
2569
                        break;
2570
                    case 0x0c2: /* V9 fmovdcc %fcc3 */
2571
                        FMOVDCC(3);
2572
                        break;
2573
                    case 0x0c3: /* V9 fmovqcc %fcc3 */
2574
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2575
                        FMOVQCC(3);
2576
                        break;
2577
#undef FMOVSCC
2578
#undef FMOVDCC
2579
#undef FMOVQCC
2580
#define FMOVSCC(icc)                                                    \
2581
                    {                                                   \
2582
                        TCGv r_cond;                                    \
2583
                        int l1;                                         \
2584
                                                                        \
2585
                        l1 = gen_new_label();                           \
2586
                        r_cond = tcg_temp_new();                        \
2587
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2588
                        gen_cond(r_cond, icc, cond, dc);                \
2589
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2590
                                           0, l1);                      \
2591
                        tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);     \
2592
                        gen_set_label(l1);                              \
2593
                        tcg_temp_free(r_cond);                          \
2594
                    }
2595
#define FMOVDCC(icc)                                                    \
2596
                    {                                                   \
2597
                        TCGv r_cond;                                    \
2598
                        int l1;                                         \
2599
                                                                        \
2600
                        l1 = gen_new_label();                           \
2601
                        r_cond = tcg_temp_new();                        \
2602
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2603
                        gen_cond(r_cond, icc, cond, dc);                \
2604
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2605
                                           0, l1);                      \
2606
                        tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)],            \
2607
                                        cpu_fpr[DFPREG(rs2)]);          \
2608
                        tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1],        \
2609
                                        cpu_fpr[DFPREG(rs2) + 1]);      \
2610
                        gen_set_label(l1);                              \
2611
                        tcg_temp_free(r_cond);                          \
2612
                    }
2613
#define FMOVQCC(icc)                                                    \
2614
                    {                                                   \
2615
                        TCGv r_cond;                                    \
2616
                        int l1;                                         \
2617
                                                                        \
2618
                        l1 = gen_new_label();                           \
2619
                        r_cond = tcg_temp_new();                        \
2620
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2621
                        gen_cond(r_cond, icc, cond, dc);                \
2622
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2623
                                           0, l1);                      \
2624
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)],            \
2625
                                        cpu_fpr[QFPREG(rs2)]);          \
2626
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1],        \
2627
                                        cpu_fpr[QFPREG(rs2) + 1]);      \
2628
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2],        \
2629
                                        cpu_fpr[QFPREG(rs2) + 2]);      \
2630
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3],        \
2631
                                        cpu_fpr[QFPREG(rs2) + 3]);      \
2632
                        gen_set_label(l1);                              \
2633
                        tcg_temp_free(r_cond);                          \
2634
                    }
2635

    
2636
                    case 0x101: /* V9 fmovscc %icc */
2637
                        FMOVSCC(0);
2638
                        break;
2639
                    case 0x102: /* V9 fmovdcc %icc */
2640
                        FMOVDCC(0);
2641
                    case 0x103: /* V9 fmovqcc %icc */
2642
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2643
                        FMOVQCC(0);
2644
                        break;
2645
                    case 0x181: /* V9 fmovscc %xcc */
2646
                        FMOVSCC(1);
2647
                        break;
2648
                    case 0x182: /* V9 fmovdcc %xcc */
2649
                        FMOVDCC(1);
2650
                        break;
2651
                    case 0x183: /* V9 fmovqcc %xcc */
2652
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2653
                        FMOVQCC(1);
2654
                        break;
2655
#undef FMOVSCC
2656
#undef FMOVDCC
2657
#undef FMOVQCC
2658
#endif
2659
                    case 0x51: /* fcmps, V9 %fcc */
2660
                        gen_op_fcmps(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]);
2661
                        break;
2662
                    case 0x52: /* fcmpd, V9 %fcc */
2663
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2664
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2665
                        gen_op_fcmpd(rd & 3);
2666
                        break;
2667
                    case 0x53: /* fcmpq, V9 %fcc */
2668
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2669
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2670
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2671
                        gen_op_fcmpq(rd & 3);
2672
                        break;
2673
                    case 0x55: /* fcmpes, V9 %fcc */
2674
                        gen_op_fcmpes(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]);
2675
                        break;
2676
                    case 0x56: /* fcmped, V9 %fcc */
2677
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2678
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2679
                        gen_op_fcmped(rd & 3);
2680
                        break;
2681
                    case 0x57: /* fcmpeq, V9 %fcc */
2682
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2683
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2684
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2685
                        gen_op_fcmpeq(rd & 3);
2686
                        break;
2687
                    default:
2688
                        goto illegal_insn;
2689
                }
2690
            } else if (xop == 0x2) {
2691
                // clr/mov shortcut
2692

    
2693
                rs1 = GET_FIELD(insn, 13, 17);
2694
                if (rs1 == 0) {
2695
                    // or %g0, x, y -> mov T0, x; mov y, T0
2696
                    if (IS_IMM) {       /* immediate */
2697
                        TCGv r_const;
2698

    
2699
                        simm = GET_FIELDs(insn, 19, 31);
2700
                        r_const = tcg_const_tl(simm);
2701
                        gen_movl_TN_reg(rd, r_const);
2702
                        tcg_temp_free(r_const);
2703
                    } else {            /* register */
2704
                        rs2 = GET_FIELD(insn, 27, 31);
2705
                        gen_movl_reg_TN(rs2, cpu_dst);
2706
                        gen_movl_TN_reg(rd, cpu_dst);
2707
                    }
2708
                } else {
2709
                    cpu_src1 = get_src1(insn, cpu_src1);
2710
                    if (IS_IMM) {       /* immediate */
2711
                        simm = GET_FIELDs(insn, 19, 31);
2712
                        tcg_gen_ori_tl(cpu_dst, cpu_src1, simm);
2713
                        gen_movl_TN_reg(rd, cpu_dst);
2714
                    } else {            /* register */
2715
                        // or x, %g0, y -> mov T1, x; mov y, T1
2716
                        rs2 = GET_FIELD(insn, 27, 31);
2717
                        if (rs2 != 0) {
2718
                            gen_movl_reg_TN(rs2, cpu_src2);
2719
                            tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
2720
                            gen_movl_TN_reg(rd, cpu_dst);
2721
                        } else
2722
                            gen_movl_TN_reg(rd, cpu_src1);
2723
                    }
2724
                }
2725
#ifdef TARGET_SPARC64
2726
            } else if (xop == 0x25) { /* sll, V9 sllx */
2727
                cpu_src1 = get_src1(insn, cpu_src1);
2728
                if (IS_IMM) {   /* immediate */
2729
                    simm = GET_FIELDs(insn, 20, 31);
2730
                    if (insn & (1 << 12)) {
2731
                        tcg_gen_shli_i64(cpu_dst, cpu_src1, simm & 0x3f);
2732
                    } else {
2733
                        tcg_gen_shli_i64(cpu_dst, cpu_src1, simm & 0x1f);
2734
                    }
2735
                } else {                /* register */
2736
                    rs2 = GET_FIELD(insn, 27, 31);
2737
                    gen_movl_reg_TN(rs2, cpu_src2);
2738
                    if (insn & (1 << 12)) {
2739
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2740
                    } else {
2741
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2742
                    }
2743
                    tcg_gen_shl_i64(cpu_dst, cpu_src1, cpu_tmp0);
2744
                }
2745
                gen_movl_TN_reg(rd, cpu_dst);
2746
            } else if (xop == 0x26) { /* srl, V9 srlx */
2747
                cpu_src1 = get_src1(insn, cpu_src1);
2748
                if (IS_IMM) {   /* immediate */
2749
                    simm = GET_FIELDs(insn, 20, 31);
2750
                    if (insn & (1 << 12)) {
2751
                        tcg_gen_shri_i64(cpu_dst, cpu_src1, simm & 0x3f);
2752
                    } else {
2753
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2754
                        tcg_gen_shri_i64(cpu_dst, cpu_dst, simm & 0x1f);
2755
                    }
2756
                } else {                /* register */
2757
                    rs2 = GET_FIELD(insn, 27, 31);
2758
                    gen_movl_reg_TN(rs2, cpu_src2);
2759
                    if (insn & (1 << 12)) {
2760
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2761
                        tcg_gen_shr_i64(cpu_dst, cpu_src1, cpu_tmp0);
2762
                    } else {
2763
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2764
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2765
                        tcg_gen_shr_i64(cpu_dst, cpu_dst, cpu_tmp0);
2766
                    }
2767
                }
2768
                gen_movl_TN_reg(rd, cpu_dst);
2769
            } else if (xop == 0x27) { /* sra, V9 srax */
2770
                cpu_src1 = get_src1(insn, cpu_src1);
2771
                if (IS_IMM) {   /* immediate */
2772
                    simm = GET_FIELDs(insn, 20, 31);
2773
                    if (insn & (1 << 12)) {
2774
                        tcg_gen_sari_i64(cpu_dst, cpu_src1, simm & 0x3f);
2775
                    } else {
2776
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2777
                        tcg_gen_ext32s_i64(cpu_dst, cpu_dst);
2778
                        tcg_gen_sari_i64(cpu_dst, cpu_dst, simm & 0x1f);
2779
                    }
2780
                } else {                /* register */
2781
                    rs2 = GET_FIELD(insn, 27, 31);
2782
                    gen_movl_reg_TN(rs2, cpu_src2);
2783
                    if (insn & (1 << 12)) {
2784
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2785
                        tcg_gen_sar_i64(cpu_dst, cpu_src1, cpu_tmp0);
2786
                    } else {
2787
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2788
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2789
                        tcg_gen_ext32s_i64(cpu_dst, cpu_dst);
2790
                        tcg_gen_sar_i64(cpu_dst, cpu_dst, cpu_tmp0);
2791
                    }
2792
                }
2793
                gen_movl_TN_reg(rd, cpu_dst);
2794
#endif
2795
            } else if (xop < 0x36) {
2796
                if (xop < 0x20) {
2797
                    cpu_src1 = get_src1(insn, cpu_src1);
2798
                    cpu_src2 = get_src2(insn, cpu_src2);
2799
                    switch (xop & ~0x10) {
2800
                    case 0x0: /* add */
2801
                        if (IS_IMM) {
2802
                            simm = GET_FIELDs(insn, 19, 31);
2803
                            if (xop & 0x10) {
2804
                                gen_op_addi_cc(cpu_dst, cpu_src1, simm);
2805
                                tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADD);
2806
                                dc->cc_op = CC_OP_ADD;
2807
                            } else {
2808
                                tcg_gen_addi_tl(cpu_dst, cpu_src1, simm);
2809
                            }
2810
                        } else {
2811
                            if (xop & 0x10) {
2812
                                gen_op_add_cc(cpu_dst, cpu_src1, cpu_src2);
2813
                                tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADD);
2814
                                dc->cc_op = CC_OP_ADD;
2815
                            } else {
2816
                                tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
2817
                            }
2818
                        }
2819
                        break;
2820
                    case 0x1: /* and */
2821
                        if (IS_IMM) {
2822
                            simm = GET_FIELDs(insn, 19, 31);
2823
                            tcg_gen_andi_tl(cpu_dst, cpu_src1, simm);
2824
                        } else {
2825
                            tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_src2);
2826
                        }
2827
                        if (xop & 0x10) {
2828
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
2829
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
2830
                            dc->cc_op = CC_OP_LOGIC;
2831
                        }
2832
                        break;
2833
                    case 0x2: /* or */
2834
                        if (IS_IMM) {
2835
                            simm = GET_FIELDs(insn, 19, 31);
2836
                            tcg_gen_ori_tl(cpu_dst, cpu_src1, simm);
2837
                        } else {
2838
                            tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
2839
                        }
2840
                        if (xop & 0x10) {
2841
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
2842
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
2843
                            dc->cc_op = CC_OP_LOGIC;
2844
                        }
2845
                        break;
2846
                    case 0x3: /* xor */
2847
                        if (IS_IMM) {
2848
                            simm = GET_FIELDs(insn, 19, 31);
2849
                            tcg_gen_xori_tl(cpu_dst, cpu_src1, simm);
2850
                        } else {
2851
                            tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
2852
                        }
2853
                        if (xop & 0x10) {
2854
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
2855
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
2856
                            dc->cc_op = CC_OP_LOGIC;
2857
                        }
2858
                        break;
2859
                    case 0x4: /* sub */
2860
                        if (IS_IMM) {
2861
                            simm = GET_FIELDs(insn, 19, 31);
2862
                            if (xop & 0x10) {
2863
                                gen_op_subi_cc(cpu_dst, cpu_src1, simm, dc);
2864
                            } else {
2865
                                tcg_gen_subi_tl(cpu_dst, cpu_src1, simm);
2866
                            }
2867
                        } else {
2868
                            if (xop & 0x10) {
2869
                                gen_op_sub_cc(cpu_dst, cpu_src1, cpu_src2);
2870
                                tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUB);
2871
                                dc->cc_op = CC_OP_SUB;
2872
                            } else {
2873
                                tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_src2);
2874
                            }
2875
                        }
2876
                        break;
2877
                    case 0x5: /* andn */
2878
                        if (IS_IMM) {
2879
                            simm = GET_FIELDs(insn, 19, 31);
2880
                            tcg_gen_andi_tl(cpu_dst, cpu_src1, ~simm);
2881
                        } else {
2882
                            tcg_gen_andc_tl(cpu_dst, cpu_src1, cpu_src2);
2883
                        }
2884
                        if (xop & 0x10) {
2885
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
2886
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
2887
                            dc->cc_op = CC_OP_LOGIC;
2888
                        }
2889
                        break;
2890
                    case 0x6: /* orn */
2891
                        if (IS_IMM) {
2892
                            simm = GET_FIELDs(insn, 19, 31);
2893
                            tcg_gen_ori_tl(cpu_dst, cpu_src1, ~simm);
2894
                        } else {
2895
                            tcg_gen_orc_tl(cpu_dst, cpu_src1, cpu_src2);
2896
                        }
2897
                        if (xop & 0x10) {
2898
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
2899
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
2900
                            dc->cc_op = CC_OP_LOGIC;
2901
                        }
2902
                        break;
2903
                    case 0x7: /* xorn */
2904
                        if (IS_IMM) {
2905
                            simm = GET_FIELDs(insn, 19, 31);
2906
                            tcg_gen_xori_tl(cpu_dst, cpu_src1, ~simm);
2907
                        } else {
2908
                            tcg_gen_not_tl(cpu_tmp0, cpu_src2);
2909
                            tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_tmp0);
2910
                        }
2911
                        if (xop & 0x10) {
2912
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
2913
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
2914
                            dc->cc_op = CC_OP_LOGIC;
2915
                        }
2916
                        break;
2917
                    case 0x8: /* addx, V9 addc */
2918
                        if (IS_IMM) {
2919
                            simm = GET_FIELDs(insn, 19, 31);
2920
                            if (xop & 0x10) {
2921
                                gen_helper_compute_psr();
2922
                                gen_op_addxi_cc(cpu_dst, cpu_src1, simm);
2923
                                tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADDX);
2924
                                dc->cc_op = CC_OP_ADDX;
2925
                            } else {
2926
                                gen_helper_compute_psr();
2927
                                gen_mov_reg_C(cpu_tmp0, cpu_psr);
2928
                                tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, simm);
2929
                                tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_tmp0);
2930
                            }
2931
                        } else {
2932
                            if (xop & 0x10) {
2933
                                gen_helper_compute_psr();
2934
                                gen_op_addx_cc(cpu_dst, cpu_src1, cpu_src2);
2935
                                tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADDX);
2936
                                dc->cc_op = CC_OP_ADDX;
2937
                            } else {
2938
                                gen_helper_compute_psr();
2939
                                gen_mov_reg_C(cpu_tmp0, cpu_psr);
2940
                                tcg_gen_add_tl(cpu_tmp0, cpu_src2, cpu_tmp0);
2941
                                tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_tmp0);
2942
                            }
2943
                        }
2944
                        break;
2945
#ifdef TARGET_SPARC64
2946
                    case 0x9: /* V9 mulx */
2947
                        if (IS_IMM) {
2948
                            simm = GET_FIELDs(insn, 19, 31);
2949
                            tcg_gen_muli_i64(cpu_dst, cpu_src1, simm);
2950
                        } else {
2951
                            tcg_gen_mul_i64(cpu_dst, cpu_src1, cpu_src2);
2952
                        }
2953
                        break;
2954
#endif
2955
                    case 0xa: /* umul */
2956
                        CHECK_IU_FEATURE(dc, MUL);
2957
                        gen_op_umul(cpu_dst, cpu_src1, cpu_src2);
2958
                        if (xop & 0x10) {
2959
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
2960
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
2961
                            dc->cc_op = CC_OP_LOGIC;
2962
                        }
2963
                        break;
2964
                    case 0xb: /* smul */
2965
                        CHECK_IU_FEATURE(dc, MUL);
2966
                        gen_op_smul(cpu_dst, cpu_src1, cpu_src2);
2967
                        if (xop & 0x10) {
2968
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
2969
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
2970
                            dc->cc_op = CC_OP_LOGIC;
2971
                        }
2972
                        break;
2973
                    case 0xc: /* subx, V9 subc */
2974
                        if (IS_IMM) {
2975
                            simm = GET_FIELDs(insn, 19, 31);
2976
                            if (xop & 0x10) {
2977
                                gen_helper_compute_psr();
2978
                                gen_op_subxi_cc(cpu_dst, cpu_src1, simm);
2979
                                tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUBX);
2980
                                dc->cc_op = CC_OP_SUBX;
2981
                            } else {
2982
                                gen_helper_compute_psr();
2983
                                gen_mov_reg_C(cpu_tmp0, cpu_psr);
2984
                                tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, simm);
2985
                                tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_tmp0);
2986
                            }
2987
                        } else {
2988
                            if (xop & 0x10) {
2989
                                gen_helper_compute_psr();
2990
                                gen_op_subx_cc(cpu_dst, cpu_src1, cpu_src2);
2991
                                tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUBX);
2992
                                dc->cc_op = CC_OP_SUBX;
2993
                            } else {
2994
                                gen_helper_compute_psr();
2995
                                gen_mov_reg_C(cpu_tmp0, cpu_psr);
2996
                                tcg_gen_add_tl(cpu_tmp0, cpu_src2, cpu_tmp0);
2997
                                tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_tmp0);
2998
                            }
2999
                        }
3000
                        break;
3001
#ifdef TARGET_SPARC64
3002
                    case 0xd: /* V9 udivx */
3003
                        tcg_gen_mov_tl(cpu_cc_src, cpu_src1);
3004
                        tcg_gen_mov_tl(cpu_cc_src2, cpu_src2);
3005
                        gen_trap_ifdivzero_tl(cpu_cc_src2);
3006
                        tcg_gen_divu_i64(cpu_dst, cpu_cc_src, cpu_cc_src2);
3007
                        break;
3008
#endif
3009
                    case 0xe: /* udiv */
3010
                        CHECK_IU_FEATURE(dc, DIV);
3011
                        gen_helper_udiv(cpu_dst, cpu_src1, cpu_src2);
3012
                        if (xop & 0x10) {
3013
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3014
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_DIV);
3015
                            dc->cc_op = CC_OP_DIV;
3016
                        }
3017
                        break;
3018
                    case 0xf: /* sdiv */
3019
                        CHECK_IU_FEATURE(dc, DIV);
3020
                        gen_helper_sdiv(cpu_dst, cpu_src1, cpu_src2);
3021
                        if (xop & 0x10) {
3022
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3023
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_DIV);
3024
                            dc->cc_op = CC_OP_DIV;
3025
                        }
3026
                        break;
3027
                    default:
3028
                        goto illegal_insn;
3029
                    }
3030
                    gen_movl_TN_reg(rd, cpu_dst);
3031
                } else {
3032
                    cpu_src1 = get_src1(insn, cpu_src1);
3033
                    cpu_src2 = get_src2(insn, cpu_src2);
3034
                    switch (xop) {
3035
                    case 0x20: /* taddcc */
3036
                        gen_op_tadd_cc(cpu_dst, cpu_src1, cpu_src2);
3037
                        gen_movl_TN_reg(rd, cpu_dst);
3038
                        tcg_gen_movi_i32(cpu_cc_op, CC_OP_TADD);
3039
                        dc->cc_op = CC_OP_TADD;
3040
                        break;
3041
                    case 0x21: /* tsubcc */
3042
                        gen_op_tsub_cc(cpu_dst, cpu_src1, cpu_src2);
3043
                        gen_movl_TN_reg(rd, cpu_dst);
3044
                        tcg_gen_movi_i32(cpu_cc_op, CC_OP_TSUB);
3045
                        dc->cc_op = CC_OP_TSUB;
3046
                        break;
3047
                    case 0x22: /* taddcctv */
3048
                        save_state(dc, cpu_cond);
3049
                        gen_op_tadd_ccTV(cpu_dst, cpu_src1, cpu_src2);
3050
                        gen_movl_TN_reg(rd, cpu_dst);
3051
                        tcg_gen_movi_i32(cpu_cc_op, CC_OP_TADDTV);
3052
                        dc->cc_op = CC_OP_TADDTV;
3053
                        break;
3054
                    case 0x23: /* tsubcctv */
3055
                        save_state(dc, cpu_cond);
3056
                        gen_op_tsub_ccTV(cpu_dst, cpu_src1, cpu_src2);
3057
                        gen_movl_TN_reg(rd, cpu_dst);
3058
                        tcg_gen_movi_i32(cpu_cc_op, CC_OP_TSUBTV);
3059
                        dc->cc_op = CC_OP_TSUBTV;
3060
                        break;
3061
                    case 0x24: /* mulscc */
3062
                        gen_helper_compute_psr();
3063
                        gen_op_mulscc(cpu_dst, cpu_src1, cpu_src2);
3064
                        gen_movl_TN_reg(rd, cpu_dst);
3065
                        tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADD);
3066
                        dc->cc_op = CC_OP_ADD;
3067
                        break;
3068
#ifndef TARGET_SPARC64
3069
                    case 0x25:  /* sll */
3070
                        if (IS_IMM) { /* immediate */
3071
                            simm = GET_FIELDs(insn, 20, 31);
3072
                            tcg_gen_shli_tl(cpu_dst, cpu_src1, simm & 0x1f);
3073
                        } else { /* register */
3074
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3075
                            tcg_gen_shl_tl(cpu_dst, cpu_src1, cpu_tmp0);
3076
                        }
3077
                        gen_movl_TN_reg(rd, cpu_dst);
3078
                        break;
3079
                    case 0x26:  /* srl */
3080
                        if (IS_IMM) { /* immediate */
3081
                            simm = GET_FIELDs(insn, 20, 31);
3082
                            tcg_gen_shri_tl(cpu_dst, cpu_src1, simm & 0x1f);
3083
                        } else { /* register */
3084
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3085
                            tcg_gen_shr_tl(cpu_dst, cpu_src1, cpu_tmp0);
3086
                        }
3087
                        gen_movl_TN_reg(rd, cpu_dst);
3088
                        break;
3089
                    case 0x27:  /* sra */
3090
                        if (IS_IMM) { /* immediate */
3091
                            simm = GET_FIELDs(insn, 20, 31);
3092
                            tcg_gen_sari_tl(cpu_dst, cpu_src1, simm & 0x1f);
3093
                        } else { /* register */
3094
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3095
                            tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0);
3096
                        }
3097
                        gen_movl_TN_reg(rd, cpu_dst);
3098
                        break;
3099
#endif
3100
                    case 0x30:
3101
                        {
3102
                            switch(rd) {
3103
                            case 0: /* wry */
3104
                                tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
3105
                                tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
3106
                                break;
3107
#ifndef TARGET_SPARC64
3108
                            case 0x01 ... 0x0f: /* undefined in the
3109
                                                   SPARCv8 manual, nop
3110
                                                   on the microSPARC
3111
                                                   II */
3112
                            case 0x10 ... 0x1f: /* implementation-dependent
3113
                                                   in the SPARCv8
3114
                                                   manual, nop on the
3115
                                                   microSPARC II */
3116
                                break;
3117
#else
3118
                            case 0x2: /* V9 wrccr */
3119
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3120
                                gen_helper_wrccr(cpu_dst);
3121
                                tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS);
3122
                                dc->cc_op = CC_OP_FLAGS;
3123
                                break;
3124
                            case 0x3: /* V9 wrasi */
3125
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3126
                                tcg_gen_trunc_tl_i32(cpu_asi, cpu_dst);
3127
                                break;
3128
                            case 0x6: /* V9 wrfprs */
3129
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3130
                                tcg_gen_trunc_tl_i32(cpu_fprs, cpu_dst);
3131
                                save_state(dc, cpu_cond);
3132
                                gen_op_next_insn();
3133
                                tcg_gen_exit_tb(0);
3134
                                dc->is_br = 1;
3135
                                break;
3136
                            case 0xf: /* V9 sir, nop if user */
3137
#if !defined(CONFIG_USER_ONLY)
3138
                                if (supervisor(dc))
3139
                                    ; // XXX
3140
#endif
3141
                                break;
3142
                            case 0x13: /* Graphics Status */
3143
                                if (gen_trap_ifnofpu(dc, cpu_cond))
3144
                                    goto jmp_insn;
3145
                                tcg_gen_xor_tl(cpu_gsr, cpu_src1, cpu_src2);
3146
                                break;
3147
                            case 0x14: /* Softint set */
3148
                                if (!supervisor(dc))
3149
                                    goto illegal_insn;
3150
                                tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2);
3151
                                gen_helper_set_softint(cpu_tmp64);
3152
                                break;
3153
                            case 0x15: /* Softint clear */
3154
                                if (!supervisor(dc))
3155
                                    goto illegal_insn;
3156
                                tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2);
3157
                                gen_helper_clear_softint(cpu_tmp64);
3158
                                break;
3159
                            case 0x16: /* Softint write */
3160
                                if (!supervisor(dc))
3161
                                    goto illegal_insn;
3162
                                tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2);
3163
                                gen_helper_write_softint(cpu_tmp64);
3164
                                break;
3165
                            case 0x17: /* Tick compare */
3166
#if !defined(CONFIG_USER_ONLY)
3167
                                if (!supervisor(dc))
3168
                                    goto illegal_insn;
3169
#endif
3170
                                {
3171
                                    TCGv_ptr r_tickptr;
3172

    
3173
                                    tcg_gen_xor_tl(cpu_tick_cmpr, cpu_src1,
3174
                                                   cpu_src2);
3175
                                    r_tickptr = tcg_temp_new_ptr();
3176
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3177
                                                   offsetof(CPUState, tick));
3178
                                    gen_helper_tick_set_limit(r_tickptr,
3179
                                                              cpu_tick_cmpr);
3180
                                    tcg_temp_free_ptr(r_tickptr);
3181
                                }
3182
                                break;
3183
                            case 0x18: /* System tick */
3184
#if !defined(CONFIG_USER_ONLY)
3185
                                if (!supervisor(dc))
3186
                                    goto illegal_insn;
3187
#endif
3188
                                {
3189
                                    TCGv_ptr r_tickptr;
3190

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

    
3209
                                    tcg_gen_xor_tl(cpu_stick_cmpr, cpu_src1,
3210
                                                   cpu_src2);
3211
                                    r_tickptr = tcg_temp_new_ptr();
3212
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3213
                                                   offsetof(CPUState, stick));
3214
                                    gen_helper_tick_set_limit(r_tickptr,
3215
                                                              cpu_stick_cmpr);
3216
                                    tcg_temp_free_ptr(r_tickptr);
3217
                                }
3218
                                break;
3219

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

    
3274
                                    r_tsptr = tcg_temp_new_ptr();
3275
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3276
                                                   offsetof(CPUState, tsptr));
3277
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3278
                                                  offsetof(trap_state, tpc));
3279
                                    tcg_temp_free_ptr(r_tsptr);
3280
                                }
3281
                                break;
3282
                            case 1: // tnpc
3283
                                {
3284
                                    TCGv_ptr r_tsptr;
3285

    
3286
                                    r_tsptr = tcg_temp_new_ptr();
3287
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3288
                                                   offsetof(CPUState, tsptr));
3289
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3290
                                                  offsetof(trap_state, tnpc));
3291
                                    tcg_temp_free_ptr(r_tsptr);
3292
                                }
3293
                                break;
3294
                            case 2: // tstate
3295
                                {
3296
                                    TCGv_ptr r_tsptr;
3297

    
3298
                                    r_tsptr = tcg_temp_new_ptr();
3299
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3300
                                                   offsetof(CPUState, tsptr));
3301
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3302
                                                  offsetof(trap_state,
3303
                                                           tstate));
3304
                                    tcg_temp_free_ptr(r_tsptr);
3305
                                }
3306
                                break;
3307
                            case 3: // tt
3308
                                {
3309
                                    TCGv_ptr r_tsptr;
3310

    
3311
                                    r_tsptr = tcg_temp_new_ptr();
3312
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3313
                                                   offsetof(CPUState, tsptr));
3314
                                    tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3315
                                    tcg_gen_st_i32(cpu_tmp32, r_tsptr,
3316
                                                   offsetof(trap_state, tt));
3317
                                    tcg_temp_free_ptr(r_tsptr);
3318
                                }
3319
                                break;
3320
                            case 4: // tick
3321
                                {
3322
                                    TCGv_ptr r_tickptr;
3323

    
3324
                                    r_tickptr = tcg_temp_new_ptr();
3325
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3326
                                                   offsetof(CPUState, tick));
3327
                                    gen_helper_tick_set_count(r_tickptr,
3328
                                                              cpu_tmp0);
3329
                                    tcg_temp_free_ptr(r_tickptr);
3330
                                }
3331
                                break;
3332
                            case 5: // tba
3333
                                tcg_gen_mov_tl(cpu_tbr, cpu_tmp0);
3334
                                break;
3335
                            case 6: // pstate
3336
                                save_state(dc, cpu_cond);
3337
                                gen_helper_wrpstate(cpu_tmp0);
3338
                                gen_op_next_insn();
3339
                                tcg_gen_exit_tb(0);
3340
                                dc->is_br = 1;
3341
                                break;
3342
                            case 7: // tl
3343
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3344
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3345
                                               offsetof(CPUSPARCState, tl));
3346
                                break;
3347
                            case 8: // pil
3348
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3349
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3350
                                               offsetof(CPUSPARCState,
3351
                                                        psrpil));
3352
                                break;
3353
                            case 9: // cwp
3354
                                gen_helper_wrcwp(cpu_tmp0);
3355
                                break;
3356
                            case 10: // cansave
3357
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3358
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3359
                                               offsetof(CPUSPARCState,
3360
                                                        cansave));
3361
                                break;
3362
                            case 11: // canrestore
3363
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3364
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3365
                                               offsetof(CPUSPARCState,
3366
                                                        canrestore));
3367
                                break;
3368
                            case 12: // cleanwin
3369
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3370
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3371
                                               offsetof(CPUSPARCState,
3372
                                                        cleanwin));
3373
                                break;
3374
                            case 13: // otherwin
3375
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3376
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3377
                                               offsetof(CPUSPARCState,
3378
                                                        otherwin));
3379
                                break;
3380
                            case 14: // wstate
3381
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3382
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3383
                                               offsetof(CPUSPARCState,
3384
                                                        wstate));
3385
                                break;
3386
                            case 16: // UA2005 gl
3387
                                CHECK_IU_FEATURE(dc, GL);
3388
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3389
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3390
                                               offsetof(CPUSPARCState, gl));
3391
                                break;
3392
                            case 26: // UA2005 strand status
3393
                                CHECK_IU_FEATURE(dc, HYPV);
3394
                                if (!hypervisor(dc))
3395
                                    goto priv_insn;
3396
                                tcg_gen_mov_tl(cpu_ssr, cpu_tmp0);
3397
                                break;
3398
                            default:
3399
                                goto illegal_insn;
3400
                            }
3401
#else
3402
                            tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3403
                            if (dc->def->nwindows != 32)
3404
                                tcg_gen_andi_tl(cpu_tmp32, cpu_tmp32,
3405
                                                (1 << dc->def->nwindows) - 1);
3406
                            tcg_gen_mov_i32(cpu_wim, cpu_tmp32);
3407
#endif
3408
                        }
3409
                        break;
3410
                    case 0x33: /* wrtbr, UA2005 wrhpr */
3411
                        {
3412
#ifndef TARGET_SPARC64
3413
                            if (!supervisor(dc))
3414
                                goto priv_insn;
3415
                            tcg_gen_xor_tl(cpu_tbr, cpu_src1, cpu_src2);
3416
#else
3417
                            CHECK_IU_FEATURE(dc, HYPV);
3418
                            if (!hypervisor(dc))
3419
                                goto priv_insn;
3420
                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
3421
                            switch (rd) {
3422
                            case 0: // hpstate
3423
                                // XXX gen_op_wrhpstate();
3424
                                save_state(dc, cpu_cond);
3425
                                gen_op_next_insn();
3426
                                tcg_gen_exit_tb(0);
3427
                                dc->is_br = 1;
3428
                                break;
3429
                            case 1: // htstate
3430
                                // XXX gen_op_wrhtstate();
3431
                                break;
3432
                            case 3: // hintp
3433
                                tcg_gen_mov_tl(cpu_hintp, cpu_tmp0);
3434
                                break;
3435
                            case 5: // htba
3436
                                tcg_gen_mov_tl(cpu_htba, cpu_tmp0);
3437
                                break;
3438
                            case 31: // hstick_cmpr
3439
                                {
3440
                                    TCGv_ptr r_tickptr;
3441

    
3442
                                    tcg_gen_mov_tl(cpu_hstick_cmpr, cpu_tmp0);
3443
                                    r_tickptr = tcg_temp_new_ptr();
3444
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3445
                                                   offsetof(CPUState, hstick));
3446
                                    gen_helper_tick_set_limit(r_tickptr,
3447
                                                              cpu_hstick_cmpr);
3448
                                    tcg_temp_free_ptr(r_tickptr);
3449
                                }
3450
                                break;
3451
                            case 6: // hver readonly
3452
                            default:
3453
                                goto illegal_insn;
3454
                            }
3455
#endif
3456
                        }
3457
                        break;
3458
#endif
3459
#ifdef TARGET_SPARC64
3460
                    case 0x2c: /* V9 movcc */
3461
                        {
3462
                            int cc = GET_FIELD_SP(insn, 11, 12);
3463
                            int cond = GET_FIELD_SP(insn, 14, 17);
3464
                            TCGv r_cond;
3465
                            int l1;
3466

    
3467
                            r_cond = tcg_temp_new();
3468
                            if (insn & (1 << 18)) {
3469
                                if (cc == 0)
3470
                                    gen_cond(r_cond, 0, cond, dc);
3471
                                else if (cc == 2)
3472
                                    gen_cond(r_cond, 1, cond, dc);
3473
                                else
3474
                                    goto illegal_insn;
3475
                            } else {
3476
                                gen_fcond(r_cond, cc, cond);
3477
                            }
3478

    
3479
                            l1 = gen_new_label();
3480

    
3481
                            tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
3482
                            if (IS_IMM) {       /* immediate */
3483
                                TCGv r_const;
3484

    
3485
                                simm = GET_FIELD_SPs(insn, 0, 10);
3486
                                r_const = tcg_const_tl(simm);
3487
                                gen_movl_TN_reg(rd, r_const);
3488
                                tcg_temp_free(r_const);
3489
                            } else {
3490
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3491
                                gen_movl_reg_TN(rs2, cpu_tmp0);
3492
                                gen_movl_TN_reg(rd, cpu_tmp0);
3493
                            }
3494
                            gen_set_label(l1);
3495
                            tcg_temp_free(r_cond);
3496
                            break;
3497
                        }
3498
                    case 0x2d: /* V9 sdivx */
3499
                        gen_op_sdivx(cpu_dst, cpu_src1, cpu_src2);
3500
                        gen_movl_TN_reg(rd, cpu_dst);
3501
                        break;
3502
                    case 0x2e: /* V9 popc */
3503
                        {
3504
                            cpu_src2 = get_src2(insn, cpu_src2);
3505
                            gen_helper_popc(cpu_dst, cpu_src2);
3506
                            gen_movl_TN_reg(rd, cpu_dst);
3507
                        }
3508
                    case 0x2f: /* V9 movr */
3509
                        {
3510
                            int cond = GET_FIELD_SP(insn, 10, 12);
3511
                            int l1;
3512

    
3513
                            cpu_src1 = get_src1(insn, cpu_src1);
3514

    
3515
                            l1 = gen_new_label();
3516

    
3517
                            tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond],
3518
                                              cpu_src1, 0, l1);
3519
                            if (IS_IMM) {       /* immediate */
3520
                                TCGv r_const;
3521

    
3522
                                simm = GET_FIELD_SPs(insn, 0, 9);
3523
                                r_const = tcg_const_tl(simm);
3524
                                gen_movl_TN_reg(rd, r_const);
3525
                                tcg_temp_free(r_const);
3526
                            } else {
3527
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3528
                                gen_movl_reg_TN(rs2, cpu_tmp0);
3529
                                gen_movl_TN_reg(rd, cpu_tmp0);
3530
                            }
3531
                            gen_set_label(l1);
3532
                            break;
3533
                        }
3534
#endif
3535
                    default:
3536
                        goto illegal_insn;
3537
                    }
3538
                }
3539
            } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
3540
#ifdef TARGET_SPARC64
3541
                int opf = GET_FIELD_SP(insn, 5, 13);
3542
                rs1 = GET_FIELD(insn, 13, 17);
3543
                rs2 = GET_FIELD(insn, 27, 31);
3544
                if (gen_trap_ifnofpu(dc, cpu_cond))
3545
                    goto jmp_insn;
3546

    
3547
                switch (opf) {
3548
                case 0x000: /* VIS I edge8cc */
3549
                case 0x001: /* VIS II edge8n */
3550
                case 0x002: /* VIS I edge8lcc */
3551
                case 0x003: /* VIS II edge8ln */
3552
                case 0x004: /* VIS I edge16cc */
3553
                case 0x005: /* VIS II edge16n */
3554
                case 0x006: /* VIS I edge16lcc */
3555
                case 0x007: /* VIS II edge16ln */
3556
                case 0x008: /* VIS I edge32cc */
3557
                case 0x009: /* VIS II edge32n */
3558
                case 0x00a: /* VIS I edge32lcc */
3559
                case 0x00b: /* VIS II edge32ln */
3560
                    // XXX
3561
                    goto illegal_insn;
3562
                case 0x010: /* VIS I array8 */
3563
                    CHECK_FPU_FEATURE(dc, VIS1);
3564
                    cpu_src1 = get_src1(insn, cpu_src1);
3565
                    gen_movl_reg_TN(rs2, cpu_src2);
3566
                    gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
3567
                    gen_movl_TN_reg(rd, cpu_dst);
3568
                    break;
3569
                case 0x012: /* VIS I array16 */
3570
                    CHECK_FPU_FEATURE(dc, VIS1);
3571
                    cpu_src1 = get_src1(insn, cpu_src1);
3572
                    gen_movl_reg_TN(rs2, cpu_src2);
3573
                    gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
3574
                    tcg_gen_shli_i64(cpu_dst, cpu_dst, 1);
3575
                    gen_movl_TN_reg(rd, cpu_dst);
3576
                    break;
3577
                case 0x014: /* VIS I array32 */
3578
                    CHECK_FPU_FEATURE(dc, VIS1);
3579
                    cpu_src1 = get_src1(insn, cpu_src1);
3580
                    gen_movl_reg_TN(rs2, cpu_src2);
3581
                    gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
3582
                    tcg_gen_shli_i64(cpu_dst, cpu_dst, 2);
3583
                    gen_movl_TN_reg(rd, cpu_dst);
3584
                    break;
3585
                case 0x018: /* VIS I alignaddr */
3586
                    CHECK_FPU_FEATURE(dc, VIS1);
3587
                    cpu_src1 = get_src1(insn, cpu_src1);
3588
                    gen_movl_reg_TN(rs2, cpu_src2);
3589
                    gen_helper_alignaddr(cpu_dst, cpu_src1, cpu_src2);
3590
                    gen_movl_TN_reg(rd, cpu_dst);
3591
                    break;
3592
                case 0x019: /* VIS II bmask */
3593
                case 0x01a: /* VIS I alignaddrl */
3594
                    // XXX
3595
                    goto illegal_insn;
3596
                case 0x020: /* VIS I fcmple16 */
3597
                    CHECK_FPU_FEATURE(dc, VIS1);
3598
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3599
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3600
                    gen_helper_fcmple16();
3601
                    gen_op_store_DT0_fpr(DFPREG(rd));
3602
                    break;
3603
                case 0x022: /* VIS I fcmpne16 */
3604
                    CHECK_FPU_FEATURE(dc, VIS1);
3605
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3606
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3607
                    gen_helper_fcmpne16();
3608
                    gen_op_store_DT0_fpr(DFPREG(rd));
3609
                    break;
3610
                case 0x024: /* VIS I fcmple32 */
3611
                    CHECK_FPU_FEATURE(dc, VIS1);
3612
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3613
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3614
                    gen_helper_fcmple32();
3615
                    gen_op_store_DT0_fpr(DFPREG(rd));
3616
                    break;
3617
                case 0x026: /* VIS I fcmpne32 */
3618
                    CHECK_FPU_FEATURE(dc, VIS1);
3619
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3620
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3621
                    gen_helper_fcmpne32();
3622
                    gen_op_store_DT0_fpr(DFPREG(rd));
3623
                    break;
3624
                case 0x028: /* VIS I fcmpgt16 */
3625
                    CHECK_FPU_FEATURE(dc, VIS1);
3626
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3627
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3628
                    gen_helper_fcmpgt16();
3629
                    gen_op_store_DT0_fpr(DFPREG(rd));
3630
                    break;
3631
                case 0x02a: /* VIS I fcmpeq16 */
3632
                    CHECK_FPU_FEATURE(dc, VIS1);
3633
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3634
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3635
                    gen_helper_fcmpeq16();
3636
                    gen_op_store_DT0_fpr(DFPREG(rd));
3637
                    break;
3638
                case 0x02c: /* VIS I fcmpgt32 */
3639
                    CHECK_FPU_FEATURE(dc, VIS1);
3640
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3641
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3642
                    gen_helper_fcmpgt32();
3643
                    gen_op_store_DT0_fpr(DFPREG(rd));
3644
                    break;
3645
                case 0x02e: /* VIS I fcmpeq32 */
3646
                    CHECK_FPU_FEATURE(dc, VIS1);
3647
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3648
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3649
                    gen_helper_fcmpeq32();
3650
                    gen_op_store_DT0_fpr(DFPREG(rd));
3651
                    break;
3652
                case 0x031: /* VIS I fmul8x16 */
3653
                    CHECK_FPU_FEATURE(dc, VIS1);
3654
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3655
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3656
                    gen_helper_fmul8x16();
3657
                    gen_op_store_DT0_fpr(DFPREG(rd));
3658
                    break;
3659
                case 0x033: /* VIS I fmul8x16au */
3660
                    CHECK_FPU_FEATURE(dc, VIS1);
3661
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3662
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3663
                    gen_helper_fmul8x16au();
3664
                    gen_op_store_DT0_fpr(DFPREG(rd));
3665
                    break;
3666
                case 0x035: /* VIS I fmul8x16al */
3667
                    CHECK_FPU_FEATURE(dc, VIS1);
3668
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3669
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3670
                    gen_helper_fmul8x16al();
3671
                    gen_op_store_DT0_fpr(DFPREG(rd));
3672
                    break;
3673
                case 0x036: /* VIS I fmul8sux16 */
3674
                    CHECK_FPU_FEATURE(dc, VIS1);
3675
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3676
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3677
                    gen_helper_fmul8sux16();
3678
                    gen_op_store_DT0_fpr(DFPREG(rd));
3679
                    break;
3680
                case 0x037: /* VIS I fmul8ulx16 */
3681
                    CHECK_FPU_FEATURE(dc, VIS1);
3682
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3683
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3684
                    gen_helper_fmul8ulx16();
3685
                    gen_op_store_DT0_fpr(DFPREG(rd));
3686
                    break;
3687
                case 0x038: /* VIS I fmuld8sux16 */
3688
                    CHECK_FPU_FEATURE(dc, VIS1);
3689
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3690
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3691
                    gen_helper_fmuld8sux16();
3692
                    gen_op_store_DT0_fpr(DFPREG(rd));
3693
                    break;
3694
                case 0x039: /* VIS I fmuld8ulx16 */
3695
                    CHECK_FPU_FEATURE(dc, VIS1);
3696
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3697
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3698
                    gen_helper_fmuld8ulx16();
3699
                    gen_op_store_DT0_fpr(DFPREG(rd));
3700
                    break;
3701
                case 0x03a: /* VIS I fpack32 */
3702
                case 0x03b: /* VIS I fpack16 */
3703
                case 0x03d: /* VIS I fpackfix */
3704
                case 0x03e: /* VIS I pdist */
3705
                    // XXX
3706
                    goto illegal_insn;
3707
                case 0x048: /* VIS I faligndata */
3708
                    CHECK_FPU_FEATURE(dc, VIS1);
3709
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3710
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3711
                    gen_helper_faligndata();
3712
                    gen_op_store_DT0_fpr(DFPREG(rd));
3713
                    break;
3714
                case 0x04b: /* VIS I fpmerge */
3715
                    CHECK_FPU_FEATURE(dc, VIS1);
3716
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3717
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3718
                    gen_helper_fpmerge();
3719
                    gen_op_store_DT0_fpr(DFPREG(rd));
3720
                    break;
3721
                case 0x04c: /* VIS II bshuffle */
3722
                    // XXX
3723
                    goto illegal_insn;
3724
                case 0x04d: /* VIS I fexpand */
3725
                    CHECK_FPU_FEATURE(dc, VIS1);
3726
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3727
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3728
                    gen_helper_fexpand();
3729
                    gen_op_store_DT0_fpr(DFPREG(rd));
3730
                    break;
3731
                case 0x050: /* VIS I fpadd16 */
3732
                    CHECK_FPU_FEATURE(dc, VIS1);
3733
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3734
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3735
                    gen_helper_fpadd16();
3736
                    gen_op_store_DT0_fpr(DFPREG(rd));
3737
                    break;
3738
                case 0x051: /* VIS I fpadd16s */
3739
                    CHECK_FPU_FEATURE(dc, VIS1);
3740
                    gen_helper_fpadd16s(cpu_fpr[rd],
3741
                                        cpu_fpr[rs1], cpu_fpr[rs2]);
3742
                    break;
3743
                case 0x052: /* VIS I fpadd32 */
3744
                    CHECK_FPU_FEATURE(dc, VIS1);
3745
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3746
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3747
                    gen_helper_fpadd32();
3748
                    gen_op_store_DT0_fpr(DFPREG(rd));
3749
                    break;
3750
                case 0x053: /* VIS I fpadd32s */
3751
                    CHECK_FPU_FEATURE(dc, VIS1);
3752
                    gen_helper_fpadd32s(cpu_fpr[rd],
3753
                                        cpu_fpr[rs1], cpu_fpr[rs2]);
3754
                    break;
3755
                case 0x054: /* VIS I fpsub16 */
3756
                    CHECK_FPU_FEATURE(dc, VIS1);
3757
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3758
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3759
                    gen_helper_fpsub16();
3760
                    gen_op_store_DT0_fpr(DFPREG(rd));
3761
                    break;
3762
                case 0x055: /* VIS I fpsub16s */
3763
                    CHECK_FPU_FEATURE(dc, VIS1);
3764
                    gen_helper_fpsub16s(cpu_fpr[rd],
3765
                                        cpu_fpr[rs1], cpu_fpr[rs2]);
3766
                    break;
3767
                case 0x056: /* VIS I fpsub32 */
3768
                    CHECK_FPU_FEATURE(dc, VIS1);
3769
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3770
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3771
                    gen_helper_fpsub32();
3772
                    gen_op_store_DT0_fpr(DFPREG(rd));
3773
                    break;
3774
                case 0x057: /* VIS I fpsub32s */
3775
                    CHECK_FPU_FEATURE(dc, VIS1);
3776
                    gen_helper_fpsub32s(cpu_fpr[rd],
3777
                                        cpu_fpr[rs1], cpu_fpr[rs2]);
3778
                    break;
3779
                case 0x060: /* VIS I fzero */
3780
                    CHECK_FPU_FEATURE(dc, VIS1);
3781
                    tcg_gen_movi_i32(cpu_fpr[DFPREG(rd)], 0);
3782
                    tcg_gen_movi_i32(cpu_fpr[DFPREG(rd) + 1], 0);
3783
                    break;
3784
                case 0x061: /* VIS I fzeros */
3785
                    CHECK_FPU_FEATURE(dc, VIS1);
3786
                    tcg_gen_movi_i32(cpu_fpr[rd], 0);
3787
                    break;
3788
                case 0x062: /* VIS I fnor */
3789
                    CHECK_FPU_FEATURE(dc, VIS1);
3790
                    tcg_gen_nor_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1)],
3791
                                    cpu_fpr[DFPREG(rs2)]);
3792
                    tcg_gen_nor_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1) + 1],
3793
                                    cpu_fpr[DFPREG(rs2) + 1]);
3794
                    break;
3795
                case 0x063: /* VIS I fnors */
3796
                    CHECK_FPU_FEATURE(dc, VIS1);
3797
                    tcg_gen_nor_i32(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
3798
                    break;
3799
                case 0x064: /* VIS I fandnot2 */
3800
                    CHECK_FPU_FEATURE(dc, VIS1);
3801
                    tcg_gen_andc_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
3802
                                     cpu_fpr[DFPREG(rs2)]);
3803
                    tcg_gen_andc_i32(cpu_fpr[DFPREG(rd) + 1],
3804
                                     cpu_fpr[DFPREG(rs1) + 1],
3805
                                     cpu_fpr[DFPREG(rs2) + 1]);
3806
                    break;
3807
                case 0x065: /* VIS I fandnot2s */
3808
                    CHECK_FPU_FEATURE(dc, VIS1);
3809
                    tcg_gen_andc_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
3810
                    break;
3811
                case 0x066: /* VIS I fnot2 */
3812
                    CHECK_FPU_FEATURE(dc, VIS1);
3813
                    tcg_gen_not_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)]);
3814
                    tcg_gen_not_i32(cpu_fpr[DFPREG(rd) + 1],
3815
                                    cpu_fpr[DFPREG(rs2) + 1]);
3816
                    break;
3817
                case 0x067: /* VIS I fnot2s */
3818
                    CHECK_FPU_FEATURE(dc, VIS1);
3819
                    tcg_gen_not_i32(cpu_fpr[rd], cpu_fpr[rs2]);
3820
                    break;
3821
                case 0x068: /* VIS I fandnot1 */
3822
                    CHECK_FPU_FEATURE(dc, VIS1);
3823
                    tcg_gen_andc_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)],
3824
                                     cpu_fpr[DFPREG(rs1)]);
3825
                    tcg_gen_andc_i32(cpu_fpr[DFPREG(rd) + 1],
3826
                                     cpu_fpr[DFPREG(rs2) + 1],
3827
                                     cpu_fpr[DFPREG(rs1) + 1]);
3828
                    break;
3829
                case 0x069: /* VIS I fandnot1s */
3830
                    CHECK_FPU_FEATURE(dc, VIS1);
3831
                    tcg_gen_andc_i32(cpu_fpr[rd], cpu_fpr[rs2], cpu_fpr[rs1]);
3832
                    break;
3833
                case 0x06a: /* VIS I fnot1 */
3834
                    CHECK_FPU_FEATURE(dc, VIS1);
3835
                    tcg_gen_not_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)]);
3836
                    tcg_gen_not_i32(cpu_fpr[DFPREG(rd) + 1],
3837
                                    cpu_fpr[DFPREG(rs1) + 1]);
3838
                    break;
3839
                case 0x06b: /* VIS I fnot1s */
3840
                    CHECK_FPU_FEATURE(dc, VIS1);
3841
                    tcg_gen_not_i32(cpu_fpr[rd], cpu_fpr[rs1]);
3842
                    break;
3843
                case 0x06c: /* VIS I fxor */
3844
                    CHECK_FPU_FEATURE(dc, VIS1);
3845
                    tcg_gen_xor_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
3846
                                    cpu_fpr[DFPREG(rs2)]);
3847
                    tcg_gen_xor_i32(cpu_fpr[DFPREG(rd) + 1],
3848
                                    cpu_fpr[DFPREG(rs1) + 1],
3849
                                    cpu_fpr[DFPREG(rs2) + 1]);
3850
                    break;
3851
                case 0x06d: /* VIS I fxors */
3852
                    CHECK_FPU_FEATURE(dc, VIS1);
3853
                    tcg_gen_xor_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
3854
                    break;
3855
                case 0x06e: /* VIS I fnand */
3856
                    CHECK_FPU_FEATURE(dc, VIS1);
3857
                    tcg_gen_nand_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1)],
3858
                                     cpu_fpr[DFPREG(rs2)]);
3859
                    tcg_gen_nand_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1) + 1],
3860
                                     cpu_fpr[DFPREG(rs2) + 1]);
3861
                    break;
3862
                case 0x06f: /* VIS I fnands */
3863
                    CHECK_FPU_FEATURE(dc, VIS1);
3864
                    tcg_gen_nand_i32(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
3865
                    break;
3866
                case 0x070: /* VIS I fand */
3867
                    CHECK_FPU_FEATURE(dc, VIS1);
3868
                    tcg_gen_and_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
3869
                                    cpu_fpr[DFPREG(rs2)]);
3870
                    tcg_gen_and_i32(cpu_fpr[DFPREG(rd) + 1],
3871
                                    cpu_fpr[DFPREG(rs1) + 1],
3872
                                    cpu_fpr[DFPREG(rs2) + 1]);
3873
                    break;
3874
                case 0x071: /* VIS I fands */
3875
                    CHECK_FPU_FEATURE(dc, VIS1);
3876
                    tcg_gen_and_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
3877
                    break;
3878
                case 0x072: /* VIS I fxnor */
3879
                    CHECK_FPU_FEATURE(dc, VIS1);
3880
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs2)], -1);
3881
                    tcg_gen_xor_i32(cpu_fpr[DFPREG(rd)], cpu_tmp32,
3882
                                    cpu_fpr[DFPREG(rs1)]);
3883
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs2) + 1], -1);
3884
                    tcg_gen_xor_i32(cpu_fpr[DFPREG(rd) + 1], cpu_tmp32,
3885
                                    cpu_fpr[DFPREG(rs1) + 1]);
3886
                    break;
3887
                case 0x073: /* VIS I fxnors */
3888
                    CHECK_FPU_FEATURE(dc, VIS1);
3889
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[rs2], -1);
3890
                    tcg_gen_xor_i32(cpu_fpr[rd], cpu_tmp32, cpu_fpr[rs1]);
3891
                    break;
3892
                case 0x074: /* VIS I fsrc1 */
3893
                    CHECK_FPU_FEATURE(dc, VIS1);
3894
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)]);
3895
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1],
3896
                                    cpu_fpr[DFPREG(rs1) + 1]);
3897
                    break;
3898
                case 0x075: /* VIS I fsrc1s */
3899
                    CHECK_FPU_FEATURE(dc, VIS1);
3900
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs1]);
3901
                    break;
3902
                case 0x076: /* VIS I fornot2 */
3903
                    CHECK_FPU_FEATURE(dc, VIS1);
3904
                    tcg_gen_orc_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
3905
                                    cpu_fpr[DFPREG(rs2)]);
3906
                    tcg_gen_orc_i32(cpu_fpr[DFPREG(rd) + 1],
3907
                                    cpu_fpr[DFPREG(rs1) + 1],
3908
                                    cpu_fpr[DFPREG(rs2) + 1]);
3909
                    break;
3910
                case 0x077: /* VIS I fornot2s */
3911
                    CHECK_FPU_FEATURE(dc, VIS1);
3912
                    tcg_gen_orc_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
3913
                    break;
3914
                case 0x078: /* VIS I fsrc2 */
3915
                    CHECK_FPU_FEATURE(dc, VIS1);
3916
                    gen_op_load_fpr_DT0(DFPREG(rs2));
3917
                    gen_op_store_DT0_fpr(DFPREG(rd));
3918
                    break;
3919
                case 0x079: /* VIS I fsrc2s */
3920
                    CHECK_FPU_FEATURE(dc, VIS1);
3921
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);
3922
                    break;
3923
                case 0x07a: /* VIS I fornot1 */
3924
                    CHECK_FPU_FEATURE(dc, VIS1);
3925
                    tcg_gen_orc_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)],
3926
                                    cpu_fpr[DFPREG(rs1)]);
3927
                    tcg_gen_orc_i32(cpu_fpr[DFPREG(rd) + 1],
3928
                                    cpu_fpr[DFPREG(rs2) + 1],
3929
                                    cpu_fpr[DFPREG(rs1) + 1]);
3930
                    break;
3931
                case 0x07b: /* VIS I fornot1s */
3932
                    CHECK_FPU_FEATURE(dc, VIS1);
3933
                    tcg_gen_orc_i32(cpu_fpr[rd], cpu_fpr[rs2], cpu_fpr[rs1]);
3934
                    break;
3935
                case 0x07c: /* VIS I for */
3936
                    CHECK_FPU_FEATURE(dc, VIS1);
3937
                    tcg_gen_or_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
3938
                                   cpu_fpr[DFPREG(rs2)]);
3939
                    tcg_gen_or_i32(cpu_fpr[DFPREG(rd) + 1],
3940
                                   cpu_fpr[DFPREG(rs1) + 1],
3941
                                   cpu_fpr[DFPREG(rs2) + 1]);
3942
                    break;
3943
                case 0x07d: /* VIS I fors */
3944
                    CHECK_FPU_FEATURE(dc, VIS1);
3945
                    tcg_gen_or_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
3946
                    break;
3947
                case 0x07e: /* VIS I fone */
3948
                    CHECK_FPU_FEATURE(dc, VIS1);
3949
                    tcg_gen_movi_i32(cpu_fpr[DFPREG(rd)], -1);
3950
                    tcg_gen_movi_i32(cpu_fpr[DFPREG(rd) + 1], -1);
3951
                    break;
3952
                case 0x07f: /* VIS I fones */
3953
                    CHECK_FPU_FEATURE(dc, VIS1);
3954
                    tcg_gen_movi_i32(cpu_fpr[rd], -1);
3955
                    break;
3956
                case 0x080: /* VIS I shutdown */
3957
                case 0x081: /* VIS II siam */
3958
                    // XXX
3959
                    goto illegal_insn;
3960
                default:
3961
                    goto illegal_insn;
3962
                }
3963
#else
3964
                goto ncp_insn;
3965
#endif
3966
            } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
3967
#ifdef TARGET_SPARC64
3968
                goto illegal_insn;
3969
#else
3970
                goto ncp_insn;
3971
#endif
3972
#ifdef TARGET_SPARC64
3973
            } else if (xop == 0x39) { /* V9 return */
3974
                TCGv_i32 r_const;
3975

    
3976
                save_state(dc, cpu_cond);
3977
                cpu_src1 = get_src1(insn, cpu_src1);
3978
                if (IS_IMM) {   /* immediate */
3979
                    simm = GET_FIELDs(insn, 19, 31);
3980
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, simm);
3981
                } else {                /* register */
3982
                    rs2 = GET_FIELD(insn, 27, 31);
3983
                    if (rs2) {
3984
                        gen_movl_reg_TN(rs2, cpu_src2);
3985
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
3986
                    } else
3987
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
3988
                }
3989
                gen_helper_restore();
3990
                gen_mov_pc_npc(dc, cpu_cond);
3991
                r_const = tcg_const_i32(3);
3992
                gen_helper_check_align(cpu_dst, r_const);
3993
                tcg_temp_free_i32(r_const);
3994
                tcg_gen_mov_tl(cpu_npc, cpu_dst);
3995
                dc->npc = DYNAMIC_PC;
3996
                goto jmp_insn;
3997
#endif
3998
            } else {
3999
                cpu_src1 = get_src1(insn, cpu_src1);
4000
                if (IS_IMM) {   /* immediate */
4001
                    simm = GET_FIELDs(insn, 19, 31);
4002
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, simm);
4003
                } else {                /* register */
4004
                    rs2 = GET_FIELD(insn, 27, 31);
4005
                    if (rs2) {
4006
                        gen_movl_reg_TN(rs2, cpu_src2);
4007
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
4008
                    } else
4009
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
4010
                }
4011
                switch (xop) {
4012
                case 0x38:      /* jmpl */
4013
                    {
4014
                        TCGv r_pc;
4015
                        TCGv_i32 r_const;
4016

    
4017
                        r_pc = tcg_const_tl(dc->pc);
4018
                        gen_movl_TN_reg(rd, r_pc);
4019
                        tcg_temp_free(r_pc);
4020
                        gen_mov_pc_npc(dc, cpu_cond);
4021
                        r_const = tcg_const_i32(3);
4022
                        gen_helper_check_align(cpu_dst, r_const);
4023
                        tcg_temp_free_i32(r_const);
4024
                        tcg_gen_mov_tl(cpu_npc, cpu_dst);
4025
                        dc->npc = DYNAMIC_PC;
4026
                    }
4027
                    goto jmp_insn;
4028
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
4029
                case 0x39:      /* rett, V9 return */
4030
                    {
4031
                        TCGv_i32 r_const;
4032

    
4033
                        if (!supervisor(dc))
4034
                            goto priv_insn;
4035
                        gen_mov_pc_npc(dc, cpu_cond);
4036
                        r_const = tcg_const_i32(3);
4037
                        gen_helper_check_align(cpu_dst, r_const);
4038
                        tcg_temp_free_i32(r_const);
4039
                        tcg_gen_mov_tl(cpu_npc, cpu_dst);
4040
                        dc->npc = DYNAMIC_PC;
4041
                        gen_helper_rett();
4042
                    }
4043
                    goto jmp_insn;
4044
#endif
4045
                case 0x3b: /* flush */
4046
                    if (!((dc)->def->features & CPU_FEATURE_FLUSH))
4047
                        goto unimp_flush;
4048
                    gen_helper_flush(cpu_dst);
4049
                    break;
4050
                case 0x3c:      /* save */
4051
                    save_state(dc, cpu_cond);
4052
                    gen_helper_save();
4053
                    gen_movl_TN_reg(rd, cpu_dst);
4054
                    break;
4055
                case 0x3d:      /* restore */
4056
                    save_state(dc, cpu_cond);
4057
                    gen_helper_restore();
4058
                    gen_movl_TN_reg(rd, cpu_dst);
4059
                    break;
4060
#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
4061
                case 0x3e:      /* V9 done/retry */
4062
                    {
4063
                        switch (rd) {
4064
                        case 0:
4065
                            if (!supervisor(dc))
4066
                                goto priv_insn;
4067
                            dc->npc = DYNAMIC_PC;
4068
                            dc->pc = DYNAMIC_PC;
4069
                            gen_helper_done();
4070
                            goto jmp_insn;
4071
                        case 1:
4072
                            if (!supervisor(dc))
4073
                                goto priv_insn;
4074
                            dc->npc = DYNAMIC_PC;
4075
                            dc->pc = DYNAMIC_PC;
4076
                            gen_helper_retry();
4077
                            goto jmp_insn;
4078
                        default:
4079
                            goto illegal_insn;
4080
                        }
4081
                    }
4082
                    break;
4083
#endif
4084
                default:
4085
                    goto illegal_insn;
4086
                }
4087
            }
4088
            break;
4089
        }
4090
        break;
4091
    case 3:                     /* load/store instructions */
4092
        {
4093
            unsigned int xop = GET_FIELD(insn, 7, 12);
4094

    
4095
            cpu_src1 = get_src1(insn, cpu_src1);
4096
            if (xop == 0x3c || xop == 0x3e) { // V9 casa/casxa
4097
                rs2 = GET_FIELD(insn, 27, 31);
4098
                gen_movl_reg_TN(rs2, cpu_src2);
4099
                tcg_gen_mov_tl(cpu_addr, cpu_src1);
4100
            } else if (IS_IMM) {     /* immediate */
4101
                simm = GET_FIELDs(insn, 19, 31);
4102
                tcg_gen_addi_tl(cpu_addr, cpu_src1, simm);
4103
            } else {            /* register */
4104
                rs2 = GET_FIELD(insn, 27, 31);
4105
                if (rs2 != 0) {
4106
                    gen_movl_reg_TN(rs2, cpu_src2);
4107
                    tcg_gen_add_tl(cpu_addr, cpu_src1, cpu_src2);
4108
                } else
4109
                    tcg_gen_mov_tl(cpu_addr, cpu_src1);
4110
            }
4111
            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
4112
                (xop > 0x17 && xop <= 0x1d ) ||
4113
                (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
4114
                switch (xop) {
4115
                case 0x0:       /* ld, V9 lduw, load unsigned word */
4116
                    gen_address_mask(dc, cpu_addr);
4117
                    tcg_gen_qemu_ld32u(cpu_val, cpu_addr, dc->mem_idx);
4118
                    break;
4119
                case 0x1:       /* ldub, load unsigned byte */
4120
                    gen_address_mask(dc, cpu_addr);
4121
                    tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx);
4122
                    break;
4123
                case 0x2:       /* lduh, load unsigned halfword */
4124
                    gen_address_mask(dc, cpu_addr);
4125
                    tcg_gen_qemu_ld16u(cpu_val, cpu_addr, dc->mem_idx);
4126
                    break;
4127
                case 0x3:       /* ldd, load double word */
4128
                    if (rd & 1)
4129
                        goto illegal_insn;
4130
                    else {
4131
                        TCGv_i32 r_const;
4132

    
4133
                        save_state(dc, cpu_cond);
4134
                        r_const = tcg_const_i32(7);
4135
                        gen_helper_check_align(cpu_addr, r_const); // XXX remove
4136
                        tcg_temp_free_i32(r_const);
4137
                        gen_address_mask(dc, cpu_addr);
4138
                        tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
4139
                        tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
4140
                        tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffffULL);
4141
                        gen_movl_TN_reg(rd + 1, cpu_tmp0);
4142
                        tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
4143
                        tcg_gen_trunc_i64_tl(cpu_val, cpu_tmp64);
4144
                        tcg_gen_andi_tl(cpu_val, cpu_val, 0xffffffffULL);
4145
                    }
4146
                    break;
4147
                case 0x9:       /* ldsb, load signed byte */
4148
                    gen_address_mask(dc, cpu_addr);
4149
                    tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
4150
                    break;
4151
                case 0xa:       /* ldsh, load signed halfword */
4152
                    gen_address_mask(dc, cpu_addr);
4153
                    tcg_gen_qemu_ld16s(cpu_val, cpu_addr, dc->mem_idx);
4154
                    break;
4155
                case 0xd:       /* ldstub -- XXX: should be atomically */
4156
                    {
4157
                        TCGv r_const;
4158

    
4159
                        gen_address_mask(dc, cpu_addr);
4160
                        tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
4161
                        r_const = tcg_const_tl(0xff);
4162
                        tcg_gen_qemu_st8(r_const, cpu_addr, dc->mem_idx);
4163
                        tcg_temp_free(r_const);
4164
                    }
4165
                    break;
4166
                case 0x0f:      /* swap, swap register with memory. Also
4167
                                   atomically */
4168
                    CHECK_IU_FEATURE(dc, SWAP);
4169
                    gen_movl_reg_TN(rd, cpu_val);
4170
                    gen_address_mask(dc, cpu_addr);
4171
                    tcg_gen_qemu_ld32u(cpu_tmp0, cpu_addr, dc->mem_idx);
4172
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
4173
                    tcg_gen_mov_tl(cpu_val, cpu_tmp0);
4174
                    break;
4175
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4176
                case 0x10:      /* lda, V9 lduwa, load word alternate */
4177
#ifndef TARGET_SPARC64
4178
                    if (IS_IMM)
4179
                        goto illegal_insn;
4180
                    if (!supervisor(dc))
4181
                        goto priv_insn;
4182
#endif
4183
                    save_state(dc, cpu_cond);
4184
                    gen_ld_asi(cpu_val, cpu_addr, insn, 4, 0);
4185
                    break;
4186
                case 0x11:      /* lduba, load unsigned byte alternate */
4187
#ifndef TARGET_SPARC64
4188
                    if (IS_IMM)
4189
                        goto illegal_insn;
4190
                    if (!supervisor(dc))
4191
                        goto priv_insn;
4192
#endif
4193
                    save_state(dc, cpu_cond);
4194
                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 0);
4195
                    break;
4196
                case 0x12:      /* lduha, load unsigned halfword alternate */
4197
#ifndef TARGET_SPARC64
4198
                    if (IS_IMM)
4199
                        goto illegal_insn;
4200
                    if (!supervisor(dc))
4201
                        goto priv_insn;
4202
#endif
4203
                    save_state(dc, cpu_cond);
4204
                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 0);
4205
                    break;
4206
                case 0x13:      /* ldda, load double word alternate */
4207
#ifndef TARGET_SPARC64
4208
                    if (IS_IMM)
4209
                        goto illegal_insn;
4210
                    if (!supervisor(dc))
4211
                        goto priv_insn;
4212
#endif
4213
                    if (rd & 1)
4214
                        goto illegal_insn;
4215
                    save_state(dc, cpu_cond);
4216
                    gen_ldda_asi(cpu_val, cpu_addr, insn, rd);
4217
                    goto skip_move;
4218
                case 0x19:      /* ldsba, load signed byte alternate */
4219
#ifndef TARGET_SPARC64
4220
                    if (IS_IMM)
4221
                        goto illegal_insn;
4222
                    if (!supervisor(dc))
4223
                        goto priv_insn;
4224
#endif
4225
                    save_state(dc, cpu_cond);
4226
                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 1);
4227
                    break;
4228
                case 0x1a:      /* ldsha, load signed halfword alternate */
4229
#ifndef TARGET_SPARC64
4230
                    if (IS_IMM)
4231
                        goto illegal_insn;
4232
                    if (!supervisor(dc))
4233
                        goto priv_insn;
4234
#endif
4235
                    save_state(dc, cpu_cond);
4236
                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 1);
4237
                    break;
4238
                case 0x1d:      /* ldstuba -- XXX: should be atomically */
4239
#ifndef TARGET_SPARC64
4240
                    if (IS_IMM)
4241
                        goto illegal_insn;
4242
                    if (!supervisor(dc))
4243
                        goto priv_insn;
4244
#endif
4245
                    save_state(dc, cpu_cond);
4246
                    gen_ldstub_asi(cpu_val, cpu_addr, insn);
4247
                    break;
4248
                case 0x1f:      /* swapa, swap reg with alt. memory. Also
4249
                                   atomically */
4250
                    CHECK_IU_FEATURE(dc, SWAP);
4251
#ifndef TARGET_SPARC64
4252
                    if (IS_IMM)
4253
                        goto illegal_insn;
4254
                    if (!supervisor(dc))
4255
                        goto priv_insn;
4256
#endif
4257
                    save_state(dc, cpu_cond);
4258
                    gen_movl_reg_TN(rd, cpu_val);
4259
                    gen_swap_asi(cpu_val, cpu_addr, insn);
4260
                    break;
4261

    
4262
#ifndef TARGET_SPARC64
4263
                case 0x30: /* ldc */
4264
                case 0x31: /* ldcsr */
4265
                case 0x33: /* lddc */
4266
                    goto ncp_insn;
4267
#endif
4268
#endif
4269
#ifdef TARGET_SPARC64
4270
                case 0x08: /* V9 ldsw */
4271
                    gen_address_mask(dc, cpu_addr);
4272
                    tcg_gen_qemu_ld32s(cpu_val, cpu_addr, dc->mem_idx);
4273
                    break;
4274
                case 0x0b: /* V9 ldx */
4275
                    gen_address_mask(dc, cpu_addr);
4276
                    tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx);
4277
                    break;
4278
                case 0x18: /* V9 ldswa */
4279
                    save_state(dc, cpu_cond);
4280
                    gen_ld_asi(cpu_val, cpu_addr, insn, 4, 1);
4281
                    break;
4282
                case 0x1b: /* V9 ldxa */
4283
                    save_state(dc, cpu_cond);
4284
                    gen_ld_asi(cpu_val, cpu_addr, insn, 8, 0);
4285
                    break;
4286
                case 0x2d: /* V9 prefetch, no effect */
4287
                    goto skip_move;
4288
                case 0x30: /* V9 ldfa */
4289
                    save_state(dc, cpu_cond);
4290
                    gen_ldf_asi(cpu_addr, insn, 4, rd);
4291
                    goto skip_move;
4292
                case 0x33: /* V9 lddfa */
4293
                    save_state(dc, cpu_cond);
4294
                    gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd));
4295
                    goto skip_move;
4296
                case 0x3d: /* V9 prefetcha, no effect */
4297
                    goto skip_move;
4298
                case 0x32: /* V9 ldqfa */
4299
                    CHECK_FPU_FEATURE(dc, FLOAT128);
4300
                    save_state(dc, cpu_cond);
4301
                    gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd));
4302
                    goto skip_move;
4303
#endif
4304
                default:
4305
                    goto illegal_insn;
4306
                }
4307
                gen_movl_TN_reg(rd, cpu_val);
4308
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4309
            skip_move: ;
4310
#endif
4311
            } else if (xop >= 0x20 && xop < 0x24) {
4312
                if (gen_trap_ifnofpu(dc, cpu_cond))
4313
                    goto jmp_insn;
4314
                save_state(dc, cpu_cond);
4315
                switch (xop) {
4316
                case 0x20:      /* ldf, load fpreg */
4317
                    gen_address_mask(dc, cpu_addr);
4318
                    tcg_gen_qemu_ld32u(cpu_tmp0, cpu_addr, dc->mem_idx);
4319
                    tcg_gen_trunc_tl_i32(cpu_fpr[rd], cpu_tmp0);
4320
                    break;
4321
                case 0x21:      /* ldfsr, V9 ldxfsr */
4322
#ifdef TARGET_SPARC64
4323
                    gen_address_mask(dc, cpu_addr);
4324
                    if (rd == 1) {
4325
                        tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
4326
                        gen_helper_ldxfsr(cpu_tmp64);
4327
                    } else
4328
#else
4329
                    {
4330
                        tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
4331
                        gen_helper_ldfsr(cpu_tmp32);
4332
                    }
4333
#endif
4334
                    break;
4335
                case 0x22:      /* ldqf, load quad fpreg */
4336
                    {
4337
                        TCGv_i32 r_const;
4338

    
4339
                        CHECK_FPU_FEATURE(dc, FLOAT128);
4340
                        r_const = tcg_const_i32(dc->mem_idx);
4341
                        gen_helper_ldqf(cpu_addr, r_const);
4342
                        tcg_temp_free_i32(r_const);
4343
                        gen_op_store_QT0_fpr(QFPREG(rd));
4344
                    }
4345
                    break;
4346
                case 0x23:      /* lddf, load double fpreg */
4347
                    {
4348
                        TCGv_i32 r_const;
4349

    
4350
                        r_const = tcg_const_i32(dc->mem_idx);
4351
                        gen_helper_lddf(cpu_addr, r_const);
4352
                        tcg_temp_free_i32(r_const);
4353
                        gen_op_store_DT0_fpr(DFPREG(rd));
4354
                    }
4355
                    break;
4356
                default:
4357
                    goto illegal_insn;
4358
                }
4359
            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) ||
4360
                       xop == 0xe || xop == 0x1e) {
4361
                gen_movl_reg_TN(rd, cpu_val);
4362
                switch (xop) {
4363
                case 0x4: /* st, store word */
4364
                    gen_address_mask(dc, cpu_addr);
4365
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
4366
                    break;
4367
                case 0x5: /* stb, store byte */
4368
                    gen_address_mask(dc, cpu_addr);
4369
                    tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx);
4370
                    break;
4371
                case 0x6: /* sth, store halfword */
4372
                    gen_address_mask(dc, cpu_addr);
4373
                    tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx);
4374
                    break;
4375
                case 0x7: /* std, store double word */
4376
                    if (rd & 1)
4377
                        goto illegal_insn;
4378
                    else {
4379
                        TCGv_i32 r_const;
4380

    
4381
                        save_state(dc, cpu_cond);
4382
                        gen_address_mask(dc, cpu_addr);
4383
                        r_const = tcg_const_i32(7);
4384
                        gen_helper_check_align(cpu_addr, r_const); // XXX remove
4385
                        tcg_temp_free_i32(r_const);
4386
                        gen_movl_reg_TN(rd + 1, cpu_tmp0);
4387
                        tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, cpu_val);
4388
                        tcg_gen_qemu_st64(cpu_tmp64, cpu_addr, dc->mem_idx);
4389
                    }
4390
                    break;
4391
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4392
                case 0x14: /* sta, V9 stwa, store word alternate */
4393
#ifndef TARGET_SPARC64
4394
                    if (IS_IMM)
4395
                        goto illegal_insn;
4396
                    if (!supervisor(dc))
4397
                        goto priv_insn;
4398
#endif
4399
                    save_state(dc, cpu_cond);
4400
                    gen_st_asi(cpu_val, cpu_addr, insn, 4);
4401
                    break;
4402
                case 0x15: /* stba, store byte alternate */
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_st_asi(cpu_val, cpu_addr, insn, 1);
4411
                    break;
4412
                case 0x16: /* stha, store halfword alternate */
4413
#ifndef TARGET_SPARC64
4414
                    if (IS_IMM)
4415
                        goto illegal_insn;
4416
                    if (!supervisor(dc))
4417
                        goto priv_insn;
4418
#endif
4419
                    save_state(dc, cpu_cond);
4420
                    gen_st_asi(cpu_val, cpu_addr, insn, 2);
4421
                    break;
4422
                case 0x17: /* stda, store double word alternate */
4423
#ifndef TARGET_SPARC64
4424
                    if (IS_IMM)
4425
                        goto illegal_insn;
4426
                    if (!supervisor(dc))
4427
                        goto priv_insn;
4428
#endif
4429
                    if (rd & 1)
4430
                        goto illegal_insn;
4431
                    else {
4432
                        save_state(dc, cpu_cond);
4433
                        gen_stda_asi(cpu_val, cpu_addr, insn, rd);
4434
                    }
4435
                    break;
4436
#endif
4437
#ifdef TARGET_SPARC64
4438
                case 0x0e: /* V9 stx */
4439
                    gen_address_mask(dc, cpu_addr);
4440
                    tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx);
4441
                    break;
4442
                case 0x1e: /* V9 stxa */
4443
                    save_state(dc, cpu_cond);
4444
                    gen_st_asi(cpu_val, cpu_addr, insn, 8);
4445
                    break;
4446
#endif
4447
                default:
4448
                    goto illegal_insn;
4449
                }
4450
            } else if (xop > 0x23 && xop < 0x28) {
4451
                if (gen_trap_ifnofpu(dc, cpu_cond))
4452
                    goto jmp_insn;
4453
                save_state(dc, cpu_cond);
4454
                switch (xop) {
4455
                case 0x24: /* stf, store fpreg */
4456
                    gen_address_mask(dc, cpu_addr);
4457
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_fpr[rd]);
4458
                    tcg_gen_qemu_st32(cpu_tmp0, cpu_addr, dc->mem_idx);
4459
                    break;
4460
                case 0x25: /* stfsr, V9 stxfsr */
4461
#ifdef TARGET_SPARC64
4462
                    gen_address_mask(dc, cpu_addr);
4463
                    tcg_gen_ld_i64(cpu_tmp64, cpu_env, offsetof(CPUState, fsr));
4464
                    if (rd == 1)
4465
                        tcg_gen_qemu_st64(cpu_tmp64, cpu_addr, dc->mem_idx);
4466
                    else
4467
                        tcg_gen_qemu_st32(cpu_tmp64, cpu_addr, dc->mem_idx);
4468
#else
4469
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUState, fsr));
4470
                    tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx);
4471
#endif
4472
                    break;
4473
                case 0x26:
4474
#ifdef TARGET_SPARC64
4475
                    /* V9 stqf, store quad fpreg */
4476
                    {
4477
                        TCGv_i32 r_const;
4478

    
4479
                        CHECK_FPU_FEATURE(dc, FLOAT128);
4480
                        gen_op_load_fpr_QT0(QFPREG(rd));
4481
                        r_const = tcg_const_i32(dc->mem_idx);
4482
                        gen_helper_stqf(cpu_addr, r_const);
4483
                        tcg_temp_free_i32(r_const);
4484
                    }
4485
                    break;
4486
#else /* !TARGET_SPARC64 */
4487
                    /* stdfq, store floating point queue */
4488
#if defined(CONFIG_USER_ONLY)
4489
                    goto illegal_insn;
4490
#else
4491
                    if (!supervisor(dc))
4492
                        goto priv_insn;
4493
                    if (gen_trap_ifnofpu(dc, cpu_cond))
4494
                        goto jmp_insn;
4495
                    goto nfq_insn;
4496
#endif
4497
#endif
4498
                case 0x27: /* stdf, store double fpreg */
4499
                    {
4500
                        TCGv_i32 r_const;
4501

    
4502
                        gen_op_load_fpr_DT0(DFPREG(rd));
4503
                        r_const = tcg_const_i32(dc->mem_idx);
4504
                        gen_helper_stdf(cpu_addr, r_const);
4505
                        tcg_temp_free_i32(r_const);
4506
                    }
4507
                    break;
4508
                default:
4509
                    goto illegal_insn;
4510
                }
4511
            } else if (xop > 0x33 && xop < 0x3f) {
4512
                save_state(dc, cpu_cond);
4513
                switch (xop) {
4514
#ifdef TARGET_SPARC64
4515
                case 0x34: /* V9 stfa */
4516
                    gen_stf_asi(cpu_addr, insn, 4, rd);
4517
                    break;
4518
                case 0x36: /* V9 stqfa */
4519
                    {
4520
                        TCGv_i32 r_const;
4521

    
4522
                        CHECK_FPU_FEATURE(dc, FLOAT128);
4523
                        r_const = tcg_const_i32(7);
4524
                        gen_helper_check_align(cpu_addr, r_const);
4525
                        tcg_temp_free_i32(r_const);
4526
                        gen_op_load_fpr_QT0(QFPREG(rd));
4527
                        gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd));
4528
                    }
4529
                    break;
4530
                case 0x37: /* V9 stdfa */
4531
                    gen_op_load_fpr_DT0(DFPREG(rd));
4532
                    gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
4533
                    break;
4534
                case 0x3c: /* V9 casa */
4535
                    gen_cas_asi(cpu_val, cpu_addr, cpu_src2, insn, rd);
4536
                    gen_movl_TN_reg(rd, cpu_val);
4537
                    break;
4538
                case 0x3e: /* V9 casxa */
4539
                    gen_casx_asi(cpu_val, cpu_addr, cpu_src2, insn, rd);
4540
                    gen_movl_TN_reg(rd, cpu_val);
4541
                    break;
4542
#else
4543
                case 0x34: /* stc */
4544
                case 0x35: /* stcsr */
4545
                case 0x36: /* stdcq */
4546
                case 0x37: /* stdc */
4547
                    goto ncp_insn;
4548
#endif
4549
                default:
4550
                    goto illegal_insn;
4551
                }
4552
            } else
4553
                goto illegal_insn;
4554
        }
4555
        break;
4556
    }
4557
    /* default case for non jump instructions */
4558
    if (dc->npc == DYNAMIC_PC) {
4559
        dc->pc = DYNAMIC_PC;
4560
        gen_op_next_insn();
4561
    } else if (dc->npc == JUMP_PC) {
4562
        /* we can do a static jump */
4563
        gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
4564
        dc->is_br = 1;
4565
    } else {
4566
        dc->pc = dc->npc;
4567
        dc->npc = dc->npc + 4;
4568
    }
4569
 jmp_insn:
4570
    return;
4571
 illegal_insn:
4572
    {
4573
        TCGv_i32 r_const;
4574

    
4575
        save_state(dc, cpu_cond);
4576
        r_const = tcg_const_i32(TT_ILL_INSN);
4577
        gen_helper_raise_exception(r_const);
4578
        tcg_temp_free_i32(r_const);
4579
        dc->is_br = 1;
4580
    }
4581
    return;
4582
 unimp_flush:
4583
    {
4584
        TCGv_i32 r_const;
4585

    
4586
        save_state(dc, cpu_cond);
4587
        r_const = tcg_const_i32(TT_UNIMP_FLUSH);
4588
        gen_helper_raise_exception(r_const);
4589
        tcg_temp_free_i32(r_const);
4590
        dc->is_br = 1;
4591
    }
4592
    return;
4593
#if !defined(CONFIG_USER_ONLY)
4594
 priv_insn:
4595
    {
4596
        TCGv_i32 r_const;
4597

    
4598
        save_state(dc, cpu_cond);
4599
        r_const = tcg_const_i32(TT_PRIV_INSN);
4600
        gen_helper_raise_exception(r_const);
4601
        tcg_temp_free_i32(r_const);
4602
        dc->is_br = 1;
4603
    }
4604
    return;
4605
#endif
4606
 nfpu_insn:
4607
    save_state(dc, cpu_cond);
4608
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
4609
    dc->is_br = 1;
4610
    return;
4611
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
4612
 nfq_insn:
4613
    save_state(dc, cpu_cond);
4614
    gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
4615
    dc->is_br = 1;
4616
    return;
4617
#endif
4618
#ifndef TARGET_SPARC64
4619
 ncp_insn:
4620
    {
4621
        TCGv r_const;
4622

    
4623
        save_state(dc, cpu_cond);
4624
        r_const = tcg_const_i32(TT_NCP_INSN);
4625
        gen_helper_raise_exception(r_const);
4626
        tcg_temp_free(r_const);
4627
        dc->is_br = 1;
4628
    }
4629
    return;
4630
#endif
4631
}
4632

    
4633
static inline void gen_intermediate_code_internal(TranslationBlock * tb,
4634
                                                  int spc, CPUSPARCState *env)
4635
{
4636
    target_ulong pc_start, last_pc;
4637
    uint16_t *gen_opc_end;
4638
    DisasContext dc1, *dc = &dc1;
4639
    CPUBreakpoint *bp;
4640
    int j, lj = -1;
4641
    int num_insns;
4642
    int max_insns;
4643

    
4644
    memset(dc, 0, sizeof(DisasContext));
4645
    dc->tb = tb;
4646
    pc_start = tb->pc;
4647
    dc->pc = pc_start;
4648
    last_pc = dc->pc;
4649
    dc->npc = (target_ulong) tb->cs_base;
4650
    dc->cc_op = CC_OP_DYNAMIC;
4651
    dc->mem_idx = cpu_mmu_index(env);
4652
    dc->def = env->def;
4653
    if ((dc->def->features & CPU_FEATURE_FLOAT))
4654
        dc->fpu_enabled = cpu_fpu_enabled(env);
4655
    else
4656
        dc->fpu_enabled = 0;
4657
#ifdef TARGET_SPARC64
4658
    dc->address_mask_32bit = env->pstate & PS_AM;
4659
#endif
4660
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4661

    
4662
    cpu_tmp0 = tcg_temp_new();
4663
    cpu_tmp32 = tcg_temp_new_i32();
4664
    cpu_tmp64 = tcg_temp_new_i64();
4665

    
4666
    cpu_dst = tcg_temp_local_new();
4667

    
4668
    // loads and stores
4669
    cpu_val = tcg_temp_local_new();
4670
    cpu_addr = tcg_temp_local_new();
4671

    
4672
    num_insns = 0;
4673
    max_insns = tb->cflags & CF_COUNT_MASK;
4674
    if (max_insns == 0)
4675
        max_insns = CF_COUNT_MASK;
4676
    gen_icount_start();
4677
    do {
4678
        if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
4679
            TAILQ_FOREACH(bp, &env->breakpoints, entry) {
4680
                if (bp->pc == dc->pc) {
4681
                    if (dc->pc != pc_start)
4682
                        save_state(dc, cpu_cond);
4683
                    gen_helper_debug();
4684
                    tcg_gen_exit_tb(0);
4685
                    dc->is_br = 1;
4686
                    goto exit_gen_loop;
4687
                }
4688
            }
4689
        }
4690
        if (spc) {
4691
            qemu_log("Search PC...\n");
4692
            j = gen_opc_ptr - gen_opc_buf;
4693
            if (lj < j) {
4694
                lj++;
4695
                while (lj < j)
4696
                    gen_opc_instr_start[lj++] = 0;
4697
                gen_opc_pc[lj] = dc->pc;
4698
                gen_opc_npc[lj] = dc->npc;
4699
                gen_opc_instr_start[lj] = 1;
4700
                gen_opc_icount[lj] = num_insns;
4701
            }
4702
        }
4703
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
4704
            gen_io_start();
4705
        last_pc = dc->pc;
4706
        disas_sparc_insn(dc);
4707
        num_insns++;
4708

    
4709
        if (dc->is_br)
4710
            break;
4711
        /* if the next PC is different, we abort now */
4712
        if (dc->pc != (last_pc + 4))
4713
            break;
4714
        /* if we reach a page boundary, we stop generation so that the
4715
           PC of a TT_TFAULT exception is always in the right page */
4716
        if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
4717
            break;
4718
        /* if single step mode, we generate only one instruction and
4719
           generate an exception */
4720
        if (env->singlestep_enabled || singlestep) {
4721
            tcg_gen_movi_tl(cpu_pc, dc->pc);
4722
            tcg_gen_exit_tb(0);
4723
            break;
4724
        }
4725
    } while ((gen_opc_ptr < gen_opc_end) &&
4726
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32) &&
4727
             num_insns < max_insns);
4728

    
4729
 exit_gen_loop:
4730
    tcg_temp_free(cpu_addr);
4731
    tcg_temp_free(cpu_val);
4732
    tcg_temp_free(cpu_dst);
4733
    tcg_temp_free_i64(cpu_tmp64);
4734
    tcg_temp_free_i32(cpu_tmp32);
4735
    tcg_temp_free(cpu_tmp0);
4736
    if (tb->cflags & CF_LAST_IO)
4737
        gen_io_end();
4738
    if (!dc->is_br) {
4739
        if (dc->pc != DYNAMIC_PC &&
4740
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
4741
            /* static PC and NPC: we can use direct chaining */
4742
            gen_goto_tb(dc, 0, dc->pc, dc->npc);
4743
        } else {
4744
            if (dc->pc != DYNAMIC_PC)
4745
                tcg_gen_movi_tl(cpu_pc, dc->pc);
4746
            save_npc(dc, cpu_cond);
4747
            tcg_gen_exit_tb(0);
4748
        }
4749
    }
4750
    gen_icount_end(tb, num_insns);
4751
    *gen_opc_ptr = INDEX_op_end;
4752
    if (spc) {
4753
        j = gen_opc_ptr - gen_opc_buf;
4754
        lj++;
4755
        while (lj <= j)
4756
            gen_opc_instr_start[lj++] = 0;
4757
#if 0
4758
        log_page_dump();
4759
#endif
4760
        gen_opc_jump_pc[0] = dc->jump_pc[0];
4761
        gen_opc_jump_pc[1] = dc->jump_pc[1];
4762
    } else {
4763
        tb->size = last_pc + 4 - pc_start;
4764
        tb->icount = num_insns;
4765
    }
4766
#ifdef DEBUG_DISAS
4767
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
4768
        qemu_log("--------------\n");
4769
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
4770
        log_target_disas(pc_start, last_pc + 4 - pc_start, 0);
4771
        qemu_log("\n");
4772
    }
4773
#endif
4774
}
4775

    
4776
void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
4777
{
4778
    gen_intermediate_code_internal(tb, 0, env);
4779
}
4780

    
4781
void gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
4782
{
4783
    gen_intermediate_code_internal(tb, 1, env);
4784
}
4785

    
4786
void gen_intermediate_code_init(CPUSPARCState *env)
4787
{
4788
    unsigned int i;
4789
    static int inited;
4790
    static const char * const gregnames[8] = {
4791
        NULL, // g0 not used
4792
        "g1",
4793
        "g2",
4794
        "g3",
4795
        "g4",
4796
        "g5",
4797
        "g6",
4798
        "g7",
4799
    };
4800
    static const char * const fregnames[64] = {
4801
        "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
4802
        "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
4803
        "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
4804
        "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
4805
        "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
4806
        "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
4807
        "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
4808
        "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
4809
    };
4810

    
4811
    /* init various static tables */
4812
    if (!inited) {
4813
        inited = 1;
4814

    
4815
        cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
4816
        cpu_regwptr = tcg_global_mem_new_ptr(TCG_AREG0,
4817
                                             offsetof(CPUState, regwptr),
4818
                                             "regwptr");
4819
#ifdef TARGET_SPARC64
4820
        cpu_xcc = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, xcc),
4821
                                         "xcc");
4822
        cpu_asi = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, asi),
4823
                                         "asi");
4824
        cpu_fprs = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, fprs),
4825
                                          "fprs");
4826
        cpu_gsr = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, gsr),
4827
                                     "gsr");
4828
        cpu_tick_cmpr = tcg_global_mem_new(TCG_AREG0,
4829
                                           offsetof(CPUState, tick_cmpr),
4830
                                           "tick_cmpr");
4831
        cpu_stick_cmpr = tcg_global_mem_new(TCG_AREG0,
4832
                                            offsetof(CPUState, stick_cmpr),
4833
                                            "stick_cmpr");
4834
        cpu_hstick_cmpr = tcg_global_mem_new(TCG_AREG0,
4835
                                             offsetof(CPUState, hstick_cmpr),
4836
                                             "hstick_cmpr");
4837
        cpu_hintp = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, hintp),
4838
                                       "hintp");
4839
        cpu_htba = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, htba),
4840
                                      "htba");
4841
        cpu_hver = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, hver),
4842
                                      "hver");
4843
        cpu_ssr = tcg_global_mem_new(TCG_AREG0,
4844
                                     offsetof(CPUState, ssr), "ssr");
4845
        cpu_ver = tcg_global_mem_new(TCG_AREG0,
4846
                                     offsetof(CPUState, version), "ver");
4847
        cpu_softint = tcg_global_mem_new_i32(TCG_AREG0,
4848
                                             offsetof(CPUState, softint),
4849
                                             "softint");
4850
#else
4851
        cpu_wim = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, wim),
4852
                                     "wim");
4853
#endif
4854
        cpu_cond = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cond),
4855
                                      "cond");
4856
        cpu_cc_src = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_src),
4857
                                        "cc_src");
4858
        cpu_cc_src2 = tcg_global_mem_new(TCG_AREG0,
4859
                                         offsetof(CPUState, cc_src2),
4860
                                         "cc_src2");
4861
        cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_dst),
4862
                                        "cc_dst");
4863
        cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, cc_op),
4864
                                           "cc_op");
4865
        cpu_psr = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, psr),
4866
                                         "psr");
4867
        cpu_fsr = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, fsr),
4868
                                     "fsr");
4869
        cpu_pc = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, pc),
4870
                                    "pc");
4871
        cpu_npc = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, npc),
4872
                                     "npc");
4873
        cpu_y = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, y), "y");
4874
#ifndef CONFIG_USER_ONLY
4875
        cpu_tbr = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, tbr),
4876
                                     "tbr");
4877
#endif
4878
        for (i = 1; i < 8; i++)
4879
            cpu_gregs[i] = tcg_global_mem_new(TCG_AREG0,
4880
                                              offsetof(CPUState, gregs[i]),
4881
                                              gregnames[i]);
4882
        for (i = 0; i < TARGET_FPREGS; i++)
4883
            cpu_fpr[i] = tcg_global_mem_new_i32(TCG_AREG0,
4884
                                                offsetof(CPUState, fpr[i]),
4885
                                                fregnames[i]);
4886

    
4887
        /* register helpers */
4888

    
4889
#define GEN_HELPER 2
4890
#include "helper.h"
4891
    }
4892
}
4893

    
4894
void gen_pc_load(CPUState *env, TranslationBlock *tb,
4895
                unsigned long searched_pc, int pc_pos, void *puc)
4896
{
4897
    target_ulong npc;
4898
    env->pc = gen_opc_pc[pc_pos];
4899
    npc = gen_opc_npc[pc_pos];
4900
    if (npc == 1) {
4901
        /* dynamic NPC: already stored */
4902
    } else if (npc == 2) {
4903
        target_ulong t2 = (target_ulong)(unsigned long)puc;
4904
        /* jump PC: use T2 and the jump targets of the translation */
4905
        if (t2)
4906
            env->npc = gen_opc_jump_pc[0];
4907
        else
4908
            env->npc = gen_opc_jump_pc[1];
4909
    } else {
4910
        env->npc = npc;
4911
    }
4912
}