Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ 0dcda9be

History | View | Annotate | Download (175.5 kB)

1
/*
2
   SPARC translation
3

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

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

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

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

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

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

    
34
#define DEBUG_DISAS
35

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
125
static void gen_op_store_DT0_fpr(unsigned int dst)
126
{
127
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) + offsetof(CPU_DoubleU, l.upper));
128
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst]));
129
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) + offsetof(CPU_DoubleU, l.lower));
130
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 1]));
131
}
132

    
133
static void gen_op_load_fpr_QT0(unsigned int src)
134
{
135
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
136
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upmost));
137
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
138
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upper));
139
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 2]));
140
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lower));
141
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 3]));
142
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lowest));
143
}
144

    
145
static void gen_op_load_fpr_QT1(unsigned int src)
146
{
147
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
148
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.upmost));
149
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
150
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.upper));
151
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 2]));
152
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.lower));
153
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 3]));
154
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + offsetof(CPU_QuadU, l.lowest));
155
}
156

    
157
static void gen_op_store_QT0_fpr(unsigned int dst)
158
{
159
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upmost));
160
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst]));
161
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upper));
162
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 1]));
163
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lower));
164
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 2]));
165
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lowest));
166
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 3]));
167
}
168

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

    
183
#ifdef TARGET_ABI32
184
#define ABI32_MASK(addr) tcg_gen_andi_tl(addr, addr, 0xffffffffULL);
185
#else
186
#define ABI32_MASK(addr)
187
#endif
188

    
189
static inline void gen_movl_reg_TN(int reg, TCGv tn)
190
{
191
    if (reg == 0)
192
        tcg_gen_movi_tl(tn, 0);
193
    else if (reg < 8)
194
        tcg_gen_mov_tl(tn, cpu_gregs[reg]);
195
    else {
196
        tcg_gen_ld_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
197
    }
198
}
199

    
200
static inline void gen_movl_TN_reg(int reg, TCGv tn)
201
{
202
    if (reg == 0)
203
        return;
204
    else if (reg < 8)
205
        tcg_gen_mov_tl(cpu_gregs[reg], tn);
206
    else {
207
        tcg_gen_st_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
208
    }
209
}
210

    
211
static inline void gen_goto_tb(DisasContext *s, int tb_num,
212
                               target_ulong pc, target_ulong npc)
213
{
214
    TranslationBlock *tb;
215

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

    
232
// XXX suboptimal
233
static inline void gen_mov_reg_N(TCGv reg, TCGv src)
234
{
235
    tcg_gen_extu_i32_tl(reg, src);
236
    tcg_gen_shri_tl(reg, reg, PSR_NEG_SHIFT);
237
    tcg_gen_andi_tl(reg, reg, 0x1);
238
}
239

    
240
static inline void gen_mov_reg_Z(TCGv reg, TCGv src)
241
{
242
    tcg_gen_extu_i32_tl(reg, src);
243
    tcg_gen_shri_tl(reg, reg, PSR_ZERO_SHIFT);
244
    tcg_gen_andi_tl(reg, reg, 0x1);
245
}
246

    
247
static inline void gen_mov_reg_V(TCGv reg, TCGv src)
248
{
249
    tcg_gen_extu_i32_tl(reg, src);
250
    tcg_gen_shri_tl(reg, reg, PSR_OVF_SHIFT);
251
    tcg_gen_andi_tl(reg, reg, 0x1);
252
}
253

    
254
static inline void gen_mov_reg_C(TCGv reg, TCGv src)
255
{
256
    tcg_gen_extu_i32_tl(reg, src);
257
    tcg_gen_shri_tl(reg, reg, PSR_CARRY_SHIFT);
258
    tcg_gen_andi_tl(reg, reg, 0x1);
259
}
260

    
261
static inline void gen_cc_clear_icc(void)
262
{
263
    tcg_gen_movi_i32(cpu_psr, 0);
264
}
265

    
266
#ifdef TARGET_SPARC64
267
static inline void gen_cc_clear_xcc(void)
268
{
269
    tcg_gen_movi_i32(cpu_xcc, 0);
270
}
271
#endif
272

    
273
/* old op:
274
    if (!T0)
275
        env->psr |= PSR_ZERO;
276
    if ((int32_t) T0 < 0)
277
        env->psr |= PSR_NEG;
278
*/
279
static inline void gen_cc_NZ_icc(TCGv dst)
280
{
281
    TCGv r_temp;
282
    int l1, l2;
283

    
284
    l1 = gen_new_label();
285
    l2 = gen_new_label();
286
    r_temp = tcg_temp_new(TCG_TYPE_TL);
287
    tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
288
    tcg_gen_brcond_tl(TCG_COND_NE, r_temp, tcg_const_tl(0), l1);
289
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_ZERO);
290
    gen_set_label(l1);
291
    tcg_gen_ext_i32_tl(r_temp, dst);
292
    tcg_gen_brcond_tl(TCG_COND_GE, r_temp, tcg_const_tl(0), l2);
293
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_NEG);
294
    gen_set_label(l2);
295
}
296

    
297
#ifdef TARGET_SPARC64
298
static inline void gen_cc_NZ_xcc(TCGv dst)
299
{
300
    int l1, l2;
301

    
302
    l1 = gen_new_label();
303
    l2 = gen_new_label();
304
    tcg_gen_brcond_tl(TCG_COND_NE, dst, tcg_const_tl(0), l1);
305
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_ZERO);
306
    gen_set_label(l1);
307
    tcg_gen_brcond_tl(TCG_COND_GE, dst, tcg_const_tl(0), l2);
308
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_NEG);
309
    gen_set_label(l2);
310
}
311
#endif
312

    
313
/* old op:
314
    if (T0 < src1)
315
        env->psr |= PSR_CARRY;
316
*/
317
static inline void gen_cc_C_add_icc(TCGv dst, TCGv src1)
318
{
319
    TCGv r_temp;
320
    int l1;
321

    
322
    l1 = gen_new_label();
323
    r_temp = tcg_temp_new(TCG_TYPE_TL);
324
    tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
325
    tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l1);
326
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
327
    gen_set_label(l1);
328
}
329

    
330
#ifdef TARGET_SPARC64
331
static inline void gen_cc_C_add_xcc(TCGv dst, TCGv src1)
332
{
333
    int l1;
334

    
335
    l1 = gen_new_label();
336
    tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l1);
337
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
338
    gen_set_label(l1);
339
}
340
#endif
341

    
342
/* old op:
343
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
344
        env->psr |= PSR_OVF;
345
*/
346
static inline void gen_cc_V_add_icc(TCGv dst, TCGv src1, TCGv src2)
347
{
348
    TCGv r_temp;
349

    
350
    r_temp = tcg_temp_new(TCG_TYPE_TL);
351
    tcg_gen_xor_tl(r_temp, src1, src2);
352
    tcg_gen_xori_tl(r_temp, r_temp, -1);
353
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
354
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
355
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
356
    tcg_gen_shri_tl(r_temp, r_temp, 31 - PSR_OVF_SHIFT);
357
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
358
    tcg_gen_or_i32(cpu_psr, cpu_psr, cpu_tmp32);
359
}
360

    
361
#ifdef TARGET_SPARC64
362
static inline void gen_cc_V_add_xcc(TCGv dst, TCGv src1, TCGv src2)
363
{
364
    TCGv r_temp;
365

    
366
    r_temp = tcg_temp_new(TCG_TYPE_TL);
367
    tcg_gen_xor_tl(r_temp, src1, src2);
368
    tcg_gen_xori_tl(r_temp, r_temp, -1);
369
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
370
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
371
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
372
    tcg_gen_shri_tl(r_temp, r_temp, 63 - PSR_OVF_SHIFT);
373
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
374
    tcg_gen_or_i32(cpu_xcc, cpu_xcc, cpu_tmp32);
375
}
376
#endif
377

    
378
static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
379
{
380
    TCGv r_temp;
381
    int l1;
382

    
383
    l1 = gen_new_label();
384

    
385
    r_temp = tcg_temp_new(TCG_TYPE_TL);
386
    tcg_gen_xor_tl(r_temp, src1, src2);
387
    tcg_gen_xori_tl(r_temp, r_temp, -1);
388
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
389
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
390
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
391
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
392
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
393
    gen_set_label(l1);
394
}
395

    
396
static inline void gen_cc_V_tag(TCGv src1, TCGv src2)
397
{
398
    int l1;
399

    
400
    l1 = gen_new_label();
401
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
402
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
403
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
404
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
405
    gen_set_label(l1);
406
}
407

    
408
static inline void gen_tag_tv(TCGv src1, TCGv src2)
409
{
410
    int l1;
411

    
412
    l1 = gen_new_label();
413
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
414
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
415
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
416
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
417
    gen_set_label(l1);
418
}
419

    
420
static inline void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2)
421
{
422
    tcg_gen_mov_tl(cpu_cc_src, src1);
423
    tcg_gen_mov_tl(cpu_cc_src2, src2);
424
    tcg_gen_add_tl(dst, src1, src2);
425
    tcg_gen_mov_tl(cpu_cc_dst, dst);
426
    gen_cc_clear_icc();
427
    gen_cc_NZ_icc(cpu_cc_dst);
428
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
429
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
430
#ifdef TARGET_SPARC64
431
    gen_cc_clear_xcc();
432
    gen_cc_NZ_xcc(cpu_cc_dst);
433
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
434
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
435
#endif
436
}
437

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

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

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

    
500
/* old op:
501
    if (src1 < T1)
502
        env->psr |= PSR_CARRY;
503
*/
504
static inline void gen_cc_C_sub_icc(TCGv src1, TCGv src2)
505
{
506
    TCGv r_temp1, r_temp2;
507
    int l1;
508

    
509
    l1 = gen_new_label();
510
    r_temp1 = tcg_temp_new(TCG_TYPE_TL);
511
    r_temp2 = tcg_temp_new(TCG_TYPE_TL);
512
    tcg_gen_andi_tl(r_temp1, src1, 0xffffffffULL);
513
    tcg_gen_andi_tl(r_temp2, src2, 0xffffffffULL);
514
    tcg_gen_brcond_tl(TCG_COND_GEU, r_temp1, r_temp2, l1);
515
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
516
    gen_set_label(l1);
517
}
518

    
519
#ifdef TARGET_SPARC64
520
static inline void gen_cc_C_sub_xcc(TCGv src1, TCGv src2)
521
{
522
    int l1;
523

    
524
    l1 = gen_new_label();
525
    tcg_gen_brcond_tl(TCG_COND_GEU, src1, src2, l1);
526
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
527
    gen_set_label(l1);
528
}
529
#endif
530

    
531
/* old op:
532
    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
533
        env->psr |= PSR_OVF;
534
*/
535
static inline void gen_cc_V_sub_icc(TCGv dst, TCGv src1, TCGv src2)
536
{
537
    TCGv r_temp;
538

    
539
    r_temp = tcg_temp_new(TCG_TYPE_TL);
540
    tcg_gen_xor_tl(r_temp, src1, src2);
541
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
542
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
543
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
544
    tcg_gen_shri_tl(r_temp, r_temp, 31 - PSR_OVF_SHIFT);
545
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
546
    tcg_gen_or_i32(cpu_psr, cpu_psr, cpu_tmp32);
547
}
548

    
549
#ifdef TARGET_SPARC64
550
static inline void gen_cc_V_sub_xcc(TCGv dst, TCGv src1, TCGv src2)
551
{
552
    TCGv r_temp;
553

    
554
    r_temp = tcg_temp_new(TCG_TYPE_TL);
555
    tcg_gen_xor_tl(r_temp, src1, src2);
556
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
557
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
558
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
559
    tcg_gen_shri_tl(r_temp, r_temp, 63 - PSR_OVF_SHIFT);
560
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
561
    tcg_gen_or_i32(cpu_xcc, cpu_xcc, cpu_tmp32);
562
}
563
#endif
564

    
565
static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
566
{
567
    TCGv r_temp;
568
    int l1;
569

    
570
    l1 = gen_new_label();
571

    
572
    r_temp = tcg_temp_new(TCG_TYPE_TL);
573
    tcg_gen_xor_tl(r_temp, src1, src2);
574
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
575
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
576
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
577
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
578
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
579
    gen_set_label(l1);
580
}
581

    
582
static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2)
583
{
584
    tcg_gen_mov_tl(cpu_cc_src, src1);
585
    tcg_gen_mov_tl(cpu_cc_src2, src2);
586
    tcg_gen_sub_tl(dst, src1, src2);
587
    tcg_gen_mov_tl(cpu_cc_dst, dst);
588
    gen_cc_clear_icc();
589
    gen_cc_NZ_icc(cpu_cc_dst);
590
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
591
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
592
#ifdef TARGET_SPARC64
593
    gen_cc_clear_xcc();
594
    gen_cc_NZ_xcc(cpu_cc_dst);
595
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
596
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
597
#endif
598
}
599

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

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

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

    
662
static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
663
{
664
    TCGv r_temp, r_temp2;
665
    int l1;
666

    
667
    l1 = gen_new_label();
668
    r_temp = tcg_temp_new(TCG_TYPE_TL);
669
    r_temp2 = tcg_temp_new(TCG_TYPE_I32);
670

    
671
    /* old op:
672
    if (!(env->y & 1))
673
        T1 = 0;
674
    */
675
    tcg_gen_mov_tl(cpu_cc_src, src1);
676
    tcg_gen_ld32u_tl(r_temp, cpu_env, offsetof(CPUSPARCState, y));
677
    tcg_gen_trunc_tl_i32(r_temp2, r_temp);
678
    tcg_gen_andi_i32(r_temp2, r_temp2, 0x1);
679
    tcg_gen_mov_tl(cpu_cc_src2, src2);
680
    tcg_gen_brcond_i32(TCG_COND_NE, r_temp2, tcg_const_i32(0), l1);
681
    tcg_gen_movi_tl(cpu_cc_src2, 0);
682
    gen_set_label(l1);
683

    
684
    // b2 = T0 & 1;
685
    // env->y = (b2 << 31) | (env->y >> 1);
686
    tcg_gen_trunc_tl_i32(r_temp2, cpu_cc_src);
687
    tcg_gen_andi_i32(r_temp2, r_temp2, 0x1);
688
    tcg_gen_shli_i32(r_temp2, r_temp2, 31);
689
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, y));
690
    tcg_gen_shri_i32(cpu_tmp32, cpu_tmp32, 1);
691
    tcg_gen_or_i32(cpu_tmp32, cpu_tmp32, r_temp2);
692
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, y));
693

    
694
    // b1 = N ^ V;
695
    gen_mov_reg_N(cpu_tmp0, cpu_psr);
696
    gen_mov_reg_V(r_temp, cpu_psr);
697
    tcg_gen_xor_tl(cpu_tmp0, cpu_tmp0, r_temp);
698

    
699
    // T0 = (b1 << 31) | (T0 >> 1);
700
    // src1 = T0;
701
    tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
702
    tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
703
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
704

    
705
    /* do addition and update flags */
706
    tcg_gen_add_tl(dst, cpu_cc_src, cpu_cc_src2);
707
    tcg_gen_mov_tl(cpu_cc_dst, dst);
708

    
709
    gen_cc_clear_icc();
710
    gen_cc_NZ_icc(cpu_cc_dst);
711
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
712
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
713
}
714

    
715
static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
716
{
717
    TCGv r_temp, r_temp2;
718

    
719
    r_temp = tcg_temp_new(TCG_TYPE_I64);
720
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);
721

    
722
    tcg_gen_extu_tl_i64(r_temp, src2);
723
    tcg_gen_extu_tl_i64(r_temp2, src1);
724
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
725

    
726
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
727
    tcg_gen_trunc_i64_i32(r_temp, r_temp);
728
    tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
729
#ifdef TARGET_SPARC64
730
    tcg_gen_mov_i64(dst, r_temp2);
731
#else
732
    tcg_gen_trunc_i64_tl(dst, r_temp2);
733
#endif
734
}
735

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

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

    
743
    tcg_gen_ext_tl_i64(r_temp, src2);
744
    tcg_gen_ext_tl_i64(r_temp2, src1);
745
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
746

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

    
757
#ifdef TARGET_SPARC64
758
static inline void gen_trap_ifdivzero_tl(TCGv divisor)
759
{
760
    int l1;
761

    
762
    l1 = gen_new_label();
763
    tcg_gen_brcond_tl(TCG_COND_NE, divisor, tcg_const_tl(0), l1);
764
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_DIV_ZERO));
765
    gen_set_label(l1);
766
}
767

    
768
static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
769
{
770
    int l1, l2;
771

    
772
    l1 = gen_new_label();
773
    l2 = gen_new_label();
774
    tcg_gen_mov_tl(cpu_cc_src, src1);
775
    tcg_gen_mov_tl(cpu_cc_src2, src2);
776
    gen_trap_ifdivzero_tl(src2);
777
    tcg_gen_brcond_tl(TCG_COND_NE, cpu_cc_src, tcg_const_tl(INT64_MIN), l1);
778
    tcg_gen_brcond_tl(TCG_COND_NE, cpu_cc_src2, tcg_const_tl(-1), l1);
779
    tcg_gen_movi_i64(dst, INT64_MIN);
780
    tcg_gen_br(l2);
781
    gen_set_label(l1);
782
    tcg_gen_div_i64(dst, cpu_cc_src, cpu_cc_src2);
783
    gen_set_label(l2);
784
}
785
#endif
786

    
787
static inline void gen_op_div_cc(TCGv dst)
788
{
789
    int l1;
790

    
791
    tcg_gen_mov_tl(cpu_cc_dst, dst);
792
    gen_cc_clear_icc();
793
    gen_cc_NZ_icc(cpu_cc_dst);
794
    l1 = gen_new_label();
795
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, cc_src2));
796
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
797
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
798
    gen_set_label(l1);
