Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ 7c60cc4b

History | View | Annotate | Download (175.7 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
/*
23
   TODO-list:
24

25
   Rest of V9 instructions, VIS instructions
26
   NPC/PC static optimisations (use JUMP_TB when possible)
27
   Optimize synthetic instructions
28
*/
29

    
30
#include <stdarg.h>
31
#include <stdlib.h>
32
#include <stdio.h>
33
#include <string.h>
34
#include <inttypes.h>
35

    
36
#include "cpu.h"
37
#include "exec-all.h"
38
#include "disas.h"
39
#include "helper.h"
40
#include "tcg-op.h"
41

    
42
#define DEBUG_DISAS
43

    
44
#define DYNAMIC_PC  1 /* dynamic pc value */
45
#define JUMP_PC     2 /* dynamic pc value which takes only two values
46
                         according to jump_pc[T2] */
47

    
48
/* global register indexes */
49
static TCGv cpu_env, cpu_T[2], cpu_regwptr, cpu_cc_src, cpu_cc_src2, cpu_cc_dst;
50
static TCGv cpu_psr, cpu_fsr, cpu_pc, cpu_npc, cpu_gregs[8];
51
static TCGv cpu_cond, cpu_src1, cpu_src2, cpu_dst, cpu_addr, cpu_val;
52
#ifdef TARGET_SPARC64
53
static TCGv cpu_xcc;
54
#endif
55
/* local register indexes (only used inside old micro ops) */
56
static TCGv cpu_tmp0, cpu_tmp32, cpu_tmp64;
57

    
58
typedef struct DisasContext {
59
    target_ulong pc;    /* current Program Counter: integer or DYNAMIC_PC */
60
    target_ulong npc;   /* next PC: integer or DYNAMIC_PC or JUMP_PC */
61
    target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
62
    int is_br;
63
    int mem_idx;
64
    int fpu_enabled;
65
    struct TranslationBlock *tb;
66
    uint32_t features;
67
} DisasContext;
68

    
69
// This function uses non-native bit order
70
#define GET_FIELD(X, FROM, TO) \
71
  ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
72

    
73
// This function uses the order in the manuals, i.e. bit 0 is 2^0
74
#define GET_FIELD_SP(X, FROM, TO) \
75
    GET_FIELD(X, 31 - (TO), 31 - (FROM))
76

    
77
#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
78
#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
79

    
80
#ifdef TARGET_SPARC64
81
#define FFPREG(r) (r)
82
#define DFPREG(r) (((r & 1) << 5) | (r & 0x1e))
83
#define QFPREG(r) (((r & 1) << 5) | (r & 0x1c))
84
#else
85
#define FFPREG(r) (r)
86
#define DFPREG(r) (r & 0x1e)
87
#define QFPREG(r) (r & 0x1c)
88
#endif
89

    
90
static int sign_extend(int x, int len)
91
{
92
    len = 32 - len;
93
    return (x << len) >> len;
94
}
95

    
96
#define IS_IMM (insn & (1<<13))
97

    
98
/* floating point registers moves */
99
static void gen_op_load_fpr_FT0(unsigned int src)
100
{
101
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
102
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft0));
103
}
104

    
105
static void gen_op_load_fpr_FT1(unsigned int src)
106
{
107
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
108
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft1));
109
}
110

    
111
static void gen_op_store_FT0_fpr(unsigned int dst)
112
{
113
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft0));
114
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst]));
115
}
116

    
117
static void gen_op_load_fpr_DT0(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, dt0) + 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, dt0) + offsetof(CPU_DoubleU, l.lower));
123
}
124

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

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

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

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

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

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

    
191
#ifdef TARGET_ABI32
192
#define ABI32_MASK(addr) tcg_gen_andi_tl(addr, addr, 0xffffffffULL);
193
#else
194
#define ABI32_MASK(addr)
195
#endif
196

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
330
    l1 = gen_new_label();
331
    r_temp = tcg_temp_new(TCG_TYPE_TL);
332
    tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
333
    tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l1);
334
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
335
    gen_set_label(l1);
336
}
337

    
338
#ifdef TARGET_SPARC64
339
static inline void gen_cc_C_add_xcc(TCGv dst, TCGv src1)
340
{
341
    int l1;
342

    
343
    l1 = gen_new_label();
344
    tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l1);
345
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
346
    gen_set_label(l1);
347
}
348
#endif
349

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

    
358
    r_temp = tcg_temp_new(TCG_TYPE_TL);
359
    tcg_gen_xor_tl(r_temp, src1, src2);
360
    tcg_gen_xori_tl(r_temp, r_temp, -1);
361
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
362
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
363
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
364
    tcg_gen_shri_tl(r_temp, r_temp, 31 - PSR_OVF_SHIFT);
365
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
366
    tcg_gen_or_i32(cpu_psr, cpu_psr, cpu_tmp32);