799
}
800

    
801
static inline void gen_op_logic_cc(TCGv dst)
802
{
803
    tcg_gen_mov_tl(cpu_cc_dst, dst);
804

    
805
    gen_cc_clear_icc();
806
    gen_cc_NZ_icc(cpu_cc_dst);
807
#ifdef TARGET_SPARC64
808
    gen_cc_clear_xcc();
809
    gen_cc_NZ_xcc(cpu_cc_dst);
810
#endif
811
}
812

    
813
// 1
814
static inline void gen_op_eval_ba(TCGv dst)
815
{
816
    tcg_gen_movi_tl(dst, 1);
817
}
818

    
819
// Z
820
static inline void gen_op_eval_be(TCGv dst, TCGv src)
821
{
822
    gen_mov_reg_Z(dst, src);
823
}
824

    
825
// Z | (N ^ V)
826
static inline void gen_op_eval_ble(TCGv dst, TCGv src)
827
{
828
    gen_mov_reg_N(cpu_tmp0, src);
829
    gen_mov_reg_V(dst, src);
830
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
831
    gen_mov_reg_Z(cpu_tmp0, src);
832
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
833
}
834

    
835
// N ^ V
836
static inline void gen_op_eval_bl(TCGv dst, TCGv src)
837
{
838
    gen_mov_reg_V(cpu_tmp0, src);
839
    gen_mov_reg_N(dst, src);
840
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
841
}
842

    
843
// C | Z
844
static inline void gen_op_eval_bleu(TCGv dst, TCGv src)
845
{
846
    gen_mov_reg_Z(cpu_tmp0, src);
847
    gen_mov_reg_C(dst, src);
848
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
849
}
850

    
851
// C
852
static inline void gen_op_eval_bcs(TCGv dst, TCGv src)
853
{
854
    gen_mov_reg_C(dst, src);
855
}
856

    
857
// V
858
static inline void gen_op_eval_bvs(TCGv dst, TCGv src)
859
{
860
    gen_mov_reg_V(dst, src);
861
}
862

    
863
// 0
864
static inline void gen_op_eval_bn(TCGv dst)
865
{
866
    tcg_gen_movi_tl(dst, 0);
867
}
868

    
869
// N
870
static inline void gen_op_eval_bneg(TCGv dst, TCGv src)
871
{
872
    gen_mov_reg_N(dst, src);
873
}
874

    
875
// !Z
876
static inline void gen_op_eval_bne(TCGv dst, TCGv src)
877
{
878
    gen_mov_reg_Z(dst, src);
879
    tcg_gen_xori_tl(dst, dst, 0x1);
880
}
881

    
882
// !(Z | (N ^ V))
883
static inline void gen_op_eval_bg(TCGv dst, TCGv src)
884
{
885
    gen_mov_reg_N(cpu_tmp0, src);
886
    gen_mov_reg_V(dst, src);
887
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
888
    gen_mov_reg_Z(cpu_tmp0, src);
889
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
890
    tcg_gen_xori_tl(dst, dst, 0x1);
891
}
892

    
893
// !(N ^ V)
894
static inline void gen_op_eval_bge(TCGv dst, TCGv src)
895
{
896
    gen_mov_reg_V(cpu_tmp0, src);
897
    gen_mov_reg_N(dst, src);
898
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
899
    tcg_gen_xori_tl(dst, dst, 0x1);
900
}
901

    
902
// !(C | Z)
903
static inline void gen_op_eval_bgu(TCGv dst, TCGv src)
904
{
905
    gen_mov_reg_Z(cpu_tmp0, src);
906
    gen_mov_reg_C(dst, src);
907
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
908
    tcg_gen_xori_tl(dst, dst, 0x1);
909
}
910

    
911
// !C
912
static inline void gen_op_eval_bcc(TCGv dst, TCGv src)
913
{
914
    gen_mov_reg_C(dst, src);
915
    tcg_gen_xori_tl(dst, dst, 0x1);
916
}
917

    
918
// !N
919
static inline void gen_op_eval_bpos(TCGv dst, TCGv src)
920
{
921
    gen_mov_reg_N(dst, src);
922
    tcg_gen_xori_tl(dst, dst, 0x1);
923
}
924

    
925
// !V
926
static inline void gen_op_eval_bvc(TCGv dst, TCGv src)
927
{
928
    gen_mov_reg_V(dst, src);
929
    tcg_gen_xori_tl(dst, dst, 0x1);
930
}
931

    
932
/*
933
  FPSR bit field FCC1 | FCC0:
934
   0 =
935
   1 <
936
   2 >
937
   3 unordered
938
*/
939
static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src,
940
                                    unsigned int fcc_offset)
941
{
942
    tcg_gen_extu_i32_tl(reg, src);
943
    tcg_gen_shri_tl(reg, reg, FSR_FCC0_SHIFT + fcc_offset);
944
    tcg_gen_andi_tl(reg, reg, 0x1);
945
}
946

    
947
static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
948
                                    unsigned int fcc_offset)
949
{
950
    tcg_gen_extu_i32_tl(reg, src);
951
    tcg_gen_shri_tl(reg, reg, FSR_FCC1_SHIFT + fcc_offset);
952
    tcg_gen_andi_tl(reg, reg, 0x1);
953
}
954

    
955
// !0: FCC0 | FCC1
956
static inline void gen_op_eval_fbne(TCGv dst, TCGv src,
957
                                    unsigned int fcc_offset)
958
{
959
    gen_mov_reg_FCC0(dst, src, fcc_offset);
960
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
961
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
962
}
963

    
964
// 1 or 2: FCC0 ^ FCC1
965
static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
966
                                    unsigned int fcc_offset)
967
{
968
    gen_mov_reg_FCC0(dst, src, fcc_offset);
969
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
970
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
971
}
972

    
973
// 1 or 3: FCC0
974
static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
975
                                    unsigned int fcc_offset)
976
{
977
    gen_mov_reg_FCC0(dst, src, fcc_offset);
978
}
979

    
980
// 1: FCC0 & !FCC1
981
static inline void gen_op_eval_fbl(TCGv dst, TCGv src,
982
                                    unsigned int fcc_offset)
983
{
984
    gen_mov_reg_FCC0(dst, src, fcc_offset);
985
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
986
    tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
987
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
988
}
989

    
990
// 2 or 3: FCC1
991
static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
992
                                    unsigned int fcc_offset)
993
{
994
    gen_mov_reg_FCC1(dst, src, fcc_offset);
995
}
996

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

    
1007
// 3: FCC0 & FCC1
1008
static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
1009
                                    unsigned int fcc_offset)
1010
{
1011
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1012
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1013
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1014
}
1015

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

    
1026
// 0 or 3: !(FCC0 ^ FCC1)
1027
static inline void gen_op_eval_fbue(TCGv dst, TCGv src,
1028
                                    unsigned int fcc_offset)
1029
{
1030
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1031
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1032
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1033
    tcg_gen_xori_tl(dst, dst, 0x1);
1034
}
1035

    
1036
// 0 or 2: !FCC0
1037
static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
1038
                                    unsigned int fcc_offset)
1039
{
1040
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1041
    tcg_gen_xori_tl(dst, dst, 0x1);
1042
}
1043

    
1044
// !1: !(FCC0 & !FCC1)
1045
static inline void gen_op_eval_fbuge(TCGv dst, TCGv src,
1046
                                    unsigned int fcc_offset)
1047
{
1048
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1049
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1050
    tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
1051
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1052
    tcg_gen_xori_tl(dst, dst, 0x1);
1053
}
1054

    
1055
// 0 or 1: !FCC1
1056
static inline void gen_op_eval_fble(TCGv dst, TCGv src,
1057
                                    unsigned int fcc_offset)
1058
{
1059
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1060
    tcg_gen_xori_tl(dst, dst, 0x1);
1061
}
1062

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

    
1074
// !3: !(FCC0 & FCC1)
1075
static inline void gen_op_eval_fbo(TCGv dst, TCGv src,
1076
                                    unsigned int fcc_offset)
1077
{
1078
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1079
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1080
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1081
    tcg_gen_xori_tl(dst, dst, 0x1);
1082
}
1083

    
1084
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
1085
                               target_ulong pc2, TCGv r_cond)
1086
{
1087
    int l1;
1088

    
1089
    l1 = gen_new_label();
1090

    
1091
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1092

    
1093
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
1094

    
1095
    gen_set_label(l1);
1096
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
1097
}
1098

    
1099
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
1100
                                target_ulong pc2, TCGv r_cond)
1101
{
1102
    int l1;
1103

    
1104
    l1 = gen_new_label();
1105

    
1106
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1107

    
1108
    gen_goto_tb(dc, 0, pc2, pc1);
1109

    
1110
    gen_set_label(l1);
1111
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
1112
}
1113

    
1114
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
1115
                                      TCGv r_cond)
1116
{
1117
    int l1, l2;
1118

    
1119
    l1 = gen_new_label();
1120
    l2 = gen_new_label();
1121

    
1122
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1123

    
1124
    tcg_gen_movi_tl(cpu_npc, npc1);
1125
    tcg_gen_br(l2);
1126

    
1127
    gen_set_label(l1);
1128
    tcg_gen_movi_tl(cpu_npc, npc2);
1129
    gen_set_label(l2);
1130
}
1131

    
1132
/* call this function before using the condition register as it may
1133
   have been set for a jump */
1134
static inline void flush_cond(DisasContext *dc, TCGv cond)
1135
{
1136
    if (dc->npc == JUMP_PC) {
1137
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1138
        dc->npc = DYNAMIC_PC;
1139
    }
1140
}
1141

    
1142
static inline void save_npc(DisasContext *dc, TCGv cond)
1143
{
1144
    if (dc->npc == JUMP_PC) {
1145
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1146
        dc->npc = DYNAMIC_PC;
1147
    } else if (dc->npc != DYNAMIC_PC) {
1148
        tcg_gen_movi_tl(cpu_npc, dc->npc);
1149
    }
1150
}
1151

    
1152
static inline void save_state(DisasContext *dc, TCGv cond)
1153
{
1154
    tcg_gen_movi_tl(cpu_pc, dc->pc);
1155
    save_npc(dc, cond);
1156
}
1157

    
1158
static inline void gen_mov_pc_npc(DisasContext *dc, TCGv cond)
1159
{
1160
    if (dc->npc == JUMP_PC) {
1161
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1162
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1163
        dc->pc = DYNAMIC_PC;
1164
    } else if (dc->npc == DYNAMIC_PC) {
1165
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1166
        dc->pc = DYNAMIC_PC;
1167
    } else {
1168
        dc->pc = dc->npc;
1169
    }
1170
}
1171

    
1172
static inline void gen_op_next_insn(void)
1173
{
1174
    tcg_gen_mov_tl(cpu_pc, cpu_npc);
1175
    tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
1176
}
1177

    
1178
static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond)
1179
{
1180
    TCGv r_src;
1181

    
1182
#ifdef TARGET_SPARC64
1183
    if (cc)
1184
        r_src = cpu_xcc;
1185
    else
1186
        r_src = cpu_psr;
1187
#else
1188
    r_src = cpu_psr;
1189
#endif
1190
    switch (cond) {
1191
    case 0x0:
1192
        gen_op_eval_bn(r_dst);
1193
        break;
1194
    case 0x1:
1195
        gen_op_eval_be(r_dst, r_src);
1196
        break;
1197
    case 0x2:
1198
        gen_op_eval_ble(r_dst, r_src);
1199
        break;
1200
    case 0x3:
1201
        gen_op_eval_bl(r_dst, r_src);
1202
        break;
1203
    case 0x4:
1204
        gen_op_eval_bleu(r_dst, r_src);
1205
        break;
1206
    case 0x5:
1207
        gen_op_eval_bcs(r_dst, r_src);
1208
        break;
1209
    case 0x6:
1210
        gen_op_eval_bneg(r_dst, r_src);
1211
        break;
1212
    case 0x7:
1213
        gen_op_eval_bvs(r_dst, r_src);
1214
        break;
1215
    case 0x8:
1216
        gen_op_eval_ba(r_dst);
1217
        break;
1218
    case 0x9:
1219
        gen_op_eval_bne(r_dst, r_src);
1220
        break;
1221
    case 0xa:
1222
        gen_op_eval_bg(r_dst, r_src);
1223
        break;
1224
    case 0xb:
1225
        gen_op_eval_bge(r_dst, r_src);
1226
        break;
1227
    case 0xc:
1228
        gen_op_eval_bgu(r_dst, r_src);
1229
        break;
1230
    case 0xd:
1231
        gen_op_eval_bcc(r_dst, r_src);
1232
        break;
1233
    case 0xe:
1234
        gen_op_eval_bpos(r_dst, r_src);
1235
        break;
1236
    case 0xf:
1237
        gen_op_eval_bvc(r_dst, r_src);
1238
        break;
1239
    }
1240
}
1241

    
1242
static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
1243
{
1244
    unsigned int offset;
1245

    
1246
    switch (cc) {
1247
    default:
1248
    case 0x0:
1249
        offset = 0;
1250
        break;
1251
    case 0x1:
1252
        offset = 32 - 10;
1253
        break;
1254
    case 0x2:
1255
        offset = 34 - 10;
1256
        break;
1257
    case 0x3:
1258
        offset = 36 - 10;
1259
        break;
1260
    }
1261

    
1262
    switch (cond) {
1263
    case 0x0:
1264
        gen_op_eval_bn(r_dst);
1265
        break;
1266
    case 0x1:
1267
        gen_op_eval_fbne(r_dst, cpu_fsr, offset);
1268
        break;
1269
    case 0x2:
1270
        gen_op_eval_fblg(r_dst, cpu_fsr, offset);
1271
        break;
1272
    case 0x3:
1273
        gen_op_eval_fbul(r_dst, cpu_fsr, offset);
1274
        break;
1275
    case 0x4:
1276
        gen_op_eval_fbl(r_dst, cpu_fsr, offset);
1277
        break;
1278
    case 0x5:
1279
        gen_op_eval_fbug(r_dst, cpu_fsr, offset);
1280
        break;
1281
    case 0x6:
1282
        gen_op_eval_fbg(r_dst, cpu_fsr, offset);
1283
        break;
1284
    case 0x7:
1285
        gen_op_eval_fbu(r_dst, cpu_fsr, offset);
1286
        break;
1287
    case 0x8:
1288
        gen_op_eval_ba(r_dst);
1289
        break;
1290
    case 0x9:
1291
        gen_op_eval_fbe(r_dst, cpu_fsr, offset);
1292
        break;
1293
    case 0xa:
1294
        gen_op_eval_fbue(r_dst, cpu_fsr, offset);
1295
        break;
1296
    case 0xb:
1297
        gen_op_eval_fbge(r_dst, cpu_fsr, offset);
1298
        break;
1299
    case 0xc:
1300
        gen_op_eval_fbuge(r_dst, cpu_fsr, offset);
1301
        break;
1302
    case 0xd:
1303
        gen_op_eval_fble(r_dst, cpu_fsr, offset);
1304
        break;
1305
    case 0xe:
1306
        gen_op_eval_fbule(r_dst, cpu_fsr, offset);
1307
        break;
1308
    case 0xf:
1309
        gen_op_eval_fbo(r_dst, cpu_fsr, offset);
1310
        break;
1311
    }
1312
}
1313

    
1314
#ifdef TARGET_SPARC64
1315
// Inverted logic
1316
static const int gen_tcg_cond_reg[8] = {
1317
    -1,
1318
    TCG_COND_NE,
1319
    TCG_COND_GT,
1320
    TCG_COND_GE,
1321
    -1,
1322
    TCG_COND_EQ,
1323
    TCG_COND_LE,
1324
    TCG_COND_LT,
1325
};
1326

    
1327
static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
1328
{
1329
    int l1;
1330

    
1331
    l1 = gen_new_label();
1332
    tcg_gen_movi_tl(r_dst, 0);
1333
    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], r_src, tcg_const_tl(0), l1);
1334
    tcg_gen_movi_tl(r_dst, 1);
1335
    gen_set_label(l1);
1336
}
1337
#endif
1338

    
1339
/* XXX: potentially incorrect if dynamic npc */
1340
static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1341
                      TCGv r_cond)
1342
{
1343
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1344
    target_ulong target = dc->pc + offset;
1345

    
1346
    if (cond == 0x0) {
1347
        /* unconditional not taken */
1348
        if (a) {
1349
            dc->pc = dc->npc + 4;
1350
            dc->npc = dc->pc + 4;
1351
        } else {
1352
            dc->pc = dc->npc;
1353
            dc->npc = dc->pc + 4;
1354
        }
1355
    } else if (cond == 0x8) {
1356
        /* unconditional taken */
1357
        if (a) {
1358
            dc->pc = target;
1359
            dc->npc = dc->pc + 4;
1360
        } else {
1361
            dc->pc = dc->npc;
1362
            dc->npc = target;
1363
        }
1364
    } else {
1365
        flush_cond(dc, r_cond);
1366
        gen_cond(r_cond, cc, cond);
1367
        if (a) {
1368
            gen_branch_a(dc, target, dc->npc, r_cond);
1369
            dc->is_br = 1;
1370
        } else {
1371
            dc->pc = dc->npc;
1372
            dc->jump_pc[0] = target;
1373
            dc->jump_pc[1] = dc->npc + 4;
1374
            dc->npc = JUMP_PC;
1375
        }
1376
    }
1377
}
1378

    
1379
/* XXX: potentially incorrect if dynamic npc */
1380
static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1381
                      TCGv r_cond)
1382
{
1383
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1384
    target_ulong target = dc->pc + offset;
1385

    
1386
    if (cond == 0x0) {
1387
        /* unconditional not taken */
1388
        if (a) {
1389
            dc->pc = dc->npc + 4;
1390
            dc->npc = dc->pc + 4;
1391
        } else {
1392
            dc->pc = dc->npc;
1393
            dc->npc = dc->pc + 4;
1394
        }
1395
    } else if (cond == 0x8) {
1396
        /* unconditional taken */
1397
        if (a) {
1398
            dc->pc = target;
1399
            dc->npc = dc->pc + 4;
1400
        } else {
1401
            dc->pc = dc->npc;
1402
            dc->npc = target;
1403
        }
1404
    } else {
1405
        flush_cond(dc, r_cond);
1406
        gen_fcond(r_cond, cc, cond);
1407
        if (a) {
1408
            gen_branch_a(dc, target, dc->npc, r_cond);
1409
            dc->is_br = 1;
1410
        } else {
1411
            dc->pc = dc->npc;
1412
            dc->jump_pc[0] = target;
1413
            dc->jump_pc[1] = dc->npc + 4;
1414
            dc->npc = JUMP_PC;
1415
        }
1416
    }
1417
}
1418

    
1419
#ifdef TARGET_SPARC64
1420
/* XXX: potentially incorrect if dynamic npc */
1421
static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
1422
                          TCGv r_cond, TCGv r_reg)