367
}
368

    
369
#ifdef TARGET_SPARC64
370
static inline void gen_cc_V_add_xcc(TCGv dst, TCGv src1, TCGv src2)
371
{
372
    TCGv r_temp;
373

    
374
    r_temp = tcg_temp_new(TCG_TYPE_TL);
375
    tcg_gen_xor_tl(r_temp, src1, src2);
376
    tcg_gen_xori_tl(r_temp, r_temp, -1);
377
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
378
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
379
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
380
    tcg_gen_shri_tl(r_temp, r_temp, 63 - PSR_OVF_SHIFT);
381
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
382
    tcg_gen_or_i32(cpu_xcc, cpu_xcc, cpu_tmp32);
383
}
384
#endif
385

    
386
static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
387
{
388
    TCGv r_temp;
389
    int l1;
390

    
391
    l1 = gen_new_label();
392

    
393
    r_temp = tcg_temp_new(TCG_TYPE_TL);
394
    tcg_gen_xor_tl(r_temp, src1, src2);
395
    tcg_gen_xori_tl(r_temp, r_temp, -1);
396
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
397
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
398
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
399
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
400
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
401
    gen_set_label(l1);
402
}
403

    
404
static inline void gen_cc_V_tag(TCGv src1, TCGv src2)
405
{
406
    int l1;
407

    
408
    l1 = gen_new_label();
409
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
410
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
411
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
412
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
413
    gen_set_label(l1);
414
}
415

    
416
static inline void gen_tag_tv(TCGv src1, TCGv src2)
417
{
418
    int l1;
419

    
420
    l1 = gen_new_label();
421
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
422
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
423
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
424
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
425
    gen_set_label(l1);
426
}
427

    
428
static inline void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2)
429
{
430
    tcg_gen_mov_tl(cpu_cc_src, src1);
431
    tcg_gen_mov_tl(cpu_cc_src2, src2);
432
    tcg_gen_add_tl(dst, src1, src2);
433
    tcg_gen_mov_tl(cpu_cc_dst, dst);
434
    gen_cc_clear_icc();
435
    gen_cc_NZ_icc(cpu_cc_dst);
436
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
437
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
438
#ifdef TARGET_SPARC64
439
    gen_cc_clear_xcc();
440
    gen_cc_NZ_xcc(cpu_cc_dst);
441
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
442
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
443
#endif
444
}
445

    
446
static inline void gen_op_addx_cc(TCGv dst, TCGv src1, TCGv src2)
447
{
448
    tcg_gen_mov_tl(cpu_cc_src, src1);
449
    tcg_gen_mov_tl(cpu_cc_src2, src2);
450
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
451
    tcg_gen_add_tl(dst, src1, cpu_tmp0);
452
    gen_cc_clear_icc();
453
    gen_cc_C_add_icc(dst, cpu_cc_src);
454
#ifdef TARGET_SPARC64
455
    gen_cc_clear_xcc();
456
    gen_cc_C_add_xcc(dst, cpu_cc_src);
457
#endif
458
    tcg_gen_add_tl(dst, dst, cpu_cc_src2);
459
    tcg_gen_mov_tl(cpu_cc_dst, dst);
460
    gen_cc_NZ_icc(cpu_cc_dst);
461
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
462
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
463
#ifdef TARGET_SPARC64
464
    gen_cc_NZ_xcc(cpu_cc_dst);
465
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
466
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
467
#endif
468
}
469

    
470
static inline void gen_op_tadd_cc(TCGv dst, TCGv src1, TCGv src2)
471
{
472
    tcg_gen_mov_tl(cpu_cc_src, src1);
473
    tcg_gen_mov_tl(cpu_cc_src2, src2);
474
    tcg_gen_add_tl(dst, src1, src2);
475
    tcg_gen_mov_tl(cpu_cc_dst, dst);
476
    gen_cc_clear_icc();
477
    gen_cc_NZ_icc(cpu_cc_dst);
478
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
479
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
480
    gen_cc_V_tag(cpu_cc_src, cpu_cc_src2);
481
#ifdef TARGET_SPARC64
482
    gen_cc_clear_xcc();
483
    gen_cc_NZ_xcc(cpu_cc_dst);
484
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
485
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
486
#endif
487
}
488

    
489
static inline void gen_op_tadd_ccTV(TCGv dst, TCGv src1, TCGv src2)
490
{
491
    tcg_gen_mov_tl(cpu_cc_src, src1);
492
    tcg_gen_mov_tl(cpu_cc_src2, src2);
493
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
494
    tcg_gen_add_tl(dst, src1, src2);
495
    tcg_gen_mov_tl(cpu_cc_dst, dst);
496
    gen_add_tv(dst, cpu_cc_src, cpu_cc_src2);
497
    gen_cc_clear_icc();
498
    gen_cc_NZ_icc(cpu_cc_dst);
499
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
500
#ifdef TARGET_SPARC64
501
    gen_cc_clear_xcc();
502
    gen_cc_NZ_xcc(cpu_cc_dst);
503
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
504
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
505
#endif
506
}
507

    
508
/* old op:
509
    if (src1 < T1)
510
        env->psr |= PSR_CARRY;
511
*/
512
static inline void gen_cc_C_sub_icc(TCGv src1, TCGv src2)
513
{
514
    TCGv r_temp1, r_temp2;
515
    int l1;
516

    
517
    l1 = gen_new_label();
518
    r_temp1 = tcg_temp_new(TCG_TYPE_TL);
519
    r_temp2 = tcg_temp_new(TCG_TYPE_TL);
520
    tcg_gen_andi_tl(r_temp1, src1, 0xffffffffULL);
521
    tcg_gen_andi_tl(r_temp2, src2, 0xffffffffULL);
522
    tcg_gen_brcond_tl(TCG_COND_GEU, r_temp1, r_temp2, l1);
523
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
524
    gen_set_label(l1);
525
}
526

    
527
#ifdef TARGET_SPARC64
528
static inline void gen_cc_C_sub_xcc(TCGv src1, TCGv src2)
529
{
530
    int l1;
531

    
532
    l1 = gen_new_label();
533
    tcg_gen_brcond_tl(TCG_COND_GEU, src1, src2, l1);
534
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
535
    gen_set_label(l1);
536
}
537
#endif
538

    
539
/* old op:
540
    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
541
        env->psr |= PSR_OVF;
542
*/
543
static inline void gen_cc_V_sub_icc(TCGv dst, TCGv src1, TCGv src2)
544
{
545
    TCGv r_temp;
546

    
547
    r_temp = tcg_temp_new(TCG_TYPE_TL);
548
    tcg_gen_xor_tl(r_temp, src1, src2);
549
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
550
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
551
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
552
    tcg_gen_shri_tl(r_temp, r_temp, 31 - PSR_OVF_SHIFT);
553
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
554
    tcg_gen_or_i32(cpu_psr, cpu_psr, cpu_tmp32);
555
}
556

    
557
#ifdef TARGET_SPARC64
558
static inline void gen_cc_V_sub_xcc(TCGv dst, TCGv src1, TCGv src2)
559
{
560
    TCGv r_temp;
561

    
562
    r_temp = tcg_temp_new(TCG_TYPE_TL);
563
    tcg_gen_xor_tl(r_temp, src1, src2);
564
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
565
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
566
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
567
    tcg_gen_shri_tl(r_temp, r_temp, 63 - PSR_OVF_SHIFT);
568
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
569
    tcg_gen_or_i32(cpu_xcc, cpu_xcc, cpu_tmp32);
570
}
571
#endif
572

    
573
static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
574
{
575
    TCGv r_temp;
576
    int l1;
577

    
578
    l1 = gen_new_label();
579

    
580
    r_temp = tcg_temp_new(TCG_TYPE_TL);
581
    tcg_gen_xor_tl(r_temp, src1, src2);
582
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
583
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
584
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
585
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
586
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
587
    gen_set_label(l1);
588
}
589

    
590
static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2)
591
{
592
    tcg_gen_mov_tl(cpu_cc_src, src1);
593
    tcg_gen_mov_tl(cpu_cc_src2, src2);
594
    tcg_gen_sub_tl(dst, src1, src2);
595
    tcg_gen_mov_tl(cpu_cc_dst, dst);
596
    gen_cc_clear_icc();
597
    gen_cc_NZ_icc(cpu_cc_dst);
598
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
599
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
600
#ifdef TARGET_SPARC64
601
    gen_cc_clear_xcc();
602
    gen_cc_NZ_xcc(cpu_cc_dst);
603
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
604
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
605
#endif
606
}
607

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

    
632
static inline void gen_op_tsub_cc(TCGv dst, TCGv src1, TCGv src2)
633
{
634
    tcg_gen_mov_tl(cpu_cc_src, src1);
635
    tcg_gen_mov_tl(cpu_cc_src2, src2);
636
    tcg_gen_sub_tl(dst, src1, src2);
637
    tcg_gen_mov_tl(cpu_cc_dst, dst);
638
    gen_cc_clear_icc();
639
    gen_cc_NZ_icc(cpu_cc_dst);
640
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
641
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
642
    gen_cc_V_tag(cpu_cc_src, cpu_cc_src2);
643
#ifdef TARGET_SPARC64
644
    gen_cc_clear_xcc();
645
    gen_cc_NZ_xcc(cpu_cc_dst);
646
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
647
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
648
#endif
649
}
650

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

    
670
static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
671
{
672
    TCGv r_temp, r_temp2;
673
    int l1;
674

    
675
    l1 = gen_new_label();
676
    r_temp = tcg_temp_new(TCG_TYPE_TL);
677
    r_temp2 = tcg_temp_new(TCG_TYPE_I32);
678

    
679
    /* old op:
680
    if (!(env->y & 1))
681
        T1 = 0;
682
    */
683
    tcg_gen_mov_tl(cpu_cc_src, src1);
684
    tcg_gen_ld32u_tl(r_temp, cpu_env, offsetof(CPUSPARCState, y));
685
    tcg_gen_trunc_tl_i32(r_temp2, r_temp);
686
    tcg_gen_andi_i32(r_temp2, r_temp2, 0x1);
687
    tcg_gen_mov_tl(cpu_cc_src2, src2);
688
    tcg_gen_brcond_i32(TCG_COND_NE, r_temp2, tcg_const_i32(0), l1);
689
    tcg_gen_movi_tl(cpu_cc_src2, 0);
690
    gen_set_label(l1);
691

    
692
    // b2 = T0 & 1;
693
    // env->y = (b2 << 31) | (env->y >> 1);
694
    tcg_gen_trunc_tl_i32(r_temp2, cpu_cc_src);
695
    tcg_gen_andi_i32(r_temp2, r_temp2, 0x1);
696
    tcg_gen_shli_i32(r_temp2, r_temp2, 31);
697
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, y));
698
    tcg_gen_shri_i32(cpu_tmp32, cpu_tmp32, 1);