1423
{
1424
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1425
    target_ulong target = dc->pc + offset;
1426

    
1427
    flush_cond(dc, r_cond);
1428
    gen_cond_reg(r_cond, cond, r_reg);
1429
    if (a) {
1430
        gen_branch_a(dc, target, dc->npc, r_cond);
1431
        dc->is_br = 1;
1432
    } else {
1433
        dc->pc = dc->npc;
1434
        dc->jump_pc[0] = target;
1435
        dc->jump_pc[1] = dc->npc + 4;
1436
        dc->npc = JUMP_PC;
1437
    }
1438
}
1439

    
1440
static GenOpFunc * const gen_fcmps[4] = {
1441
    helper_fcmps,
1442
    helper_fcmps_fcc1,
1443
    helper_fcmps_fcc2,
1444
    helper_fcmps_fcc3,
1445
};
1446

    
1447
static GenOpFunc * const gen_fcmpd[4] = {
1448
    helper_fcmpd,
1449
    helper_fcmpd_fcc1,
1450
    helper_fcmpd_fcc2,
1451
    helper_fcmpd_fcc3,
1452
};
1453

    
1454
static GenOpFunc * const gen_fcmpq[4] = {
1455
    helper_fcmpq,
1456
    helper_fcmpq_fcc1,
1457
    helper_fcmpq_fcc2,
1458
    helper_fcmpq_fcc3,
1459
};
1460

    
1461
static GenOpFunc * const gen_fcmpes[4] = {
1462
    helper_fcmpes,
1463
    helper_fcmpes_fcc1,
1464
    helper_fcmpes_fcc2,
1465
    helper_fcmpes_fcc3,
1466
};
1467

    
1468
static GenOpFunc * const gen_fcmped[4] = {
1469
    helper_fcmped,
1470
    helper_fcmped_fcc1,
1471
    helper_fcmped_fcc2,
1472
    helper_fcmped_fcc3,
1473
};
1474

    
1475
static GenOpFunc * const gen_fcmpeq[4] = {
1476
    helper_fcmpeq,
1477
    helper_fcmpeq_fcc1,
1478
    helper_fcmpeq_fcc2,
1479
    helper_fcmpeq_fcc3,
1480
};
1481

    
1482
static inline void gen_op_fcmps(int fccno)
1483
{
1484
    tcg_gen_helper_0_0(gen_fcmps[fccno]);
1485
}
1486

    
1487
static inline void gen_op_fcmpd(int fccno)
1488
{
1489
    tcg_gen_helper_0_0(gen_fcmpd[fccno]);
1490
}
1491

    
1492
static inline void gen_op_fcmpq(int fccno)
1493
{
1494
    tcg_gen_helper_0_0(gen_fcmpq[fccno]);
1495
}
1496

    
1497
static inline void gen_op_fcmpes(int fccno)
1498
{
1499
    tcg_gen_helper_0_0(gen_fcmpes[fccno]);
1500
}
1501

    
1502
static inline void gen_op_fcmped(int fccno)
1503
{
1504
    tcg_gen_helper_0_0(gen_fcmped[fccno]);
1505
}
1506

    
1507
static inline void gen_op_fcmpeq(int fccno)
1508
{
1509
    tcg_gen_helper_0_0(gen_fcmpeq[fccno]);
1510
}
1511

    
1512
#else
1513

    
1514
static inline void gen_op_fcmps(int fccno)
1515
{
1516
    tcg_gen_helper_0_0(helper_fcmps);
1517
}
1518

    
1519
static inline void gen_op_fcmpd(int fccno)
1520
{
1521
    tcg_gen_helper_0_0(helper_fcmpd);
1522
}
1523

    
1524
static inline void gen_op_fcmpq(int fccno)
1525
{
1526
    tcg_gen_helper_0_0(helper_fcmpq);
1527
}
1528

    
1529
static inline void gen_op_fcmpes(int fccno)
1530
{
1531
    tcg_gen_helper_0_0(helper_fcmpes);
1532
}
1533

    
1534
static inline void gen_op_fcmped(int fccno)
1535
{
1536
    tcg_gen_helper_0_0(helper_fcmped);
1537
}
1538

    
1539
static inline void gen_op_fcmpeq(int fccno)
1540
{
1541
    tcg_gen_helper_0_0(helper_fcmpeq);
1542
}
1543
#endif
1544

    
1545
static inline void gen_op_fpexception_im(int fsr_flags)
1546
{
1547
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~FSR_FTT_MASK);
1548
    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
1549
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_FP_EXCP));
1550
}
1551

    
1552
static int gen_trap_ifnofpu(DisasContext *dc, TCGv r_cond)
1553
{
1554
#if !defined(CONFIG_USER_ONLY)
1555
    if (!dc->fpu_enabled) {
1556
        save_state(dc, r_cond);
1557
        tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_NFPU_INSN));
1558
        dc->is_br = 1;
1559
        return 1;
1560
    }
1561
#endif
1562
    return 0;
1563
}
1564

    
1565
static inline void gen_op_clear_ieee_excp_and_FTT(void)
1566
{
1567
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~(FSR_FTT_MASK | FSR_CEXC_MASK));
1568
}
1569

    
1570
static inline void gen_clear_float_exceptions(void)
1571
{
1572
    tcg_gen_helper_0_0(helper_clear_float_exceptions);
1573
}
1574

    
1575
/* asi moves */
1576
#ifdef TARGET_SPARC64
1577
static inline TCGv gen_get_asi(int insn, TCGv r_addr)
1578
{
1579
    int asi, offset;
1580
    TCGv r_asi;
1581

    
1582
    if (IS_IMM) {
1583
        r_asi = tcg_temp_new(TCG_TYPE_I32);
1584
        offset = GET_FIELD(insn, 25, 31);
1585
        tcg_gen_addi_tl(r_addr, r_addr, offset);
1586
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
1587
    } else {
1588
        asi = GET_FIELD(insn, 19, 26);
1589
        r_asi = tcg_const_i32(asi);
1590
    }
1591
    return r_asi;
1592
}
1593

    
1594
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size, int sign)
1595
{
1596
    TCGv r_asi;
1597

    
1598
    r_asi = gen_get_asi(insn, addr);
1599
    tcg_gen_helper_1_4(helper_ld_asi, dst, addr, r_asi,
1600
                       tcg_const_i32(size), tcg_const_i32(sign));
1601
}
1602

    
1603
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1604
{
1605
    TCGv r_asi;
1606

    
1607
    r_asi = gen_get_asi(insn, addr);
1608
    tcg_gen_helper_0_4(helper_st_asi, addr, src, r_asi, tcg_const_i32(size));
1609
}
1610

    
1611
static inline void gen_ldf_asi(TCGv addr, int insn, int size, int rd)
1612
{
1613
    TCGv r_asi;
1614

    
1615
    r_asi = gen_get_asi(insn, addr);
1616
    tcg_gen_helper_0_4(helper_ldf_asi, addr, r_asi, tcg_const_i32(size),
1617
                       tcg_const_i32(rd));
1618
}
1619

    
1620
static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
1621
{
1622
    TCGv r_asi;
1623

    
1624
    r_asi = gen_get_asi(insn, addr);
1625
    tcg_gen_helper_0_4(helper_stf_asi, addr, r_asi, tcg_const_i32(size),
1626
                       tcg_const_i32(rd));
1627
}
1628

    
1629
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1630
{
1631
    TCGv r_temp, r_asi;
1632

    
1633
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1634
    r_asi = gen_get_asi(insn, addr);
1635
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, addr, r_asi,
1636
                       tcg_const_i32(4), tcg_const_i32(0));
1637
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, r_asi,
1638
                       tcg_const_i32(4));
1639
    tcg_gen_extu_i32_tl(dst, r_temp);
1640
}
1641

    
1642
static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn)
1643
{
1644
    TCGv r_asi;
1645

    
1646
    r_asi = gen_get_asi(insn, addr);
1647
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi,
1648
                       tcg_const_i32(8), tcg_const_i32(0));
1649
    tcg_gen_andi_i64(lo, cpu_tmp64, 0xffffffffULL);
1650
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1651
    tcg_gen_andi_i64(hi, cpu_tmp64, 0xffffffffULL);
1652
}
1653

    
1654
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1655
{
1656
    TCGv r_temp, r_asi;
1657

    
1658
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1659
    gen_movl_reg_TN(rd + 1, r_temp);
1660
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi,
1661
                       r_temp);
1662
    r_asi = gen_get_asi(insn, addr);
1663
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi,
1664
                       tcg_const_i32(8));
1665
}
1666

    
1667
static inline void gen_cas_asi(TCGv dst, TCGv addr, TCGv val2, int insn, int rd)
1668
{
1669
    TCGv r_val1, r_asi;
1670

    
1671
    r_val1 = tcg_temp_new(TCG_TYPE_I32);
1672
    gen_movl_reg_TN(rd, r_val1);
1673
    r_asi = gen_get_asi(insn, addr);
1674
    tcg_gen_helper_1_4(helper_cas_asi, dst, addr, r_val1, val2, r_asi);
1675
}
1676

    
1677
static inline void gen_casx_asi(TCGv dst, TCGv addr, TCGv val2, int insn, int rd)
1678
{
1679
    TCGv r_asi;
1680

    
1681
    gen_movl_reg_TN(rd, cpu_tmp64);
1682
    r_asi = gen_get_asi(insn, addr);
1683
    tcg_gen_helper_1_4(helper_casx_asi, dst, addr, cpu_tmp64, val2, r_asi);
1684
}
1685

    
1686
#elif !defined(CONFIG_USER_ONLY)
1687

    
1688
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size, int sign)
1689
{
1690
    int asi;
1691

    
1692
    asi = GET_FIELD(insn, 19, 26);
1693
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, tcg_const_i32(asi),
1694
                       tcg_const_i32(size), tcg_const_i32(sign));
1695
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1696
}
1697

    
1698
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1699
{
1700
    int asi;
1701

    
1702
    tcg_gen_extu_tl_i64(cpu_tmp64, src);
1703
    asi = GET_FIELD(insn, 19, 26);
1704
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, tcg_const_i32(asi),
1705
                       tcg_const_i32(size));
1706
}
1707

    
1708
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1709
{
1710
    int asi;
1711
    TCGv r_temp;
1712

    
1713
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1714
    asi = GET_FIELD(insn, 19, 26);
1715
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, addr, tcg_const_i32(asi),
1716
                       tcg_const_i32(4), tcg_const_i32(0));
1717
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, tcg_const_i32(asi),
1718
                       tcg_const_i32(4));
1719
    tcg_gen_extu_i32_tl(dst, r_temp);
1720
}
1721

    
1722
static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn)
1723
{
1724
    int asi;
1725

    
1726
    asi = GET_FIELD(insn, 19, 26);
1727
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, tcg_const_i32(asi),
1728
                       tcg_const_i32(8), tcg_const_i32(0));
1729
    tcg_gen_trunc_i64_tl(lo, cpu_tmp64);
1730
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1731
    tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
1732
}
1733

    
1734
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1735
{
1736
    int asi;
1737
    TCGv r_temp;
1738

    
1739
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1740
    gen_movl_reg_TN(rd + 1, r_temp);
1741
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi, r_temp);
1742
    asi = GET_FIELD(insn, 19, 26);
1743
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, tcg_const_i32(asi),
1744
                       tcg_const_i32(8));
1745
}
1746
#endif
1747

    
1748
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1749
static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
1750
{
1751
    int asi;
1752

    
1753
    gen_ld_asi(dst, addr, insn, 1, 0);
1754

    
1755
    asi = GET_FIELD(insn, 19, 26);
1756
    tcg_gen_helper_0_4(helper_st_asi, addr, tcg_const_i64(0xffULL),
1757
                       tcg_const_i32(asi), tcg_const_i32(1));
1758
}
1759
#endif
1760

    
1761
static inline TCGv get_src1(unsigned int insn, TCGv def)
1762
{
1763
    TCGv r_rs1 = def;
1764
    unsigned int rs1;
1765

    
1766
    rs1 = GET_FIELD(insn, 13, 17);
1767
    if (rs1 == 0)
1768
        //r_rs1 = tcg_const_tl(0);
1769
        tcg_gen_movi_tl(def, 0);
1770
    else if (rs1 < 8)
1771
        //r_rs1 = cpu_gregs[rs1];
1772
        tcg_gen_mov_tl(def, cpu_gregs[rs1]);
1773
    else
1774
        tcg_gen_ld_tl(def, cpu_regwptr, (rs1 - 8) * sizeof(target_ulong));
1775
    return r_rs1;
1776
}
1777

    
1778
static inline TCGv get_src2(unsigned int insn, TCGv def)
1779
{
1780
    TCGv r_rs2 = def;
1781
    unsigned int rs2;
1782

    
1783
    if (IS_IMM) { /* immediate */
1784
        rs2 = GET_FIELDs(insn, 19, 31);
1785
        r_rs2 = tcg_const_tl((int)rs2);
1786
    } else { /* register */
1787
        rs2 = GET_FIELD(insn, 27, 31);
1788
        if (rs2 == 0)
1789
            r_rs2 = tcg_const_tl(0);
1790
        else if (rs2 < 8)
1791
            r_rs2 = cpu_gregs[rs2];
1792
        else
1793
            tcg_gen_ld_tl(def, cpu_regwptr, (rs2 - 8) * sizeof(target_ulong));
1794
    }
1795
    return r_rs2;
1796
}
1797

    
1798
#define CHECK_IU_FEATURE(dc, FEATURE)                      \
1799
    if (!((dc)->features & CPU_FEATURE_ ## FEATURE))       \
1800
        goto illegal_insn;
1801
#define CHECK_FPU_FEATURE(dc, FEATURE)                     \
1802
    if (!((dc)->features & CPU_FEATURE_ ## FEATURE))       \
1803
        goto nfpu_insn;
1804

    
1805
/* before an instruction, dc->pc must be static */
1806
static void disas_sparc_insn(DisasContext * dc)
1807
{
1808
    unsigned int insn, opc, rs1, rs2, rd;
1809

    
1810
    insn = ldl_code(dc->pc);
1811
    opc = GET_FIELD(insn, 0, 1);
1812

    
1813
    rd = GET_FIELD(insn, 2, 6);
1814

    
1815
    cpu_dst = cpu_T[0];
1816
    cpu_src1 = cpu_T[0]; // const
1817
    cpu_src2 = cpu_T[1]; // const
1818

    
1819
    // loads and stores
1820
    cpu_addr = cpu_T[0];
1821
    cpu_val = cpu_T[1];
1822

    
1823
    switch (opc) {
1824
    case 0:                     /* branches/sethi */
1825
        {
1826
            unsigned int xop = GET_FIELD(insn, 7, 9);
1827
            int32_t target;
1828
            switch (xop) {
1829
#ifdef TARGET_SPARC64
1830
            case 0x1:           /* V9 BPcc */
1831
                {
1832
                    int cc;
1833

    
1834
                    target = GET_FIELD_SP(insn, 0, 18);
1835
                    target = sign_extend(target, 18);
1836
                    target <<= 2;
1837
                    cc = GET_FIELD_SP(insn, 20, 21);
1838
                    if (cc == 0)
1839
                        do_branch(dc, target, insn, 0, cpu_cond);
1840
                    else if (cc == 2)
1841
                        do_branch(dc, target, insn, 1, cpu_cond);
1842
                    else
1843
                        goto illegal_insn;
1844
                    goto jmp_insn;
1845
                }
1846
            case 0x3:           /* V9 BPr */
1847
                {
1848
                    target = GET_FIELD_SP(insn, 0, 13) |
1849
                        (GET_FIELD_SP(insn, 20, 21) << 14);
1850
                    target = sign_extend(target, 16);
1851
                    target <<= 2;
1852
                    cpu_src1 = get_src1(insn, cpu_src1);
1853
                    do_branch_reg(dc, target, insn, cpu_cond, cpu_src1);
1854
                    goto jmp_insn;
1855
                }
1856
            case 0x5:           /* V9 FBPcc */
1857
                {
1858
                    int cc = GET_FIELD_SP(insn, 20, 21);
1859
                    if (gen_trap_ifnofpu(dc, cpu_cond))
1860
                        goto jmp_insn;
1861
                    target = GET_FIELD_SP(insn, 0, 18);
1862
                    target = sign_extend(target, 19);
1863
                    target <<= 2;
1864
                    do_fbranch(dc, target, insn, cc, cpu_cond);
1865
                    goto jmp_insn;
1866
                }
1867
#else
1868
            case 0x7:           /* CBN+x */
1869
                {
1870
                    goto ncp_insn;
1871
                }
1872
#endif
1873
            case 0x2:           /* BN+x */
1874
                {
1875
                    target = GET_FIELD(insn, 10, 31);
1876
                    target = sign_extend(target, 22);
1877
                    target <<= 2;
1878
                    do_branch(dc, target, insn, 0, cpu_cond);
1879
                    goto jmp_insn;
1880
                }
1881
            case 0x6:           /* FBN+x */
1882
                {
1883
                    if (gen_trap_ifnofpu(dc, cpu_cond))
1884
                        goto jmp_insn;
1885
                    target = GET_FIELD(insn, 10, 31);
1886
                    target = sign_extend(target, 22);
1887
                    target <<= 2;
1888
                    do_fbranch(dc, target, insn, 0, cpu_cond);
1889
                    goto jmp_insn;
1890
                }
1891
            case 0x4:           /* SETHI */
1892
                if (rd) { // nop
1893
                    uint32_t value = GET_FIELD(insn, 10, 31);
1894
                    gen_movl_TN_reg(rd, tcg_const_tl(value << 10));
1895
                }
1896
                break;
1897
            case 0x0:           /* UNIMPL */
1898
            default:
1899
                goto illegal_insn;
1900
            }
1901
            break;
1902
        }
1903
        break;
1904
    case 1:
1905
        /*CALL*/ {
1906
            target_long target = GET_FIELDs(insn, 2, 31) << 2;
1907

    
1908
            gen_movl_TN_reg(15, tcg_const_tl(dc->pc));
1909
            target += dc->pc;
1910
            gen_mov_pc_npc(dc, cpu_cond);
1911
            dc->npc = target;
1912
        }
1913
        goto jmp_insn;
1914
    case 2:                     /* FPU & Logical Operations */
1915
        {
1916
            unsigned int xop = GET_FIELD(insn, 7, 12);
1917
            if (xop == 0x3a) {  /* generate trap */
1918
                int cond;
1919

    
1920
                cpu_src1 = get_src1(insn, cpu_src1);
1921
                if (IS_IMM) {
1922
                    rs2 = GET_FIELD(insn, 25, 31);
1923
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, rs2);
1924
                } else {
1925
                    rs2 = GET_FIELD(insn, 27, 31);
1926
                    if (rs2 != 0) {
1927
                        gen_movl_reg_TN(rs2, cpu_src2);
1928
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
1929
                    } else
1930
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
1931
                }
1932
                cond = GET_FIELD(insn, 3, 6);
1933
                if (cond == 0x8) {
1934
                    save_state(dc, cpu_cond);
1935
                    tcg_gen_helper_0_1(helper_trap, cpu_dst);
1936
                } else if (cond != 0) {
1937
                    TCGv r_cond = tcg_temp_new(TCG_TYPE_TL);
1938
#ifdef TARGET_SPARC64
1939
                    /* V9 icc/xcc */
1940
                    int cc = GET_FIELD_SP(insn, 11, 12);
1941

    
1942
                    save_state(dc, cpu_cond);
1943
                    if (cc == 0)
1944
                        gen_cond(r_cond, 0, cond);
1945
                    else if (cc == 2)
1946
                        gen_cond(r_cond, 1, cond);
1947
                    else
1948
                        goto illegal_insn;
1949
#else
1950
                    save_state(dc, cpu_cond);
1951
                    gen_cond(r_cond, 0, cond);
1952
#endif
1953
                    tcg_gen_helper_0_2(helper_trapcc, cpu_dst, r_cond);
1954
                }
1955
                gen_op_next_insn();
1956
                tcg_gen_exit_tb(0);
1957
                dc->is_br = 1;
1958
                goto jmp_insn;
1959
            } else if (xop == 0x28) {
1960
                rs1 = GET_FIELD(insn, 13, 17);
1961
                switch(rs1) {
1962
                case 0: /* rdy */
1963
#ifndef TARGET_SPARC64
1964
                case 0x01 ... 0x0e: /* undefined in the SPARCv8
1965
                                       manual, rdy on the microSPARC
1966
                                       II */
1967
                case 0x0f:          /* stbar in the SPARCv8 manual,
1968
                                       rdy on the microSPARC II */
1969
                case 0x10 ... 0x1f: /* implementation-dependent in the
1970
                                       SPARCv8 manual, rdy on the
1971
                                       microSPARC II */
1972
#endif
1973
                    tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, y));
1974
                    gen_movl_TN_reg(rd, cpu_dst);
1975
                    break;
1976
#ifdef TARGET_SPARC64
1977
                case 0x2: /* V9 rdccr */
1978
                    tcg_gen_helper_1_0(helper_rdccr, cpu_dst);
1979
                    gen_movl_TN_reg(rd, cpu_dst);
1980
                    break;
1981
                case 0x3: /* V9 rdasi */
1982
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, asi));
1983
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
1984
                    gen_movl_TN_reg(rd, cpu_dst);
1985
                    break;
1986
                case 0x4: /* V9 rdtick */
1987
                    {
1988
                        TCGv r_tickptr;
1989

    
1990
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
1991
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
1992
                                       offsetof(CPUState, tick));
1993
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst,
1994
                                           r_tickptr);
1995
                        gen_movl_TN_reg(rd, cpu_dst);
1996
                    }
1997
                    break;
1998
                case 0x5: /* V9 rdpc */
1999
                    gen_movl_TN_reg(rd, tcg_const_tl(dc->pc));
2000
                    break;
2001
                case 0x6: /* V9 rdfprs */
2002
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fprs));
2003
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2004
                    gen_movl_TN_reg(rd, cpu_dst);