699
    tcg_gen_or_i32(cpu_tmp32, cpu_tmp32, r_temp2);
700
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, y));
701

    
702
    // b1 = N ^ V;
703
    gen_mov_reg_N(cpu_tmp0, cpu_psr);
704
    gen_mov_reg_V(r_temp, cpu_psr);
705
    tcg_gen_xor_tl(cpu_tmp0, cpu_tmp0, r_temp);
706

    
707
    // T0 = (b1 << 31) | (T0 >> 1);
708
    // src1 = T0;
709
    tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
710
    tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
711
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
712

    
713
    /* do addition and update flags */
714
    tcg_gen_add_tl(dst, cpu_cc_src, cpu_cc_src2);
715
    tcg_gen_mov_tl(cpu_cc_dst, dst);
716

    
717
    gen_cc_clear_icc();
718
    gen_cc_NZ_icc(cpu_cc_dst);
719
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
720
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
721
}
722

    
723
static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
724
{
725
    TCGv r_temp, r_temp2;
726

    
727
    r_temp = tcg_temp_new(TCG_TYPE_I64);
728
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);
729

    
730
    tcg_gen_extu_tl_i64(r_temp, src2);
731
    tcg_gen_extu_tl_i64(r_temp2, src1);
732
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
733

    
734
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
735
    tcg_gen_trunc_i64_i32(r_temp, r_temp);
736
    tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
737
#ifdef TARGET_SPARC64
738
    tcg_gen_mov_i64(dst, r_temp2);
739
#else
740
    tcg_gen_trunc_i64_tl(dst, r_temp2);
741
#endif
742
}
743

    
744
static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
745
{
746
    TCGv r_temp, r_temp2;
747

    
748
    r_temp = tcg_temp_new(TCG_TYPE_I64);
749
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);
750

    
751
    tcg_gen_ext_tl_i64(r_temp, src2);
752
    tcg_gen_ext_tl_i64(r_temp2, src1);
753
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
754

    
755
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
756
    tcg_gen_trunc_i64_i32(r_temp, r_temp);
757
    tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
758
#ifdef TARGET_SPARC64
759
    tcg_gen_mov_i64(dst, r_temp2);
760
#else
761
    tcg_gen_trunc_i64_tl(dst, r_temp2);
762
#endif
763
}
764

    
765
#ifdef TARGET_SPARC64
766
static inline void gen_trap_ifdivzero_tl(TCGv divisor)
767
{
768
    int l1;
769

    
770
    l1 = gen_new_label();
771
    tcg_gen_brcond_tl(TCG_COND_NE, divisor, tcg_const_tl(0), l1);
772
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_DIV_ZERO));
773
    gen_set_label(l1);
774
}
775

    
776
static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
777
{
778
    int l1, l2;
779

    
780
    l1 = gen_new_label();
781
    l2 = gen_new_label();
782
    tcg_gen_mov_tl(cpu_cc_src, src1);
783
    tcg_gen_mov_tl(cpu_cc_src2, src2);
784
    gen_trap_ifdivzero_tl(src2);
785
    tcg_gen_brcond_tl(TCG_COND_NE, cpu_cc_src, tcg_const_tl(INT64_MIN), l1);
786
    tcg_gen_brcond_tl(TCG_COND_NE, cpu_cc_src2, tcg_const_tl(-1), l1);
787
    tcg_gen_movi_i64(dst, INT64_MIN);
788
    tcg_gen_br(l2);
789
    gen_set_label(l1);
790
    tcg_gen_div_i64(dst, cpu_cc_src, cpu_cc_src2);
791
    gen_set_label(l2);
792
}
793
#endif
794

    
795
static inline void gen_op_div_cc(TCGv dst)
796
{
797
    int l1;
798

    
799
    tcg_gen_mov_tl(cpu_cc_dst, dst);
800
    gen_cc_clear_icc();
801
    gen_cc_NZ_icc(cpu_cc_dst);
802
    l1 = gen_new_label();
803
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, cc_src2));
804
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
805
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
806
    gen_set_label(l1);
807
}
808

    
809
static inline void gen_op_logic_cc(TCGv dst)
810
{
811
    tcg_gen_mov_tl(cpu_cc_dst, dst);
812

    
813
    gen_cc_clear_icc();
814
    gen_cc_NZ_icc(cpu_cc_dst);
815
#ifdef TARGET_SPARC64
816
    gen_cc_clear_xcc();
817
    gen_cc_NZ_xcc(cpu_cc_dst);
818
#endif
819
}
820

    
821
// 1
822
static inline void gen_op_eval_ba(TCGv dst)
823
{
824
    tcg_gen_movi_tl(dst, 1);
825
}
826

    
827
// Z
828
static inline void gen_op_eval_be(TCGv dst, TCGv src)
829
{
830
    gen_mov_reg_Z(dst, src);
831
}
832

    
833
// Z | (N ^ V)
834
static inline void gen_op_eval_ble(TCGv dst, TCGv src)
835
{
836
    gen_mov_reg_N(cpu_tmp0, src);
837
    gen_mov_reg_V(dst, src);
838
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
839
    gen_mov_reg_Z(cpu_tmp0, src);
840
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
841
}
842

    
843
// N ^ V
844
static inline void gen_op_eval_bl(TCGv dst, TCGv src)
845
{
846
    gen_mov_reg_V(cpu_tmp0, src);
847
    gen_mov_reg_N(dst, src);
848
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
849
}
850

    
851
// C | Z
852
static inline void gen_op_eval_bleu(TCGv dst, TCGv src)
853
{
854
    gen_mov_reg_Z(cpu_tmp0, src);
855
    gen_mov_reg_C(dst, src);
856
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
857
}
858

    
859
// C
860
static inline void gen_op_eval_bcs(TCGv dst, TCGv src)
861
{
862
    gen_mov_reg_C(dst, src);
863
}
864

    
865
// V
866
static inline void gen_op_eval_bvs(TCGv dst, TCGv src)
867
{
868
    gen_mov_reg_V(dst, src);
869
}
870

    
871
// 0
872
static inline void gen_op_eval_bn(TCGv dst)
873
{
874
    tcg_gen_movi_tl(dst, 0);
875
}
876

    
877
// N
878
static inline void gen_op_eval_bneg(TCGv dst, TCGv src)
879
{
880
    gen_mov_reg_N(dst, src);
881
}
882

    
883
// !Z
884
static inline void gen_op_eval_bne(TCGv dst, TCGv src)
885
{
886
    gen_mov_reg_Z(dst, src);
887
    tcg_gen_xori_tl(dst, dst, 0x1);
888
}
889

    
890
// !(Z | (N ^ V))
891
static inline void gen_op_eval_bg(TCGv dst, TCGv src)
892
{
893
    gen_mov_reg_N(cpu_tmp0, src);
894
    gen_mov_reg_V(dst, src);
895
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
896
    gen_mov_reg_Z(cpu_tmp0, src);
897
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
898
    tcg_gen_xori_tl(dst, dst, 0x1);
899
}
900

    
901
// !(N ^ V)
902
static inline void gen_op_eval_bge(TCGv dst, TCGv src)
903
{
904
    gen_mov_reg_V(cpu_tmp0, src);
905
    gen_mov_reg_N(dst, src);
906
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
907
    tcg_gen_xori_tl(dst, dst, 0x1);
908
}
909

    
910
// !(C | Z)
911
static inline void gen_op_eval_bgu(TCGv dst, TCGv src)
912
{
913
    gen_mov_reg_Z(cpu_tmp0, src);
914
    gen_mov_reg_C(dst, src);
915
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
916
    tcg_gen_xori_tl(dst, dst, 0x1);
917
}
918

    
919
// !C
920
static inline void gen_op_eval_bcc(TCGv dst, TCGv src)
921
{
922
    gen_mov_reg_C(dst, src);
923
    tcg_gen_xori_tl(dst, dst, 0x1);
924
}
925

    
926
// !N
927
static inline void gen_op_eval_bpos(TCGv dst, TCGv src)
928
{
929
    gen_mov_reg_N(dst, src);
930
    tcg_gen_xori_tl(dst, dst, 0x1);
931
}
932

    
933
// !V
934
static inline void gen_op_eval_bvc(TCGv dst, TCGv src)
935
{
936
    gen_mov_reg_V(dst, src);
937
    tcg_gen_xori_tl(dst, dst, 0x1);
938
}
939

    
940
/*
941
  FPSR bit field FCC1 | FCC0:
942
   0 =
943
   1 <
944
   2 >
945
   3 unordered
946
*/
947
static inline void gen_mov_reg_FCC0(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_FCC0_SHIFT + fcc_offset);
952
    tcg_gen_andi_tl(reg, reg, 0x1);
953
}
954

    
955
static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
956
                                    unsigned int fcc_offset)
957
{
958
    tcg_gen_extu_i32_tl(reg, src);
959
    tcg_gen_shri_tl(reg, reg, FSR_FCC1_SHIFT + fcc_offset);
960
    tcg_gen_andi_tl(reg, reg, 0x1);
961
}
962

    
963
// !0: FCC0 | FCC1
964
static inline void gen_op_eval_fbne(TCGv dst, TCGv src,
965
                                    unsigned int fcc_offset)
966
{
967
    gen_mov_reg_FCC0(dst, src, fcc_offset);
968
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
969
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
970
}
971

    
972
// 1 or 2: FCC0 ^ FCC1
973
static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
974
                                    unsigned int fcc_offset)
975
{
976
    gen_mov_reg_FCC0(dst, src, fcc_offset);
977
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
978
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
979
}
980

    
981
// 1 or 3: FCC0
982
static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
983
                                    unsigned int fcc_offset)
984
{
985
    gen_mov_reg_FCC0(dst, src, fcc_offset);
986
}
987

    
988
// 1: FCC0 & !FCC1
989
static inline void gen_op_eval_fbl(TCGv dst, TCGv src,
990
                                    unsigned int fcc_offset)
991
{
992
    gen_mov_reg_FCC0(dst, src, fcc_offset);
993
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
994
    tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
995
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
996
}
997

    
998
// 2 or 3: FCC1
999
static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
1000
                                    unsigned int fcc_offset)
1001
{
1002
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1003
}
1004

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

    
1015
// 3: FCC0 & FCC1
1016
static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
1017
                                    unsigned int fcc_offset)
1018
{
1019
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1020
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1021
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1022
}
1023

    
1024
// 0: !(FCC0 | FCC1)
1025
static inline void gen_op_eval_fbe(TCGv dst, TCGv src,
1026
                                    unsigned int fcc_offset)
1027
{
1028
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1029
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1030
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
1031
    tcg_gen_xori_tl(dst, dst, 0x1);
1032
}
1033

    
1034
// 0 or 3: !(FCC0 ^ FCC1)
1035
static inline void gen_op_eval_fbue(TCGv dst, TCGv src,
1036
                                    unsigned int fcc_offset)
1037
{
1038
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1039
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1040
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1041
    tcg_gen_xori_tl(dst, dst, 0x1);
1042
}
1043

    
1044
// 0 or 2: !FCC0
1045
static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
1046
                                    unsigned int fcc_offset)
1047
{
1048
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1049
    tcg_gen_xori_tl(dst, dst, 0x1);
1050
}
1051

    
1052
// !1: !(FCC0 & !FCC1)
1053
static inline void gen_op_eval_fbuge(TCGv dst, TCGv src,
1054
                                    unsigned int fcc_offset)
1055
{
1056
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1057
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1058
    tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
1059
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1060
    tcg_gen_xori_tl(dst, dst, 0x1);
1061
}
1062

    
1063
// 0 or 1: !FCC1
1064
static inline void gen_op_eval_fble(TCGv dst, TCGv src,
1065
                                    unsigned int fcc_offset)
1066
{
1067
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1068
    tcg_gen_xori_tl(dst, dst, 0x1);
1069
}
1070

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

    
1082
// !3: !(FCC0 & FCC1)
1083
static inline void gen_op_eval_fbo(TCGv dst, TCGv src,
1084
                                    unsigned int fcc_offset)
1085
{
1086
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1087
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1088
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1089
    tcg_gen_xori_tl(dst, dst, 0x1);
1090
}
1091

    
1092
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
1093
                               target_ulong pc2, TCGv r_cond)
1094
{
1095
    int l1;
1096

    
1097
    l1 = gen_new_label();
1098

    
1099
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1100

    
1101
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
1102

    
1103
    gen_set_label(l1);
1104
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
1105
}
1106

    
1107
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
1108
                                target_ulong pc2, TCGv r_cond)
1109
{
1110
    int l1;
1111

    
1112
    l1 = gen_new_label();
1113

    
1114
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1115

    
1116
    gen_goto_tb(dc, 0, pc2, pc1);
1117

    
1118
    gen_set_label(l1);
1119
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
1120
}
1121

    
1122
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
1123
                                      TCGv r_cond)
1124
{
1125
    int l1, l2;
1126

    
1127
    l1 = gen_new_label();
1128
    l2 = gen_new_label();
1129

    
1130
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1131

    
1132
    tcg_gen_movi_tl(cpu_npc, npc1);
1133
    tcg_gen_br(l2);
1134

    
1135
    gen_set_label(l1);
1136
    tcg_gen_movi_tl(cpu_npc, npc2);
1137
    gen_set_label(l2);
1138
}
1139

    
1140
/* call this function before using the condition register as it may
1141
   have been set for a jump */
1142
static inline void flush_cond(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
    }