2005
                    break;
2006
                case 0xf: /* V9 membar */
2007
                    break; /* no effect */
2008
                case 0x13: /* Graphics Status */
2009
                    if (gen_trap_ifnofpu(dc, cpu_cond))
2010
                        goto jmp_insn;
2011
                    tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, gsr));
2012
                    gen_movl_TN_reg(rd, cpu_dst);
2013
                    break;
2014
                case 0x17: /* Tick compare */
2015
                    tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, tick_cmpr));
2016
                    gen_movl_TN_reg(rd, cpu_dst);
2017
                    break;
2018
                case 0x18: /* System tick */
2019
                    {
2020
                        TCGv r_tickptr;
2021

    
2022
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2023
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2024
                                       offsetof(CPUState, stick));
2025
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst,
2026
                                           r_tickptr);
2027
                        gen_movl_TN_reg(rd, cpu_dst);
2028
                    }
2029
                    break;
2030
                case 0x19: /* System tick compare */
2031
                    tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, stick_cmpr));
2032
                    gen_movl_TN_reg(rd, cpu_dst);
2033
                    break;
2034
                case 0x10: /* Performance Control */
2035
                case 0x11: /* Performance Instrumentation Counter */
2036
                case 0x12: /* Dispatch Control */
2037
                case 0x14: /* Softint set, WO */
2038
                case 0x15: /* Softint clear, WO */
2039
                case 0x16: /* Softint write */
2040
#endif
2041
                default:
2042
                    goto illegal_insn;
2043
                }
2044
#if !defined(CONFIG_USER_ONLY)
2045
            } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
2046
#ifndef TARGET_SPARC64
2047
                if (!supervisor(dc))
2048
                    goto priv_insn;
2049
                tcg_gen_helper_1_0(helper_rdpsr, cpu_dst);
2050
#else
2051
                if (!hypervisor(dc))
2052
                    goto priv_insn;
2053
                rs1 = GET_FIELD(insn, 13, 17);
2054
                switch (rs1) {
2055
                case 0: // hpstate
2056
                    // gen_op_rdhpstate();
2057
                    break;
2058
                case 1: // htstate
2059
                    // gen_op_rdhtstate();
2060
                    break;
2061
                case 3: // hintp
2062
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, hintp));
2063
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2064
                    break;
2065
                case 5: // htba
2066
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, htba));
2067
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2068
                    break;
2069
                case 6: // hver
2070
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, hver));
2071
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2072
                    break;
2073
                case 31: // hstick_cmpr
2074
                    tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2075
                    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, hstick_cmpr));
2076
                    break;
2077
                default:
2078
                    goto illegal_insn;
2079
                }
2080
#endif
2081
                gen_movl_TN_reg(rd, cpu_dst);
2082
                break;
2083
            } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
2084
                if (!supervisor(dc))
2085
                    goto priv_insn;
2086
#ifdef TARGET_SPARC64
2087
                rs1 = GET_FIELD(insn, 13, 17);
2088
                switch (rs1) {
2089
                case 0: // tpc
2090
                    {
2091
                        TCGv r_tsptr;
2092

    
2093
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2094
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2095
                                       offsetof(CPUState, tsptr));
2096
                        tcg_gen_ld_tl(cpu_dst, r_tsptr,
2097
                                      offsetof(trap_state, tpc));
2098
                    }
2099
                    break;
2100
                case 1: // tnpc
2101
                    {
2102
                        TCGv r_tsptr;
2103

    
2104
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2105
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2106
                                       offsetof(CPUState, tsptr));
2107
                        tcg_gen_ld_tl(cpu_dst, r_tsptr,
2108
                                      offsetof(trap_state, tnpc));
2109
                    }
2110
                    break;
2111
                case 2: // tstate
2112
                    {
2113
                        TCGv r_tsptr;
2114

    
2115
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2116
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2117
                                       offsetof(CPUState, tsptr));
2118
                        tcg_gen_ld_tl(cpu_dst, r_tsptr,
2119
                                      offsetof(trap_state, tstate));
2120
                    }
2121
                    break;
2122
                case 3: // tt
2123
                    {
2124
                        TCGv r_tsptr;
2125

    
2126
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2127
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2128
                                       offsetof(CPUState, tsptr));
2129
                        tcg_gen_ld_i32(cpu_dst, r_tsptr,
2130
                                       offsetof(trap_state, tt));
2131
                    }
2132
                    break;
2133
                case 4: // tick
2134
                    {
2135
                        TCGv r_tickptr;
2136

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

    
2557
                    l1 = gen_new_label();
2558
                    cond = GET_FIELD_SP(insn, 14, 17);
2559
                    cpu_src1 = get_src1(insn, cpu_src1);
2560
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_src1,
2561
                                      tcg_const_tl(0), l1);
2562
                    gen_op_load_fpr_FT0(rs2);
2563
                    gen_op_store_FT0_fpr(rd);
2564
                    gen_set_label(l1);
2565
                    break;
2566
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
2567
                    int l1;
2568

    
2569
                    l1 = gen_new_label();
2570
                    cond = GET_FIELD_SP(insn, 14, 17);
2571
                    cpu_src1 = get_src1(insn, cpu_src1);
2572
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_src1,
2573
                                      tcg_const_tl(0), l1);
2574
                    gen_op_load_fpr_DT0(DFPREG(rs2));
2575
                    gen_op_store_DT0_fpr(DFPREG(rd));
2576
                    gen_set_label(l1);
2577
                    break;
2578
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
2579
                    int l1;
2580

    
2581
                    CHECK_FPU_FEATURE(dc, FLOAT128);
2582
                    l1 = gen_new_label();
2583
                    cond = GET_FIELD_SP(insn, 14, 17);
2584
                    cpu_src1 = get_src1(insn, cpu_src1);
2585
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_src1,
2586
                                      tcg_const_tl(0), l1);
2587
                    gen_op_load_fpr_QT0(QFPREG(rs2));
2588
                    gen_op_store_QT0_fpr(QFPREG(rd));
2589
                    gen_set_label(l1);
2590
                    break;
2591
                }
2592
#endif
2593
                switch (xop) {
2594
#ifdef TARGET_SPARC64
2595
#define FMOVCC(size_FDQ, fcc)                                           \
2596
                    {                                                   \
2597
                        TCGv r_cond;                                    \
2598
                        int l1;                                         \
2599
                                                                        \
2600
                        l1 = gen_new_label();                           \
2601
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2602
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2603
                        gen_fcond(r_cond, fcc, cond);                   \
2604
                        tcg_gen_brcond_tl(TCG_COND_EQ, r_cond,          \
2605
                                          tcg_const_tl(0), l1);         \
2606
                        glue(glue(gen_op_load_fpr_, size_FDQ), T0)(glue(size_FDQ, FPREG(rs2))); \
2607
                        glue(glue(gen_op_store_, size_FDQ), T0_fpr)(glue(size_FDQ, FPREG(rd))); \
2608
                        gen_set_label(l1);                              \
2609
                    }
2610
                    case 0x001: /* V9 fmovscc %fcc0 */
2611
                        FMOVCC(F, 0);
2612
                        break;
2613
                    case 0x002: /* V9 fmovdcc %fcc0 */
2614
                        FMOVCC(D, 0);
2615
                        break;
2616
                    case 0x003: /* V9 fmovqcc %fcc0 */
2617
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2618
                        FMOVCC(Q, 0);
2619
                        break;
2620
                    case 0x041: /* V9 fmovscc %fcc1 */
2621
                        FMOVCC(F, 1);
2622
                        break;
2623
                    case 0x042: /* V9 fmovdcc %fcc1 */
2624
                        FMOVCC(D, 1);
2625
                        break;
2626
                    case 0x043: /* V9 fmovqcc %fcc1 */
2627
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2628
                        FMOVCC(Q, 1);
2629
                        break;
2630
                    case 0x081: /* V9 fmovscc %fcc2 */
2631
                        FMOVCC(F, 2);
2632
                        break;
2633
                    case 0x082: /* V9 fmovdcc %fcc2 */
2634
                        FMOVCC(D, 2);
2635
                        break;
2636
                    case 0x083: /* V9 fmovqcc %fcc2 */
2637
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2638
                        FMOVCC(Q, 2);
2639
                        break;
2640
                    case 0x0c1: /* V9 fmovscc %fcc3 */
2641
                        FMOVCC(F, 3);
2642
                        break;
2643
                    case 0x0c2: /* V9 fmovdcc %fcc3 */
2644
                        FMOVCC(D, 3);
2645
                        break;
2646
                    case 0x0c3: /* V9 fmovqcc %fcc3 */
2647
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2648
                        FMOVCC(Q, 3);
2649
                        break;
2650
#undef FMOVCC
2651
#define FMOVCC(size_FDQ, icc)                                           \
2652
                    {                                                   \
2653
                        TCGv r_cond;                                    \
2654
                        int l1;                                         \
2655
                                                                        \
2656
                        l1 = gen_new_label();                           \
2657
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2658
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2659
                        gen_cond(r_cond, icc, cond);                    \
2660
                        tcg_gen_brcond_tl(TCG_COND_EQ, r_cond,          \
2661
                                          tcg_const_tl(0), l1);         \
2662
                        glue(glue(gen_op_load_fpr_, size_FDQ), T0)(glue(size_FDQ, FPREG(rs2))); \
2663
                        glue(glue(gen_op_store_, size_FDQ), T0_fpr)(glue(size_FDQ, FPREG(rd))); \
2664
                        gen_set_label(l1);                              \
2665
                    }
2666

    
2667
                    case 0x101: /* V9 fmovscc %icc */
2668
                        FMOVCC(F, 0);
2669
                        break;
2670
                    case 0x102: /* V9 fmovdcc %icc */
2671
                        FMOVCC(D, 0);
2672
                    case 0x103: /* V9 fmovqcc %icc */
2673
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2674
                        FMOVCC(Q, 0);
2675
                        break;
2676
                    case 0x181: /* V9 fmovscc %xcc */
2677
                        FMOVCC(F, 1);
2678
                        break;
2679
                    case 0x182: /* V9 fmovdcc %xcc */
2680
                        FMOVCC(D, 1);
2681
                        break;
2682
                    case 0x183: /* V9 fmovqcc %xcc */
2683
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2684
                        FMOVCC(Q, 1);
2685
                        break;
2686
#undef FMOVCC
2687
#endif
2688
                    case 0x51: /* fcmps, V9 %fcc */
2689
                        gen_op_load_fpr_FT0(rs1);
2690
                        gen_op_load_fpr_FT1(rs2);
2691
                        gen_op_fcmps(rd & 3);
2692
                        break;
2693
                    case 0x52: /* fcmpd, V9 %fcc */
2694
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2695
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2696
                        gen_op_fcmpd(rd & 3);
2697
                        break;
2698
                    case 0x53: /* fcmpq, V9 %fcc */
2699
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2700
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2701
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2702
                        gen_op_fcmpq(rd & 3);
2703
                        break;
2704
                    case 0x55: /* fcmpes, V9 %fcc */
2705
                        gen_op_load_fpr_FT0(rs1);
2706
                        gen_op_load_fpr_FT1(rs2);
2707
                        gen_op_fcmpes(rd & 3);
2708
                        break;
2709
                    case 0x56: /* fcmped, V9 %fcc */
2710
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2711
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2712
                        gen_op_fcmped(rd & 3);
2713
                        break;
2714
                    case 0x57: /* fcmpeq, V9 %fcc */
2715
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2716
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2717
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2718
                        gen_op_fcmpeq(rd & 3);
2719
                        break;
2720
                    default:
2721
                        goto illegal_insn;
2722
                }
2723
            } else if (xop == 0x2) {
2724
                // clr/mov shortcut
2725

    
2726
                rs1 = GET_FIELD(insn, 13, 17);
2727
                if (rs1 == 0) {
2728
                    // or %g0, x, y -> mov T0, x; mov y, T0
2729
                    if (IS_IMM) {       /* immediate */
2730
                        rs2 = GET_FIELDs(insn, 19, 31);
2731
                        gen_movl_TN_reg(rd, tcg_const_tl((int)rs2));
2732
                    } else {            /* register */
2733
                        rs2 = GET_FIELD(insn, 27, 31);
2734
                        gen_movl_reg_TN(rs2, cpu_dst);
2735
                        gen_movl_TN_reg(rd, cpu_dst);
2736
                    }
2737
                } else {
2738
                    cpu_src1 = get_src1(insn, cpu_src1);
2739
                    if (IS_IMM) {       /* immediate */
2740
                        rs2 = GET_FIELDs(insn, 19, 31);
2741
                        tcg_gen_ori_tl(cpu_dst, cpu_src1, (int)rs2);
2742
                        gen_movl_TN_reg(rd, cpu_dst);
2743
                    } else {            /* register */
2744
                        // or x, %g0, y -> mov T1, x; mov y, T1
2745
                        rs2 = GET_FIELD(insn, 27, 31);
2746
                        if (rs2 != 0) {
2747
                            gen_movl_reg_TN(rs2, cpu_src2);
2748
                            tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
2749
                            gen_movl_TN_reg(rd, cpu_dst);
2750
                        } else
2751
                            gen_movl_TN_reg(rd, cpu_src1);
2752
                    }
2753
                }
2754
#ifdef TARGET_SPARC64
2755
            } else if (xop == 0x25) { /* sll, V9 sllx */
2756
                cpu_src1 = get_src1(insn, cpu_src1);
2757
                if (IS_IMM) {   /* immediate */
2758
                    rs2 = GET_FIELDs(insn, 20, 31);
2759
                    if (insn & (1 << 12)) {
2760
                        tcg_gen_shli_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
2761
                    } else {
2762
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2763
                        tcg_gen_shli_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
2764
                    }
2765
                } else {                /* register */
2766
                    rs2 = GET_FIELD(insn, 27, 31);
2767
                    gen_movl_reg_TN(rs2, cpu_src2);
2768
                    if (insn & (1 << 12)) {
2769
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2770
                        tcg_gen_shl_i64(cpu_dst, cpu_src1, cpu_tmp0);
2771
                    } else {
2772
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2773
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2774
                        tcg_gen_shl_i64(cpu_dst, cpu_dst, cpu_tmp0);
2775
                    }
2776
                }
2777
                gen_movl_TN_reg(rd, cpu_dst);
2778
            } else if (xop == 0x26) { /* srl, V9 srlx */
2779
                cpu_src1 = get_src1(insn, cpu_src1);
2780
                if (IS_IMM) {   /* immediate */
2781
                    rs2 = GET_FIELDs(insn, 20, 31);
2782
                    if (insn & (1 << 12)) {
2783
                        tcg_gen_shri_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
2784
                    } else {
2785
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2786
                        tcg_gen_shri_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
2787
                    }
2788
                } else {                /* register */
2789
                    rs2 = GET_FIELD(insn, 27, 31);
2790
                    gen_movl_reg_TN(rs2, cpu_src2);
2791
                    if (insn & (1 << 12)) {
2792
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2793
                        tcg_gen_shr_i64(cpu_dst, cpu_src1, cpu_tmp0);
2794
                    } else {
2795
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2796
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2797
                        tcg_gen_shr_i64(cpu_dst, cpu_dst, cpu_tmp0);
2798
                    }
2799
                }
2800
                gen_movl_TN_reg(rd, cpu_dst);
2801
            } else if (xop == 0x27) { /* sra, V9 srax */
2802
                cpu_src1 = get_src1(insn, cpu_src1);
2803
                if (IS_IMM) {   /* immediate */
2804
                    rs2 = GET_FIELDs(insn, 20, 31);
2805
                    if (insn & (1 << 12)) {
2806
                        tcg_gen_sari_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
2807
                    } else {
2808
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2809
                        tcg_gen_ext_i32_i64(cpu_dst, cpu_dst);
2810
                        tcg_gen_sari_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
2811
                    }
2812
                } else {                /* register */
2813
                    rs2 = GET_FIELD(insn, 27, 31);
2814
                    gen_movl_reg_TN(rs2, cpu_src2);
2815
                    if (insn & (1 << 12)) {
2816
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2817
                        tcg_gen_sar_i64(cpu_dst, cpu_src1, cpu_tmp0);
2818
                    } else {
2819
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2820
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2821
                        tcg_gen_sar_i64(cpu_dst, cpu_dst, cpu_tmp0);
2822
                    }
2823
                }
2824
                gen_movl_TN_reg(rd, cpu_dst);
2825
#endif
2826
            } else if (xop < 0x36) {
2827
                cpu_src1 = get_src1(insn, cpu_src1);
2828
                cpu_src2 = get_src2(insn, cpu_src2);
2829
                if (xop < 0x20) {
2830
                    switch (xop & ~0x10) {
2831
                    case 0x0:
2832
                        if (xop & 0x10)
2833
                            gen_op_add_cc(cpu_dst, cpu_src1, cpu_src2);
2834
                        else
2835
                            tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
2836
                        break;
2837
                    case 0x1:
2838
                        tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_src2);
2839
                        if (xop & 0x10)
2840
                            gen_op_logic_cc(cpu_dst);
2841
                        break;
2842
                    case 0x2:
2843
                        tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
2844
                        if (xop & 0x10)
2845
                            gen_op_logic_cc(cpu_dst);
2846
                        break;
2847
                    case 0x3:
2848
                        tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
2849
                        if (xop & 0x10)
2850
                            gen_op_logic_cc(cpu_dst);
2851
                        break;
2852
                    case 0x4:
2853
                        if (xop & 0x10)
2854
                            gen_op_sub_cc(cpu_dst, cpu_src1, cpu_src2);
2855
                        else
2856
                            tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_src2);
2857
                        break;
2858
                    case 0x5:
2859
                        tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
2860
                        tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_tmp0);
2861
                        if (xop & 0x10)
2862
                            gen_op_logic_cc(cpu_dst);
2863
                        break;
2864
                    case 0x6:
2865
                        tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
2866
                        tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_tmp0);
2867
                        if (xop & 0x10)
2868
                            gen_op_logic_cc(cpu_dst);
2869
                        break;
2870
                    case 0x7:
2871
                        tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
2872
                        tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_tmp0);
2873
                        if (xop & 0x10)
2874
                            gen_op_logic_cc(cpu_dst);
2875
                        break;
2876
                    case 0x8:
2877
                        if (xop & 0x10)
2878
                            gen_op_addx_cc(cpu_dst, cpu_src1, cpu_src2);
2879
                        else {
2880
                            gen_mov_reg_C(cpu_tmp0, cpu_psr);
2881
                            tcg_gen_add_tl(cpu_tmp0, cpu_src2, cpu_tmp0);
2882
                            tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_tmp0);
2883
                        }
2884
                        break;
2885
#ifdef TARGET_SPARC64
2886
                    case 0x9: /* V9 mulx */
2887
                        tcg_gen_mul_i64(cpu_dst, cpu_src1, cpu_src2);
2888
                        break;
2889
#endif
2890
                    case 0xa:
2891
                        CHECK_IU_FEATURE(dc, MUL);
2892
                        gen_op_umul(cpu_dst, cpu_src1, cpu_src2);
2893
                        if (xop & 0x10)
2894
                            gen_op_logic_cc(cpu_dst);
2895
                        break;
2896
                    case 0xb:
2897
                        CHECK_IU_FEATURE(dc, MUL);
2898
                        gen_op_smul(cpu_dst, cpu_src1, cpu_src2);
2899
                        if (xop & 0x10)
2900
                            gen_op_logic_cc(cpu_dst);
2901
                        break;
2902
                    case 0xc:
2903
                        if (xop & 0x10)
2904
                            gen_op_subx_cc(cpu_dst, cpu_src1, cpu_src2);
2905
                        else {
2906
                            gen_mov_reg_C(cpu_tmp0, cpu_psr);
2907
                            tcg_gen_add_tl(cpu_tmp0, cpu_src2, cpu_tmp0);
2908
                            tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_tmp0);
2909
                        }
2910
                        break;
2911
#ifdef TARGET_SPARC64
2912
                    case 0xd: /* V9 udivx */
2913
                        gen_trap_ifdivzero_tl(cpu_src2);
2914
                        tcg_gen_divu_i64(cpu_dst, cpu_src1, cpu_src2);
2915
                        break;
2916
#endif
2917
                    case 0xe:
2918
                        CHECK_IU_FEATURE(dc, DIV);
2919
                        tcg_gen_helper_1_2(helper_udiv, cpu_dst, cpu_src1, cpu_src2);
2920
                        if (xop & 0x10)
2921
                            gen_op_div_cc(cpu_dst);
2922
                        break;
2923
                    case 0xf:
2924
                        CHECK_IU_FEATURE(dc, DIV);
2925
                        tcg_gen_helper_1_2(helper_sdiv, cpu_dst, cpu_src1, cpu_src2);
2926
                        if (xop & 0x10)
2927
                            gen_op_div_cc(cpu_dst);
2928
                        break;
2929
                    default:
2930
                        goto illegal_insn;
2931
                    }
2932
                    gen_movl_TN_reg(rd, cpu_dst);
2933
                } else {
2934
                    switch (xop) {
2935
                    case 0x20: /* taddcc */
2936
                        gen_op_tadd_cc(cpu_dst, cpu_src1, cpu_src2);
2937
                        gen_movl_TN_reg(rd, cpu_dst);
2938
                        break;
2939
                    case 0x21: /* tsubcc */
2940
                        gen_op_tsub_cc(cpu_dst, cpu_src1, cpu_src2);
2941
                        gen_movl_TN_reg(rd, cpu_dst);
2942
                        break;
2943
                    case 0x22: /* taddcctv */
2944
                        save_state(dc, cpu_cond);
2945
                        gen_op_tadd_ccTV(cpu_dst, cpu_src1, cpu_src2);
2946
                        gen_movl_TN_reg(rd, cpu_dst);
2947
                        break;
2948
                    case 0x23: /* tsubcctv */
2949
                        save_state(dc, cpu_cond);
2950
                        gen_op_tsub_ccTV(cpu_dst, cpu_src1, cpu_src2);
2951
                        gen_movl_TN_reg(rd, cpu_dst);
2952
                        break;
2953
                    case 0x24: /* mulscc */
2954
                        gen_op_mulscc(cpu_dst, cpu_src1, cpu_src2);
2955
                        gen_movl_TN_reg(rd, cpu_dst);
2956
                        break;
2957
#ifndef TARGET_SPARC64
2958
                    case 0x25:  /* sll */
2959
                        tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
2960
                        tcg_gen_shl_tl(cpu_dst, cpu_src1, cpu_tmp0);
2961
                        gen_movl_TN_reg(rd, cpu_dst);
2962
                        break;
2963
                    case 0x26:  /* srl */
2964
                        tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
2965
                        tcg_gen_shr_tl(cpu_dst, cpu_src1, cpu_tmp0);
2966
                        gen_movl_TN_reg(rd, cpu_dst);
2967
                        break;
2968
                    case 0x27:  /* sra */
2969
                        tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
2970
                        tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0);
2971
                        gen_movl_TN_reg(rd, cpu_dst);
2972
                        break;
2973
#endif
2974
                    case 0x30:
2975
                        {
2976
                            switch(rd) {
2977
                            case 0: /* wry */
2978
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
2979
                                tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, y));
2980
                                break;
2981
#ifndef TARGET_SPARC64
2982
                            case 0x01 ... 0x0f: /* undefined in the
2983
                                                   SPARCv8 manual, nop
2984
                                                   on the microSPARC
2985
                                                   II */
2986
                            case 0x10 ... 0x1f: /* implementation-dependent
2987
                                                   in the SPARCv8
2988
                                                   manual, nop on the
2989
                                                   microSPARC II */
2990
                                break;
2991
#else
2992
                            case 0x2: /* V9 wrccr */
2993
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
2994
                                tcg_gen_helper_0_1(helper_wrccr, cpu_dst);
2995
                                break;
2996
                            case 0x3: /* V9 wrasi */
2997
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
2998
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2999
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, asi));
3000
                                break;
3001
                            case 0x6: /* V9 wrfprs */
3002
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3003
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3004
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fprs));
3005
                                save_state(dc, cpu_cond);
3006
                                gen_op_next_insn();
3007
                                tcg_gen_exit_tb(0);
3008
                                dc->is_br = 1;
3009
                                break;
3010
                            case 0xf: /* V9 sir, nop if user */
3011
#if !defined(CONFIG_USER_ONLY)
3012
                                if (supervisor(dc))
3013
                                    ; // XXX
3014
#endif
3015
                                break;
3016
                            case 0x13: /* Graphics Status */
3017
                                if (gen_trap_ifnofpu(dc, cpu_cond))
3018
                                    goto jmp_insn;
3019
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3020
                                tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, gsr));
3021
                                break;
3022
                            case 0x17: /* Tick compare */
3023
#if !defined(CONFIG_USER_ONLY)
3024
                                if (!supervisor(dc))
3025
                                    goto illegal_insn;
3026
#endif
3027
                                {
3028
                                    TCGv r_tickptr;
3029

    
3030
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
3031
                                                   cpu_src2);
3032
                                    tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState,
3033
                                                                 tick_cmpr));
3034
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3035
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3036
                                                   offsetof(CPUState, tick));
3037
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3038
                                                       r_tickptr, cpu_dst);
3039
                                }
3040
                                break;
3041
                            case 0x18: /* System tick */
3042
#if !defined(CONFIG_USER_ONLY)
3043
                                if (!supervisor(dc))
3044
                                    goto illegal_insn;
3045
#endif
3046
                                {
3047
                                    TCGv r_tickptr;
3048

    
3049
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
3050
                                                   cpu_src2);
3051
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3052
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3053
                                                   offsetof(CPUState, stick));
3054
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3055
                                                       r_tickptr, cpu_dst);
3056
                                }
3057
                                break;
3058
                            case 0x19: /* System tick compare */
3059
#if !defined(CONFIG_USER_ONLY)
3060
                                if (!supervisor(dc))
3061
                                    goto illegal_insn;
3062
#endif
3063
                                {
3064
                                    TCGv r_tickptr;
3065

    
3066
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
3067
                                                   cpu_src2);
3068
                                    tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState,
3069
                                                                 stick_cmpr));
3070
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3071
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3072
                                                   offsetof(CPUState, stick));
3073
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3074
                                                       r_tickptr, cpu_dst);
3075
                                }
3076
                                break;
3077

    
3078
                            case 0x10: /* Performance Control */
3079
                            case 0x11: /* Performance Instrumentation Counter */
3080
                            case 0x12: /* Dispatch Control */
3081
                            case 0x14: /* Softint set */
3082
                            case 0x15: /* Softint clear */
3083
                            case 0x16: /* Softint write */
3084
#endif
3085
                            default:
3086
                                goto illegal_insn;
3087
                            }
3088
                        }
3089
                        break;
3090
#if !defined(CONFIG_USER_ONLY)
3091
                    case 0x31: /* wrpsr, V9 saved, restored */
3092
                        {
3093
                            if (!supervisor(dc))
3094
                                goto priv_insn;
3095
#ifdef TARGET_SPARC64
3096
                            switch (rd) {
3097
                            case 0:
3098
                                tcg_gen_helper_0_0(helper_saved);
3099
                                break;
3100
                            case 1:
3101
                                tcg_gen_helper_0_0(helper_restored);
3102
                                break;
3103
                            case 2: /* UA2005 allclean */
3104
                            case 3: /* UA2005 otherw */
3105
                            case 4: /* UA2005 normalw */
3106
                            case 5: /* UA2005 invalw */
3107
                                // XXX
3108
                            default:
3109
                                goto illegal_insn;
3110
                            }
3111
#else
3112
                            tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3113
                            tcg_gen_helper_0_1(helper_wrpsr, cpu_dst);
3114
                            save_state(dc, cpu_cond);
3115
                            gen_op_next_insn();
3116
                            tcg_gen_exit_tb(0);
3117
                            dc->is_br = 1;
3118
#endif
3119
                        }
3120
                        break;
3121
                    case 0x32: /* wrwim, V9 wrpr */
3122
                        {
3123
                            if (!supervisor(dc))
3124
                                goto priv_insn;
3125
                            tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3126
#ifdef TARGET_SPARC64
3127
                            switch (rd) {
3128
                            case 0: // tpc
3129
                                {
3130
                                    TCGv r_tsptr;
3131

    
3132
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3133
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3134
                                                   offsetof(CPUState, tsptr));
3135
                                    tcg_gen_st_tl(cpu_dst, r_tsptr,
3136
                                                  offsetof(trap_state, tpc));
3137
                                }
3138
                                break;
3139
                            case 1: // tnpc
3140
                                {
3141
                                    TCGv r_tsptr;
3142

    
3143
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3144
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3145
                                                   offsetof(CPUState, tsptr));
3146
                                    tcg_gen_st_tl(cpu_dst, r_tsptr,
3147
                                                  offsetof(trap_state, tnpc));
3148
                                }
3149
                                break;
3150
                            case 2: // tstate
3151
                                {
3152
                                    TCGv r_tsptr;
3153

    
3154
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3155
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3156
                                                   offsetof(CPUState, tsptr));
3157
                                    tcg_gen_st_tl(cpu_dst, r_tsptr,
3158
                                                  offsetof(trap_state, tstate));
3159
                                }
3160
                                break;
3161
                            case 3: // tt
3162
                                {
3163
                                    TCGv r_tsptr;
3164

    
3165
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3166
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3167
                                                   offsetof(CPUState, tsptr));
3168
                                    tcg_gen_st_i32(cpu_dst, r_tsptr,
3169
                                                   offsetof(trap_state, tt));
3170
                                }
3171
                                break;
3172
                            case 4: // tick
3173
                                {
3174
                                    TCGv r_tickptr;
3175

    
3176
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3177
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3178
                                                   offsetof(CPUState, tick));
3179
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3180
                                                       r_tickptr, cpu_dst);
3181
                                }
3182
                                break;
3183
                            case 5: // tba
3184
                                tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, tbr));
3185
                                break;
3186
                            case 6: // pstate
3187
                                save_state(dc, cpu_cond);
3188
                                tcg_gen_helper_0_1(helper_wrpstate, cpu_dst);
3189
                                gen_op_next_insn();
3190
                                tcg_gen_exit_tb(0);
3191
                                dc->is_br = 1;
3192
                                break;
3193
                            case 7: // tl
3194
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3195
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, tl));
3196
                                break;
3197
                            case 8: // pil
3198
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3199
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, psrpil));
3200
                                break;
3201
                            case 9: // cwp
3202
                                tcg_gen_helper_0_1(helper_wrcwp, cpu_dst);
3203
                                break;
3204
                            case 10: // cansave
3205
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3206
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, cansave));
3207
                                break;
3208
                            case 11: // canrestore
3209
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3210
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, canrestore));
3211
                                break;
3212
                            case 12: // cleanwin
3213
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3214
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, cleanwin));
3215
                                break;
3216
                            case 13: // otherwin
3217
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3218
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, otherwin));
3219
                                break;
3220
                            case 14: // wstate
3221
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3222
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, wstate));
3223
                                break;
3224
                            case 16: // UA2005 gl
3225
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3226
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, gl));
3227
                                break;
3228
                            case 26: // UA2005 strand status
3229
                                if (!hypervisor(dc))
3230
                                    goto priv_insn;
3231
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3232
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ssr));
3233
                                break;
3234
                            default:
3235
                                goto illegal_insn;
3236
                            }
3237
#else
3238
                            tcg_gen_andi_tl(cpu_dst, cpu_dst, ((1 << NWINDOWS) - 1));
3239
                            tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3240
                            tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, wim));
3241
#endif
3242
                        }
3243
                        break;
3244
                    case 0x33: /* wrtbr, UA2005 wrhpr */
3245
                        {
3246
#ifndef TARGET_SPARC64
3247
                            if (!supervisor(dc))
3248
                                goto priv_insn;
3249
                            tcg_gen_xor_tl(cpu_dst, cpu_dst, cpu_src2);
3250
                            tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, tbr));
3251
#else
3252
                            if (!hypervisor(dc))
3253
                                goto priv_insn;
3254
                            tcg_gen_xor_tl(cpu_dst, cpu_dst, cpu_src2);
3255
                            switch (rd) {
3256
                            case 0: // hpstate
3257
                                // XXX gen_op_wrhpstate();
3258
                                save_state(dc, cpu_cond);
3259
                                gen_op_next_insn();
3260
                                tcg_gen_exit_tb(0);
3261
                                dc->is_br = 1;
3262
                                break;
3263
                            case 1: // htstate
3264
                                // XXX gen_op_wrhtstate();
3265
                                break;
3266
                            case 3: // hintp
3267
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3268
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, hintp));
3269
                                break;
3270
                            case 5: // htba
3271
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3272
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, htba));
3273
                                break;
3274
                            case 31: // hstick_cmpr
3275
                                {
3276
                                    TCGv r_tickptr;
3277

    
3278
                                    tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState,
3279
                                                                 hstick_cmpr));
3280
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3281
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3282
                                                   offsetof(CPUState, hstick));
3283
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3284
                                                       r_tickptr, cpu_dst);
3285
                                }
3286
                                break;
3287
                            case 6: // hver readonly
3288
                            default:
3289
                                goto illegal_insn;
3290
                            }
3291
#endif
3292
                        }
3293
                        break;
3294
#endif
3295
#ifdef TARGET_SPARC64
3296
                    case 0x2c: /* V9 movcc */
3297
                        {
3298
                            int cc = GET_FIELD_SP(insn, 11, 12);
3299
                            int cond = GET_FIELD_SP(insn, 14, 17);
3300
                            TCGv r_cond;
3301
                            int l1;
3302

    
3303
                            r_cond = tcg_temp_new(TCG_TYPE_TL);
3304
                            if (insn & (1 << 18)) {
3305
                                if (cc == 0)
3306
                                    gen_cond(r_cond, 0, cond);
3307
                                else if (cc == 2)
3308
                                    gen_cond(r_cond, 1, cond);
3309
                                else
3310
                                    goto illegal_insn;
3311
                            } else {
3312
                                gen_fcond(r_cond, cc, cond);
3313
                            }
3314

    
3315
                            l1 = gen_new_label();
3316

    
3317
                            tcg_gen_brcond_tl(TCG_COND_EQ, r_cond,
3318
                                              tcg_const_tl(0), l1);
3319
                            if (IS_IMM) {       /* immediate */
3320
                                rs2 = GET_FIELD_SPs(insn, 0, 10);
3321
                                gen_movl_TN_reg(rd, tcg_const_tl((int)rs2));
3322
                            } else {
3323
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3324
                                gen_movl_reg_TN(rs2, cpu_tmp0);
3325
                                gen_movl_TN_reg(rd, cpu_tmp0);
3326
                            }
3327
                            gen_set_label(l1);
3328
                            break;
3329
                        }
3330
                    case 0x2d: /* V9 sdivx */
3331
                        gen_op_sdivx(cpu_dst, cpu_src1, cpu_src2);
3332
                        gen_movl_TN_reg(rd, cpu_dst);
3333
                        break;
3334
                    case 0x2e: /* V9 popc */
3335
                        {
3336
                            cpu_src2 = get_src2(insn, cpu_src2);
3337
                            tcg_gen_helper_1_1(helper_popc, cpu_dst,
3338
                                               cpu_src2);
3339
                            gen_movl_TN_reg(rd, cpu_dst);
3340
                        }