1148
}
1149

    
1150
static inline void save_npc(DisasContext *dc, TCGv cond)
1151
{
1152
    if (dc->npc == JUMP_PC) {
1153
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1154
        dc->npc = DYNAMIC_PC;
1155
    } else if (dc->npc != DYNAMIC_PC) {
1156
        tcg_gen_movi_tl(cpu_npc, dc->npc);
1157
    }
1158
}
1159

    
1160
static inline void save_state(DisasContext *dc, TCGv cond)
1161
{
1162
    tcg_gen_movi_tl(cpu_pc, dc->pc);
1163
    save_npc(dc, cond);
1164
}
1165

    
1166
static inline void gen_mov_pc_npc(DisasContext *dc, TCGv cond)
1167
{
1168
    if (dc->npc == JUMP_PC) {
1169
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1170
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1171
        dc->pc = DYNAMIC_PC;
1172
    } else if (dc->npc == DYNAMIC_PC) {
1173
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1174
        dc->pc = DYNAMIC_PC;
1175
    } else {
1176
        dc->pc = dc->npc;
1177
    }
1178
}
1179

    
1180
static inline void gen_op_next_insn(void)
1181
{
1182
    tcg_gen_mov_tl(cpu_pc, cpu_npc);
1183
    tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
1184
}
1185

    
1186
static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond)
1187
{
1188
    TCGv r_src;
1189

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

    
1250
static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
1251
{
1252
    unsigned int offset;
1253

    
1254
    switch (cc) {
1255
    default:
1256
    case 0x0:
1257
        offset = 0;
1258
        break;
1259
    case 0x1:
1260
        offset = 32 - 10;
1261
        break;
1262
    case 0x2:
1263
        offset = 34 - 10;
1264
        break;
1265
    case 0x3:
1266
        offset = 36 - 10;
1267
        break;
1268
    }
1269

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

    
1322
#ifdef TARGET_SPARC64
1323
// Inverted logic
1324
static const int gen_tcg_cond_reg[8] = {
1325
    -1,
1326
    TCG_COND_NE,
1327
    TCG_COND_GT,
1328
    TCG_COND_GE,
1329
    -1,
1330
    TCG_COND_EQ,
1331
    TCG_COND_LE,
1332
    TCG_COND_LT,
1333
};
1334

    
1335
static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
1336
{
1337
    int l1;
1338

    
1339
    l1 = gen_new_label();
1340
    tcg_gen_movi_tl(r_dst, 0);
1341
    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], r_src, tcg_const_tl(0), l1);
1342
    tcg_gen_movi_tl(r_dst, 1);
1343
    gen_set_label(l1);
1344
}
1345
#endif
1346

    
1347
/* XXX: potentially incorrect if dynamic npc */
1348
static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1349
                      TCGv r_cond)
1350
{
1351
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1352
    target_ulong target = dc->pc + offset;
1353

    
1354
    if (cond == 0x0) {
1355
        /* unconditional not taken */
1356
        if (a) {
1357
            dc->pc = dc->npc + 4;
1358
            dc->npc = dc->pc + 4;
1359
        } else {
1360
            dc->pc = dc->npc;
1361
            dc->npc = dc->pc + 4;
1362
        }
1363
    } else if (cond == 0x8) {
1364
        /* unconditional taken */
1365
        if (a) {
1366
            dc->pc = target;
1367
            dc->npc = dc->pc + 4;
1368
        } else {
1369
            dc->pc = dc->npc;
1370
            dc->npc = target;
1371
        }
1372
    } else {
1373
        flush_cond(dc, r_cond);
1374
        gen_cond(r_cond, cc, cond);
1375
        if (a) {
1376
            gen_branch_a(dc, target, dc->npc, r_cond);
1377
            dc->is_br = 1;
1378
        } else {
1379
            dc->pc = dc->npc;
1380
            dc->jump_pc[0] = target;
1381
            dc->jump_pc[1] = dc->npc + 4;
1382
            dc->npc = JUMP_PC;
1383
        }
1384
    }
1385
}
1386

    
1387
/* XXX: potentially incorrect if dynamic npc */
1388
static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1389
                      TCGv r_cond)
1390
{
1391
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1392
    target_ulong target = dc->pc + offset;
1393

    
1394
    if (cond == 0x0) {
1395
        /* unconditional not taken */
1396
        if (a) {
1397
            dc->pc = dc->npc + 4;
1398
            dc->npc = dc->pc + 4;
1399
        } else {
1400
            dc->pc = dc->npc;
1401
            dc->npc = dc->pc + 4;
1402
        }
1403
    } else if (cond == 0x8) {
1404
        /* unconditional taken */
1405
        if (a) {
1406
            dc->pc = target;
1407
            dc->npc = dc->pc + 4;
1408
        } else {
1409
            dc->pc = dc->npc;
1410
            dc->npc = target;
1411
        }
1412
    } else {
1413
        flush_cond(dc, r_cond);
1414
        gen_fcond(r_cond, cc, cond);
1415
        if (a) {
1416
            gen_branch_a(dc, target, dc->npc, r_cond);
1417
            dc->is_br = 1;
1418
        } else {
1419
            dc->pc = dc->npc;
1420
            dc->jump_pc[0] = target;
1421
            dc->jump_pc[1] = dc->npc + 4;
1422
            dc->npc = JUMP_PC;
1423
        }
1424
    }
1425
}
1426

    
1427
#ifdef TARGET_SPARC64
1428
/* XXX: potentially incorrect if dynamic npc */
1429
static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
1430
                          TCGv r_cond, TCGv r_reg)