3341
                    case 0x2f: /* V9 movr */
3342
                        {
3343
                            int cond = GET_FIELD_SP(insn, 10, 12);
3344
                            int l1;
3345

    
3346
                            cpu_src1 = get_src1(insn, cpu_src1);
3347

    
3348
                            l1 = gen_new_label();
3349

    
3350
                            tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_src1,
3351
                                              tcg_const_tl(0), l1);
3352
                            if (IS_IMM) {       /* immediate */
3353
                                rs2 = GET_FIELD_SPs(insn, 0, 9);
3354
                                gen_movl_TN_reg(rd, tcg_const_tl((int)rs2));
3355
                            } else {
3356
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3357
                                gen_movl_reg_TN(rs2, cpu_tmp0);
3358
                                gen_movl_TN_reg(rd, cpu_tmp0);
3359
                            }
3360
                            gen_set_label(l1);
3361
                            break;
3362
                        }
3363
#endif
3364
                    default:
3365
                        goto illegal_insn;
3366
                    }
3367
                }
3368
            } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
3369
#ifdef TARGET_SPARC64
3370
                int opf = GET_FIELD_SP(insn, 5, 13);
3371
                rs1 = GET_FIELD(insn, 13, 17);
3372
                rs2 = GET_FIELD(insn, 27, 31);
3373
                if (gen_trap_ifnofpu(dc, cpu_cond))
3374
                    goto jmp_insn;
3375

    
3376
                switch (opf) {
3377
                case 0x000: /* VIS I edge8cc */
3378
                case 0x001: /* VIS II edge8n */
3379
                case 0x002: /* VIS I edge8lcc */
3380
                case 0x003: /* VIS II edge8ln */
3381
                case 0x004: /* VIS I edge16cc */
3382
                case 0x005: /* VIS II edge16n */
3383
                case 0x006: /* VIS I edge16lcc */
3384
                case 0x007: /* VIS II edge16ln */
3385
                case 0x008: /* VIS I edge32cc */
3386
                case 0x009: /* VIS II edge32n */
3387
                case 0x00a: /* VIS I edge32lcc */
3388
                case 0x00b: /* VIS II edge32ln */
3389
                    // XXX
3390
                    goto illegal_insn;
3391
                case 0x010: /* VIS I array8 */
3392
                    CHECK_FPU_FEATURE(dc, VIS1);
3393
                    cpu_src1 = get_src1(insn, cpu_src1);
3394
                    gen_movl_reg_TN(rs2, cpu_src2);
3395
                    tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
3396
                                       cpu_src2);
3397
                    gen_movl_TN_reg(rd, cpu_dst);
3398
                    break;
3399
                case 0x012: /* VIS I array16 */
3400
                    CHECK_FPU_FEATURE(dc, VIS1);
3401
                    cpu_src1 = get_src1(insn, cpu_src1);
3402
                    gen_movl_reg_TN(rs2, cpu_src2);
3403
                    tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
3404
                                       cpu_src2);
3405
                    tcg_gen_shli_i64(cpu_dst, cpu_dst, 1);
3406
                    gen_movl_TN_reg(rd, cpu_dst);
3407
                    break;
3408
                case 0x014: /* VIS I array32 */
3409
                    CHECK_FPU_FEATURE(dc, VIS1);
3410
                    cpu_src1 = get_src1(insn, cpu_src1);
3411
                    gen_movl_reg_TN(rs2, cpu_src2);
3412
                    tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
3413
                                       cpu_src2);
3414
                    tcg_gen_shli_i64(cpu_dst, cpu_dst, 2);
3415
                    gen_movl_TN_reg(rd, cpu_dst);
3416
                    break;
3417
                case 0x018: /* VIS I alignaddr */
3418
                    CHECK_FPU_FEATURE(dc, VIS1);
3419
                    cpu_src1 = get_src1(insn, cpu_src1);
3420
                    gen_movl_reg_TN(rs2, cpu_src2);
3421
                    tcg_gen_helper_1_2(helper_alignaddr, cpu_dst, cpu_src1,
3422
                                       cpu_src2);
3423
                    gen_movl_TN_reg(rd, cpu_dst);
3424
                    break;
3425
                case 0x019: /* VIS II bmask */
3426
                case 0x01a: /* VIS I alignaddrl */
3427
                    // XXX
3428
                    goto illegal_insn;
3429
                case 0x020: /* VIS I fcmple16 */
3430
                    CHECK_FPU_FEATURE(dc, VIS1);
3431
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3432
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3433
                    tcg_gen_helper_0_0(helper_fcmple16);
3434
                    gen_op_store_DT0_fpr(DFPREG(rd));
3435
                    break;
3436
                case 0x022: /* VIS I fcmpne16 */
3437
                    CHECK_FPU_FEATURE(dc, VIS1);
3438
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3439
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3440
                    tcg_gen_helper_0_0(helper_fcmpne16);
3441
                    gen_op_store_DT0_fpr(DFPREG(rd));
3442
                    break;
3443
                case 0x024: /* VIS I fcmple32 */
3444
                    CHECK_FPU_FEATURE(dc, VIS1);
3445
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3446
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3447
                    tcg_gen_helper_0_0(helper_fcmple32);
3448
                    gen_op_store_DT0_fpr(DFPREG(rd));
3449
                    break;
3450
                case 0x026: /* VIS I fcmpne32 */
3451
                    CHECK_FPU_FEATURE(dc, VIS1);
3452
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3453
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3454
                    tcg_gen_helper_0_0(helper_fcmpne32);
3455
                    gen_op_store_DT0_fpr(DFPREG(rd));
3456
                    break;
3457
                case 0x028: /* VIS I fcmpgt16 */
3458
                    CHECK_FPU_FEATURE(dc, VIS1);
3459
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3460
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3461
                    tcg_gen_helper_0_0(helper_fcmpgt16);
3462
                    gen_op_store_DT0_fpr(DFPREG(rd));
3463
                    break;
3464
                case 0x02a: /* VIS I fcmpeq16 */
3465
                    CHECK_FPU_FEATURE(dc, VIS1);
3466
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3467
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3468
                    tcg_gen_helper_0_0(helper_fcmpeq16);
3469
                    gen_op_store_DT0_fpr(DFPREG(rd));
3470
                    break;
3471
                case 0x02c: /* VIS I fcmpgt32 */
3472
                    CHECK_FPU_FEATURE(dc, VIS1);
3473
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3474
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3475
                    tcg_gen_helper_0_0(helper_fcmpgt32);
3476
                    gen_op_store_DT0_fpr(DFPREG(rd));
3477
                    break;
3478
                case 0x02e: /* VIS I fcmpeq32 */
3479
                    CHECK_FPU_FEATURE(dc, VIS1);
3480
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3481
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3482
                    tcg_gen_helper_0_0(helper_fcmpeq32);
3483
                    gen_op_store_DT0_fpr(DFPREG(rd));
3484
                    break;
3485
                case 0x031: /* VIS I fmul8x16 */
3486
                    CHECK_FPU_FEATURE(dc, VIS1);
3487
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3488
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3489
                    tcg_gen_helper_0_0(helper_fmul8x16);
3490
                    gen_op_store_DT0_fpr(DFPREG(rd));
3491
                    break;
3492
                case 0x033: /* VIS I fmul8x16au */
3493
                    CHECK_FPU_FEATURE(dc, VIS1);
3494
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3495
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3496
                    tcg_gen_helper_0_0(helper_fmul8x16au);
3497
                    gen_op_store_DT0_fpr(DFPREG(rd));
3498
                    break;
3499
                case 0x035: /* VIS I fmul8x16al */
3500
                    CHECK_FPU_FEATURE(dc, VIS1);
3501
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3502
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3503
                    tcg_gen_helper_0_0(helper_fmul8x16al);
3504
                    gen_op_store_DT0_fpr(DFPREG(rd));
3505
                    break;
3506
                case 0x036: /* VIS I fmul8sux16 */
3507
                    CHECK_FPU_FEATURE(dc, VIS1);
3508
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3509
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3510
                    tcg_gen_helper_0_0(helper_fmul8sux16);
3511
                    gen_op_store_DT0_fpr(DFPREG(rd));
3512
                    break;
3513
                case 0x037: /* VIS I fmul8ulx16 */
3514
                    CHECK_FPU_FEATURE(dc, VIS1);
3515
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3516
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3517
                    tcg_gen_helper_0_0(helper_fmul8ulx16);
3518
                    gen_op_store_DT0_fpr(DFPREG(rd));
3519
                    break;
3520
                case 0x038: /* VIS I fmuld8sux16 */
3521
                    CHECK_FPU_FEATURE(dc, VIS1);
3522
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3523
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3524
                    tcg_gen_helper_0_0(helper_fmuld8sux16);
3525
                    gen_op_store_DT0_fpr(DFPREG(rd));
3526
                    break;
3527
                case 0x039: /* VIS I fmuld8ulx16 */
3528
                    CHECK_FPU_FEATURE(dc, VIS1);
3529
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3530
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3531
                    tcg_gen_helper_0_0(helper_fmuld8ulx16);
3532
                    gen_op_store_DT0_fpr(DFPREG(rd));
3533
                    break;
3534
                case 0x03a: /* VIS I fpack32 */
3535
                case 0x03b: /* VIS I fpack16 */
3536
                case 0x03d: /* VIS I fpackfix */
3537
                case 0x03e: /* VIS I pdist */
3538
                    // XXX
3539
                    goto illegal_insn;
3540
                case 0x048: /* VIS I faligndata */
3541
                    CHECK_FPU_FEATURE(dc, VIS1);
3542
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3543
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3544
                    tcg_gen_helper_0_0(helper_faligndata);
3545
                    gen_op_store_DT0_fpr(DFPREG(rd));
3546
                    break;
3547
                case 0x04b: /* VIS I fpmerge */
3548
                    CHECK_FPU_FEATURE(dc, VIS1);
3549
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3550
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3551
                    tcg_gen_helper_0_0(helper_fpmerge);
3552
                    gen_op_store_DT0_fpr(DFPREG(rd));
3553
                    break;
3554
                case 0x04c: /* VIS II bshuffle */
3555
                    // XXX
3556
                    goto illegal_insn;
3557
                case 0x04d: /* VIS I fexpand */
3558
                    CHECK_FPU_FEATURE(dc, VIS1);
3559
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3560
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3561
                    tcg_gen_helper_0_0(helper_fexpand);
3562
                    gen_op_store_DT0_fpr(DFPREG(rd));
3563
                    break;
3564
                case 0x050: /* VIS I fpadd16 */
3565
                    CHECK_FPU_FEATURE(dc, VIS1);
3566
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3567
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3568
                    tcg_gen_helper_0_0(helper_fpadd16);
3569
                    gen_op_store_DT0_fpr(DFPREG(rd));
3570
                    break;
3571
                case 0x051: /* VIS I fpadd16s */
3572
                    CHECK_FPU_FEATURE(dc, VIS1);
3573
                    gen_op_load_fpr_FT0(rs1);
3574
                    gen_op_load_fpr_FT1(rs2);
3575
                    tcg_gen_helper_0_0(helper_fpadd16s);
3576
                    gen_op_store_FT0_fpr(rd);
3577
                    break;
3578
                case 0x052: /* VIS I fpadd32 */
3579
                    CHECK_FPU_FEATURE(dc, VIS1);
3580
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3581
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3582
                    tcg_gen_helper_0_0(helper_fpadd32);
3583
                    gen_op_store_DT0_fpr(DFPREG(rd));
3584
                    break;
3585
                case 0x053: /* VIS I fpadd32s */
3586
                    CHECK_FPU_FEATURE(dc, VIS1);
3587
                    gen_op_load_fpr_FT0(rs1);
3588
                    gen_op_load_fpr_FT1(rs2);
3589
                    tcg_gen_helper_0_0(helper_fpadd32s);
3590
                    gen_op_store_FT0_fpr(rd);
3591
                    break;
3592
                case 0x054: /* VIS I fpsub16 */
3593
                    CHECK_FPU_FEATURE(dc, VIS1);
3594
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3595
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3596
                    tcg_gen_helper_0_0(helper_fpsub16);
3597
                    gen_op_store_DT0_fpr(DFPREG(rd));
3598
                    break;
3599
                case 0x055: /* VIS I fpsub16s */
3600
                    CHECK_FPU_FEATURE(dc, VIS1);
3601
                    gen_op_load_fpr_FT0(rs1);
3602
                    gen_op_load_fpr_FT1(rs2);
3603
                    tcg_gen_helper_0_0(helper_fpsub16s);
3604
                    gen_op_store_FT0_fpr(rd);
3605
                    break;
3606
                case 0x056: /* VIS I fpsub32 */
3607
                    CHECK_FPU_FEATURE(dc, VIS1);
3608
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3609
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3610
                    tcg_gen_helper_0_0(helper_fpadd32);
3611
                    gen_op_store_DT0_fpr(DFPREG(rd));
3612
                    break;
3613
                case 0x057: /* VIS I fpsub32s */
3614
                    CHECK_FPU_FEATURE(dc, VIS1);
3615
                    gen_op_load_fpr_FT0(rs1);
3616
                    gen_op_load_fpr_FT1(rs2);
3617
                    tcg_gen_helper_0_0(helper_fpsub32s);
3618
                    gen_op_store_FT0_fpr(rd);
3619
                    break;
3620
                case 0x060: /* VIS I fzero */
3621
                    CHECK_FPU_FEATURE(dc, VIS1);
3622
                    tcg_gen_helper_0_0(helper_movl_DT0_0);
3623
                    gen_op_store_DT0_fpr(DFPREG(rd));
3624
                    break;
3625
                case 0x061: /* VIS I fzeros */
3626
                    CHECK_FPU_FEATURE(dc, VIS1);
3627
                    tcg_gen_helper_0_0(helper_movl_FT0_0);
3628
                    gen_op_store_FT0_fpr(rd);
3629
                    break;
3630
                case 0x062: /* VIS I fnor */
3631
                    CHECK_FPU_FEATURE(dc, VIS1);
3632
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3633
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3634
                    tcg_gen_helper_0_0(helper_fnor);
3635
                    gen_op_store_DT0_fpr(DFPREG(rd));
3636
                    break;
3637
                case 0x063: /* VIS I fnors */
3638
                    CHECK_FPU_FEATURE(dc, VIS1);
3639
                    gen_op_load_fpr_FT0(rs1);
3640
                    gen_op_load_fpr_FT1(rs2);
3641
                    tcg_gen_helper_0_0(helper_fnors);
3642
                    gen_op_store_FT0_fpr(rd);
3643
                    break;
3644
                case 0x064: /* VIS I fandnot2 */
3645
                    CHECK_FPU_FEATURE(dc, VIS1);
3646
                    gen_op_load_fpr_DT1(DFPREG(rs1));
3647
                    gen_op_load_fpr_DT0(DFPREG(rs2));
3648
                    tcg_gen_helper_0_0(helper_fandnot);
3649
                    gen_op_store_DT0_fpr(DFPREG(rd));
3650
                    break;
3651
                case 0x065: /* VIS I fandnot2s */
3652
                    CHECK_FPU_FEATURE(dc, VIS1);
3653
                    gen_op_load_fpr_FT1(rs1);
3654
                    gen_op_load_fpr_FT0(rs2);
3655
                    tcg_gen_helper_0_0(helper_fandnots);
3656
                    gen_op_store_FT0_fpr(rd);
3657
                    break;
3658
                case 0x066: /* VIS I fnot2 */
3659
                    CHECK_FPU_FEATURE(dc, VIS1);
3660
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3661
                    tcg_gen_helper_0_0(helper_fnot);
3662
                    gen_op_store_DT0_fpr(DFPREG(rd));
3663
                    break;
3664
                case 0x067: /* VIS I fnot2s */
3665
                    CHECK_FPU_FEATURE(dc, VIS1);
3666
                    gen_op_load_fpr_FT1(rs2);
3667
                    tcg_gen_helper_0_0(helper_fnot);
3668
                    gen_op_store_FT0_fpr(rd);
3669
                    break;
3670
                case 0x068: /* VIS I fandnot1 */
3671
                    CHECK_FPU_FEATURE(dc, VIS1);
3672
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3673
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3674
                    tcg_gen_helper_0_0(helper_fandnot);
3675
                    gen_op_store_DT0_fpr(DFPREG(rd));
3676
                    break;
3677
                case 0x069: /* VIS I fandnot1s */
3678
                    CHECK_FPU_FEATURE(dc, VIS1);
3679
                    gen_op_load_fpr_FT0(rs1);
3680
                    gen_op_load_fpr_FT1(rs2);
3681
                    tcg_gen_helper_0_0(helper_fandnots);
3682
                    gen_op_store_FT0_fpr(rd);
3683
                    break;
3684
                case 0x06a: /* VIS I fnot1 */
3685
                    CHECK_FPU_FEATURE(dc, VIS1);
3686
                    gen_op_load_fpr_DT1(DFPREG(rs1));
3687
                    tcg_gen_helper_0_0(helper_fnot);
3688
                    gen_op_store_DT0_fpr(DFPREG(rd));
3689
                    break;
3690
                case 0x06b: /* VIS I fnot1s */
3691
                    CHECK_FPU_FEATURE(dc, VIS1);
3692
                    gen_op_load_fpr_FT1(rs1);
3693
                    tcg_gen_helper_0_0(helper_fnot);
3694
                    gen_op_store_FT0_fpr(rd);
3695
                    break;
3696
                case 0x06c: /* VIS I fxor */
3697
                    CHECK_FPU_FEATURE(dc, VIS1);
3698
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3699
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3700
                    tcg_gen_helper_0_0(helper_fxor);
3701
                    gen_op_store_DT0_fpr(DFPREG(rd));
3702
                    break;
3703
                case 0x06d: /* VIS I fxors */
3704
                    CHECK_FPU_FEATURE(dc, VIS1);
3705
                    gen_op_load_fpr_FT0(rs1);
3706
                    gen_op_load_fpr_FT1(rs2);
3707
                    tcg_gen_helper_0_0(helper_fxors);
3708
                    gen_op_store_FT0_fpr(rd);
3709
                    break;
3710
                case 0x06e: /* VIS I fnand */
3711
                    CHECK_FPU_FEATURE(dc, VIS1);
3712
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3713
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3714
                    tcg_gen_helper_0_0(helper_fnand);
3715
                    gen_op_store_DT0_fpr(DFPREG(rd));
3716
                    break;
3717
                case 0x06f: /* VIS I fnands */
3718
                    CHECK_FPU_FEATURE(dc, VIS1);
3719
                    gen_op_load_fpr_FT0(rs1);
3720
                    gen_op_load_fpr_FT1(rs2);
3721
                    tcg_gen_helper_0_0(helper_fnands);
3722
                    gen_op_store_FT0_fpr(rd);