1431
{
1432
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1433
    target_ulong target = dc->pc + offset;
1434

    
1435
    flush_cond(dc, r_cond);
1436
    gen_cond_reg(r_cond, cond, r_reg);
1437
    if (a) {
1438
        gen_branch_a(dc, target, dc->npc, r_cond);
1439
        dc->is_br = 1;
1440
    } else {
1441
        dc->pc = dc->npc;
1442
        dc->jump_pc[0] = target;
1443
        dc->jump_pc[1] = dc->npc + 4;
1444
        dc->npc = JUMP_PC;
1445
    }
1446
}
1447

    
1448
static GenOpFunc * const gen_fcmps[4] = {
1449
    helper_fcmps,
1450
    helper_fcmps_fcc1,
1451
    helper_fcmps_fcc2,
1452
    helper_fcmps_fcc3,
1453
};
1454

    
1455
static GenOpFunc * const gen_fcmpd[4] = {
1456
    helper_fcmpd,
1457
    helper_fcmpd_fcc1,
1458
    helper_fcmpd_fcc2,
1459
    helper_fcmpd_fcc3,
1460
};
1461

    
1462
static GenOpFunc * const gen_fcmpq[4] = {
1463
    helper_fcmpq,
1464
    helper_fcmpq_fcc1,
1465
    helper_fcmpq_fcc2,
1466
    helper_fcmpq_fcc3,
1467
};
1468

    
1469
static GenOpFunc * const gen_fcmpes[4] = {
1470
    helper_fcmpes,
1471
    helper_fcmpes_fcc1,
1472
    helper_fcmpes_fcc2,
1473
    helper_fcmpes_fcc3,
1474
};
1475

    
1476
static GenOpFunc * const gen_fcmped[4] = {
1477
    helper_fcmped,
1478
    helper_fcmped_fcc1,
1479
    helper_fcmped_fcc2,
1480
    helper_fcmped_fcc3,
1481
};
1482

    
1483
static GenOpFunc * const gen_fcmpeq[4] = {
1484
    helper_fcmpeq,
1485
    helper_fcmpeq_fcc1,
1486
    helper_fcmpeq_fcc2,
1487
    helper_fcmpeq_fcc3,
1488
};
1489

    
1490
static inline void gen_op_fcmps(int fccno)
1491
{
1492
    tcg_gen_helper_0_0(gen_fcmps[fccno]);
1493
}
1494

    
1495
static inline void gen_op_fcmpd(int fccno)
1496
{
1497
    tcg_gen_helper_0_0(gen_fcmpd[fccno]);
1498
}
1499

    
1500
static inline void gen_op_fcmpq(int fccno)
1501
{
1502
    tcg_gen_helper_0_0(gen_fcmpq[fccno]);
1503
}
1504

    
1505
static inline void gen_op_fcmpes(int fccno)
1506
{
1507
    tcg_gen_helper_0_0(gen_fcmpes[fccno]);
1508
}
1509

    
1510
static inline void gen_op_fcmped(int fccno)
1511
{
1512
    tcg_gen_helper_0_0(gen_fcmped[fccno]);
1513
}
1514

    
1515
static inline void gen_op_fcmpeq(int fccno)
1516
{
1517
    tcg_gen_helper_0_0(gen_fcmpeq[fccno]);
1518
}
1519

    
1520
#else
1521

    
1522
static inline void gen_op_fcmps(int fccno)
1523
{
1524
    tcg_gen_helper_0_0(helper_fcmps);
1525
}
1526

    
1527
static inline void gen_op_fcmpd(int fccno)
1528
{
1529
    tcg_gen_helper_0_0(helper_fcmpd);
1530
}
1531

    
1532
static inline void gen_op_fcmpq(int fccno)
1533
{
1534
    tcg_gen_helper_0_0(helper_fcmpq);
1535
}
1536

    
1537
static inline void gen_op_fcmpes(int fccno)
1538
{
1539
    tcg_gen_helper_0_0(helper_fcmpes);
1540
}
1541

    
1542
static inline void gen_op_fcmped(int fccno)
1543
{
1544
    tcg_gen_helper_0_0(helper_fcmped);
1545
}
1546

    
1547
static inline void gen_op_fcmpeq(int fccno)
1548
{
1549
    tcg_gen_helper_0_0(helper_fcmpeq);
1550
}
1551
#endif
1552

    
1553
static inline void gen_op_fpexception_im(int fsr_flags)
1554
{
1555
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~FSR_FTT_MASK);
1556
    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
1557
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_FP_EXCP));
1558
}
1559

    
1560
static int gen_trap_ifnofpu(DisasContext *dc, TCGv r_cond)
1561
{
1562
#if !defined(CONFIG_USER_ONLY)
1563
    if (!dc->fpu_enabled) {
1564
        save_state(dc, r_cond);
1565
        tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_NFPU_INSN));
1566
        dc->is_br = 1;
1567
        return 1;
1568
    }
1569
#endif
1570
    return 0;
1571
}
1572

    
1573
static inline void gen_op_clear_ieee_excp_and_FTT(void)
1574
{
1575
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~(FSR_FTT_MASK | FSR_CEXC_MASK));
1576
}
1577

    
1578
static inline void gen_clear_float_exceptions(void)
1579
{
1580
    tcg_gen_helper_0_0(helper_clear_float_exceptions);
1581
}
1582

    
1583
/* asi moves */
1584
#ifdef TARGET_SPARC64
1585
static inline TCGv gen_get_asi(int insn, TCGv r_addr)
1586
{
1587
    int asi, offset;
1588
    TCGv r_asi;
1589

    
1590
    if (IS_IMM) {
1591
        r_asi = tcg_temp_new(TCG_TYPE_I32);
1592
        offset = GET_FIELD(insn, 25, 31);
1593
        tcg_gen_addi_tl(r_addr, r_addr, offset);
1594
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
1595
    } else {
1596
        asi = GET_FIELD(insn, 19, 26);
1597
        r_asi = tcg_const_i32(asi);
1598
    }
1599
    return r_asi;
1600
}
1601

    
1602
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size, int sign)
1603
{
1604
    TCGv r_asi;
1605

    
1606
    r_asi = gen_get_asi(insn, addr);
1607
    tcg_gen_helper_1_4(helper_ld_asi, dst, addr, r_asi,
1608
                       tcg_const_i32(size), tcg_const_i32(sign));
1609
}
1610

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

    
1615
    r_asi = gen_get_asi(insn, addr);
1616
    tcg_gen_helper_0_4(helper_st_asi, addr, src, r_asi, tcg_const_i32(size));
1617
}
1618

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

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

    
1628
static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
1629
{
1630
    TCGv r_asi;
1631

    
1632
    r_asi = gen_get_asi(insn, addr);
1633
    tcg_gen_helper_0_4(helper_stf_asi, addr, r_asi, tcg_const_i32(size),
1634
                       tcg_const_i32(rd));
1635
}
1636

    
1637
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1638
{
1639
    TCGv r_temp, r_asi;
1640

    
1641
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1642
    r_asi = gen_get_asi(insn, addr);
1643
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, addr, r_asi,
1644
                       tcg_const_i32(4), tcg_const_i32(0));
1645
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, r_asi,
1646
                       tcg_const_i32(4));
1647
    tcg_gen_extu_i32_tl(dst, r_temp);
1648
}
1649

    
1650
static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn)
1651
{
1652
    TCGv r_asi;
1653

    
1654
    r_asi = gen_get_asi(insn, addr);
1655
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi,
1656
                       tcg_const_i32(8), tcg_const_i32(0));
1657
    tcg_gen_andi_i64(lo, cpu_tmp64, 0xffffffffULL);
1658
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1659
    tcg_gen_andi_i64(hi, cpu_tmp64, 0xffffffffULL);
1660
}
1661

    
1662
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1663
{
1664
    TCGv r_temp, r_asi;
1665

    
1666
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1667
    gen_movl_reg_TN(rd + 1, r_temp);
1668
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi,
1669
                       r_temp);
1670
    r_asi = gen_get_asi(insn, addr);
1671
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi,
1672
                       tcg_const_i32(8));
1673
}
1674

    
1675
static inline void gen_cas_asi(TCGv dst, TCGv addr, TCGv val2, int insn, int rd)
1676
{
1677
    TCGv r_val1, r_asi;
1678

    
1679
    r_val1 = tcg_temp_new(TCG_TYPE_I32);
1680
    gen_movl_reg_TN(rd, r_val1);
1681
    r_asi = gen_get_asi(insn, addr);
1682
    tcg_gen_helper_1_4(helper_cas_asi, dst, addr, r_val1, val2, r_asi);
1683
}
1684

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

    
1689
    gen_movl_reg_TN(rd, cpu_tmp64);
1690
    r_asi = gen_get_asi(insn, addr);
1691
    tcg_gen_helper_1_4(helper_casx_asi, dst, addr, cpu_tmp64, val2, r_asi);
1692
}
1693

    
1694
#elif !defined(CONFIG_USER_ONLY)
1695

    
1696
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size, int sign)
1697
{
1698
    int asi;
1699

    
1700
    asi = GET_FIELD(insn, 19, 26);
1701
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, tcg_const_i32(asi),
1702
                       tcg_const_i32(size), tcg_const_i32(sign));
1703
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1704
}
1705

    
1706
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1707
{
1708
    int asi;
1709

    
1710
    tcg_gen_extu_tl_i64(cpu_tmp64, src);
1711
    asi = GET_FIELD(insn, 19, 26);
1712
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, tcg_const_i32(asi),
1713
                       tcg_const_i32(size));
1714
}
1715

    
1716
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1717
{
1718
    int asi;
1719
    TCGv r_temp;
1720

    
1721
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1722
    asi = GET_FIELD(insn, 19, 26);
1723
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, addr, tcg_const_i32(asi),
1724
                       tcg_const_i32(4), tcg_const_i32(0));
1725
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, tcg_const_i32(asi),
1726
                       tcg_const_i32(4));
1727
    tcg_gen_extu_i32_tl(dst, r_temp);
1728
}
1729

    
1730
static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn)
1731
{
1732
    int asi;
1733

    
1734
    asi = GET_FIELD(insn, 19, 26);
1735
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, tcg_const_i32(asi),
1736
                       tcg_const_i32(8), tcg_const_i32(0));
1737
    tcg_gen_trunc_i64_tl(lo, cpu_tmp64);
1738
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1739
    tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
1740
}
1741

    
1742
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1743
{
1744
    int asi;
1745
    TCGv r_temp;
1746

    
1747
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1748
    gen_movl_reg_TN(rd + 1, r_temp);
1749
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi, r_temp);
1750
    asi = GET_FIELD(insn, 19, 26);
1751
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, tcg_const_i32(asi),
1752
                       tcg_const_i32(8));
1753
}
1754
#endif
1755

    
1756
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1757
static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
1758
{
1759
    int asi;
1760

    
1761
    gen_ld_asi(dst, addr, insn, 1, 0);
1762

    
1763
    asi = GET_FIELD(insn, 19, 26);
1764
    tcg_gen_helper_0_4(helper_st_asi, addr, tcg_const_i64(0xffULL),
1765
                       tcg_const_i32(asi), tcg_const_i32(1));
1766
}
1767
#endif
1768

    
1769
static inline TCGv get_src1(unsigned int insn, TCGv def)
1770
{
1771
    TCGv r_rs1 = def;
1772
    unsigned int rs1;
1773

    
1774
    rs1 = GET_FIELD(insn, 13, 17);
1775
    if (rs1 == 0)
1776
        //r_rs1 = tcg_const_tl(0);
1777
        tcg_gen_movi_tl(def, 0);
1778
    else if (rs1 < 8)
1779
        //r_rs1 = cpu_gregs[rs1];
1780
        tcg_gen_mov_tl(def, cpu_gregs[rs1]);
1781
    else
1782
        tcg_gen_ld_tl(def, cpu_regwptr, (rs1 - 8) * sizeof(target_ulong));
1783
    return r_rs1;
1784
}
1785

    
1786
static inline TCGv get_src2(unsigned int insn, TCGv def)
1787
{
1788
    TCGv r_rs2 = def;
1789
    unsigned int rs2;
1790

    
1791
    if (IS_IMM) { /* immediate */
1792
        rs2 = GET_FIELDs(insn, 19, 31);
1793
        r_rs2 = tcg_const_tl((int)rs2);
1794
    } else { /* register */
1795
        rs2 = GET_FIELD(insn, 27, 31);
1796
        if (rs2 == 0)
1797
            r_rs2 = tcg_const_tl(0);
1798
        else if (rs2 < 8)
1799
            r_rs2 = cpu_gregs[rs2];
1800
        else
1801
            tcg_gen_ld_tl(def, cpu_regwptr, (rs2 - 8) * sizeof(target_ulong));
1802
    }
1803
    return r_rs2;
1804
}
1805

    
1806
#define CHECK_IU_FEATURE(dc, FEATURE)                      \
1807
    if (!((dc)->features & CPU_FEATURE_ ## FEATURE))       \
1808
        goto illegal_insn;
1809
#define CHECK_FPU_FEATURE(dc, FEATURE)                     \
1810
    if (!((dc)->features & CPU_FEATURE_ ## FEATURE))       \
1811
        goto nfpu_insn;
1812

    
1813
/* before an instruction, dc->pc must be static */
1814
static void disas_sparc_insn(DisasContext * dc)
1815
{
1816
    unsigned int insn, opc, rs1, rs2, rd;
1817

    
1818
    insn = ldl_code(dc->pc);
1819
    opc = GET_FIELD(insn, 0, 1);
1820

    
1821
    rd = GET_FIELD(insn, 2, 6);
1822

    
1823
    cpu_dst = cpu_T[0];
1824
    cpu_src1 = cpu_T[0]; // const
1825
    cpu_src2 = cpu_T[1]; // const
1826

    
1827
    // loads and stores
1828
    cpu_addr = cpu_T[0];
1829
    cpu_val = cpu_T[1];
1830

    
1831
    switch (opc) {
1832
    case 0:                     /* branches/sethi */
1833
        {
1834
            unsigned int xop = GET_FIELD(insn, 7, 9);
1835
            int32_t target;
1836
            switch (xop) {
1837
#ifdef TARGET_SPARC64
1838
            case 0x1:           /* V9 BPcc */
1839
                {
1840
                    int cc;
1841

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

    
1916
            gen_movl_TN_reg(15, tcg_const_tl(dc->pc));
1917
            target += dc->pc;
1918
            gen_mov_pc_npc(dc, cpu_cond);
1919
            dc->npc = target;
1920
        }
1921
        goto jmp_insn;
1922
    case 2:                     /* FPU & Logical Operations */
1923
        {
1924
            unsigned int xop = GET_FIELD(insn, 7, 12);
1925
            if (xop == 0x3a) {  /* generate trap */
1926
                int cond;
1927

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

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

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

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

    
2101
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2102
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2103
                                       offsetof(CPUState, tsptr));
2104
                        tcg_gen_ld_tl(cpu_dst, r_tsptr,
2105
                                      offsetof(trap_state, tpc));
2106
                    }
2107
                    break;
2108
                case 1: // tnpc
2109
                    {
2110
                        TCGv r_tsptr;
2111

    
2112
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2113
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2114
                                       offsetof(CPUState, tsptr));
2115
                        tcg_gen_ld_tl(cpu_dst, r_tsptr,
2116
                                      offsetof(trap_state, tnpc));
2117
                    }
2118
                    break;
2119
                case 2: // tstate
2120
                    {
2121
                        TCGv r_tsptr;
2122

    
2123
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2124
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2125
                                       offsetof(CPUState, tsptr));
2126
                        tcg_gen_ld_tl(cpu_dst, r_tsptr,
2127
                                      offsetof(trap_state, tstate));
2128
                    }
2129
                    break;
2130
                case 3: // tt
2131
                    {
2132
                        TCGv r_tsptr;
2133

    
2134
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2135
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2136
                                       offsetof(CPUState, tsptr));
2137
                        tcg_gen_ld_i32(cpu_dst, r_tsptr,
2138
                                       offsetof(trap_state, tt));
2139
                    }
2140
                    break;
2141
                case 4: // tick
2142
                    {
2143
                        TCGv r_tickptr;
2144

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

    
2565
                    l1 = gen_new_label();
2566
                    cond = GET_FIELD_SP(insn, 14, 17);
2567
                    cpu_src1 = get_src1(insn, cpu_src1);
2568
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_src1,
2569
                                      tcg_const_tl(0), l1);
2570
                    gen_op_load_fpr_FT0(rs2);
2571
                    gen_op_store_FT0_fpr(rd);
2572
                    gen_set_label(l1);
2573
                    break;
2574
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
2575
                    int l1;
2576

    
2577
                    l1 = gen_new_label();
2578
                    cond = GET_FIELD_SP(insn, 14, 17);
2579
                    cpu_src1 = get_src1(insn, cpu_src1);
2580
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_src1,
2581
                                      tcg_const_tl(0), l1);
2582
                    gen_op_load_fpr_DT0(DFPREG(rs2));
2583
                    gen_op_store_DT0_fpr(DFPREG(rd));
2584
                    gen_set_label(l1);
2585
                    break;
2586
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
2587
                    int l1;
2588

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

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

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

    
3038
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
3039
                                                   cpu_src2);
3040
                                    tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState,
3041
                                                                 tick_cmpr));
3042
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3043
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3044
                                                   offsetof(CPUState, tick));