3723
                    break;
3724
                case 0x070: /* VIS I fand */
3725
                    CHECK_FPU_FEATURE(dc, VIS1);
3726
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3727
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3728
                    tcg_gen_helper_0_0(helper_fand);
3729
                    gen_op_store_DT0_fpr(DFPREG(rd));
3730
                    break;
3731
                case 0x071: /* VIS I fands */
3732
                    CHECK_FPU_FEATURE(dc, VIS1);
3733
                    gen_op_load_fpr_FT0(rs1);
3734
                    gen_op_load_fpr_FT1(rs2);
3735
                    tcg_gen_helper_0_0(helper_fands);
3736
                    gen_op_store_FT0_fpr(rd);
3737
                    break;
3738
                case 0x072: /* VIS I fxnor */
3739
                    CHECK_FPU_FEATURE(dc, VIS1);
3740
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3741
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3742
                    tcg_gen_helper_0_0(helper_fxnor);
3743
                    gen_op_store_DT0_fpr(DFPREG(rd));
3744
                    break;
3745
                case 0x073: /* VIS I fxnors */
3746
                    CHECK_FPU_FEATURE(dc, VIS1);
3747
                    gen_op_load_fpr_FT0(rs1);
3748
                    gen_op_load_fpr_FT1(rs2);
3749
                    tcg_gen_helper_0_0(helper_fxnors);
3750
                    gen_op_store_FT0_fpr(rd);
3751
                    break;
3752
                case 0x074: /* VIS I fsrc1 */
3753
                    CHECK_FPU_FEATURE(dc, VIS1);
3754
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3755
                    gen_op_store_DT0_fpr(DFPREG(rd));
3756
                    break;
3757
                case 0x075: /* VIS I fsrc1s */
3758
                    CHECK_FPU_FEATURE(dc, VIS1);
3759
                    gen_op_load_fpr_FT0(rs1);
3760
                    gen_op_store_FT0_fpr(rd);
3761
                    break;
3762
                case 0x076: /* VIS I fornot2 */
3763
                    CHECK_FPU_FEATURE(dc, VIS1);
3764
                    gen_op_load_fpr_DT1(DFPREG(rs1));
3765
                    gen_op_load_fpr_DT0(DFPREG(rs2));
3766
                    tcg_gen_helper_0_0(helper_fornot);
3767
                    gen_op_store_DT0_fpr(DFPREG(rd));
3768
                    break;
3769
                case 0x077: /* VIS I fornot2s */
3770
                    CHECK_FPU_FEATURE(dc, VIS1);
3771
                    gen_op_load_fpr_FT1(rs1);
3772
                    gen_op_load_fpr_FT0(rs2);
3773
                    tcg_gen_helper_0_0(helper_fornots);
3774
                    gen_op_store_FT0_fpr(rd);
3775
                    break;
3776
                case 0x078: /* VIS I fsrc2 */
3777
                    CHECK_FPU_FEATURE(dc, VIS1);
3778
                    gen_op_load_fpr_DT0(DFPREG(rs2));
3779
                    gen_op_store_DT0_fpr(DFPREG(rd));
3780
                    break;
3781
                case 0x079: /* VIS I fsrc2s */
3782
                    CHECK_FPU_FEATURE(dc, VIS1);
3783
                    gen_op_load_fpr_FT0(rs2);
3784
                    gen_op_store_FT0_fpr(rd);
3785
                    break;
3786
                case 0x07a: /* VIS I fornot1 */
3787
                    CHECK_FPU_FEATURE(dc, VIS1);
3788
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3789
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3790
                    tcg_gen_helper_0_0(helper_fornot);
3791
                    gen_op_store_DT0_fpr(DFPREG(rd));
3792
                    break;
3793
                case 0x07b: /* VIS I fornot1s */
3794
                    CHECK_FPU_FEATURE(dc, VIS1);
3795
                    gen_op_load_fpr_FT0(rs1);
3796
                    gen_op_load_fpr_FT1(rs2);
3797
                    tcg_gen_helper_0_0(helper_fornots);
3798
                    gen_op_store_FT0_fpr(rd);
3799
                    break;
3800
                case 0x07c: /* VIS I for */
3801
                    CHECK_FPU_FEATURE(dc, VIS1);
3802
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3803
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3804
                    tcg_gen_helper_0_0(helper_for);
3805
                    gen_op_store_DT0_fpr(DFPREG(rd));
3806
                    break;
3807
                case 0x07d: /* VIS I fors */
3808
                    CHECK_FPU_FEATURE(dc, VIS1);
3809
                    gen_op_load_fpr_FT0(rs1);
3810
                    gen_op_load_fpr_FT1(rs2);
3811
                    tcg_gen_helper_0_0(helper_fors);
3812
                    gen_op_store_FT0_fpr(rd);
3813
                    break;
3814
                case 0x07e: /* VIS I fone */
3815
                    CHECK_FPU_FEATURE(dc, VIS1);
3816
                    tcg_gen_helper_0_0(helper_movl_DT0_1);
3817
                    gen_op_store_DT0_fpr(DFPREG(rd));
3818
                    break;
3819
                case 0x07f: /* VIS I fones */
3820
                    CHECK_FPU_FEATURE(dc, VIS1);
3821
                    tcg_gen_helper_0_0(helper_movl_FT0_1);
3822
                    gen_op_store_FT0_fpr(rd);
3823
                    break;
3824
                case 0x080: /* VIS I shutdown */
3825
                case 0x081: /* VIS II siam */
3826
                    // XXX
3827
                    goto illegal_insn;
3828
                default:
3829
                    goto illegal_insn;
3830
                }
3831
#else
3832
                goto ncp_insn;
3833
#endif
3834
            } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
3835
#ifdef TARGET_SPARC64
3836
                goto illegal_insn;
3837
#else
3838
                goto ncp_insn;
3839
#endif
3840
#ifdef TARGET_SPARC64
3841
            } else if (xop == 0x39) { /* V9 return */
3842
                save_state(dc, cpu_cond);
3843
                cpu_src1 = get_src1(insn, cpu_src1);
3844
                if (IS_IMM) {   /* immediate */
3845
                    rs2 = GET_FIELDs(insn, 19, 31);
3846
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, (int)rs2);
3847
                } else {                /* register */
3848
                    rs2 = GET_FIELD(insn, 27, 31);
3849
                    if (rs2) {
3850
                        gen_movl_reg_TN(rs2, cpu_src2);
3851
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
3852
                    } else
3853
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
3854
                }
3855
                tcg_gen_helper_0_0(helper_restore);
3856
                gen_mov_pc_npc(dc, cpu_cond);
3857
                tcg_gen_helper_0_2(helper_check_align, cpu_dst, tcg_const_i32(3));
3858
                tcg_gen_mov_tl(cpu_npc, cpu_dst);
3859
                dc->npc = DYNAMIC_PC;
3860
                goto jmp_insn;
3861
#endif
3862
            } else {
3863
                cpu_src1 = get_src1(insn, cpu_src1);
3864
                if (IS_IMM) {   /* immediate */
3865
                    rs2 = GET_FIELDs(insn, 19, 31);
3866
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, (int)rs2);
3867
                } else {                /* register */
3868
                    rs2 = GET_FIELD(insn, 27, 31);
3869
                    if (rs2) {
3870
                        gen_movl_reg_TN(rs2, cpu_src2);
3871
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
3872
                    } else
3873
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
3874
                }
3875
                switch (xop) {
3876
                case 0x38:      /* jmpl */
3877
                    {
3878
                        gen_movl_TN_reg(rd, tcg_const_tl(dc->pc));
3879
                        gen_mov_pc_npc(dc, cpu_cond);
3880
                        tcg_gen_helper_0_2(helper_check_align, cpu_dst, tcg_const_i32(3));
3881
                        tcg_gen_mov_tl(cpu_npc, cpu_dst);
3882
                        dc->npc = DYNAMIC_PC;
3883
                    }
3884
                    goto jmp_insn;
3885
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
3886
                case 0x39:      /* rett, V9 return */
3887
                    {
3888
                        if (!supervisor(dc))
3889
                            goto priv_insn;
3890
                        gen_mov_pc_npc(dc, cpu_cond);
3891
                        tcg_gen_helper_0_2(helper_check_align, cpu_dst, tcg_const_i32(3));
3892
                        tcg_gen_mov_tl(cpu_npc, cpu_dst);
3893
                        dc->npc = DYNAMIC_PC;
3894
                        tcg_gen_helper_0_0(helper_rett);
3895
                    }
3896
                    goto jmp_insn;
3897
#endif
3898
                case 0x3b: /* flush */
3899
                    if (!((dc)->features & CPU_FEATURE_FLUSH))
3900
                        goto unimp_flush;
3901
                    tcg_gen_helper_0_1(helper_flush, cpu_dst);
3902
                    break;
3903
                case 0x3c:      /* save */
3904
                    save_state(dc, cpu_cond);
3905
                    tcg_gen_helper_0_0(helper_save);
3906
                    gen_movl_TN_reg(rd, cpu_dst);
3907
                    break;
3908
                case 0x3d:      /* restore */
3909
                    save_state(dc, cpu_cond);
3910
                    tcg_gen_helper_0_0(helper_restore);
3911
                    gen_movl_TN_reg(rd, cpu_dst);
3912
                    break;
3913
#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
3914
                case 0x3e:      /* V9 done/retry */
3915
                    {
3916
                        switch (rd) {
3917
                        case 0:
3918
                            if (!supervisor(dc))
3919
                                goto priv_insn;
3920
                            dc->npc = DYNAMIC_PC;
3921
                            dc->pc = DYNAMIC_PC;
3922
                            tcg_gen_helper_0_0(helper_done);
3923
                            goto jmp_insn;
3924
                        case 1:
3925
                            if (!supervisor(dc))
3926
                                goto priv_insn;
3927
                            dc->npc = DYNAMIC_PC;
3928
                            dc->pc = DYNAMIC_PC;
3929
                            tcg_gen_helper_0_0(helper_retry);
3930
                            goto jmp_insn;
3931
                        default:
3932
                            goto illegal_insn;
3933
                        }
3934
                    }
3935
                    break;
3936
#endif
3937
                default:
3938
                    goto illegal_insn;
3939
                }
3940
            }
3941
            break;
3942
        }
3943
        break;
3944
    case 3:                     /* load/store instructions */
3945
        {
3946
            unsigned int xop = GET_FIELD(insn, 7, 12);
3947

    
3948
            save_state(dc, cpu_cond);
3949
            cpu_src1 = get_src1(insn, cpu_src1);
3950
            if (xop == 0x3c || xop == 0x3e)
3951
            {
3952
                rs2 = GET_FIELD(insn, 27, 31);
3953
                gen_movl_reg_TN(rs2, cpu_src2);
3954
            }
3955
            else if (IS_IMM) {       /* immediate */
3956
                rs2 = GET_FIELDs(insn, 19, 31);
3957
                tcg_gen_addi_tl(cpu_addr, cpu_src1, (int)rs2);
3958
            } else {            /* register */
3959
                rs2 = GET_FIELD(insn, 27, 31);
3960
                if (rs2 != 0) {
3961
                    gen_movl_reg_TN(rs2, cpu_src2);
3962
                    tcg_gen_add_tl(cpu_addr, cpu_src1, cpu_src2);
3963
                } else
3964
                    tcg_gen_mov_tl(cpu_addr, cpu_src1);
3965
            }
3966
            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
3967
                (xop > 0x17 && xop <= 0x1d ) ||
3968
                (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
3969
                switch (xop) {
3970
                case 0x0:       /* load unsigned word */
3971
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
3972
                    ABI32_MASK(cpu_addr);
3973
                    tcg_gen_qemu_ld32u(cpu_val, cpu_addr, dc->mem_idx);
3974
                    break;
3975
                case 0x1:       /* load unsigned byte */
3976
                    ABI32_MASK(cpu_addr);
3977
                    tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx);
3978
                    break;
3979
                case 0x2:       /* load unsigned halfword */
3980
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
3981
                    ABI32_MASK(cpu_addr);
3982
                    tcg_gen_qemu_ld16u(cpu_val, cpu_addr, dc->mem_idx);
3983
                    break;
3984
                case 0x3:       /* load double word */
3985
                    if (rd & 1)
3986
                        goto illegal_insn;
3987
                    else {
3988
                        tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
3989
                        ABI32_MASK(cpu_addr);
3990
                        tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
3991
                        tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
3992
                        tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffffULL);
3993
                        gen_movl_TN_reg(rd + 1, cpu_tmp0);
3994
                        tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
3995
                        tcg_gen_trunc_i64_tl(cpu_val, cpu_tmp64);
3996
                        tcg_gen_andi_tl(cpu_val, cpu_val, 0xffffffffULL);
3997
                    }
3998
                    break;
3999
                case 0x9:       /* load signed byte */
4000
                    ABI32_MASK(cpu_addr);
4001
                    tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
4002
                    break;
4003
                case 0xa:       /* load signed halfword */
4004
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
4005
                    ABI32_MASK(cpu_addr);
4006
                    tcg_gen_qemu_ld16s(cpu_val, cpu_addr, dc->mem_idx);
4007
                    break;
4008
                case 0xd:       /* ldstub -- XXX: should be atomically */
4009
                    ABI32_MASK(cpu_addr);
4010
                    tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
4011
                    tcg_gen_qemu_st8(tcg_const_tl(0xff), cpu_addr, dc->mem_idx);
4012
                    break;
4013
                case 0x0f:      /* swap register with memory. Also atomically */
4014
                    CHECK_IU_FEATURE(dc, SWAP);
4015
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4016
                    gen_movl_reg_TN(rd, cpu_val);
4017
                    ABI32_MASK(cpu_addr);
4018
                    tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
4019
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
4020
                    tcg_gen_extu_i32_tl(cpu_val, cpu_tmp32);
4021
                    break;
4022
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4023
                case 0x10:      /* load word alternate */
4024
#ifndef TARGET_SPARC64
4025
                    if (IS_IMM)
4026
                        goto illegal_insn;
4027
                    if (!supervisor(dc))
4028
                        goto priv_insn;
4029
#endif
4030
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4031
                    gen_ld_asi(cpu_val, cpu_addr, insn, 4, 0);
4032
                    break;
4033
                case 0x11:      /* load unsigned byte alternate */
4034
#ifndef TARGET_SPARC64
4035
                    if (IS_IMM)
4036
                        goto illegal_insn;
4037
                    if (!supervisor(dc))
4038
                        goto priv_insn;
4039
#endif
4040
                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 0);
4041
                    break;
4042
                case 0x12:      /* load unsigned halfword alternate */
4043
#ifndef TARGET_SPARC64
4044
                    if (IS_IMM)
4045
                        goto illegal_insn;
4046
                    if (!supervisor(dc))
4047
                        goto priv_insn;
4048
#endif
4049
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
4050
                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 0);
4051
                    break;
4052
                case 0x13:      /* load double word alternate */
4053
#ifndef TARGET_SPARC64
4054
                    if (IS_IMM)
4055
                        goto illegal_insn;
4056
                    if (!supervisor(dc))
4057
                        goto priv_insn;
4058
#endif
4059
                    if (rd & 1)
4060
                        goto illegal_insn;
4061
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4062
                    gen_ldda_asi(cpu_tmp0, cpu_val, cpu_addr, insn);
4063
                    gen_movl_TN_reg(rd + 1, cpu_tmp0);
4064
                    break;
4065
                case 0x19:      /* load signed byte alternate */
4066
#ifndef TARGET_SPARC64
4067
                    if (IS_IMM)
4068
                        goto illegal_insn;
4069
                    if (!supervisor(dc))
4070
                        goto priv_insn;
4071
#endif
4072
                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 1);
4073
                    break;
4074
                case 0x1a:      /* load signed halfword alternate */
4075
#ifndef TARGET_SPARC64
4076
                    if (IS_IMM)
4077
                        goto illegal_insn;
4078
                    if (!supervisor(dc))
4079
                        goto priv_insn;
4080
#endif
4081
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
4082
                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 1);
4083
                    break;
4084
                case 0x1d:      /* ldstuba -- XXX: should be atomically */
4085
#ifndef TARGET_SPARC64
4086
                    if (IS_IMM)
4087
                        goto illegal_insn;
4088
                    if (!supervisor(dc))
4089
                        goto priv_insn;
4090
#endif
4091
                    gen_ldstub_asi(cpu_val, cpu_addr, insn);
4092
                    break;
4093
                case 0x1f:      /* swap reg with alt. memory. Also atomically */
4094
                    CHECK_IU_FEATURE(dc, SWAP);
4095
#ifndef TARGET_SPARC64
4096
                    if (IS_IMM)
4097
                        goto illegal_insn;
4098
                    if (!supervisor(dc))
4099
                        goto priv_insn;
4100
#endif
4101
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4102
                    gen_movl_reg_TN(rd, cpu_val);
4103
                    gen_swap_asi(cpu_val, cpu_addr, insn);
4104
                    break;
4105

    
4106
#ifndef TARGET_SPARC64
4107
                case 0x30: /* ldc */
4108
                case 0x31: /* ldcsr */
4109
                case 0x33: /* lddc */
4110
                    goto ncp_insn;
4111
#endif
4112
#endif
4113
#ifdef TARGET_SPARC64
4114
                case 0x08: /* V9 ldsw */
4115
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4116
                    ABI32_MASK(cpu_addr);
4117
                    tcg_gen_qemu_ld32s(cpu_val, cpu_addr, dc->mem_idx);
4118
                    break;
4119
                case 0x0b: /* V9 ldx */
4120
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4121
                    ABI32_MASK(cpu_addr);
4122
                    tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx);
4123
                    break;
4124
                case 0x18: /* V9 ldswa */
4125
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4126
                    gen_ld_asi(cpu_val, cpu_addr, insn, 4, 1);
4127
                    break;
4128
                case 0x1b: /* V9 ldxa */
4129
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4130
                    gen_ld_asi(cpu_val, cpu_addr, insn, 8, 0);
4131
                    break;
4132
                case 0x2d: /* V9 prefetch, no effect */
4133
                    goto skip_move;
4134
                case 0x30: /* V9 ldfa */
4135
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4136
                    gen_ldf_asi(cpu_addr, insn, 4, rd);
4137
                    goto skip_move;
4138
                case 0x33: /* V9 lddfa */
4139
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4140
                    gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd));
4141
                    goto skip_move;
4142
                case 0x3d: /* V9 prefetcha, no effect */
4143
                    goto skip_move;
4144
                case 0x32: /* V9 ldqfa */
4145
                    CHECK_FPU_FEATURE(dc, FLOAT128);
4146
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4147
                    gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd));
4148
                    goto skip_move;
4149
#endif
4150
                default:
4151
                    goto illegal_insn;
4152
                }
4153
                gen_movl_TN_reg(rd, cpu_val);