3045
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3046
                                                       r_tickptr, cpu_dst);
3047
                                }
3048
                                break;
3049
                            case 0x18: /* System tick */
3050
#if !defined(CONFIG_USER_ONLY)
3051
                                if (!supervisor(dc))
3052
                                    goto illegal_insn;
3053
#endif
3054
                                {
3055
                                    TCGv r_tickptr;
3056

    
3057
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
3058
                                                   cpu_src2);
3059
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3060
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3061
                                                   offsetof(CPUState, stick));
3062
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3063
                                                       r_tickptr, cpu_dst);
3064
                                }
3065
                                break;
3066
                            case 0x19: /* System tick compare */
3067
#if !defined(CONFIG_USER_ONLY)
3068
                                if (!supervisor(dc))
3069
                                    goto illegal_insn;
3070
#endif
3071
                                {
3072
                                    TCGv r_tickptr;
3073

    
3074
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
3075
                                                   cpu_src2);
3076
                                    tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState,
3077
                                                                 stick_cmpr));
3078
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3079
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3080
                                                   offsetof(CPUState, stick));
3081
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3082
                                                       r_tickptr, cpu_dst);
3083
                                }
3084
                                break;
3085

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

    
3140
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3141
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3142
                                                   offsetof(CPUState, tsptr));
3143
                                    tcg_gen_st_tl(cpu_dst, r_tsptr,
3144
                                                  offsetof(trap_state, tpc));
3145
                                }
3146
                                break;
3147
                            case 1: // tnpc
3148
                                {
3149
                                    TCGv r_tsptr;
3150

    
3151
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3152
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3153
                                                   offsetof(CPUState, tsptr));
3154
                                    tcg_gen_st_tl(cpu_dst, r_tsptr,
3155
                                                  offsetof(trap_state, tnpc));
3156
                                }
3157
                                break;
3158
                            case 2: // tstate
3159
                                {
3160
                                    TCGv r_tsptr;
3161

    
3162
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3163
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3164
                                                   offsetof(CPUState, tsptr));
3165
                                    tcg_gen_st_tl(cpu_dst, r_tsptr,
3166
                                                  offsetof(trap_state, tstate));
3167
                                }
3168
                                break;
3169
                            case 3: // tt
3170
                                {
3171
                                    TCGv r_tsptr;
3172

    
3173
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3174
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3175
                                                   offsetof(CPUState, tsptr));
3176
                                    tcg_gen_st_i32(cpu_dst, r_tsptr,
3177
                                                   offsetof(trap_state, tt));
3178
                                }
3179
                                break;
3180
                            case 4: // tick
3181
                                {
3182
                                    TCGv r_tickptr;
3183

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

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

    
3311
                            r_cond = tcg_temp_new(TCG_TYPE_TL);
3312
                            if (insn & (1 << 18)) {
3313
                                if (cc == 0)
3314
                                    gen_cond(r_cond, 0, cond);
3315
                                else if (cc == 2)
3316
                                    gen_cond(r_cond, 1, cond);
3317
                                else
3318
                                    goto illegal_insn;
3319
                            } else {
3320
                                gen_fcond(r_cond, cc, cond);
3321
                            }
3322

    
3323
                            l1 = gen_new_label();
3324

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

    
3354
                            cpu_src1 = get_src1(insn, cpu_src1);
3355

    
3356
                            l1 = gen_new_label();
3357

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

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

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

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

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

    
4438
static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
4439
{
4440
}
4441

    
4442
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
4443
                                                 int spc, CPUSPARCState *env)
4444
{
4445
    target_ulong pc_start, last_pc;
4446
    uint16_t *gen_opc_end;
4447
    DisasContext dc1, *dc = &dc1;
4448
    int j, lj = -1;
4449

    
4450
    memset(dc, 0, sizeof(DisasContext));
4451
    dc->tb = tb;
4452
    pc_start = tb->pc;
4453
    dc->pc = pc_start;
4454
    last_pc = dc->pc;
4455
    dc->npc = (target_ulong) tb->cs_base;
4456
    dc->mem_idx = cpu_mmu_index(env);
4457
    dc->features = env->features;
4458
    if ((dc->features & CPU_FEATURE_FLOAT)) {
4459
        dc->fpu_enabled = cpu_fpu_enabled(env);
4460
#if defined(CONFIG_USER_ONLY)
4461
        dc->features |= CPU_FEATURE_FLOAT128;
4462
#endif
4463
    } else
4464
        dc->fpu_enabled = 0;
4465
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4466

    
4467
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
4468
    cpu_tmp32 = tcg_temp_new(TCG_TYPE_I32);
4469
    cpu_tmp64 = tcg_temp_new(TCG_TYPE_I64);
4470

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

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

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

    
4559
int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
4560
{
4561
    return gen_intermediate_code_internal(tb, 0, env);
4562
}
4563

    
4564
int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
4565
{
4566
    return gen_intermediate_code_internal(tb, 1, env);
4567
}
4568

    
4569
void gen_intermediate_code_init(CPUSPARCState *env)
4570
{
4571
    unsigned int i;
4572
    static int inited;
4573
    static const char * const gregnames[8] = {
4574
        NULL, // g0 not used
4575
        "g1",
4576
        "g2",
4577
        "g3",
4578
        "g4",
4579
        "g5",
4580
        "g6",
4581
        "g7",
4582
    };
4583

    
4584
    /* init various static tables */
4585
    if (!inited) {
4586
        inited = 1;
4587

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

    
4633
void gen_pc_load(CPUState *env, TranslationBlock *tb,
4634
                unsigned long searched_pc, int pc_pos, void *puc)
4635
{
4636
    target_ulong npc;
4637
    env->pc = gen_opc_pc[pc_pos];
4638
    npc = gen_opc_npc[pc_pos];
4639
    if (npc == 1) {
4640
        /* dynamic NPC: already stored */
4641
    } else if (npc == 2) {
4642
        target_ulong t2 = (target_ulong)(unsigned long)puc;
4643
        /* jump PC: use T2 and the jump targets of the translation */
4644
        if (t2)
4645
            env->npc = gen_opc_jump_pc[0];
4646
        else
4647
            env->npc = gen_opc_jump_pc[1];
4648
    } else {
4649
        env->npc = npc;
4650
    }
4651
}