4154
#ifdef TARGET_SPARC64
4155
            skip_move: ;
4156
#endif
4157
            } else if (xop >= 0x20 && xop < 0x24) {
4158
                if (gen_trap_ifnofpu(dc, cpu_cond))
4159
                    goto jmp_insn;
4160
                switch (xop) {
4161
                case 0x20:      /* load fpreg */
4162
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4163
                    tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
4164
                    tcg_gen_st_i32(cpu_tmp32, cpu_env,
4165
                                   offsetof(CPUState, fpr[rd]));
4166
                    break;
4167
                case 0x21:      /* load fsr */
4168
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4169
                    tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
4170
                    tcg_gen_st_i32(cpu_tmp32, cpu_env,
4171
                                   offsetof(CPUState, ft0));
4172
                    tcg_gen_helper_0_0(helper_ldfsr);
4173
                    break;
4174
                case 0x22:      /* load quad fpreg */
4175
                    CHECK_FPU_FEATURE(dc, FLOAT128);
4176
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr,
4177
                                       tcg_const_i32(7));
4178
                    tcg_gen_helper_0_2(helper_ldqf, cpu_addr, dc->mem_idx);
4179
                    gen_op_store_QT0_fpr(QFPREG(rd));
4180
                    break;
4181
                case 0x23:      /* load double fpreg */
4182
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr,
4183
                                       tcg_const_i32(7));
4184
                    tcg_gen_helper_0_2(helper_lddf, cpu_addr,
4185
                                       tcg_const_i32(dc->mem_idx));
4186
                    gen_op_store_DT0_fpr(DFPREG(rd));
4187
                    break;
4188
                default:
4189
                    goto illegal_insn;
4190
                }
4191
            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) || \
4192
                       xop == 0xe || xop == 0x1e) {
4193
                gen_movl_reg_TN(rd, cpu_val);
4194
                switch (xop) {
4195
                case 0x4: /* store word */
4196
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4197
                    ABI32_MASK(cpu_addr);
4198
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
4199
                    break;
4200
                case 0x5: /* store byte */
4201
                    ABI32_MASK(cpu_addr);
4202
                    tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx);
4203
                    break;
4204
                case 0x6: /* store halfword */
4205
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
4206
                    ABI32_MASK(cpu_addr);
4207
                    tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx);
4208
                    break;
4209
                case 0x7: /* store double word */
4210
                    if (rd & 1)
4211
                        goto illegal_insn;
4212
                    else {
4213
                        TCGv r_low;
4214

    
4215
                        tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4216
                        r_low = tcg_temp_new(TCG_TYPE_I32);
4217
                        gen_movl_reg_TN(rd + 1, r_low);
4218
                        tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, cpu_val,
4219
                                           r_low);
4220
                        tcg_gen_qemu_st64(cpu_tmp64, cpu_addr, dc->mem_idx);
4221
                    }
4222
                    break;
4223
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4224
                case 0x14: /* store word alternate */
4225
#ifndef TARGET_SPARC64
4226
                    if (IS_IMM)
4227
                        goto illegal_insn;
4228
                    if (!supervisor(dc))
4229
                        goto priv_insn;
4230
#endif
4231
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4232
                    gen_st_asi(cpu_val, cpu_addr, insn, 4);
4233
                    break;
4234
                case 0x15: /* store byte alternate */
4235
#ifndef TARGET_SPARC64
4236
                    if (IS_IMM)
4237
                        goto illegal_insn;
4238
                    if (!supervisor(dc))
4239
                        goto priv_insn;
4240
#endif
4241
                    gen_st_asi(cpu_val, cpu_addr, insn, 1);
4242
                    break;
4243
                case 0x16: /* store halfword alternate */
4244
#ifndef TARGET_SPARC64
4245
                    if (IS_IMM)
4246
                        goto illegal_insn;
4247
                    if (!supervisor(dc))
4248
                        goto priv_insn;
4249
#endif
4250
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
4251
                    gen_st_asi(cpu_val, cpu_addr, insn, 2);
4252
                    break;
4253
                case 0x17: /* store double word alternate */
4254
#ifndef TARGET_SPARC64
4255
                    if (IS_IMM)
4256
                        goto illegal_insn;
4257
                    if (!supervisor(dc))
4258
                        goto priv_insn;
4259
#endif
4260
                    if (rd & 1)
4261
                        goto illegal_insn;
4262
                    else {
4263
                        tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4264
                        gen_stda_asi(cpu_val, cpu_addr, insn, rd);
4265
                    }
4266
                    break;
4267
#endif
4268
#ifdef TARGET_SPARC64
4269
                case 0x0e: /* V9 stx */
4270
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4271
                    ABI32_MASK(cpu_addr);
4272
                    tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx);
4273
                    break;
4274
                case 0x1e: /* V9 stxa */
4275
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4276
                    gen_st_asi(cpu_val, cpu_addr, insn, 8);
4277
                    break;
4278
#endif
4279
                default:
4280
                    goto illegal_insn;
4281
                }
4282
            } else if (xop > 0x23 && xop < 0x28) {
4283
                if (gen_trap_ifnofpu(dc, cpu_cond))
4284
                    goto jmp_insn;
4285
                switch (xop) {
4286
                case 0x24: /* store fpreg */
4287
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4288
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
4289
                                   offsetof(CPUState, fpr[rd]));
4290
                    tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx);
4291
                    break;
4292
                case 0x25: /* stfsr, V9 stxfsr */
4293
#ifdef CONFIG_USER_ONLY
4294
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4295
#endif
4296
                    tcg_gen_helper_0_0(helper_stfsr);
4297
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
4298
                                   offsetof(CPUState, ft0));
4299
                    tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx);
4300
                    break;
4301
                case 0x26:
4302
#ifdef TARGET_SPARC64
4303
                    /* V9 stqf, store quad fpreg */
4304
                    CHECK_FPU_FEATURE(dc, FLOAT128);
4305
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr,
4306
                                       tcg_const_i32(7));
4307
                    gen_op_load_fpr_QT0(QFPREG(rd));
4308
                    tcg_gen_helper_0_2(helper_stqf, cpu_addr, dc->mem_idx);
4309
                    break;
4310
#else /* !TARGET_SPARC64 */
4311
                    /* stdfq, store floating point queue */
4312
#if defined(CONFIG_USER_ONLY)
4313
                    goto illegal_insn;
4314
#else
4315
                    if (!supervisor(dc))
4316
                        goto priv_insn;
4317
                    if (gen_trap_ifnofpu(dc, cpu_cond))
4318
                        goto jmp_insn;
4319
                    goto nfq_insn;
4320
#endif
4321
#endif
4322
                case 0x27: /* store double fpreg */
4323
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr,
4324
                                       tcg_const_i32(7));
4325
                    gen_op_load_fpr_DT0(DFPREG(rd));
4326
                    tcg_gen_helper_0_2(helper_stdf, cpu_addr,
4327
                                       tcg_const_i32(dc->mem_idx));
4328
                    break;
4329
                default:
4330
                    goto illegal_insn;
4331
                }
4332
            } else if (xop > 0x33 && xop < 0x3f) {
4333
                switch (xop) {
4334
#ifdef TARGET_SPARC64
4335
                case 0x34: /* V9 stfa */
4336
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4337
                    gen_op_load_fpr_FT0(rd);
4338
                    gen_stf_asi(cpu_addr, insn, 4, rd);
4339
                    break;
4340
                case 0x36: /* V9 stqfa */
4341
                    CHECK_FPU_FEATURE(dc, FLOAT128);
4342
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr,
4343
                                       tcg_const_i32(7));
4344
                    gen_op_load_fpr_QT0(QFPREG(rd));
4345
                    gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd));
4346
                    break;
4347
                case 0x37: /* V9 stdfa */
4348
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4349
                    gen_op_load_fpr_DT0(DFPREG(rd));
4350
                    gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
4351
                    break;
4352
                case 0x3c: /* V9 casa */
4353
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4354
                    gen_cas_asi(cpu_val, cpu_addr, cpu_val, insn, rd);
4355
                    gen_movl_TN_reg(rd, cpu_val);
4356
                    break;
4357
                case 0x3e: /* V9 casxa */
4358
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4359
                    gen_casx_asi(cpu_val, cpu_addr, cpu_val, insn, rd);
4360
                    gen_movl_TN_reg(rd, cpu_val);
4361
                    break;
4362
#else
4363
                case 0x34: /* stc */
4364
                case 0x35: /* stcsr */
4365
                case 0x36: /* stdcq */
4366
                case 0x37: /* stdc */
4367
                    goto ncp_insn;
4368
#endif
4369
                default:
4370
                    goto illegal_insn;
4371
                }
4372
            }
4373
            else
4374
                goto illegal_insn;
4375
        }
4376
        break;
4377
    }
4378
    /* default case for non jump instructions */
4379
    if (dc->npc == DYNAMIC_PC) {
4380
        dc->pc = DYNAMIC_PC;
4381
        gen_op_next_insn();
4382
    } else if (dc->npc == JUMP_PC) {
4383
        /* we can do a static jump */
4384
        gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
4385
        dc->is_br = 1;
4386
    } else {
4387
        dc->pc = dc->npc;
4388
        dc->npc = dc->npc + 4;
4389
    }
4390
 jmp_insn:
4391
    return;
4392
 illegal_insn:
4393
    save_state(dc, cpu_cond);
4394
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_ILL_INSN));
4395
    dc->is_br = 1;
4396
    return;
4397
 unimp_flush:
4398
    save_state(dc, cpu_cond);
4399
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_UNIMP_FLUSH));
4400
    dc->is_br = 1;
4401
    return;
4402
#if !defined(CONFIG_USER_ONLY)
4403
 priv_insn:
4404
    save_state(dc, cpu_cond);
4405
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_PRIV_INSN));
4406
    dc->is_br = 1;
4407
    return;
4408
#endif
4409
 nfpu_insn:
4410
    save_state(dc, cpu_cond);
4411
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
4412
    dc->is_br = 1;
4413
    return;
4414
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
4415
 nfq_insn:
4416
    save_state(dc, cpu_cond);
4417
    gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
4418
    dc->is_br = 1;
4419
    return;
4420
#endif
4421
#ifndef TARGET_SPARC64
4422
 ncp_insn:
4423
    save_state(dc, cpu_cond);
4424
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_NCP_INSN));
4425
    dc->is_br = 1;
4426
    return;
4427
#endif
4428
}
4429

    
4430
static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
4431
{
4432
}
4433

    
4434
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
4435
                                                 int spc, CPUSPARCState *env)
4436
{
4437
    target_ulong pc_start, last_pc;
4438
    uint16_t *gen_opc_end;
4439
    DisasContext dc1, *dc = &dc1;
4440
    int j, lj = -1;
4441

    
4442
    memset(dc, 0, sizeof(DisasContext));
4443
    dc->tb = tb;
4444
    pc_start = tb->pc;
4445
    dc->pc = pc_start;
4446
    last_pc = dc->pc;
4447
    dc->npc = (target_ulong) tb->cs_base;
4448
    dc->mem_idx = cpu_mmu_index(env);
4449
    dc->features = env->features;
4450
    if ((dc->features & CPU_FEATURE_FLOAT)) {
4451
        dc->fpu_enabled = cpu_fpu_enabled(env);
4452
#if defined(CONFIG_USER_ONLY)
4453
        dc->features |= CPU_FEATURE_FLOAT128;
4454
#endif
4455
    } else
4456
        dc->fpu_enabled = 0;
4457
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4458

    
4459
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
4460
    cpu_tmp32 = tcg_temp_new(TCG_TYPE_I32);
4461
    cpu_tmp64 = tcg_temp_new(TCG_TYPE_I64);
4462

    
4463
    do {
4464
        if (env->nb_breakpoints > 0) {
4465
            for(j = 0; j < env->nb_breakpoints; j++) {
4466
                if (env->breakpoints[j] == dc->pc) {
4467
                    if (dc->pc != pc_start)
4468
                        save_state(dc, cpu_cond);
4469
                    tcg_gen_helper_0_0(helper_debug);
4470
                    tcg_gen_exit_tb(0);
4471
                    dc->is_br = 1;
4472
                    goto exit_gen_loop;
4473
                }
4474
            }
4475
        }
4476
        if (spc) {
4477
            if (loglevel > 0)
4478
                fprintf(logfile, "Search PC...\n");
4479
            j = gen_opc_ptr - gen_opc_buf;
4480
            if (lj < j) {
4481
                lj++;
4482
                while (lj < j)
4483
                    gen_opc_instr_start[lj++] = 0;
4484
                gen_opc_pc[lj] = dc->pc;
4485
                gen_opc_npc[lj] = dc->npc;
4486
                gen_opc_instr_start[lj] = 1;
4487
            }
4488
        }
4489
        last_pc = dc->pc;
4490
        disas_sparc_insn(dc);
4491

    
4492
        if (dc->is_br)
4493
            break;
4494
        /* if the next PC is different, we abort now */
4495
        if (dc->pc != (last_pc + 4))
4496
            break;
4497
        /* if we reach a page boundary, we stop generation so that the
4498
           PC of a TT_TFAULT exception is always in the right page */
4499
        if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
4500
            break;
4501
        /* if single step mode, we generate only one instruction and
4502
           generate an exception */
4503
        if (env->singlestep_enabled) {
4504
            tcg_gen_movi_tl(cpu_pc, dc->pc);
4505
            tcg_gen_exit_tb(0);
4506
            break;
4507
        }
4508
    } while ((gen_opc_ptr < gen_opc_end) &&
4509
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
4510

    
4511
 exit_gen_loop:
4512
    if (!dc->is_br) {
4513
        if (dc->pc != DYNAMIC_PC &&
4514
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
4515
            /* static PC and NPC: we can use direct chaining */
4516
            gen_goto_tb(dc, 0, dc->pc, dc->npc);
4517
        } else {
4518
            if (dc->pc != DYNAMIC_PC)
4519
                tcg_gen_movi_tl(cpu_pc, dc->pc);
4520
            save_npc(dc, cpu_cond);
4521
            tcg_gen_exit_tb(0);
4522
        }
4523
    }
4524
    *gen_opc_ptr = INDEX_op_end;
4525
    if (spc) {
4526
        j = gen_opc_ptr - gen_opc_buf;
4527
        lj++;
4528
        while (lj <= j)
4529
            gen_opc_instr_start[lj++] = 0;
4530
#if 0
4531
        if (loglevel > 0) {
4532
            page_dump(logfile);
4533
        }
4534
#endif
4535
        gen_opc_jump_pc[0] = dc->jump_pc[0];
4536
        gen_opc_jump_pc[1] = dc->jump_pc[1];
4537
    } else {
4538
        tb->size = last_pc + 4 - pc_start;
4539
    }
4540
#ifdef DEBUG_DISAS
4541
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4542
        fprintf(logfile, "--------------\n");
4543
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
4544
        target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
4545
        fprintf(logfile, "\n");
4546
    }
4547
#endif
4548
    return 0;
4549
}
4550

    
4551
int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
4552
{
4553
    return gen_intermediate_code_internal(tb, 0, env);
4554
}
4555

    
4556
int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
4557
{
4558
    return gen_intermediate_code_internal(tb, 1, env);
4559
}
4560

    
4561
void gen_intermediate_code_init(CPUSPARCState *env)
4562
{
4563
    unsigned int i;
4564
    static int inited;
4565
    static const char * const gregnames[8] = {
4566
        NULL, // g0 not used
4567
        "g1",
4568
        "g2",
4569
        "g3",
4570
        "g4",
4571
        "g5",
4572
        "g6",
4573
        "g7",
4574
    };
4575

    
4576
    /* init various static tables */
4577
    if (!inited) {
4578
        inited = 1;
4579

    
4580
        tcg_set_macro_func(&tcg_ctx, tcg_macro_func);
4581
        cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
4582
        cpu_regwptr = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
4583
                                         offsetof(CPUState, regwptr),
4584
                                         "regwptr");
4585
#ifdef TARGET_SPARC64
4586
        cpu_xcc = tcg_global_mem_new(TCG_TYPE_I32,
4587
                                     TCG_AREG0, offsetof(CPUState, xcc),
4588
                                     "xcc");
4589
#endif
4590
        /* XXX: T0 and T1 should be temporaries */
4591
        cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
4592
                                      TCG_AREG0, offsetof(CPUState, t0), "T0");
4593
        cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
4594
                                      TCG_AREG0, offsetof(CPUState, t1), "T1");
4595
        cpu_cond = tcg_global_mem_new(TCG_TYPE_TL,
4596
                                      TCG_AREG0, offsetof(CPUState, cond), "cond");
4597
        cpu_cc_src = tcg_global_mem_new(TCG_TYPE_TL,
4598
                                        TCG_AREG0, offsetof(CPUState, cc_src),
4599
                                        "cc_src");
4600
        cpu_cc_src2 = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4601
                                         offsetof(CPUState, cc_src2),
4602
                                         "cc_src2");
4603
        cpu_cc_dst = tcg_global_mem_new(TCG_TYPE_TL,
4604
                                        TCG_AREG0, offsetof(CPUState, cc_dst),
4605
                                        "cc_dst");
4606
        cpu_psr = tcg_global_mem_new(TCG_TYPE_I32,
4607
                                     TCG_AREG0, offsetof(CPUState, psr),
4608
                                     "psr");
4609
        cpu_fsr = tcg_global_mem_new(TCG_TYPE_TL,
4610
                                     TCG_AREG0, offsetof(CPUState, fsr),
4611
                                     "fsr");
4612
        cpu_pc = tcg_global_mem_new(TCG_TYPE_TL,
4613
                                    TCG_AREG0, offsetof(CPUState, pc),
4614
                                    "pc");
4615
        cpu_npc = tcg_global_mem_new(TCG_TYPE_TL,
4616
                                    TCG_AREG0, offsetof(CPUState, npc),
4617
                                    "npc");
4618
        for (i = 1; i < 8; i++)
4619
            cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4620
                                              offsetof(CPUState, gregs[i]),
4621
                                              gregnames[i]);
4622
    }
4623
}
4624

    
4625
void gen_pc_load(CPUState *env, TranslationBlock *tb,
4626
                unsigned long searched_pc, int pc_pos, void *puc)
4627
{
4628
    target_ulong npc;
4629
    env->pc = gen_opc_pc[pc_pos];
4630
    npc = gen_opc_npc[pc_pos];
4631
    if (npc == 1) {
4632
        /* dynamic NPC: already stored */
4633
    } else if (npc == 2) {
4634
        target_ulong t2 = (target_ulong)(unsigned long)puc;
4635
        /* jump PC: use T2 and the jump targets of the translation */
4636
        if (t2)
4637
            env->npc = gen_opc_jump_pc[0];
4638
        else
4639
            env->npc = gen_opc_jump_pc[1];
4640
    } else {
4641
        env->npc = npc;
4642
    }
4643
}