Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ c5f2f668

History | View | Annotate | Download (184.3 kB)

1
/*
2
   SPARC translation
3

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

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

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

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

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

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

    
34
#define DEBUG_DISAS
35

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

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

    
51
#include "gen-icount.h"
52

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

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

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

    
72
#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
73
#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
74

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

    
85
static int sign_extend(int x, int len)
86
{
87
    len = 32 - len;
88
    return (x << len) >> len;
89
}
90

    
91
#define IS_IMM (insn & (1<<13))
92

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

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

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

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

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

    
132
static void gen_op_store_DT0_fpr(unsigned int dst)
133
{
134
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) +
135
                   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) +
138
                   offsetof(CPU_DoubleU, l.lower));
139
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 1]));
140
}
141

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

    
158
static void gen_op_load_fpr_QT1(unsigned int src)
159
{
160
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
161
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) +
162
                   offsetof(CPU_QuadU, l.upmost));
163
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
164
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) +
165
                   offsetof(CPU_QuadU, l.upper));
166
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 2]));
167
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) +
168
                   offsetof(CPU_QuadU, l.lower));
169
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 3]));
170
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) +
171
                   offsetof(CPU_QuadU, l.lowest));
172
}
173

    
174
static void gen_op_store_QT0_fpr(unsigned int dst)
175
{
176
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) +
177
                   offsetof(CPU_QuadU, l.upmost));
178
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst]));
179
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) +
180
                   offsetof(CPU_QuadU, l.upper));
181
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 1]));
182
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) +
183
                   offsetof(CPU_QuadU, l.lower));
184
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 2]));
185
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) +
186
                   offsetof(CPU_QuadU, l.lowest));
187
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 3]));
188
}
189

    
190
/* moves */
191
#ifdef CONFIG_USER_ONLY
192
#define supervisor(dc) 0
193
#ifdef TARGET_SPARC64
194
#define hypervisor(dc) 0
195
#endif
196
#else
197
#define supervisor(dc) (dc->mem_idx >= 1)
198
#ifdef TARGET_SPARC64
199
#define hypervisor(dc) (dc->mem_idx == 2)
200
#else
201
#endif
202
#endif
203

    
204
#ifdef TARGET_ABI32
205
#define ABI32_MASK(addr) tcg_gen_andi_tl(addr, addr, 0xffffffffULL);
206
#else
207
#define ABI32_MASK(addr)
208
#endif
209

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

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

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

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

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

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

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

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

    
282
static inline void gen_cc_clear_icc(void)
283
{
284
    tcg_gen_movi_i32(cpu_psr, 0);
285
}
286

    
287
#ifdef TARGET_SPARC64
288
static inline void gen_cc_clear_xcc(void)
289
{
290
    tcg_gen_movi_i32(cpu_xcc, 0);
291
}
292
#endif
293

    
294
/* old op:
295
    if (!T0)
296
        env->psr |= PSR_ZERO;
297
    if ((int32_t) T0 < 0)
298
        env->psr |= PSR_NEG;
299
*/
300
static inline void gen_cc_NZ_icc(TCGv dst)
301
{
302
    TCGv r_temp;
303
    int l1, l2;
304

    
305
    l1 = gen_new_label();
306
    l2 = gen_new_label();
307
    r_temp = tcg_temp_new(TCG_TYPE_TL);
308
    tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
309
    tcg_gen_brcondi_tl(TCG_COND_NE, r_temp, 0, l1);
310
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_ZERO);
311
    gen_set_label(l1);
312
    tcg_gen_ext_i32_tl(r_temp, dst);
313
    tcg_gen_brcondi_tl(TCG_COND_GE, r_temp, 0, l2);
314
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_NEG);
315
    gen_set_label(l2);
316
    tcg_temp_free(r_temp);
317
}
318

    
319
#ifdef TARGET_SPARC64
320
static inline void gen_cc_NZ_xcc(TCGv dst)
321
{
322
    int l1, l2;
323

    
324
    l1 = gen_new_label();
325
    l2 = gen_new_label();
326
    tcg_gen_brcondi_tl(TCG_COND_NE, dst, 0, l1);
327
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_ZERO);
328
    gen_set_label(l1);
329
    tcg_gen_brcondi_tl(TCG_COND_GE, dst, 0, l2);
330
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_NEG);
331
    gen_set_label(l2);
332
}
333
#endif
334

    
335
/* old op:
336
    if (T0 < src1)
337
        env->psr |= PSR_CARRY;
338
*/
339
static inline void gen_cc_C_add_icc(TCGv dst, TCGv src1)
340
{
341
    TCGv r_temp;
342
    int l1;
343

    
344
    l1 = gen_new_label();
345
    r_temp = tcg_temp_new(TCG_TYPE_TL);
346
    tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
347
    tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l1);
348
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
349
    gen_set_label(l1);
350
    tcg_temp_free(r_temp);
351
}
352

    
353
#ifdef TARGET_SPARC64
354
static inline void gen_cc_C_add_xcc(TCGv dst, TCGv src1)
355
{
356
    int l1;
357

    
358
    l1 = gen_new_label();
359
    tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l1);
360
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
361
    gen_set_label(l1);
362
}
363
#endif
364

    
365
/* old op:
366
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
367
        env->psr |= PSR_OVF;
368
*/
369
static inline void gen_cc_V_add_icc(TCGv dst, TCGv src1, TCGv src2)
370
{
371
    TCGv r_temp;
372

    
373
    r_temp = tcg_temp_new(TCG_TYPE_TL);
374
    tcg_gen_xor_tl(r_temp, src1, src2);
375
    tcg_gen_xori_tl(r_temp, r_temp, -1);
376
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
377
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
378
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
379
    tcg_gen_shri_tl(r_temp, r_temp, 31 - PSR_OVF_SHIFT);
380
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
381
    tcg_temp_free(r_temp);
382
    tcg_gen_or_i32(cpu_psr, cpu_psr, cpu_tmp32);
383
}
384

    
385
#ifdef TARGET_SPARC64
386
static inline void gen_cc_V_add_xcc(TCGv dst, TCGv src1, TCGv src2)
387
{
388
    TCGv r_temp;
389

    
390
    r_temp = tcg_temp_new(TCG_TYPE_TL);
391
    tcg_gen_xor_tl(r_temp, src1, src2);
392
    tcg_gen_xori_tl(r_temp, r_temp, -1);
393
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
394
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
395
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
396
    tcg_gen_shri_tl(r_temp, r_temp, 63 - PSR_OVF_SHIFT);
397
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
398
    tcg_temp_free(r_temp);
399
    tcg_gen_or_i32(cpu_xcc, cpu_xcc, cpu_tmp32);
400
}
401
#endif
402

    
403
static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
404
{
405
    TCGv r_temp, r_const;
406
    int l1;
407

    
408
    l1 = gen_new_label();
409

    
410
    r_temp = tcg_temp_new(TCG_TYPE_TL);
411
    tcg_gen_xor_tl(r_temp, src1, src2);
412
    tcg_gen_xori_tl(r_temp, r_temp, -1);
413
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
414
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
415
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
416
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
417
    r_const = tcg_const_i32(TT_TOVF);
418
    tcg_gen_helper_0_1(raise_exception, r_const);
419
    tcg_temp_free(r_const);
420
    gen_set_label(l1);
421
    tcg_temp_free(r_temp);
422
}
423

    
424
static inline void gen_cc_V_tag(TCGv src1, TCGv src2)
425
{
426
    int l1;
427

    
428
    l1 = gen_new_label();
429
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
430
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
431
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
432
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
433
    gen_set_label(l1);
434
}
435

    
436
static inline void gen_tag_tv(TCGv src1, TCGv src2)
437
{
438
    int l1;
439
    TCGv r_const;
440

    
441
    l1 = gen_new_label();
442
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
443
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
444
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
445
    r_const = tcg_const_i32(TT_TOVF);
446
    tcg_gen_helper_0_1(raise_exception, r_const);
447
    tcg_temp_free(r_const);
448
    gen_set_label(l1);
449
}
450

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

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

    
493
static inline void gen_op_tadd_cc(TCGv dst, TCGv src1, TCGv src2)
494
{
495
    tcg_gen_mov_tl(cpu_cc_src, src1);
496
    tcg_gen_mov_tl(cpu_cc_src2, src2);
497
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
498
    gen_cc_clear_icc();
499
    gen_cc_NZ_icc(cpu_cc_dst);
500
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
501
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
502
    gen_cc_V_tag(cpu_cc_src, cpu_cc_src2);
503
#ifdef TARGET_SPARC64
504
    gen_cc_clear_xcc();
505
    gen_cc_NZ_xcc(cpu_cc_dst);
506
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
507
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
508
#endif
509
    tcg_gen_mov_tl(dst, cpu_cc_dst);
510
}
511

    
512
static inline void gen_op_tadd_ccTV(TCGv dst, TCGv src1, TCGv src2)
513
{
514
    tcg_gen_mov_tl(cpu_cc_src, src1);
515
    tcg_gen_mov_tl(cpu_cc_src2, src2);
516
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
517
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
518
    gen_add_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
519
    gen_cc_clear_icc();
520
    gen_cc_NZ_icc(cpu_cc_dst);
521
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
522
#ifdef TARGET_SPARC64
523
    gen_cc_clear_xcc();
524
    gen_cc_NZ_xcc(cpu_cc_dst);
525
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
526
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
527
#endif
528
    tcg_gen_mov_tl(dst, cpu_cc_dst);
529
}
530

    
531
/* old op:
532
    if (src1 < T1)
533
        env->psr |= PSR_CARRY;
534
*/
535
static inline void gen_cc_C_sub_icc(TCGv src1, TCGv src2)
536
{
537
    TCGv r_temp1, r_temp2;
538
    int l1;
539

    
540
    l1 = gen_new_label();
541
    r_temp1 = tcg_temp_new(TCG_TYPE_TL);
542
    r_temp2 = tcg_temp_new(TCG_TYPE_TL);
543
    tcg_gen_andi_tl(r_temp1, src1, 0xffffffffULL);
544
    tcg_gen_andi_tl(r_temp2, src2, 0xffffffffULL);
545
    tcg_gen_brcond_tl(TCG_COND_GEU, r_temp1, r_temp2, l1);
546
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
547
    gen_set_label(l1);
548
    tcg_temp_free(r_temp1);
549
    tcg_temp_free(r_temp2);
550
}
551

    
552
#ifdef TARGET_SPARC64
553
static inline void gen_cc_C_sub_xcc(TCGv src1, TCGv src2)
554
{
555
    int l1;
556

    
557
    l1 = gen_new_label();
558
    tcg_gen_brcond_tl(TCG_COND_GEU, src1, src2, l1);
559
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
560
    gen_set_label(l1);
561
}
562
#endif
563

    
564
/* old op:
565
    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
566
        env->psr |= PSR_OVF;
567
*/
568
static inline void gen_cc_V_sub_icc(TCGv dst, TCGv src1, TCGv src2)
569
{
570
    TCGv r_temp;
571

    
572
    r_temp = tcg_temp_new(TCG_TYPE_TL);
573
    tcg_gen_xor_tl(r_temp, src1, src2);
574
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
575
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
576
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
577
    tcg_gen_shri_tl(r_temp, r_temp, 31 - PSR_OVF_SHIFT);
578
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
579
    tcg_gen_or_i32(cpu_psr, cpu_psr, cpu_tmp32);
580
    tcg_temp_free(r_temp);
581
}
582

    
583
#ifdef TARGET_SPARC64
584
static inline void gen_cc_V_sub_xcc(TCGv dst, TCGv src1, TCGv src2)
585
{
586
    TCGv r_temp;
587

    
588
    r_temp = tcg_temp_new(TCG_TYPE_TL);
589
    tcg_gen_xor_tl(r_temp, src1, src2);
590
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
591
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
592
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
593
    tcg_gen_shri_tl(r_temp, r_temp, 63 - PSR_OVF_SHIFT);
594
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
595
    tcg_gen_or_i32(cpu_xcc, cpu_xcc, cpu_tmp32);
596
    tcg_temp_free(r_temp);
597
}
598
#endif
599

    
600
static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
601
{
602
    TCGv r_temp, r_const;
603
    int l1;
604

    
605
    l1 = gen_new_label();
606

    
607
    r_temp = tcg_temp_new(TCG_TYPE_TL);
608
    tcg_gen_xor_tl(r_temp, src1, src2);
609
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
610
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
611
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
612
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
613
    r_const = tcg_const_i32(TT_TOVF);
614
    tcg_gen_helper_0_1(raise_exception, r_const);
615
    tcg_temp_free(r_const);
616
    gen_set_label(l1);
617
    tcg_temp_free(r_temp);
618
}
619

    
620
static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2)
621
{
622
    tcg_gen_mov_tl(cpu_cc_src, src1);
623
    tcg_gen_mov_tl(cpu_cc_src2, src2);
624
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
625
    gen_cc_clear_icc();
626
    gen_cc_NZ_icc(cpu_cc_dst);
627
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
628
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
629
#ifdef TARGET_SPARC64
630
    gen_cc_clear_xcc();
631
    gen_cc_NZ_xcc(cpu_cc_dst);
632
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
633
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
634
#endif
635
    tcg_gen_mov_tl(dst, cpu_cc_dst);
636
}
637

    
638
static inline void gen_op_subx_cc(TCGv dst, TCGv src1, TCGv src2)
639
{
640
    tcg_gen_mov_tl(cpu_cc_src, src1);
641
    tcg_gen_mov_tl(cpu_cc_src2, src2);
642
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
643
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_tmp0);
644
    gen_cc_clear_icc();
645
    gen_cc_C_sub_icc(cpu_cc_dst, cpu_cc_src);
646
#ifdef TARGET_SPARC64
647
    gen_cc_clear_xcc();
648
    gen_cc_C_sub_xcc(cpu_cc_dst, cpu_cc_src);
649
#endif
650
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_dst, cpu_cc_src2);
651
    gen_cc_NZ_icc(cpu_cc_dst);
652
    gen_cc_C_sub_icc(cpu_cc_dst, cpu_cc_src);
653
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
654
#ifdef TARGET_SPARC64
655
    gen_cc_NZ_xcc(cpu_cc_dst);
656
    gen_cc_C_sub_xcc(cpu_cc_dst, cpu_cc_src);
657
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
658
#endif
659
    tcg_gen_mov_tl(dst, cpu_cc_dst);
660
}
661

    
662
static inline void gen_op_tsub_cc(TCGv dst, TCGv src1, TCGv src2)
663
{
664
    tcg_gen_mov_tl(cpu_cc_src, src1);
665
    tcg_gen_mov_tl(cpu_cc_src2, src2);
666
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
667
    gen_cc_clear_icc();
668
    gen_cc_NZ_icc(cpu_cc_dst);
669
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
670
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
671
    gen_cc_V_tag(cpu_cc_src, cpu_cc_src2);
672
#ifdef TARGET_SPARC64
673
    gen_cc_clear_xcc();
674
    gen_cc_NZ_xcc(cpu_cc_dst);
675
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
676
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
677
#endif
678
    tcg_gen_mov_tl(dst, cpu_cc_dst);
679
}
680

    
681
static inline void gen_op_tsub_ccTV(TCGv dst, TCGv src1, TCGv src2)
682
{
683
    tcg_gen_mov_tl(cpu_cc_src, src1);
684
    tcg_gen_mov_tl(cpu_cc_src2, src2);
685
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
686
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
687
    gen_sub_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
688
    gen_cc_clear_icc();
689
    gen_cc_NZ_icc(cpu_cc_dst);
690
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
691
#ifdef TARGET_SPARC64
692
    gen_cc_clear_xcc();
693
    gen_cc_NZ_xcc(cpu_cc_dst);
694
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
695
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
696
#endif
697
    tcg_gen_mov_tl(dst, cpu_cc_dst);
698
}
699

    
700
static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
701
{
702
    TCGv r_temp, r_temp2;
703
    int l1;
704

    
705
    l1 = gen_new_label();
706
    r_temp = tcg_temp_new(TCG_TYPE_TL);
707
    r_temp2 = tcg_temp_new(TCG_TYPE_I32);
708

    
709
    /* old op:
710
    if (!(env->y & 1))
711
        T1 = 0;
712
    */
713
    tcg_gen_mov_tl(cpu_cc_src, src1);
714
    tcg_gen_ld32u_tl(r_temp, cpu_env, offsetof(CPUSPARCState, y));
715
    tcg_gen_trunc_tl_i32(r_temp2, r_temp);
716
    tcg_gen_andi_i32(r_temp2, r_temp2, 0x1);
717
    tcg_gen_mov_tl(cpu_cc_src2, src2);
718
    tcg_gen_brcondi_i32(TCG_COND_NE, r_temp2, 0, l1);
719
    tcg_gen_movi_tl(cpu_cc_src2, 0);
720
    gen_set_label(l1);
721

    
722
    // b2 = T0 & 1;
723
    // env->y = (b2 << 31) | (env->y >> 1);
724
    tcg_gen_trunc_tl_i32(r_temp2, cpu_cc_src);
725
    tcg_gen_andi_i32(r_temp2, r_temp2, 0x1);
726
    tcg_gen_shli_i32(r_temp2, r_temp2, 31);
727
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, y));
728
    tcg_gen_shri_i32(cpu_tmp32, cpu_tmp32, 1);
729
    tcg_gen_or_i32(cpu_tmp32, cpu_tmp32, r_temp2);
730
    tcg_temp_free(r_temp2);
731
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, y));
732

    
733
    // b1 = N ^ V;
734
    gen_mov_reg_N(cpu_tmp0, cpu_psr);
735
    gen_mov_reg_V(r_temp, cpu_psr);
736
    tcg_gen_xor_tl(cpu_tmp0, cpu_tmp0, r_temp);
737
    tcg_temp_free(r_temp);
738

    
739
    // T0 = (b1 << 31) | (T0 >> 1);
740
    // src1 = T0;
741
    tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
742
    tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
743
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
744

    
745
    /* do addition and update flags */
746
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
747

    
748
    gen_cc_clear_icc();
749
    gen_cc_NZ_icc(cpu_cc_dst);
750
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
751
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
752
    tcg_gen_mov_tl(dst, cpu_cc_dst);
753
}
754

    
755
static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
756
{
757
    TCGv r_temp, r_temp2;
758

    
759
    r_temp = tcg_temp_new(TCG_TYPE_I64);
760
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);
761

    
762
    tcg_gen_extu_tl_i64(r_temp, src2);
763
    tcg_gen_extu_tl_i64(r_temp2, src1);
764
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
765

    
766
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
767
    tcg_gen_trunc_i64_i32(r_temp, r_temp);
768
    tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
769
    tcg_temp_free(r_temp);
770
#ifdef TARGET_SPARC64
771
    tcg_gen_mov_i64(dst, r_temp2);
772
#else
773
    tcg_gen_trunc_i64_tl(dst, r_temp2);
774
#endif
775
    tcg_temp_free(r_temp2);
776
}
777

    
778
static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
779
{
780
    TCGv r_temp, r_temp2;
781

    
782
    r_temp = tcg_temp_new(TCG_TYPE_I64);
783
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);
784

    
785
    tcg_gen_ext_tl_i64(r_temp, src2);
786
    tcg_gen_ext_tl_i64(r_temp2, src1);
787
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
788

    
789
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
790
    tcg_gen_trunc_i64_i32(r_temp, r_temp);
791
    tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
792
    tcg_temp_free(r_temp);
793
#ifdef TARGET_SPARC64
794
    tcg_gen_mov_i64(dst, r_temp2);
795
#else
796
    tcg_gen_trunc_i64_tl(dst, r_temp2);
797
#endif
798
    tcg_temp_free(r_temp2);
799
}
800

    
801
#ifdef TARGET_SPARC64
802
static inline void gen_trap_ifdivzero_tl(TCGv divisor)
803
{
804
    TCGv r_const;
805
    int l1;
806

    
807
    l1 = gen_new_label();
808
    tcg_gen_brcondi_tl(TCG_COND_NE, divisor, 0, l1);
809
    r_const = tcg_const_i32(TT_DIV_ZERO);
810
    tcg_gen_helper_0_1(raise_exception, r_const);
811
    tcg_temp_free(r_const);
812
    gen_set_label(l1);
813
}
814

    
815
static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
816
{
817
    int l1, l2;
818

    
819
    l1 = gen_new_label();
820
    l2 = gen_new_label();
821
    tcg_gen_mov_tl(cpu_cc_src, src1);
822
    tcg_gen_mov_tl(cpu_cc_src2, src2);
823
    gen_trap_ifdivzero_tl(cpu_cc_src2);
824
    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc_src, INT64_MIN, l1);
825
    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc_src2, -1, l1);
826
    tcg_gen_movi_i64(dst, INT64_MIN);
827
    tcg_gen_br(l2);
828
    gen_set_label(l1);
829
    tcg_gen_div_i64(dst, cpu_cc_src, cpu_cc_src2);
830
    gen_set_label(l2);
831
}
832
#endif
833

    
834
static inline void gen_op_div_cc(TCGv dst)
835
{
836
    int l1;
837

    
838
    tcg_gen_mov_tl(cpu_cc_dst, dst);
839
    gen_cc_clear_icc();
840
    gen_cc_NZ_icc(cpu_cc_dst);
841
    l1 = gen_new_label();
842
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cc_src2, 0, l1);
843
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
844
    gen_set_label(l1);
845
}
846

    
847
static inline void gen_op_logic_cc(TCGv dst)
848
{
849
    tcg_gen_mov_tl(cpu_cc_dst, dst);
850

    
851
    gen_cc_clear_icc();
852
    gen_cc_NZ_icc(cpu_cc_dst);
853
#ifdef TARGET_SPARC64
854
    gen_cc_clear_xcc();
855
    gen_cc_NZ_xcc(cpu_cc_dst);
856
#endif
857
}
858

    
859
// 1
860
static inline void gen_op_eval_ba(TCGv dst)
861
{
862
    tcg_gen_movi_tl(dst, 1);
863
}
864

    
865
// Z
866
static inline void gen_op_eval_be(TCGv dst, TCGv src)
867
{
868
    gen_mov_reg_Z(dst, src);
869
}
870

    
871
// Z | (N ^ V)
872
static inline void gen_op_eval_ble(TCGv dst, TCGv src)
873
{
874
    gen_mov_reg_N(cpu_tmp0, src);
875
    gen_mov_reg_V(dst, src);
876
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
877
    gen_mov_reg_Z(cpu_tmp0, src);
878
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
879
}
880

    
881
// N ^ V
882
static inline void gen_op_eval_bl(TCGv dst, TCGv src)
883
{
884
    gen_mov_reg_V(cpu_tmp0, src);
885
    gen_mov_reg_N(dst, src);
886
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
887
}
888

    
889
// C | Z
890
static inline void gen_op_eval_bleu(TCGv dst, TCGv src)
891
{
892
    gen_mov_reg_Z(cpu_tmp0, src);
893
    gen_mov_reg_C(dst, src);
894
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
895
}
896

    
897
// C
898
static inline void gen_op_eval_bcs(TCGv dst, TCGv src)
899
{
900
    gen_mov_reg_C(dst, src);
901
}
902

    
903
// V
904
static inline void gen_op_eval_bvs(TCGv dst, TCGv src)
905
{
906
    gen_mov_reg_V(dst, src);
907
}
908

    
909
// 0
910
static inline void gen_op_eval_bn(TCGv dst)
911
{
912
    tcg_gen_movi_tl(dst, 0);
913
}
914

    
915
// N
916
static inline void gen_op_eval_bneg(TCGv dst, TCGv src)
917
{
918
    gen_mov_reg_N(dst, src);
919
}
920

    
921
// !Z
922
static inline void gen_op_eval_bne(TCGv dst, TCGv src)
923
{
924
    gen_mov_reg_Z(dst, src);
925
    tcg_gen_xori_tl(dst, dst, 0x1);
926
}
927

    
928
// !(Z | (N ^ V))
929
static inline void gen_op_eval_bg(TCGv dst, TCGv src)
930
{
931
    gen_mov_reg_N(cpu_tmp0, src);
932
    gen_mov_reg_V(dst, src);
933
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
934
    gen_mov_reg_Z(cpu_tmp0, src);
935
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
936
    tcg_gen_xori_tl(dst, dst, 0x1);
937
}
938

    
939
// !(N ^ V)
940
static inline void gen_op_eval_bge(TCGv dst, TCGv src)
941
{
942
    gen_mov_reg_V(cpu_tmp0, src);
943
    gen_mov_reg_N(dst, src);
944
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
945
    tcg_gen_xori_tl(dst, dst, 0x1);
946
}
947

    
948
// !(C | Z)
949
static inline void gen_op_eval_bgu(TCGv dst, TCGv src)
950
{
951
    gen_mov_reg_Z(cpu_tmp0, src);
952
    gen_mov_reg_C(dst, src);
953
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
954
    tcg_gen_xori_tl(dst, dst, 0x1);
955
}
956

    
957
// !C
958
static inline void gen_op_eval_bcc(TCGv dst, TCGv src)
959
{
960
    gen_mov_reg_C(dst, src);
961
    tcg_gen_xori_tl(dst, dst, 0x1);
962
}
963

    
964
// !N
965
static inline void gen_op_eval_bpos(TCGv dst, TCGv src)
966
{
967
    gen_mov_reg_N(dst, src);
968
    tcg_gen_xori_tl(dst, dst, 0x1);
969
}
970

    
971
// !V
972
static inline void gen_op_eval_bvc(TCGv dst, TCGv src)
973
{
974
    gen_mov_reg_V(dst, src);
975
    tcg_gen_xori_tl(dst, dst, 0x1);
976
}
977

    
978
/*
979
  FPSR bit field FCC1 | FCC0:
980
   0 =
981
   1 <
982
   2 >
983
   3 unordered
984
*/
985
static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src,
986
                                    unsigned int fcc_offset)
987
{
988
    tcg_gen_extu_i32_tl(reg, src);
989
    tcg_gen_shri_tl(reg, reg, FSR_FCC0_SHIFT + fcc_offset);
990
    tcg_gen_andi_tl(reg, reg, 0x1);
991
}
992

    
993
static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
994
                                    unsigned int fcc_offset)
995
{
996
    tcg_gen_extu_i32_tl(reg, src);
997
    tcg_gen_shri_tl(reg, reg, FSR_FCC1_SHIFT + fcc_offset);
998
    tcg_gen_andi_tl(reg, reg, 0x1);
999
}
1000

    
1001
// !0: FCC0 | FCC1
1002
static inline void gen_op_eval_fbne(TCGv dst, TCGv src,
1003
                                    unsigned int fcc_offset)
1004
{
1005
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1006
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1007
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
1008
}
1009

    
1010
// 1 or 2: FCC0 ^ FCC1
1011
static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
1012
                                    unsigned int fcc_offset)
1013
{
1014
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1015
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1016
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1017
}
1018

    
1019
// 1 or 3: FCC0
1020
static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
1021
                                    unsigned int fcc_offset)
1022
{
1023
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1024
}
1025

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

    
1036
// 2 or 3: FCC1
1037
static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
1038
                                    unsigned int fcc_offset)
1039
{
1040
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1041
}
1042

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

    
1053
// 3: FCC0 & FCC1
1054
static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
1055
                                    unsigned int fcc_offset)
1056
{
1057
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1058
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1059
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1060
}
1061

    
1062
// 0: !(FCC0 | FCC1)
1063
static inline void gen_op_eval_fbe(TCGv dst, TCGv src,
1064
                                    unsigned int fcc_offset)
1065
{
1066
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1067
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1068
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
1069
    tcg_gen_xori_tl(dst, dst, 0x1);
1070
}
1071

    
1072
// 0 or 3: !(FCC0 ^ FCC1)
1073
static inline void gen_op_eval_fbue(TCGv dst, TCGv src,
1074
                                    unsigned int fcc_offset)
1075
{
1076
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1077
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1078
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1079
    tcg_gen_xori_tl(dst, dst, 0x1);
1080
}
1081

    
1082
// 0 or 2: !FCC0
1083
static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
1084
                                    unsigned int fcc_offset)
1085
{
1086
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1087
    tcg_gen_xori_tl(dst, dst, 0x1);
1088
}
1089

    
1090
// !1: !(FCC0 & !FCC1)
1091
static inline void gen_op_eval_fbuge(TCGv dst, TCGv src,
1092
                                    unsigned int fcc_offset)
1093
{
1094
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1095
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1096
    tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
1097
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1098
    tcg_gen_xori_tl(dst, dst, 0x1);
1099
}
1100

    
1101
// 0 or 1: !FCC1
1102
static inline void gen_op_eval_fble(TCGv dst, TCGv src,
1103
                                    unsigned int fcc_offset)
1104
{
1105
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1106
    tcg_gen_xori_tl(dst, dst, 0x1);
1107
}
1108

    
1109
// !2: !(!FCC0 & FCC1)
1110
static inline void gen_op_eval_fbule(TCGv dst, TCGv src,
1111
                                    unsigned int fcc_offset)
1112
{
1113
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1114
    tcg_gen_xori_tl(dst, dst, 0x1);
1115
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1116
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1117
    tcg_gen_xori_tl(dst, dst, 0x1);
1118
}
1119

    
1120
// !3: !(FCC0 & FCC1)
1121
static inline void gen_op_eval_fbo(TCGv dst, TCGv src,
1122
                                    unsigned int fcc_offset)
1123
{
1124
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1125
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1126
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1127
    tcg_gen_xori_tl(dst, dst, 0x1);
1128
}
1129

    
1130
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
1131
                               target_ulong pc2, TCGv r_cond)
1132
{
1133
    int l1;
1134

    
1135
    l1 = gen_new_label();
1136

    
1137
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
1138

    
1139
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
1140

    
1141
    gen_set_label(l1);
1142
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
1143
}
1144

    
1145
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
1146
                                target_ulong pc2, TCGv r_cond)
1147
{
1148
    int l1;
1149

    
1150
    l1 = gen_new_label();
1151

    
1152
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
1153

    
1154
    gen_goto_tb(dc, 0, pc2, pc1);
1155

    
1156
    gen_set_label(l1);
1157
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
1158
}
1159

    
1160
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
1161
                                      TCGv r_cond)
1162
{
1163
    int l1, l2;
1164

    
1165
    l1 = gen_new_label();
1166
    l2 = gen_new_label();
1167

    
1168
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
1169

    
1170
    tcg_gen_movi_tl(cpu_npc, npc1);
1171
    tcg_gen_br(l2);
1172

    
1173
    gen_set_label(l1);
1174
    tcg_gen_movi_tl(cpu_npc, npc2);
1175
    gen_set_label(l2);
1176
}
1177

    
1178
/* call this function before using the condition register as it may
1179
   have been set for a jump */
1180
static inline void flush_cond(DisasContext *dc, TCGv cond)
1181
{
1182
    if (dc->npc == JUMP_PC) {
1183
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1184
        dc->npc = DYNAMIC_PC;
1185
    }
1186
}
1187

    
1188
static inline void save_npc(DisasContext *dc, TCGv cond)
1189
{
1190
    if (dc->npc == JUMP_PC) {
1191
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1192
        dc->npc = DYNAMIC_PC;
1193
    } else if (dc->npc != DYNAMIC_PC) {
1194
        tcg_gen_movi_tl(cpu_npc, dc->npc);
1195
    }
1196
}
1197

    
1198
static inline void save_state(DisasContext *dc, TCGv cond)
1199
{
1200
    tcg_gen_movi_tl(cpu_pc, dc->pc);
1201
    save_npc(dc, cond);
1202
}
1203

    
1204
static inline void gen_mov_pc_npc(DisasContext *dc, TCGv cond)
1205
{
1206
    if (dc->npc == JUMP_PC) {
1207
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1208
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1209
        dc->pc = DYNAMIC_PC;
1210
    } else if (dc->npc == DYNAMIC_PC) {
1211
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1212
        dc->pc = DYNAMIC_PC;
1213
    } else {
1214
        dc->pc = dc->npc;
1215
    }
1216
}
1217

    
1218
static inline void gen_op_next_insn(void)
1219
{
1220
    tcg_gen_mov_tl(cpu_pc, cpu_npc);
1221
    tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
1222
}
1223

    
1224
static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond)
1225
{
1226
    TCGv r_src;
1227

    
1228
#ifdef TARGET_SPARC64
1229
    if (cc)
1230
        r_src = cpu_xcc;
1231
    else
1232
        r_src = cpu_psr;
1233
#else
1234
    r_src = cpu_psr;
1235
#endif
1236
    switch (cond) {
1237
    case 0x0:
1238
        gen_op_eval_bn(r_dst);
1239
        break;
1240
    case 0x1:
1241
        gen_op_eval_be(r_dst, r_src);
1242
        break;
1243
    case 0x2:
1244
        gen_op_eval_ble(r_dst, r_src);
1245
        break;
1246
    case 0x3:
1247
        gen_op_eval_bl(r_dst, r_src);
1248
        break;
1249
    case 0x4:
1250
        gen_op_eval_bleu(r_dst, r_src);
1251
        break;
1252
    case 0x5:
1253
        gen_op_eval_bcs(r_dst, r_src);
1254
        break;
1255
    case 0x6:
1256
        gen_op_eval_bneg(r_dst, r_src);
1257
        break;
1258
    case 0x7:
1259
        gen_op_eval_bvs(r_dst, r_src);
1260
        break;
1261
    case 0x8:
1262
        gen_op_eval_ba(r_dst);
1263
        break;
1264
    case 0x9:
1265
        gen_op_eval_bne(r_dst, r_src);
1266
        break;
1267
    case 0xa:
1268
        gen_op_eval_bg(r_dst, r_src);
1269
        break;
1270
    case 0xb:
1271
        gen_op_eval_bge(r_dst, r_src);
1272
        break;
1273
    case 0xc:
1274
        gen_op_eval_bgu(r_dst, r_src);
1275
        break;
1276
    case 0xd:
1277
        gen_op_eval_bcc(r_dst, r_src);
1278
        break;
1279
    case 0xe:
1280
        gen_op_eval_bpos(r_dst, r_src);
1281
        break;
1282
    case 0xf:
1283
        gen_op_eval_bvc(r_dst, r_src);
1284
        break;
1285
    }
1286
}
1287

    
1288
static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
1289
{
1290
    unsigned int offset;
1291

    
1292
    switch (cc) {
1293
    default:
1294
    case 0x0:
1295
        offset = 0;
1296
        break;
1297
    case 0x1:
1298
        offset = 32 - 10;
1299
        break;
1300
    case 0x2:
1301
        offset = 34 - 10;
1302
        break;
1303
    case 0x3:
1304
        offset = 36 - 10;
1305
        break;
1306
    }
1307

    
1308
    switch (cond) {
1309
    case 0x0:
1310
        gen_op_eval_bn(r_dst);
1311
        break;
1312
    case 0x1:
1313
        gen_op_eval_fbne(r_dst, cpu_fsr, offset);
1314
        break;
1315
    case 0x2:
1316
        gen_op_eval_fblg(r_dst, cpu_fsr, offset);
1317
        break;
1318
    case 0x3:
1319
        gen_op_eval_fbul(r_dst, cpu_fsr, offset);
1320
        break;
1321
    case 0x4:
1322
        gen_op_eval_fbl(r_dst, cpu_fsr, offset);
1323
        break;
1324
    case 0x5:
1325
        gen_op_eval_fbug(r_dst, cpu_fsr, offset);
1326
        break;
1327
    case 0x6:
1328
        gen_op_eval_fbg(r_dst, cpu_fsr, offset);
1329
        break;
1330
    case 0x7:
1331
        gen_op_eval_fbu(r_dst, cpu_fsr, offset);
1332
        break;
1333
    case 0x8:
1334
        gen_op_eval_ba(r_dst);
1335
        break;
1336
    case 0x9:
1337
        gen_op_eval_fbe(r_dst, cpu_fsr, offset);
1338
        break;
1339
    case 0xa:
1340
        gen_op_eval_fbue(r_dst, cpu_fsr, offset);
1341
        break;
1342
    case 0xb:
1343
        gen_op_eval_fbge(r_dst, cpu_fsr, offset);
1344
        break;
1345
    case 0xc:
1346
        gen_op_eval_fbuge(r_dst, cpu_fsr, offset);
1347
        break;
1348
    case 0xd:
1349
        gen_op_eval_fble(r_dst, cpu_fsr, offset);
1350
        break;
1351
    case 0xe:
1352
        gen_op_eval_fbule(r_dst, cpu_fsr, offset);
1353
        break;
1354
    case 0xf:
1355
        gen_op_eval_fbo(r_dst, cpu_fsr, offset);
1356
        break;
1357
    }
1358
}
1359

    
1360
#ifdef TARGET_SPARC64
1361
// Inverted logic
1362
static const int gen_tcg_cond_reg[8] = {
1363
    -1,
1364
    TCG_COND_NE,
1365
    TCG_COND_GT,
1366
    TCG_COND_GE,
1367
    -1,
1368
    TCG_COND_EQ,
1369
    TCG_COND_LE,
1370
    TCG_COND_LT,
1371
};
1372

    
1373
static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
1374
{
1375
    int l1;
1376

    
1377
    l1 = gen_new_label();
1378
    tcg_gen_movi_tl(r_dst, 0);
1379
    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], r_src, 0, l1);
1380
    tcg_gen_movi_tl(r_dst, 1);
1381
    gen_set_label(l1);
1382
}
1383
#endif
1384

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

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

    
1425
/* XXX: potentially incorrect if dynamic npc */
1426
static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1427
                      TCGv r_cond)
1428
{
1429
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1430
    target_ulong target = dc->pc + offset;
1431

    
1432
    if (cond == 0x0) {
1433
        /* unconditional not taken */
1434
        if (a) {
1435
            dc->pc = dc->npc + 4;
1436
            dc->npc = dc->pc + 4;
1437
        } else {
1438
            dc->pc = dc->npc;
1439
            dc->npc = dc->pc + 4;
1440
        }
1441
    } else if (cond == 0x8) {
1442
        /* unconditional taken */
1443
        if (a) {
1444
            dc->pc = target;
1445
            dc->npc = dc->pc + 4;
1446
        } else {
1447
            dc->pc = dc->npc;
1448
            dc->npc = target;
1449
        }
1450
    } else {
1451
        flush_cond(dc, r_cond);
1452
        gen_fcond(r_cond, cc, cond);
1453
        if (a) {
1454
            gen_branch_a(dc, target, dc->npc, r_cond);
1455
            dc->is_br = 1;
1456
        } else {
1457
            dc->pc = dc->npc;
1458
            dc->jump_pc[0] = target;
1459
            dc->jump_pc[1] = dc->npc + 4;
1460
            dc->npc = JUMP_PC;
1461
        }
1462
    }
1463
}
1464

    
1465
#ifdef TARGET_SPARC64
1466
/* XXX: potentially incorrect if dynamic npc */
1467
static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
1468
                          TCGv r_cond, TCGv r_reg)
1469
{
1470
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1471
    target_ulong target = dc->pc + offset;
1472

    
1473
    flush_cond(dc, r_cond);
1474
    gen_cond_reg(r_cond, cond, r_reg);
1475
    if (a) {
1476
        gen_branch_a(dc, target, dc->npc, r_cond);
1477
        dc->is_br = 1;
1478
    } else {
1479
        dc->pc = dc->npc;
1480
        dc->jump_pc[0] = target;
1481
        dc->jump_pc[1] = dc->npc + 4;
1482
        dc->npc = JUMP_PC;
1483
    }
1484
}
1485

    
1486
static GenOpFunc * const gen_fcmps[4] = {
1487
    helper_fcmps,
1488
    helper_fcmps_fcc1,
1489
    helper_fcmps_fcc2,
1490
    helper_fcmps_fcc3,
1491
};
1492

    
1493
static GenOpFunc * const gen_fcmpd[4] = {
1494
    helper_fcmpd,
1495
    helper_fcmpd_fcc1,
1496
    helper_fcmpd_fcc2,
1497
    helper_fcmpd_fcc3,
1498
};
1499

    
1500
static GenOpFunc * const gen_fcmpq[4] = {
1501
    helper_fcmpq,
1502
    helper_fcmpq_fcc1,
1503
    helper_fcmpq_fcc2,
1504
    helper_fcmpq_fcc3,
1505
};
1506

    
1507
static GenOpFunc * const gen_fcmpes[4] = {
1508
    helper_fcmpes,
1509
    helper_fcmpes_fcc1,
1510
    helper_fcmpes_fcc2,
1511
    helper_fcmpes_fcc3,
1512
};
1513

    
1514
static GenOpFunc * const gen_fcmped[4] = {
1515
    helper_fcmped,
1516
    helper_fcmped_fcc1,
1517
    helper_fcmped_fcc2,
1518
    helper_fcmped_fcc3,
1519
};
1520

    
1521
static GenOpFunc * const gen_fcmpeq[4] = {
1522
    helper_fcmpeq,
1523
    helper_fcmpeq_fcc1,
1524
    helper_fcmpeq_fcc2,
1525
    helper_fcmpeq_fcc3,
1526
};
1527

    
1528
static inline void gen_op_fcmps(int fccno)
1529
{
1530
    tcg_gen_helper_0_0(gen_fcmps[fccno]);
1531
}
1532

    
1533
static inline void gen_op_fcmpd(int fccno)
1534
{
1535
    tcg_gen_helper_0_0(gen_fcmpd[fccno]);
1536
}
1537

    
1538
static inline void gen_op_fcmpq(int fccno)
1539
{
1540
    tcg_gen_helper_0_0(gen_fcmpq[fccno]);
1541
}
1542

    
1543
static inline void gen_op_fcmpes(int fccno)
1544
{
1545
    tcg_gen_helper_0_0(gen_fcmpes[fccno]);
1546
}
1547

    
1548
static inline void gen_op_fcmped(int fccno)
1549
{
1550
    tcg_gen_helper_0_0(gen_fcmped[fccno]);
1551
}
1552

    
1553
static inline void gen_op_fcmpeq(int fccno)
1554
{
1555
    tcg_gen_helper_0_0(gen_fcmpeq[fccno]);
1556
}
1557

    
1558
#else
1559

    
1560
static inline void gen_op_fcmps(int fccno)
1561
{
1562
    tcg_gen_helper_0_0(helper_fcmps);
1563
}
1564

    
1565
static inline void gen_op_fcmpd(int fccno)
1566
{
1567
    tcg_gen_helper_0_0(helper_fcmpd);
1568
}
1569

    
1570
static inline void gen_op_fcmpq(int fccno)
1571
{
1572
    tcg_gen_helper_0_0(helper_fcmpq);
1573
}
1574

    
1575
static inline void gen_op_fcmpes(int fccno)
1576
{
1577
    tcg_gen_helper_0_0(helper_fcmpes);
1578
}
1579

    
1580
static inline void gen_op_fcmped(int fccno)
1581
{
1582
    tcg_gen_helper_0_0(helper_fcmped);
1583
}
1584

    
1585
static inline void gen_op_fcmpeq(int fccno)
1586
{
1587
    tcg_gen_helper_0_0(helper_fcmpeq);
1588
}
1589
#endif
1590

    
1591
static inline void gen_op_fpexception_im(int fsr_flags)
1592
{
1593
    TCGv r_const;
1594

    
1595
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~FSR_FTT_MASK);
1596
    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
1597
    r_const = tcg_const_i32(TT_FP_EXCP);
1598
    tcg_gen_helper_0_1(raise_exception, r_const);
1599
    tcg_temp_free(r_const);
1600
}
1601

    
1602
static int gen_trap_ifnofpu(DisasContext *dc, TCGv r_cond)
1603
{
1604
#if !defined(CONFIG_USER_ONLY)
1605
    if (!dc->fpu_enabled) {
1606
        TCGv r_const;
1607

    
1608
        save_state(dc, r_cond);
1609
        r_const = tcg_const_i32(TT_NFPU_INSN);
1610
        tcg_gen_helper_0_1(raise_exception, r_const);
1611
        tcg_temp_free(r_const);
1612
        dc->is_br = 1;
1613
        return 1;
1614
    }
1615
#endif
1616
    return 0;
1617
}
1618

    
1619
static inline void gen_op_clear_ieee_excp_and_FTT(void)
1620
{
1621
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~(FSR_FTT_MASK | FSR_CEXC_MASK));
1622
}
1623

    
1624
static inline void gen_clear_float_exceptions(void)
1625
{
1626
    tcg_gen_helper_0_0(helper_clear_float_exceptions);
1627
}
1628

    
1629
/* asi moves */
1630
#ifdef TARGET_SPARC64
1631
static inline TCGv gen_get_asi(int insn, TCGv r_addr)
1632
{
1633
    int asi, offset;
1634
    TCGv r_asi;
1635

    
1636
    if (IS_IMM) {
1637
        r_asi = tcg_temp_new(TCG_TYPE_I32);
1638
        offset = GET_FIELD(insn, 25, 31);
1639
        tcg_gen_addi_tl(r_addr, r_addr, offset);
1640
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
1641
    } else {
1642
        asi = GET_FIELD(insn, 19, 26);
1643
        r_asi = tcg_const_i32(asi);
1644
    }
1645
    return r_asi;
1646
}
1647

    
1648
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
1649
                              int sign)
1650
{
1651
    TCGv r_asi, r_size, r_sign;
1652

    
1653
    r_asi = gen_get_asi(insn, addr);
1654
    r_size = tcg_const_i32(size);
1655
    r_sign = tcg_const_i32(sign);
1656
    tcg_gen_helper_1_4(helper_ld_asi, dst, addr, r_asi, r_size, r_sign);
1657
    tcg_temp_free(r_sign);
1658
    tcg_temp_free(r_size);
1659
    tcg_temp_free(r_asi);
1660
}
1661

    
1662
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1663
{
1664
    TCGv r_asi, r_size;
1665

    
1666
    r_asi = gen_get_asi(insn, addr);
1667
    r_size = tcg_const_i32(size);
1668
    tcg_gen_helper_0_4(helper_st_asi, addr, src, r_asi, r_size);
1669
    tcg_temp_free(r_size);
1670
    tcg_temp_free(r_asi);
1671
}
1672

    
1673
static inline void gen_ldf_asi(TCGv addr, int insn, int size, int rd)
1674
{
1675
    TCGv r_asi, r_size, r_rd;
1676

    
1677
    r_asi = gen_get_asi(insn, addr);
1678
    r_size = tcg_const_i32(size);
1679
    r_rd = tcg_const_i32(rd);
1680
    tcg_gen_helper_0_4(helper_ldf_asi, addr, r_asi, r_size, r_rd);
1681
    tcg_temp_free(r_rd);
1682
    tcg_temp_free(r_size);
1683
    tcg_temp_free(r_asi);
1684
}
1685

    
1686
static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
1687
{
1688
    TCGv r_asi, r_size, r_rd;
1689

    
1690
    r_asi = gen_get_asi(insn, addr);
1691
    r_size = tcg_const_i32(size);
1692
    r_rd = tcg_const_i32(rd);
1693
    tcg_gen_helper_0_4(helper_stf_asi, addr, r_asi, r_size, r_rd);
1694
    tcg_temp_free(r_rd);
1695
    tcg_temp_free(r_size);
1696
    tcg_temp_free(r_asi);
1697
}
1698

    
1699
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1700
{
1701
    TCGv r_asi, r_size, r_sign;
1702

    
1703
    r_asi = gen_get_asi(insn, addr);
1704
    r_size = tcg_const_i32(4);
1705
    r_sign = tcg_const_i32(0);
1706
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
1707
    tcg_temp_free(r_sign);
1708
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, r_asi, r_size);
1709
    tcg_temp_free(r_size);
1710
    tcg_temp_free(r_asi);
1711
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1712
}
1713

    
1714
static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn)
1715
{
1716
    TCGv r_asi, r_size, r_sign;
1717

    
1718
    r_asi = gen_get_asi(insn, addr);
1719
    r_size = tcg_const_i32(8);
1720
    r_sign = tcg_const_i32(0);
1721
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
1722
    tcg_temp_free(r_sign);
1723
    tcg_temp_free(r_size);
1724
    tcg_temp_free(r_asi);
1725
    tcg_gen_andi_i64(lo, cpu_tmp64, 0xffffffffULL);
1726
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1727
    tcg_gen_andi_i64(hi, cpu_tmp64, 0xffffffffULL);
1728
}
1729

    
1730
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1731
{
1732
    TCGv r_temp, r_asi, r_size;
1733

    
1734
    r_temp = tcg_temp_new(TCG_TYPE_TL);
1735
    gen_movl_reg_TN(rd + 1, r_temp);
1736
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi,
1737
                       r_temp);
1738
    tcg_temp_free(r_temp);
1739
    r_asi = gen_get_asi(insn, addr);
1740
    r_size = tcg_const_i32(8);
1741
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi, r_size);
1742
    tcg_temp_free(r_size);
1743
    tcg_temp_free(r_asi);
1744
}
1745

    
1746
static inline void gen_cas_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
1747
                               int rd)
1748
{
1749
    TCGv r_val1, r_asi;
1750

    
1751
    r_val1 = tcg_temp_new(TCG_TYPE_TL);
1752
    gen_movl_reg_TN(rd, r_val1);
1753
    r_asi = gen_get_asi(insn, addr);
1754
    tcg_gen_helper_1_4(helper_cas_asi, dst, addr, r_val1, val2, r_asi);
1755
    tcg_temp_free(r_asi);
1756
    tcg_temp_free(r_val1);
1757
}
1758

    
1759
static inline void gen_casx_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
1760
                                int rd)
1761
{
1762
    TCGv r_asi;
1763

    
1764
    gen_movl_reg_TN(rd, cpu_tmp64);
1765
    r_asi = gen_get_asi(insn, addr);
1766
    tcg_gen_helper_1_4(helper_casx_asi, dst, addr, cpu_tmp64, val2, r_asi);
1767
    tcg_temp_free(r_asi);
1768
}
1769

    
1770
#elif !defined(CONFIG_USER_ONLY)
1771

    
1772
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
1773
                              int sign)
1774
{
1775
    TCGv r_asi, r_size, r_sign;
1776

    
1777
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1778
    r_size = tcg_const_i32(size);
1779
    r_sign = tcg_const_i32(sign);
1780
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
1781
    tcg_temp_free(r_sign);
1782
    tcg_temp_free(r_size);
1783
    tcg_temp_free(r_asi);
1784
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1785
}
1786

    
1787
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1788
{
1789
    TCGv r_asi, r_size;
1790

    
1791
    tcg_gen_extu_tl_i64(cpu_tmp64, src);
1792
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1793
    r_size = tcg_const_i32(size);
1794
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi, r_size);
1795
    tcg_temp_free(r_size);
1796
    tcg_temp_free(r_asi);
1797
}
1798

    
1799
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1800
{
1801
    TCGv r_asi, r_size, r_sign;
1802

    
1803
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1804
    r_size = tcg_const_i32(4);
1805
    r_sign = tcg_const_i32(0);
1806
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
1807
    tcg_temp_free(r_sign);
1808
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, r_asi, r_size);
1809
    tcg_temp_free(r_size);
1810
    tcg_temp_free(r_asi);
1811
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1812
}
1813

    
1814
static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn)
1815
{
1816
    TCGv r_asi, r_size, r_sign;
1817

    
1818
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1819
    r_size = tcg_const_i32(8);
1820
    r_sign = tcg_const_i32(0);
1821
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
1822
    tcg_temp_free(r_sign);
1823
    tcg_temp_free(r_size);
1824
    tcg_temp_free(r_asi);
1825
    tcg_gen_trunc_i64_tl(lo, cpu_tmp64);
1826
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1827
    tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
1828
}
1829

    
1830
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1831
{
1832
    TCGv r_temp, r_asi, r_size;
1833

    
1834
    r_temp = tcg_temp_new(TCG_TYPE_TL);
1835
    gen_movl_reg_TN(rd + 1, r_temp);
1836
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi, r_temp);
1837
    tcg_temp_free(r_temp);
1838
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1839
    r_size = tcg_const_i32(8);
1840
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi, r_size);
1841
    tcg_temp_free(r_size);
1842
    tcg_temp_free(r_asi);
1843
}
1844
#endif
1845

    
1846
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1847
static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
1848
{
1849
    TCGv r_val, r_asi, r_size;
1850

    
1851
    gen_ld_asi(dst, addr, insn, 1, 0);
1852

    
1853
    r_val = tcg_const_i64(0xffULL);
1854
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1855
    r_size = tcg_const_i32(1);
1856
    tcg_gen_helper_0_4(helper_st_asi, addr, r_val, r_asi, r_size);
1857
    tcg_temp_free(r_size);
1858
    tcg_temp_free(r_asi);
1859
    tcg_temp_free(r_val);
1860
}
1861
#endif
1862

    
1863
static inline TCGv get_src1(unsigned int insn, TCGv def)
1864
{
1865
    TCGv r_rs1 = def;
1866
    unsigned int rs1;
1867

    
1868
    rs1 = GET_FIELD(insn, 13, 17);
1869
    if (rs1 == 0)
1870
        r_rs1 = tcg_const_tl(0); // XXX how to free?
1871
    else if (rs1 < 8)
1872
        r_rs1 = cpu_gregs[rs1];
1873
    else
1874
        tcg_gen_ld_tl(def, cpu_regwptr, (rs1 - 8) * sizeof(target_ulong));
1875
    return r_rs1;
1876
}
1877

    
1878
static inline TCGv get_src2(unsigned int insn, TCGv def)
1879
{
1880
    TCGv r_rs2 = def;
1881
    unsigned int rs2;
1882

    
1883
    if (IS_IMM) { /* immediate */
1884
        rs2 = GET_FIELDs(insn, 19, 31);
1885
        r_rs2 = tcg_const_tl((int)rs2); // XXX how to free?
1886
    } else { /* register */
1887
        rs2 = GET_FIELD(insn, 27, 31);
1888
        if (rs2 == 0)
1889
            r_rs2 = tcg_const_tl(0); // XXX how to free?
1890
        else if (rs2 < 8)
1891
            r_rs2 = cpu_gregs[rs2];
1892
        else
1893
            tcg_gen_ld_tl(def, cpu_regwptr, (rs2 - 8) * sizeof(target_ulong));
1894
    }
1895
    return r_rs2;
1896
}
1897

    
1898
#define CHECK_IU_FEATURE(dc, FEATURE)                      \
1899
    if (!((dc)->features & CPU_FEATURE_ ## FEATURE))       \
1900
        goto illegal_insn;
1901
#define CHECK_FPU_FEATURE(dc, FEATURE)                     \
1902
    if (!((dc)->features & CPU_FEATURE_ ## FEATURE))       \
1903
        goto nfpu_insn;
1904

    
1905
/* before an instruction, dc->pc must be static */
1906
static void disas_sparc_insn(DisasContext * dc)
1907
{
1908
    unsigned int insn, opc, rs1, rs2, rd;
1909

    
1910
    if (unlikely(loglevel & CPU_LOG_TB_OP))
1911
        tcg_gen_debug_insn_start(dc->pc);
1912
    insn = ldl_code(dc->pc);
1913
    opc = GET_FIELD(insn, 0, 1);
1914

    
1915
    rd = GET_FIELD(insn, 2, 6);
1916

    
1917
    cpu_src1 = tcg_temp_new(TCG_TYPE_TL); // const
1918
    cpu_src2 = tcg_temp_new(TCG_TYPE_TL); // const
1919

    
1920
    switch (opc) {
1921
    case 0:                     /* branches/sethi */
1922
        {
1923
            unsigned int xop = GET_FIELD(insn, 7, 9);
1924
            int32_t target;
1925
            switch (xop) {
1926
#ifdef TARGET_SPARC64
1927
            case 0x1:           /* V9 BPcc */
1928
                {
1929
                    int cc;
1930

    
1931
                    target = GET_FIELD_SP(insn, 0, 18);
1932
                    target = sign_extend(target, 18);
1933
                    target <<= 2;
1934
                    cc = GET_FIELD_SP(insn, 20, 21);
1935
                    if (cc == 0)
1936
                        do_branch(dc, target, insn, 0, cpu_cond);
1937
                    else if (cc == 2)
1938
                        do_branch(dc, target, insn, 1, cpu_cond);
1939
                    else
1940
                        goto illegal_insn;
1941
                    goto jmp_insn;
1942
                }
1943
            case 0x3:           /* V9 BPr */
1944
                {
1945
                    target = GET_FIELD_SP(insn, 0, 13) |
1946
                        (GET_FIELD_SP(insn, 20, 21) << 14);
1947
                    target = sign_extend(target, 16);
1948
                    target <<= 2;
1949
                    cpu_src1 = get_src1(insn, cpu_src1);
1950
                    do_branch_reg(dc, target, insn, cpu_cond, cpu_src1);
1951
                    goto jmp_insn;
1952
                }
1953
            case 0x5:           /* V9 FBPcc */
1954
                {
1955
                    int cc = GET_FIELD_SP(insn, 20, 21);
1956
                    if (gen_trap_ifnofpu(dc, cpu_cond))
1957
                        goto jmp_insn;
1958
                    target = GET_FIELD_SP(insn, 0, 18);
1959
                    target = sign_extend(target, 19);
1960
                    target <<= 2;
1961
                    do_fbranch(dc, target, insn, cc, cpu_cond);
1962
                    goto jmp_insn;
1963
                }
1964
#else
1965
            case 0x7:           /* CBN+x */
1966
                {
1967
                    goto ncp_insn;
1968
                }
1969
#endif
1970
            case 0x2:           /* BN+x */
1971
                {
1972
                    target = GET_FIELD(insn, 10, 31);
1973
                    target = sign_extend(target, 22);
1974
                    target <<= 2;
1975
                    do_branch(dc, target, insn, 0, cpu_cond);
1976
                    goto jmp_insn;
1977
                }
1978
            case 0x6:           /* FBN+x */
1979
                {
1980
                    if (gen_trap_ifnofpu(dc, cpu_cond))
1981
                        goto jmp_insn;
1982
                    target = GET_FIELD(insn, 10, 31);
1983
                    target = sign_extend(target, 22);
1984
                    target <<= 2;
1985
                    do_fbranch(dc, target, insn, 0, cpu_cond);
1986
                    goto jmp_insn;
1987
                }
1988
            case 0x4:           /* SETHI */
1989
                if (rd) { // nop
1990
                    uint32_t value = GET_FIELD(insn, 10, 31);
1991
                    TCGv r_const;
1992

    
1993
                    r_const = tcg_const_tl(value << 10);
1994
                    gen_movl_TN_reg(rd, r_const);
1995
                    tcg_temp_free(r_const);
1996
                }
1997
                break;
1998
            case 0x0:           /* UNIMPL */
1999
            default:
2000
                goto illegal_insn;
2001
            }
2002
            break;
2003
        }
2004
        break;
2005
    case 1:
2006
        /*CALL*/ {
2007
            target_long target = GET_FIELDs(insn, 2, 31) << 2;
2008
            TCGv r_const;
2009

    
2010
            r_const = tcg_const_tl(dc->pc);
2011
            gen_movl_TN_reg(15, r_const);
2012
            tcg_temp_free(r_const);
2013
            target += dc->pc;
2014
            gen_mov_pc_npc(dc, cpu_cond);
2015
            dc->npc = target;
2016
        }
2017
        goto jmp_insn;
2018
    case 2:                     /* FPU & Logical Operations */
2019
        {
2020
            unsigned int xop = GET_FIELD(insn, 7, 12);
2021
            if (xop == 0x3a) {  /* generate trap */
2022
                int cond;
2023

    
2024
                cpu_src1 = get_src1(insn, cpu_src1);
2025
                if (IS_IMM) {
2026
                    rs2 = GET_FIELD(insn, 25, 31);
2027
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, rs2);
2028
                } else {
2029
                    rs2 = GET_FIELD(insn, 27, 31);
2030
                    if (rs2 != 0) {
2031
                        gen_movl_reg_TN(rs2, cpu_src2);
2032
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
2033
                    } else
2034
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
2035
                }
2036
                cond = GET_FIELD(insn, 3, 6);
2037
                if (cond == 0x8) {
2038
                    save_state(dc, cpu_cond);
2039
                    tcg_gen_helper_0_1(helper_trap, cpu_dst);
2040
                } else if (cond != 0) {
2041
                    TCGv r_cond = tcg_temp_new(TCG_TYPE_TL);
2042
#ifdef TARGET_SPARC64
2043
                    /* V9 icc/xcc */
2044
                    int cc = GET_FIELD_SP(insn, 11, 12);
2045

    
2046
                    save_state(dc, cpu_cond);
2047
                    if (cc == 0)
2048
                        gen_cond(r_cond, 0, cond);
2049
                    else if (cc == 2)
2050
                        gen_cond(r_cond, 1, cond);
2051
                    else
2052
                        goto illegal_insn;
2053
#else
2054
                    save_state(dc, cpu_cond);
2055
                    gen_cond(r_cond, 0, cond);
2056
#endif
2057
                    tcg_gen_helper_0_2(helper_trapcc, cpu_dst, r_cond);
2058
                    tcg_temp_free(r_cond);
2059
                }
2060
                gen_op_next_insn();
2061
                tcg_gen_exit_tb(0);
2062
                dc->is_br = 1;
2063
                goto jmp_insn;
2064
            } else if (xop == 0x28) {
2065
                rs1 = GET_FIELD(insn, 13, 17);
2066
                switch(rs1) {
2067
                case 0: /* rdy */
2068
#ifndef TARGET_SPARC64
2069
                case 0x01 ... 0x0e: /* undefined in the SPARCv8
2070
                                       manual, rdy on the microSPARC
2071
                                       II */
2072
                case 0x0f:          /* stbar in the SPARCv8 manual,
2073
                                       rdy on the microSPARC II */
2074
                case 0x10 ... 0x1f: /* implementation-dependent in the
2075
                                       SPARCv8 manual, rdy on the
2076
                                       microSPARC II */
2077
#endif
2078
                    tcg_gen_ld_tl(cpu_tmp0, cpu_env,
2079
                                  offsetof(CPUSPARCState, y));
2080
                    gen_movl_TN_reg(rd, cpu_tmp0);
2081
                    break;
2082
#ifdef TARGET_SPARC64
2083
                case 0x2: /* V9 rdccr */
2084
                    tcg_gen_helper_1_0(helper_rdccr, cpu_dst);
2085
                    gen_movl_TN_reg(rd, cpu_dst);
2086
                    break;
2087
                case 0x3: /* V9 rdasi */
2088
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2089
                                   offsetof(CPUSPARCState, asi));
2090
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2091
                    gen_movl_TN_reg(rd, cpu_dst);
2092
                    break;
2093
                case 0x4: /* V9 rdtick */
2094
                    {
2095
                        TCGv r_tickptr;
2096

    
2097
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2098
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2099
                                       offsetof(CPUState, tick));
2100
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst,
2101
                                           r_tickptr);
2102
                        tcg_temp_free(r_tickptr);
2103
                        gen_movl_TN_reg(rd, cpu_dst);
2104
                    }
2105
                    break;
2106
                case 0x5: /* V9 rdpc */
2107
                    {
2108
                        TCGv r_const;
2109

    
2110
                        r_const = tcg_const_tl(dc->pc);
2111
                        gen_movl_TN_reg(rd, r_const);
2112
                        tcg_temp_free(r_const);
2113
                    }
2114
                    break;
2115
                case 0x6: /* V9 rdfprs */
2116
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2117
                                   offsetof(CPUSPARCState, fprs));
2118
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2119
                    gen_movl_TN_reg(rd, cpu_dst);
2120
                    break;
2121
                case 0xf: /* V9 membar */
2122
                    break; /* no effect */
2123
                case 0x13: /* Graphics Status */
2124
                    if (gen_trap_ifnofpu(dc, cpu_cond))
2125
                        goto jmp_insn;
2126
                    tcg_gen_ld_tl(cpu_tmp0, cpu_env,
2127
                                  offsetof(CPUSPARCState, gsr));
2128
                    gen_movl_TN_reg(rd, cpu_tmp0);
2129
                    break;
2130
                case 0x17: /* Tick compare */
2131
                    tcg_gen_ld_tl(cpu_tmp0, cpu_env,
2132
                                  offsetof(CPUSPARCState, tick_cmpr));
2133
                    gen_movl_TN_reg(rd, cpu_tmp0);
2134
                    break;
2135
                case 0x18: /* System tick */
2136
                    {
2137
                        TCGv r_tickptr;
2138

    
2139
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2140
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2141
                                       offsetof(CPUState, stick));
2142
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst,
2143
                                           r_tickptr);
2144
                        tcg_temp_free(r_tickptr);
2145
                        gen_movl_TN_reg(rd, cpu_dst);
2146
                    }
2147
                    break;
2148
                case 0x19: /* System tick compare */
2149
                    tcg_gen_ld_tl(cpu_tmp0, cpu_env,
2150
                                  offsetof(CPUSPARCState, stick_cmpr));
2151
                    gen_movl_TN_reg(rd, cpu_tmp0);
2152
                    break;
2153
                case 0x10: /* Performance Control */
2154
                case 0x11: /* Performance Instrumentation Counter */
2155
                case 0x12: /* Dispatch Control */
2156
                case 0x14: /* Softint set, WO */
2157
                case 0x15: /* Softint clear, WO */
2158
                case 0x16: /* Softint write */
2159
#endif
2160
                default:
2161
                    goto illegal_insn;
2162
                }
2163
#if !defined(CONFIG_USER_ONLY)
2164
            } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
2165
#ifndef TARGET_SPARC64
2166
                if (!supervisor(dc))
2167
                    goto priv_insn;
2168
                tcg_gen_helper_1_0(helper_rdpsr, cpu_dst);
2169
#else
2170
                if (!hypervisor(dc))
2171
                    goto priv_insn;
2172
                rs1 = GET_FIELD(insn, 13, 17);
2173
                switch (rs1) {
2174
                case 0: // hpstate
2175
                    // gen_op_rdhpstate();
2176
                    break;
2177
                case 1: // htstate
2178
                    // gen_op_rdhtstate();
2179
                    break;
2180
                case 3: // hintp
2181
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2182
                                   offsetof(CPUSPARCState, hintp));
2183
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2184
                    break;
2185
                case 5: // htba
2186
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2187
                                   offsetof(CPUSPARCState, htba));
2188
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2189
                    break;
2190
                case 6: // hver
2191
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2192
                                   offsetof(CPUSPARCState, hver));
2193
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2194
                    break;
2195
                case 31: // hstick_cmpr
2196
                    tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2197
                    tcg_gen_st_i32(cpu_tmp32, cpu_env,
2198
                                   offsetof(CPUSPARCState, hstick_cmpr));
2199
                    break;
2200
                default:
2201
                    goto illegal_insn;
2202
                }
2203
#endif
2204
                gen_movl_TN_reg(rd, cpu_dst);
2205
                break;
2206
            } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
2207
                if (!supervisor(dc))
2208
                    goto priv_insn;
2209
#ifdef TARGET_SPARC64
2210
                rs1 = GET_FIELD(insn, 13, 17);
2211
                switch (rs1) {
2212
                case 0: // tpc
2213
                    {
2214
                        TCGv r_tsptr;
2215

    
2216
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2217
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2218
                                       offsetof(CPUState, tsptr));
2219
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2220
                                      offsetof(trap_state, tpc));
2221
                        tcg_temp_free(r_tsptr);
2222
                    }
2223
                    break;
2224
                case 1: // tnpc
2225
                    {
2226
                        TCGv r_tsptr;
2227

    
2228
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2229
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2230
                                       offsetof(CPUState, tsptr));
2231
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2232
                                      offsetof(trap_state, tnpc));
2233
                        tcg_temp_free(r_tsptr);
2234
                    }
2235
                    break;
2236
                case 2: // tstate
2237
                    {
2238
                        TCGv r_tsptr;
2239

    
2240
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2241
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2242
                                       offsetof(CPUState, tsptr));
2243
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2244
                                      offsetof(trap_state, tstate));
2245
                        tcg_temp_free(r_tsptr);
2246
                    }
2247
                    break;
2248
                case 3: // tt
2249
                    {
2250
                        TCGv r_tsptr;
2251

    
2252
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2253
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2254
                                       offsetof(CPUState, tsptr));
2255
                        tcg_gen_ld_i32(cpu_tmp0, r_tsptr,
2256
                                       offsetof(trap_state, tt));
2257
                        tcg_temp_free(r_tsptr);
2258
                    }
2259
                    break;
2260
                case 4: // tick
2261
                    {
2262
                        TCGv r_tickptr;
2263

    
2264
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2265
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2266
                                       offsetof(CPUState, tick));
2267
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_tmp0,
2268
                                           r_tickptr);
2269
                        gen_movl_TN_reg(rd, cpu_tmp0);
2270
                        tcg_temp_free(r_tickptr);
2271
                    }
2272
                    break;
2273
                case 5: // tba
2274
                    tcg_gen_ld_tl(cpu_tmp0, cpu_env,
2275
                                  offsetof(CPUSPARCState, tbr));
2276
                    break;
2277
                case 6: // pstate
2278
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2279
                                   offsetof(CPUSPARCState, pstate));
2280
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2281
                    break;
2282
                case 7: // tl
2283
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2284
                                   offsetof(CPUSPARCState, tl));
2285
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2286
                    break;
2287
                case 8: // pil
2288
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2289
                                   offsetof(CPUSPARCState, psrpil));
2290
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2291
                    break;
2292
                case 9: // cwp
2293
                    tcg_gen_helper_1_0(helper_rdcwp, cpu_tmp0);
2294
                    break;
2295
                case 10: // cansave
2296
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2297
                                   offsetof(CPUSPARCState, cansave));
2298
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2299
                    break;
2300
                case 11: // canrestore
2301
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2302
                                   offsetof(CPUSPARCState, canrestore));
2303
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2304
                    break;
2305
                case 12: // cleanwin
2306
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2307
                                   offsetof(CPUSPARCState, cleanwin));
2308
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2309
                    break;
2310
                case 13: // otherwin
2311
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2312
                                   offsetof(CPUSPARCState, otherwin));
2313
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2314
                    break;
2315
                case 14: // wstate
2316
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2317
                                   offsetof(CPUSPARCState, wstate));
2318
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2319
                    break;
2320
                case 16: // UA2005 gl
2321
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2322
                                   offsetof(CPUSPARCState, gl));
2323
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2324
                    break;
2325
                case 26: // UA2005 strand status
2326
                    if (!hypervisor(dc))
2327
                        goto priv_insn;
2328
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2329
                                   offsetof(CPUSPARCState, ssr));
2330
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2331
                    break;
2332
                case 31: // ver
2333
                    tcg_gen_ld_tl(cpu_tmp0, cpu_env,
2334
                                  offsetof(CPUSPARCState, version));
2335
                    break;
2336
                case 15: // fq
2337
                default:
2338
                    goto illegal_insn;
2339
                }
2340
#else
2341
                tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2342
                               offsetof(CPUSPARCState, wim));
2343
                tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2344
#endif
2345
                gen_movl_TN_reg(rd, cpu_tmp0);
2346
                break;
2347
            } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
2348
#ifdef TARGET_SPARC64
2349
                save_state(dc, cpu_cond);
2350
                tcg_gen_helper_0_0(helper_flushw);
2351
#else
2352
                if (!supervisor(dc))
2353
                    goto priv_insn;
2354
                tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, tbr));
2355
                gen_movl_TN_reg(rd, cpu_tmp0);
2356
#endif
2357
                break;
2358
#endif
2359
            } else if (xop == 0x34) {   /* FPU Operations */
2360
                if (gen_trap_ifnofpu(dc, cpu_cond))
2361
                    goto jmp_insn;
2362
                gen_op_clear_ieee_excp_and_FTT();
2363
                rs1 = GET_FIELD(insn, 13, 17);
2364
                rs2 = GET_FIELD(insn, 27, 31);
2365
                xop = GET_FIELD(insn, 18, 26);
2366
                switch (xop) {
2367
                    case 0x1: /* fmovs */
2368
                        gen_op_load_fpr_FT0(rs2);
2369
                        gen_op_store_FT0_fpr(rd);
2370
                        break;
2371
                    case 0x5: /* fnegs */
2372
                        gen_op_load_fpr_FT1(rs2);
2373
                        tcg_gen_helper_0_0(helper_fnegs);
2374
                        gen_op_store_FT0_fpr(rd);
2375
                        break;
2376
                    case 0x9: /* fabss */
2377
                        gen_op_load_fpr_FT1(rs2);
2378
                        tcg_gen_helper_0_0(helper_fabss);
2379
                        gen_op_store_FT0_fpr(rd);
2380
                        break;
2381
                    case 0x29: /* fsqrts */
2382
                        CHECK_FPU_FEATURE(dc, FSQRT);
2383
                        gen_op_load_fpr_FT1(rs2);
2384
                        gen_clear_float_exceptions();
2385
                        tcg_gen_helper_0_0(helper_fsqrts);
2386
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2387
                        gen_op_store_FT0_fpr(rd);
2388
                        break;
2389
                    case 0x2a: /* fsqrtd */
2390
                        CHECK_FPU_FEATURE(dc, FSQRT);
2391
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2392
                        gen_clear_float_exceptions();
2393
                        tcg_gen_helper_0_0(helper_fsqrtd);
2394
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2395
                        gen_op_store_DT0_fpr(DFPREG(rd));
2396
                        break;
2397
                    case 0x2b: /* fsqrtq */
2398
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2399
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2400
                        gen_clear_float_exceptions();
2401
                        tcg_gen_helper_0_0(helper_fsqrtq);
2402
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2403
                        gen_op_store_QT0_fpr(QFPREG(rd));
2404
                        break;
2405
                    case 0x41:
2406
                        gen_op_load_fpr_FT0(rs1);
2407
                        gen_op_load_fpr_FT1(rs2);
2408
                        gen_clear_float_exceptions();
2409
                        tcg_gen_helper_0_0(helper_fadds);
2410
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2411
                        gen_op_store_FT0_fpr(rd);
2412
                        break;
2413
                    case 0x42:
2414
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2415
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2416
                        gen_clear_float_exceptions();
2417
                        tcg_gen_helper_0_0(helper_faddd);
2418
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2419
                        gen_op_store_DT0_fpr(DFPREG(rd));
2420
                        break;
2421
                    case 0x43: /* faddq */
2422
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2423
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2424
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2425
                        gen_clear_float_exceptions();
2426
                        tcg_gen_helper_0_0(helper_faddq);
2427
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2428
                        gen_op_store_QT0_fpr(QFPREG(rd));
2429
                        break;
2430
                    case 0x45:
2431
                        gen_op_load_fpr_FT0(rs1);
2432
                        gen_op_load_fpr_FT1(rs2);
2433
                        gen_clear_float_exceptions();
2434
                        tcg_gen_helper_0_0(helper_fsubs);
2435
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2436
                        gen_op_store_FT0_fpr(rd);
2437
                        break;
2438
                    case 0x46:
2439
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2440
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2441
                        gen_clear_float_exceptions();
2442
                        tcg_gen_helper_0_0(helper_fsubd);
2443
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2444
                        gen_op_store_DT0_fpr(DFPREG(rd));
2445
                        break;
2446
                    case 0x47: /* fsubq */
2447
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2448
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2449
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2450
                        gen_clear_float_exceptions();
2451
                        tcg_gen_helper_0_0(helper_fsubq);
2452
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2453
                        gen_op_store_QT0_fpr(QFPREG(rd));
2454
                        break;
2455
                    case 0x49: /* fmuls */
2456
                        CHECK_FPU_FEATURE(dc, FMUL);
2457
                        gen_op_load_fpr_FT0(rs1);
2458
                        gen_op_load_fpr_FT1(rs2);
2459
                        gen_clear_float_exceptions();
2460
                        tcg_gen_helper_0_0(helper_fmuls);
2461
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2462
                        gen_op_store_FT0_fpr(rd);
2463
                        break;
2464
                    case 0x4a: /* fmuld */
2465
                        CHECK_FPU_FEATURE(dc, FMUL);
2466
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2467
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2468
                        gen_clear_float_exceptions();
2469
                        tcg_gen_helper_0_0(helper_fmuld);
2470
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2471
                        gen_op_store_DT0_fpr(DFPREG(rd));
2472
                        break;
2473
                    case 0x4b: /* fmulq */
2474
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2475
                        CHECK_FPU_FEATURE(dc, FMUL);
2476
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2477
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2478
                        gen_clear_float_exceptions();
2479
                        tcg_gen_helper_0_0(helper_fmulq);
2480
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2481
                        gen_op_store_QT0_fpr(QFPREG(rd));
2482
                        break;
2483
                    case 0x4d:
2484
                        gen_op_load_fpr_FT0(rs1);
2485
                        gen_op_load_fpr_FT1(rs2);
2486
                        gen_clear_float_exceptions();
2487
                        tcg_gen_helper_0_0(helper_fdivs);
2488
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2489
                        gen_op_store_FT0_fpr(rd);
2490
                        break;
2491
                    case 0x4e:
2492
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2493
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2494
                        gen_clear_float_exceptions();
2495
                        tcg_gen_helper_0_0(helper_fdivd);
2496
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2497
                        gen_op_store_DT0_fpr(DFPREG(rd));
2498
                        break;
2499
                    case 0x4f: /* fdivq */
2500
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2501
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2502
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2503
                        gen_clear_float_exceptions();
2504
                        tcg_gen_helper_0_0(helper_fdivq);
2505
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2506
                        gen_op_store_QT0_fpr(QFPREG(rd));
2507
                        break;
2508
                    case 0x69:
2509
                        CHECK_FPU_FEATURE(dc, FSMULD);
2510
                        gen_op_load_fpr_FT0(rs1);
2511
                        gen_op_load_fpr_FT1(rs2);
2512
                        gen_clear_float_exceptions();
2513
                        tcg_gen_helper_0_0(helper_fsmuld);
2514
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2515
                        gen_op_store_DT0_fpr(DFPREG(rd));
2516
                        break;
2517
                    case 0x6e: /* fdmulq */
2518
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2519
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2520
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2521
                        gen_clear_float_exceptions();
2522
                        tcg_gen_helper_0_0(helper_fdmulq);
2523
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2524
                        gen_op_store_QT0_fpr(QFPREG(rd));
2525
                        break;
2526
                    case 0xc4:
2527
                        gen_op_load_fpr_FT1(rs2);
2528
                        gen_clear_float_exceptions();
2529
                        tcg_gen_helper_0_0(helper_fitos);
2530
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2531
                        gen_op_store_FT0_fpr(rd);
2532
                        break;
2533
                    case 0xc6:
2534
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2535
                        gen_clear_float_exceptions();
2536
                        tcg_gen_helper_0_0(helper_fdtos);
2537
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2538
                        gen_op_store_FT0_fpr(rd);
2539
                        break;
2540
                    case 0xc7: /* fqtos */
2541
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2542
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2543
                        gen_clear_float_exceptions();
2544
                        tcg_gen_helper_0_0(helper_fqtos);
2545
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2546
                        gen_op_store_FT0_fpr(rd);
2547
                        break;
2548
                    case 0xc8:
2549
                        gen_op_load_fpr_FT1(rs2);
2550
                        tcg_gen_helper_0_0(helper_fitod);
2551
                        gen_op_store_DT0_fpr(DFPREG(rd));
2552
                        break;
2553
                    case 0xc9:
2554
                        gen_op_load_fpr_FT1(rs2);
2555
                        tcg_gen_helper_0_0(helper_fstod);
2556
                        gen_op_store_DT0_fpr(DFPREG(rd));
2557
                        break;
2558
                    case 0xcb: /* fqtod */
2559
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2560
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2561
                        gen_clear_float_exceptions();
2562
                        tcg_gen_helper_0_0(helper_fqtod);
2563
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2564
                        gen_op_store_DT0_fpr(DFPREG(rd));
2565
                        break;
2566
                    case 0xcc: /* fitoq */
2567
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2568
                        gen_op_load_fpr_FT1(rs2);
2569
                        tcg_gen_helper_0_0(helper_fitoq);
2570
                        gen_op_store_QT0_fpr(QFPREG(rd));
2571
                        break;
2572
                    case 0xcd: /* fstoq */
2573
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2574
                        gen_op_load_fpr_FT1(rs2);
2575
                        tcg_gen_helper_0_0(helper_fstoq);
2576
                        gen_op_store_QT0_fpr(QFPREG(rd));
2577
                        break;
2578
                    case 0xce: /* fdtoq */
2579
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2580
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2581
                        tcg_gen_helper_0_0(helper_fdtoq);
2582
                        gen_op_store_QT0_fpr(QFPREG(rd));
2583
                        break;
2584
                    case 0xd1:
2585
                        gen_op_load_fpr_FT1(rs2);
2586
                        gen_clear_float_exceptions();
2587
                        tcg_gen_helper_0_0(helper_fstoi);
2588
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2589
                        gen_op_store_FT0_fpr(rd);
2590
                        break;
2591
                    case 0xd2:
2592
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2593
                        gen_clear_float_exceptions();
2594
                        tcg_gen_helper_0_0(helper_fdtoi);
2595
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2596
                        gen_op_store_FT0_fpr(rd);
2597
                        break;
2598
                    case 0xd3: /* fqtoi */
2599
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2600
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2601
                        gen_clear_float_exceptions();
2602
                        tcg_gen_helper_0_0(helper_fqtoi);
2603
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2604
                        gen_op_store_FT0_fpr(rd);
2605
                        break;
2606
#ifdef TARGET_SPARC64
2607
                    case 0x2: /* V9 fmovd */
2608
                        gen_op_load_fpr_DT0(DFPREG(rs2));
2609
                        gen_op_store_DT0_fpr(DFPREG(rd));
2610
                        break;
2611
                    case 0x3: /* V9 fmovq */
2612
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2613
                        gen_op_load_fpr_QT0(QFPREG(rs2));
2614
                        gen_op_store_QT0_fpr(QFPREG(rd));
2615
                        break;
2616
                    case 0x6: /* V9 fnegd */
2617
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2618
                        tcg_gen_helper_0_0(helper_fnegd);
2619
                        gen_op_store_DT0_fpr(DFPREG(rd));
2620
                        break;
2621
                    case 0x7: /* V9 fnegq */
2622
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2623
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2624
                        tcg_gen_helper_0_0(helper_fnegq);
2625
                        gen_op_store_QT0_fpr(QFPREG(rd));
2626
                        break;
2627
                    case 0xa: /* V9 fabsd */
2628
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2629
                        tcg_gen_helper_0_0(helper_fabsd);
2630
                        gen_op_store_DT0_fpr(DFPREG(rd));
2631
                        break;
2632
                    case 0xb: /* V9 fabsq */
2633
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2634
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2635
                        tcg_gen_helper_0_0(helper_fabsq);
2636
                        gen_op_store_QT0_fpr(QFPREG(rd));
2637
                        break;
2638
                    case 0x81: /* V9 fstox */
2639
                        gen_op_load_fpr_FT1(rs2);
2640
                        gen_clear_float_exceptions();
2641
                        tcg_gen_helper_0_0(helper_fstox);
2642
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2643
                        gen_op_store_DT0_fpr(DFPREG(rd));
2644
                        break;
2645
                    case 0x82: /* V9 fdtox */
2646
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2647
                        gen_clear_float_exceptions();
2648
                        tcg_gen_helper_0_0(helper_fdtox);
2649
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2650
                        gen_op_store_DT0_fpr(DFPREG(rd));
2651
                        break;
2652
                    case 0x83: /* V9 fqtox */
2653
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2654
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2655
                        gen_clear_float_exceptions();
2656
                        tcg_gen_helper_0_0(helper_fqtox);
2657
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2658
                        gen_op_store_DT0_fpr(DFPREG(rd));
2659
                        break;
2660
                    case 0x84: /* V9 fxtos */
2661
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2662
                        gen_clear_float_exceptions();
2663
                        tcg_gen_helper_0_0(helper_fxtos);
2664
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2665
                        gen_op_store_FT0_fpr(rd);
2666
                        break;
2667
                    case 0x88: /* V9 fxtod */
2668
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2669
                        gen_clear_float_exceptions();
2670
                        tcg_gen_helper_0_0(helper_fxtod);
2671
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2672
                        gen_op_store_DT0_fpr(DFPREG(rd));
2673
                        break;
2674
                    case 0x8c: /* V9 fxtoq */
2675
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2676
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2677
                        gen_clear_float_exceptions();
2678
                        tcg_gen_helper_0_0(helper_fxtoq);
2679
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2680
                        gen_op_store_QT0_fpr(QFPREG(rd));
2681
                        break;
2682
#endif
2683
                    default:
2684
                        goto illegal_insn;
2685
                }
2686
            } else if (xop == 0x35) {   /* FPU Operations */
2687
#ifdef TARGET_SPARC64
2688
                int cond;
2689
#endif
2690
                if (gen_trap_ifnofpu(dc, cpu_cond))
2691
                    goto jmp_insn;
2692
                gen_op_clear_ieee_excp_and_FTT();
2693
                rs1 = GET_FIELD(insn, 13, 17);
2694
                rs2 = GET_FIELD(insn, 27, 31);
2695
                xop = GET_FIELD(insn, 18, 26);
2696
#ifdef TARGET_SPARC64
2697
                if ((xop & 0x11f) == 0x005) { // V9 fmovsr
2698
                    int l1;
2699

    
2700
                    l1 = gen_new_label();
2701
                    cond = GET_FIELD_SP(insn, 14, 17);
2702
                    cpu_src1 = get_src1(insn, cpu_src1);
2703
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2704
                                       0, l1);
2705
                    gen_op_load_fpr_FT0(rs2);
2706
                    gen_op_store_FT0_fpr(rd);
2707
                    gen_set_label(l1);
2708
                    break;
2709
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
2710
                    int l1;
2711

    
2712
                    l1 = gen_new_label();
2713
                    cond = GET_FIELD_SP(insn, 14, 17);
2714
                    cpu_src1 = get_src1(insn, cpu_src1);
2715
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2716
                                       0, l1);
2717
                    gen_op_load_fpr_DT0(DFPREG(rs2));
2718
                    gen_op_store_DT0_fpr(DFPREG(rd));
2719
                    gen_set_label(l1);
2720
                    break;
2721
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
2722
                    int l1;
2723

    
2724
                    CHECK_FPU_FEATURE(dc, FLOAT128);
2725
                    l1 = gen_new_label();
2726
                    cond = GET_FIELD_SP(insn, 14, 17);
2727
                    cpu_src1 = get_src1(insn, cpu_src1);
2728
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2729
                                       0, l1);
2730
                    gen_op_load_fpr_QT0(QFPREG(rs2));
2731
                    gen_op_store_QT0_fpr(QFPREG(rd));
2732
                    gen_set_label(l1);
2733
                    break;
2734
                }
2735
#endif
2736
                switch (xop) {
2737
#ifdef TARGET_SPARC64
2738
#define FMOVCC(size_FDQ, fcc)                                           \
2739
                    {                                                   \
2740
                        TCGv r_cond;                                    \
2741
                        int l1;                                         \
2742
                                                                        \
2743
                        l1 = gen_new_label();                           \
2744
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2745
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2746
                        gen_fcond(r_cond, fcc, cond);                   \
2747
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2748
                                           0, l1);                      \
2749
                        glue(glue(gen_op_load_fpr_, size_FDQ), T0)      \
2750
                            (glue(size_FDQ, FPREG(rs2)));               \
2751
                        glue(glue(gen_op_store_, size_FDQ), T0_fpr)     \
2752
                            (glue(size_FDQ, FPREG(rd)));                \
2753
                        gen_set_label(l1);                              \
2754
                        tcg_temp_free(r_cond);                          \
2755
                    }
2756
                    case 0x001: /* V9 fmovscc %fcc0 */
2757
                        FMOVCC(F, 0);
2758
                        break;
2759
                    case 0x002: /* V9 fmovdcc %fcc0 */
2760
                        FMOVCC(D, 0);
2761
                        break;
2762
                    case 0x003: /* V9 fmovqcc %fcc0 */
2763
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2764
                        FMOVCC(Q, 0);
2765
                        break;
2766
                    case 0x041: /* V9 fmovscc %fcc1 */
2767
                        FMOVCC(F, 1);
2768
                        break;
2769
                    case 0x042: /* V9 fmovdcc %fcc1 */
2770
                        FMOVCC(D, 1);
2771
                        break;
2772
                    case 0x043: /* V9 fmovqcc %fcc1 */
2773
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2774
                        FMOVCC(Q, 1);
2775
                        break;
2776
                    case 0x081: /* V9 fmovscc %fcc2 */
2777
                        FMOVCC(F, 2);
2778
                        break;
2779
                    case 0x082: /* V9 fmovdcc %fcc2 */
2780
                        FMOVCC(D, 2);
2781
                        break;
2782
                    case 0x083: /* V9 fmovqcc %fcc2 */
2783
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2784
                        FMOVCC(Q, 2);
2785
                        break;
2786
                    case 0x0c1: /* V9 fmovscc %fcc3 */
2787
                        FMOVCC(F, 3);
2788
                        break;
2789
                    case 0x0c2: /* V9 fmovdcc %fcc3 */
2790
                        FMOVCC(D, 3);
2791
                        break;
2792
                    case 0x0c3: /* V9 fmovqcc %fcc3 */
2793
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2794
                        FMOVCC(Q, 3);
2795
                        break;
2796
#undef FMOVCC
2797
#define FMOVCC(size_FDQ, icc)                                           \
2798
                    {                                                   \
2799
                        TCGv r_cond;                                    \
2800
                        int l1;                                         \
2801
                                                                        \
2802
                        l1 = gen_new_label();                           \
2803
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2804
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2805
                        gen_cond(r_cond, icc, cond);                    \
2806
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2807
                                           0, l1);                      \
2808
                        glue(glue(gen_op_load_fpr_, size_FDQ), T0)      \
2809
                            (glue(size_FDQ, FPREG(rs2)));               \
2810
                        glue(glue(gen_op_store_, size_FDQ), T0_fpr)     \
2811
                            (glue(size_FDQ, FPREG(rd)));                \
2812
                        gen_set_label(l1);                              \
2813
                        tcg_temp_free(r_cond);                          \
2814
                    }
2815

    
2816
                    case 0x101: /* V9 fmovscc %icc */
2817
                        FMOVCC(F, 0);
2818
                        break;
2819
                    case 0x102: /* V9 fmovdcc %icc */
2820
                        FMOVCC(D, 0);
2821
                    case 0x103: /* V9 fmovqcc %icc */
2822
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2823
                        FMOVCC(Q, 0);
2824
                        break;
2825
                    case 0x181: /* V9 fmovscc %xcc */
2826
                        FMOVCC(F, 1);
2827
                        break;
2828
                    case 0x182: /* V9 fmovdcc %xcc */
2829
                        FMOVCC(D, 1);
2830
                        break;
2831
                    case 0x183: /* V9 fmovqcc %xcc */
2832
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2833
                        FMOVCC(Q, 1);
2834
                        break;
2835
#undef FMOVCC
2836
#endif
2837
                    case 0x51: /* fcmps, V9 %fcc */
2838
                        gen_op_load_fpr_FT0(rs1);
2839
                        gen_op_load_fpr_FT1(rs2);
2840
                        gen_op_fcmps(rd & 3);
2841
                        break;
2842
                    case 0x52: /* fcmpd, V9 %fcc */
2843
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2844
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2845
                        gen_op_fcmpd(rd & 3);
2846
                        break;
2847
                    case 0x53: /* fcmpq, V9 %fcc */
2848
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2849
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2850
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2851
                        gen_op_fcmpq(rd & 3);
2852
                        break;
2853
                    case 0x55: /* fcmpes, V9 %fcc */
2854
                        gen_op_load_fpr_FT0(rs1);
2855
                        gen_op_load_fpr_FT1(rs2);
2856
                        gen_op_fcmpes(rd & 3);
2857
                        break;
2858
                    case 0x56: /* fcmped, V9 %fcc */
2859
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2860
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2861
                        gen_op_fcmped(rd & 3);
2862
                        break;
2863
                    case 0x57: /* fcmpeq, V9 %fcc */
2864
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2865
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2866
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2867
                        gen_op_fcmpeq(rd & 3);
2868
                        break;
2869
                    default:
2870
                        goto illegal_insn;
2871
                }
2872
            } else if (xop == 0x2) {
2873
                // clr/mov shortcut
2874

    
2875
                rs1 = GET_FIELD(insn, 13, 17);
2876
                if (rs1 == 0) {
2877
                    // or %g0, x, y -> mov T0, x; mov y, T0
2878
                    if (IS_IMM) {       /* immediate */
2879
                        TCGv r_const;
2880

    
2881
                        rs2 = GET_FIELDs(insn, 19, 31);
2882
                        r_const = tcg_const_tl((int)rs2);
2883
                        gen_movl_TN_reg(rd, r_const);
2884
                        tcg_temp_free(r_const);
2885
                    } else {            /* register */
2886
                        rs2 = GET_FIELD(insn, 27, 31);
2887
                        gen_movl_reg_TN(rs2, cpu_dst);
2888
                        gen_movl_TN_reg(rd, cpu_dst);
2889
                    }
2890
                } else {
2891
                    cpu_src1 = get_src1(insn, cpu_src1);
2892
                    if (IS_IMM) {       /* immediate */
2893
                        rs2 = GET_FIELDs(insn, 19, 31);
2894
                        tcg_gen_ori_tl(cpu_dst, cpu_src1, (int)rs2);
2895
                        gen_movl_TN_reg(rd, cpu_dst);
2896
                    } else {            /* register */
2897
                        // or x, %g0, y -> mov T1, x; mov y, T1
2898
                        rs2 = GET_FIELD(insn, 27, 31);
2899
                        if (rs2 != 0) {
2900
                            gen_movl_reg_TN(rs2, cpu_src2);
2901
                            tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
2902
                            gen_movl_TN_reg(rd, cpu_dst);
2903
                        } else
2904
                            gen_movl_TN_reg(rd, cpu_src1);
2905
                    }
2906
                }
2907
#ifdef TARGET_SPARC64
2908
            } else if (xop == 0x25) { /* sll, V9 sllx */
2909
                cpu_src1 = get_src1(insn, cpu_src1);
2910
                if (IS_IMM) {   /* immediate */
2911
                    rs2 = GET_FIELDs(insn, 20, 31);
2912
                    if (insn & (1 << 12)) {
2913
                        tcg_gen_shli_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
2914
                    } else {
2915
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2916
                        tcg_gen_shli_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
2917
                    }
2918
                } else {                /* register */
2919
                    rs2 = GET_FIELD(insn, 27, 31);
2920
                    gen_movl_reg_TN(rs2, cpu_src2);
2921
                    if (insn & (1 << 12)) {
2922
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2923
                        tcg_gen_shl_i64(cpu_dst, cpu_src1, cpu_tmp0);
2924
                    } else {
2925
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2926
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2927
                        tcg_gen_shl_i64(cpu_dst, cpu_dst, cpu_tmp0);
2928
                    }
2929
                }
2930
                gen_movl_TN_reg(rd, cpu_dst);
2931
            } else if (xop == 0x26) { /* srl, V9 srlx */
2932
                cpu_src1 = get_src1(insn, cpu_src1);
2933
                if (IS_IMM) {   /* immediate */
2934
                    rs2 = GET_FIELDs(insn, 20, 31);
2935
                    if (insn & (1 << 12)) {
2936
                        tcg_gen_shri_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
2937
                    } else {
2938
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2939
                        tcg_gen_shri_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
2940
                    }
2941
                } else {                /* register */
2942
                    rs2 = GET_FIELD(insn, 27, 31);
2943
                    gen_movl_reg_TN(rs2, cpu_src2);
2944
                    if (insn & (1 << 12)) {
2945
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2946
                        tcg_gen_shr_i64(cpu_dst, cpu_src1, cpu_tmp0);
2947
                    } else {
2948
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2949
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2950
                        tcg_gen_shr_i64(cpu_dst, cpu_dst, cpu_tmp0);
2951
                    }
2952
                }
2953
                gen_movl_TN_reg(rd, cpu_dst);
2954
            } else if (xop == 0x27) { /* sra, V9 srax */
2955
                cpu_src1 = get_src1(insn, cpu_src1);
2956
                if (IS_IMM) {   /* immediate */
2957
                    rs2 = GET_FIELDs(insn, 20, 31);
2958
                    if (insn & (1 << 12)) {
2959
                        tcg_gen_sari_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
2960
                    } else {
2961
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2962
                        tcg_gen_ext_i32_i64(cpu_dst, cpu_dst);
2963
                        tcg_gen_sari_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
2964
                    }
2965
                } else {                /* register */
2966
                    rs2 = GET_FIELD(insn, 27, 31);
2967
                    gen_movl_reg_TN(rs2, cpu_src2);
2968
                    if (insn & (1 << 12)) {
2969
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2970
                        tcg_gen_sar_i64(cpu_dst, cpu_src1, cpu_tmp0);
2971
                    } else {
2972
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2973
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2974
                        tcg_gen_sar_i64(cpu_dst, cpu_dst, cpu_tmp0);
2975
                    }
2976
                }
2977
                gen_movl_TN_reg(rd, cpu_dst);
2978
#endif
2979
            } else if (xop < 0x36) {
2980
                cpu_src1 = get_src1(insn, cpu_src1);
2981
                cpu_src2 = get_src2(insn, cpu_src2);
2982
                if (xop < 0x20) {
2983
                    switch (xop & ~0x10) {
2984
                    case 0x0:
2985
                        if (xop & 0x10)
2986
                            gen_op_add_cc(cpu_dst, cpu_src1, cpu_src2);
2987
                        else
2988
                            tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
2989
                        break;
2990
                    case 0x1:
2991
                        tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_src2);
2992
                        if (xop & 0x10)
2993
                            gen_op_logic_cc(cpu_dst);
2994
                        break;
2995
                    case 0x2:
2996
                        tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
2997
                        if (xop & 0x10)
2998
                            gen_op_logic_cc(cpu_dst);
2999
                        break;
3000
                    case 0x3:
3001
                        tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3002
                        if (xop & 0x10)
3003
                            gen_op_logic_cc(cpu_dst);
3004
                        break;
3005
                    case 0x4:
3006
                        if (xop & 0x10)
3007
                            gen_op_sub_cc(cpu_dst, cpu_src1, cpu_src2);
3008
                        else
3009
                            tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_src2);
3010
                        break;
3011
                    case 0x5:
3012
                        tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
3013
                        tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_tmp0);
3014
                        if (xop & 0x10)
3015
                            gen_op_logic_cc(cpu_dst);
3016
                        break;
3017
                    case 0x6:
3018
                        tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
3019
                        tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_tmp0);
3020
                        if (xop & 0x10)
3021
                            gen_op_logic_cc(cpu_dst);
3022
                        break;
3023
                    case 0x7:
3024
                        tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
3025
                        tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_tmp0);
3026
                        if (xop & 0x10)
3027
                            gen_op_logic_cc(cpu_dst);
3028
                        break;
3029
                    case 0x8:
3030
                        if (xop & 0x10)
3031
                            gen_op_addx_cc(cpu_dst, cpu_src1, cpu_src2);
3032
                        else {
3033
                            gen_mov_reg_C(cpu_tmp0, cpu_psr);
3034
                            tcg_gen_add_tl(cpu_tmp0, cpu_src2, cpu_tmp0);
3035
                            tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_tmp0);
3036
                        }
3037
                        break;
3038
#ifdef TARGET_SPARC64
3039
                    case 0x9: /* V9 mulx */
3040
                        tcg_gen_mul_i64(cpu_dst, cpu_src1, cpu_src2);
3041
                        break;
3042
#endif
3043
                    case 0xa:
3044
                        CHECK_IU_FEATURE(dc, MUL);
3045
                        gen_op_umul(cpu_dst, cpu_src1, cpu_src2);
3046
                        if (xop & 0x10)
3047
                            gen_op_logic_cc(cpu_dst);
3048
                        break;
3049
                    case 0xb:
3050
                        CHECK_IU_FEATURE(dc, MUL);
3051
                        gen_op_smul(cpu_dst, cpu_src1, cpu_src2);
3052
                        if (xop & 0x10)
3053
                            gen_op_logic_cc(cpu_dst);
3054
                        break;
3055
                    case 0xc:
3056
                        if (xop & 0x10)
3057
                            gen_op_subx_cc(cpu_dst, cpu_src1, cpu_src2);
3058
                        else {
3059
                            gen_mov_reg_C(cpu_tmp0, cpu_psr);
3060
                            tcg_gen_add_tl(cpu_tmp0, cpu_src2, cpu_tmp0);
3061
                            tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_tmp0);
3062
                        }
3063
                        break;
3064
#ifdef TARGET_SPARC64
3065
                    case 0xd: /* V9 udivx */
3066
                        tcg_gen_mov_tl(cpu_cc_src, cpu_src1);
3067
                        tcg_gen_mov_tl(cpu_cc_src2, cpu_src2);
3068
                        gen_trap_ifdivzero_tl(cpu_cc_src2);
3069
                        tcg_gen_divu_i64(cpu_dst, cpu_cc_src, cpu_cc_src2);
3070
                        break;
3071
#endif
3072
                    case 0xe:
3073
                        CHECK_IU_FEATURE(dc, DIV);
3074
                        tcg_gen_helper_1_2(helper_udiv, cpu_dst, cpu_src1,
3075
                                           cpu_src2);
3076
                        if (xop & 0x10)
3077
                            gen_op_div_cc(cpu_dst);
3078
                        break;
3079
                    case 0xf:
3080
                        CHECK_IU_FEATURE(dc, DIV);
3081
                        tcg_gen_helper_1_2(helper_sdiv, cpu_dst, cpu_src1,
3082
                                           cpu_src2);
3083
                        if (xop & 0x10)
3084
                            gen_op_div_cc(cpu_dst);
3085
                        break;
3086
                    default:
3087
                        goto illegal_insn;
3088
                    }
3089
                    gen_movl_TN_reg(rd, cpu_dst);
3090
                } else {
3091
                    switch (xop) {
3092
                    case 0x20: /* taddcc */
3093
                        gen_op_tadd_cc(cpu_dst, cpu_src1, cpu_src2);
3094
                        gen_movl_TN_reg(rd, cpu_dst);
3095
                        break;
3096
                    case 0x21: /* tsubcc */
3097
                        gen_op_tsub_cc(cpu_dst, cpu_src1, cpu_src2);
3098
                        gen_movl_TN_reg(rd, cpu_dst);
3099
                        break;
3100
                    case 0x22: /* taddcctv */
3101
                        save_state(dc, cpu_cond);
3102
                        gen_op_tadd_ccTV(cpu_dst, cpu_src1, cpu_src2);
3103
                        gen_movl_TN_reg(rd, cpu_dst);
3104
                        break;
3105
                    case 0x23: /* tsubcctv */
3106
                        save_state(dc, cpu_cond);
3107
                        gen_op_tsub_ccTV(cpu_dst, cpu_src1, cpu_src2);
3108
                        gen_movl_TN_reg(rd, cpu_dst);
3109
                        break;
3110
                    case 0x24: /* mulscc */
3111
                        gen_op_mulscc(cpu_dst, cpu_src1, cpu_src2);
3112
                        gen_movl_TN_reg(rd, cpu_dst);
3113
                        break;
3114
#ifndef TARGET_SPARC64
3115
                    case 0x25:  /* sll */
3116
                        if (IS_IMM) { /* immediate */
3117
                            rs2 = GET_FIELDs(insn, 20, 31);
3118
                            tcg_gen_shli_tl(cpu_dst, cpu_src1, rs2 & 0x1f);
3119
                        } else { /* register */
3120
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3121
                            tcg_gen_shl_tl(cpu_dst, cpu_src1, cpu_tmp0);
3122
                        }
3123
                        gen_movl_TN_reg(rd, cpu_dst);
3124
                        break;
3125
                    case 0x26:  /* srl */
3126
                        if (IS_IMM) { /* immediate */
3127
                            rs2 = GET_FIELDs(insn, 20, 31);
3128
                            tcg_gen_shri_tl(cpu_dst, cpu_src1, rs2 & 0x1f);
3129
                        } else { /* register */
3130
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3131
                            tcg_gen_shr_tl(cpu_dst, cpu_src1, cpu_tmp0);
3132
                        }
3133
                        gen_movl_TN_reg(rd, cpu_dst);
3134
                        break;
3135
                    case 0x27:  /* sra */
3136
                        if (IS_IMM) { /* immediate */
3137
                            rs2 = GET_FIELDs(insn, 20, 31);
3138
                            tcg_gen_sari_tl(cpu_dst, cpu_src1, rs2 & 0x1f);
3139
                        } else { /* register */
3140
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3141
                            tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0);
3142
                        }
3143
                        gen_movl_TN_reg(rd, cpu_dst);
3144
                        break;
3145
#endif
3146
                    case 0x30:
3147
                        {
3148
                            switch(rd) {
3149
                            case 0: /* wry */
3150
                                tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
3151
                                tcg_gen_st_tl(cpu_tmp0, cpu_env,
3152
                                              offsetof(CPUSPARCState, y));
3153
                                break;
3154
#ifndef TARGET_SPARC64
3155
                            case 0x01 ... 0x0f: /* undefined in the
3156
                                                   SPARCv8 manual, nop
3157
                                                   on the microSPARC
3158
                                                   II */
3159
                            case 0x10 ... 0x1f: /* implementation-dependent
3160
                                                   in the SPARCv8
3161
                                                   manual, nop on the
3162
                                                   microSPARC II */
3163
                                break;
3164
#else
3165
                            case 0x2: /* V9 wrccr */
3166
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3167
                                tcg_gen_helper_0_1(helper_wrccr, cpu_dst);
3168
                                break;
3169
                            case 0x3: /* V9 wrasi */
3170
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3171
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3172
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3173
                                               offsetof(CPUSPARCState, asi));
3174
                                break;
3175
                            case 0x6: /* V9 wrfprs */
3176
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3177
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3178
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3179
                                               offsetof(CPUSPARCState, fprs));
3180
                                save_state(dc, cpu_cond);
3181
                                gen_op_next_insn();
3182
                                tcg_gen_exit_tb(0);
3183
                                dc->is_br = 1;
3184
                                break;
3185
                            case 0xf: /* V9 sir, nop if user */
3186
#if !defined(CONFIG_USER_ONLY)
3187
                                if (supervisor(dc))
3188
                                    ; // XXX
3189
#endif
3190
                                break;
3191
                            case 0x13: /* Graphics Status */
3192
                                if (gen_trap_ifnofpu(dc, cpu_cond))
3193
                                    goto jmp_insn;
3194
                                tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
3195
                                tcg_gen_st_tl(cpu_tmp0, cpu_env,
3196
                                              offsetof(CPUSPARCState, gsr));
3197
                                break;
3198
                            case 0x17: /* Tick compare */
3199
#if !defined(CONFIG_USER_ONLY)
3200
                                if (!supervisor(dc))
3201
                                    goto illegal_insn;
3202
#endif
3203
                                {
3204
                                    TCGv r_tickptr;
3205

    
3206
                                    tcg_gen_xor_tl(cpu_tmp0, cpu_src1,
3207
                                                   cpu_src2);
3208
                                    tcg_gen_st_tl(cpu_tmp0, cpu_env,
3209
                                                  offsetof(CPUSPARCState,
3210
                                                           tick_cmpr));
3211
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3212
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3213
                                                   offsetof(CPUState, tick));
3214
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3215
                                                       r_tickptr, cpu_tmp0);
3216
                                    tcg_temp_free(r_tickptr);
3217
                                }
3218
                                break;
3219
                            case 0x18: /* System tick */
3220
#if !defined(CONFIG_USER_ONLY)
3221
                                if (!supervisor(dc))
3222
                                    goto illegal_insn;
3223
#endif
3224
                                {
3225
                                    TCGv r_tickptr;
3226

    
3227
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
3228
                                                   cpu_src2);
3229
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3230
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3231
                                                   offsetof(CPUState, stick));
3232
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3233
                                                       r_tickptr, cpu_dst);
3234
                                    tcg_temp_free(r_tickptr);
3235
                                }
3236
                                break;
3237
                            case 0x19: /* System tick compare */
3238
#if !defined(CONFIG_USER_ONLY)
3239
                                if (!supervisor(dc))
3240
                                    goto illegal_insn;
3241
#endif
3242
                                {
3243
                                    TCGv r_tickptr;
3244

    
3245
                                    tcg_gen_xor_tl(cpu_tmp0, cpu_src1,
3246
                                                   cpu_src2);
3247
                                    tcg_gen_st_tl(cpu_tmp0, cpu_env,
3248
                                                  offsetof(CPUSPARCState,
3249
                                                           stick_cmpr));
3250
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3251
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3252
                                                   offsetof(CPUState, stick));
3253
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3254
                                                       r_tickptr, cpu_tmp0);
3255
                                    tcg_temp_free(r_tickptr);
3256
                                }
3257
                                break;
3258

    
3259
                            case 0x10: /* Performance Control */
3260
                            case 0x11: /* Performance Instrumentation
3261
                                          Counter */
3262
                            case 0x12: /* Dispatch Control */
3263
                            case 0x14: /* Softint set */
3264
                            case 0x15: /* Softint clear */
3265
                            case 0x16: /* Softint write */
3266
#endif
3267
                            default:
3268
                                goto illegal_insn;
3269
                            }
3270
                        }
3271
                        break;
3272
#if !defined(CONFIG_USER_ONLY)
3273
                    case 0x31: /* wrpsr, V9 saved, restored */
3274
                        {
3275
                            if (!supervisor(dc))
3276
                                goto priv_insn;
3277
#ifdef TARGET_SPARC64
3278
                            switch (rd) {
3279
                            case 0:
3280
                                tcg_gen_helper_0_0(helper_saved);
3281
                                break;
3282
                            case 1:
3283
                                tcg_gen_helper_0_0(helper_restored);
3284
                                break;
3285
                            case 2: /* UA2005 allclean */
3286
                            case 3: /* UA2005 otherw */
3287
                            case 4: /* UA2005 normalw */
3288
                            case 5: /* UA2005 invalw */
3289
                                // XXX
3290
                            default:
3291
                                goto illegal_insn;
3292
                            }
3293
#else
3294
                            tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3295
                            tcg_gen_helper_0_1(helper_wrpsr, cpu_dst);
3296
                            save_state(dc, cpu_cond);
3297
                            gen_op_next_insn();
3298
                            tcg_gen_exit_tb(0);
3299
                            dc->is_br = 1;
3300
#endif
3301
                        }
3302
                        break;
3303
                    case 0x32: /* wrwim, V9 wrpr */
3304
                        {
3305
                            if (!supervisor(dc))
3306
                                goto priv_insn;
3307
                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
3308
#ifdef TARGET_SPARC64
3309
                            switch (rd) {
3310
                            case 0: // tpc
3311
                                {
3312
                                    TCGv r_tsptr;
3313

    
3314
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3315
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3316
                                                   offsetof(CPUState, tsptr));
3317
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3318
                                                  offsetof(trap_state, tpc));
3319
                                    tcg_temp_free(r_tsptr);
3320
                                }
3321
                                break;
3322
                            case 1: // tnpc
3323
                                {
3324
                                    TCGv r_tsptr;
3325

    
3326
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3327
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3328
                                                   offsetof(CPUState, tsptr));
3329
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3330
                                                  offsetof(trap_state, tnpc));
3331
                                    tcg_temp_free(r_tsptr);
3332
                                }
3333
                                break;
3334
                            case 2: // tstate
3335
                                {
3336
                                    TCGv r_tsptr;
3337

    
3338
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3339
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3340
                                                   offsetof(CPUState, tsptr));
3341
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3342
                                                  offsetof(trap_state,
3343
                                                           tstate));
3344
                                    tcg_temp_free(r_tsptr);
3345
                                }
3346
                                break;
3347
                            case 3: // tt
3348
                                {
3349
                                    TCGv r_tsptr;
3350

    
3351
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3352
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3353
                                                   offsetof(CPUState, tsptr));
3354
                                    tcg_gen_st_i32(cpu_tmp0, r_tsptr,
3355
                                                   offsetof(trap_state, tt));
3356
                                    tcg_temp_free(r_tsptr);
3357
                                }
3358
                                break;
3359
                            case 4: // tick
3360
                                {
3361
                                    TCGv r_tickptr;
3362

    
3363
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3364
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3365
                                                   offsetof(CPUState, tick));
3366
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3367
                                                       r_tickptr, cpu_tmp0);
3368
                                    tcg_temp_free(r_tickptr);
3369
                                }
3370
                                break;
3371
                            case 5: // tba
3372
                                tcg_gen_st_tl(cpu_tmp0, cpu_env,
3373
                                              offsetof(CPUSPARCState, tbr));
3374
                                break;
3375
                            case 6: // pstate
3376
                                save_state(dc, cpu_cond);
3377
                                tcg_gen_helper_0_1(helper_wrpstate, cpu_tmp0);
3378
                                gen_op_next_insn();
3379
                                tcg_gen_exit_tb(0);
3380
                                dc->is_br = 1;
3381
                                break;
3382
                            case 7: // tl
3383
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3384
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3385
                                               offsetof(CPUSPARCState, tl));
3386
                                break;
3387
                            case 8: // pil
3388
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3389
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3390
                                               offsetof(CPUSPARCState,
3391
                                                        psrpil));
3392
                                break;
3393
                            case 9: // cwp
3394
                                tcg_gen_helper_0_1(helper_wrcwp, cpu_tmp0);
3395
                                break;
3396
                            case 10: // cansave
3397
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3398
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3399
                                               offsetof(CPUSPARCState,
3400
                                                        cansave));
3401
                                break;
3402
                            case 11: // canrestore
3403
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3404
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3405
                                               offsetof(CPUSPARCState,
3406
                                                        canrestore));
3407
                                break;
3408
                            case 12: // cleanwin
3409
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3410
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3411
                                               offsetof(CPUSPARCState,
3412
                                                        cleanwin));
3413
                                break;
3414
                            case 13: // otherwin
3415
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3416
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3417
                                               offsetof(CPUSPARCState,
3418
                                                        otherwin));
3419
                                break;
3420
                            case 14: // wstate
3421
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3422
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3423
                                               offsetof(CPUSPARCState,
3424
                                                        wstate));
3425
                                break;
3426
                            case 16: // UA2005 gl
3427
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3428
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3429
                                               offsetof(CPUSPARCState, gl));
3430
                                break;
3431
                            case 26: // UA2005 strand status
3432
                                if (!hypervisor(dc))
3433
                                    goto priv_insn;
3434
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3435
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3436
                                               offsetof(CPUSPARCState, ssr));
3437
                                break;
3438
                            default:
3439
                                goto illegal_insn;
3440
                            }
3441
#else
3442
                            tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3443
                            tcg_gen_st_i32(cpu_tmp32, cpu_env,
3444
                                           offsetof(CPUSPARCState, wim));
3445
#endif
3446
                        }
3447
                        break;
3448
                    case 0x33: /* wrtbr, UA2005 wrhpr */
3449
                        {
3450
#ifndef TARGET_SPARC64
3451
                            if (!supervisor(dc))
3452
                                goto priv_insn;
3453
                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
3454
                            tcg_gen_st_tl(cpu_tmp0, cpu_env,
3455
                                          offsetof(CPUSPARCState, tbr));
3456
#else
3457
                            if (!hypervisor(dc))
3458
                                goto priv_insn;
3459
                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
3460
                            switch (rd) {
3461
                            case 0: // hpstate
3462
                                // XXX gen_op_wrhpstate();
3463
                                save_state(dc, cpu_cond);
3464
                                gen_op_next_insn();
3465
                                tcg_gen_exit_tb(0);
3466
                                dc->is_br = 1;
3467
                                break;
3468
                            case 1: // htstate
3469
                                // XXX gen_op_wrhtstate();
3470
                                break;
3471
                            case 3: // hintp
3472
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3473
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3474
                                               offsetof(CPUSPARCState, hintp));
3475
                                break;
3476
                            case 5: // htba
3477
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3478
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3479
                                               offsetof(CPUSPARCState, htba));
3480
                                break;
3481
                            case 31: // hstick_cmpr
3482
                                {
3483
                                    TCGv r_tickptr;
3484

    
3485
                                    tcg_gen_st_tl(cpu_tmp0, cpu_env,
3486
                                                  offsetof(CPUSPARCState,
3487
                                                           hstick_cmpr));
3488
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3489
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3490
                                                   offsetof(CPUState, hstick));
3491
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3492
                                                       r_tickptr, cpu_tmp0);
3493
                                    tcg_temp_free(r_tickptr);
3494
                                }
3495
                                break;
3496
                            case 6: // hver readonly
3497
                            default:
3498
                                goto illegal_insn;
3499
                            }
3500
#endif
3501
                        }
3502
                        break;
3503
#endif
3504
#ifdef TARGET_SPARC64
3505
                    case 0x2c: /* V9 movcc */
3506
                        {
3507
                            int cc = GET_FIELD_SP(insn, 11, 12);
3508
                            int cond = GET_FIELD_SP(insn, 14, 17);
3509
                            TCGv r_cond;
3510
                            int l1;
3511

    
3512
                            r_cond = tcg_temp_new(TCG_TYPE_TL);
3513
                            if (insn & (1 << 18)) {
3514
                                if (cc == 0)
3515
                                    gen_cond(r_cond, 0, cond);
3516
                                else if (cc == 2)
3517
                                    gen_cond(r_cond, 1, cond);
3518
                                else
3519
                                    goto illegal_insn;
3520
                            } else {
3521
                                gen_fcond(r_cond, cc, cond);
3522
                            }
3523

    
3524
                            l1 = gen_new_label();
3525

    
3526
                            tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
3527
                            if (IS_IMM) {       /* immediate */
3528
                                TCGv r_const;
3529

    
3530
                                rs2 = GET_FIELD_SPs(insn, 0, 10);
3531
                                r_const = tcg_const_tl((int)rs2);
3532
                                gen_movl_TN_reg(rd, r_const);
3533
                                tcg_temp_free(r_const);
3534
                            } else {
3535
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3536
                                gen_movl_reg_TN(rs2, cpu_tmp0);
3537
                                gen_movl_TN_reg(rd, cpu_tmp0);
3538
                            }
3539
                            gen_set_label(l1);
3540
                            tcg_temp_free(r_cond);
3541
                            break;
3542
                        }
3543
                    case 0x2d: /* V9 sdivx */
3544
                        gen_op_sdivx(cpu_dst, cpu_src1, cpu_src2);
3545
                        gen_movl_TN_reg(rd, cpu_dst);
3546
                        break;
3547
                    case 0x2e: /* V9 popc */
3548
                        {
3549
                            cpu_src2 = get_src2(insn, cpu_src2);
3550
                            tcg_gen_helper_1_1(helper_popc, cpu_dst,
3551
                                               cpu_src2);
3552
                            gen_movl_TN_reg(rd, cpu_dst);
3553
                        }
3554
                    case 0x2f: /* V9 movr */
3555
                        {
3556
                            int cond = GET_FIELD_SP(insn, 10, 12);
3557
                            int l1;
3558

    
3559
                            cpu_src1 = get_src1(insn, cpu_src1);
3560

    
3561
                            l1 = gen_new_label();
3562

    
3563
                            tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond],
3564
                                              cpu_src1, 0, l1);
3565
                            if (IS_IMM) {       /* immediate */
3566
                                TCGv r_const;
3567

    
3568
                                rs2 = GET_FIELD_SPs(insn, 0, 9);
3569
                                r_const = tcg_const_tl((int)rs2);
3570
                                gen_movl_TN_reg(rd, r_const);
3571
                                tcg_temp_free(r_const);
3572
                            } else {
3573
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3574
                                gen_movl_reg_TN(rs2, cpu_tmp0);
3575
                                gen_movl_TN_reg(rd, cpu_tmp0);
3576
                            }
3577
                            gen_set_label(l1);
3578
                            break;
3579
                        }
3580
#endif
3581
                    default:
3582
                        goto illegal_insn;
3583
                    }
3584
                }
3585
            } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
3586
#ifdef TARGET_SPARC64
3587
                int opf = GET_FIELD_SP(insn, 5, 13);
3588
                rs1 = GET_FIELD(insn, 13, 17);
3589
                rs2 = GET_FIELD(insn, 27, 31);
3590
                if (gen_trap_ifnofpu(dc, cpu_cond))
3591
                    goto jmp_insn;
3592

    
3593
                switch (opf) {
3594
                case 0x000: /* VIS I edge8cc */
3595
                case 0x001: /* VIS II edge8n */
3596
                case 0x002: /* VIS I edge8lcc */
3597
                case 0x003: /* VIS II edge8ln */
3598
                case 0x004: /* VIS I edge16cc */
3599
                case 0x005: /* VIS II edge16n */
3600
                case 0x006: /* VIS I edge16lcc */
3601
                case 0x007: /* VIS II edge16ln */
3602
                case 0x008: /* VIS I edge32cc */
3603
                case 0x009: /* VIS II edge32n */
3604
                case 0x00a: /* VIS I edge32lcc */
3605
                case 0x00b: /* VIS II edge32ln */
3606
                    // XXX
3607
                    goto illegal_insn;
3608
                case 0x010: /* VIS I array8 */
3609
                    CHECK_FPU_FEATURE(dc, VIS1);
3610
                    cpu_src1 = get_src1(insn, cpu_src1);
3611
                    gen_movl_reg_TN(rs2, cpu_src2);
3612
                    tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
3613
                                       cpu_src2);
3614
                    gen_movl_TN_reg(rd, cpu_dst);
3615
                    break;
3616
                case 0x012: /* VIS I array16 */
3617
                    CHECK_FPU_FEATURE(dc, VIS1);
3618
                    cpu_src1 = get_src1(insn, cpu_src1);
3619
                    gen_movl_reg_TN(rs2, cpu_src2);
3620
                    tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
3621
                                       cpu_src2);
3622
                    tcg_gen_shli_i64(cpu_dst, cpu_dst, 1);
3623
                    gen_movl_TN_reg(rd, cpu_dst);
3624
                    break;
3625
                case 0x014: /* VIS I array32 */
3626
                    CHECK_FPU_FEATURE(dc, VIS1);
3627
                    cpu_src1 = get_src1(insn, cpu_src1);
3628
                    gen_movl_reg_TN(rs2, cpu_src2);
3629
                    tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
3630
                                       cpu_src2);
3631
                    tcg_gen_shli_i64(cpu_dst, cpu_dst, 2);
3632
                    gen_movl_TN_reg(rd, cpu_dst);
3633
                    break;
3634
                case 0x018: /* VIS I alignaddr */
3635
                    CHECK_FPU_FEATURE(dc, VIS1);
3636
                    cpu_src1 = get_src1(insn, cpu_src1);
3637
                    gen_movl_reg_TN(rs2, cpu_src2);
3638
                    tcg_gen_helper_1_2(helper_alignaddr, cpu_dst, cpu_src1,
3639
                                       cpu_src2);
3640
                    gen_movl_TN_reg(rd, cpu_dst);
3641
                    break;
3642
                case 0x019: /* VIS II bmask */
3643
                case 0x01a: /* VIS I alignaddrl */
3644
                    // XXX
3645
                    goto illegal_insn;
3646
                case 0x020: /* VIS I fcmple16 */
3647
                    CHECK_FPU_FEATURE(dc, VIS1);
3648
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3649
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3650
                    tcg_gen_helper_0_0(helper_fcmple16);
3651
                    gen_op_store_DT0_fpr(DFPREG(rd));
3652
                    break;
3653
                case 0x022: /* VIS I fcmpne16 */
3654
                    CHECK_FPU_FEATURE(dc, VIS1);
3655
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3656
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3657
                    tcg_gen_helper_0_0(helper_fcmpne16);
3658
                    gen_op_store_DT0_fpr(DFPREG(rd));
3659
                    break;
3660
                case 0x024: /* VIS I fcmple32 */
3661
                    CHECK_FPU_FEATURE(dc, VIS1);
3662
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3663
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3664
                    tcg_gen_helper_0_0(helper_fcmple32);
3665
                    gen_op_store_DT0_fpr(DFPREG(rd));
3666
                    break;
3667
                case 0x026: /* VIS I fcmpne32 */
3668
                    CHECK_FPU_FEATURE(dc, VIS1);
3669
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3670
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3671
                    tcg_gen_helper_0_0(helper_fcmpne32);
3672
                    gen_op_store_DT0_fpr(DFPREG(rd));
3673
                    break;
3674
                case 0x028: /* VIS I fcmpgt16 */
3675
                    CHECK_FPU_FEATURE(dc, VIS1);
3676
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3677
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3678
                    tcg_gen_helper_0_0(helper_fcmpgt16);
3679
                    gen_op_store_DT0_fpr(DFPREG(rd));
3680
                    break;
3681
                case 0x02a: /* VIS I fcmpeq16 */
3682
                    CHECK_FPU_FEATURE(dc, VIS1);
3683
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3684
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3685
                    tcg_gen_helper_0_0(helper_fcmpeq16);
3686
                    gen_op_store_DT0_fpr(DFPREG(rd));
3687
                    break;
3688
                case 0x02c: /* VIS I fcmpgt32 */
3689
                    CHECK_FPU_FEATURE(dc, VIS1);
3690
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3691
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3692
                    tcg_gen_helper_0_0(helper_fcmpgt32);
3693
                    gen_op_store_DT0_fpr(DFPREG(rd));
3694
                    break;
3695
                case 0x02e: /* VIS I fcmpeq32 */
3696
                    CHECK_FPU_FEATURE(dc, VIS1);
3697
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3698
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3699
                    tcg_gen_helper_0_0(helper_fcmpeq32);
3700
                    gen_op_store_DT0_fpr(DFPREG(rd));
3701
                    break;
3702
                case 0x031: /* VIS I fmul8x16 */
3703
                    CHECK_FPU_FEATURE(dc, VIS1);
3704
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3705
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3706
                    tcg_gen_helper_0_0(helper_fmul8x16);
3707
                    gen_op_store_DT0_fpr(DFPREG(rd));
3708
                    break;
3709
                case 0x033: /* VIS I fmul8x16au */
3710
                    CHECK_FPU_FEATURE(dc, VIS1);
3711
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3712
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3713
                    tcg_gen_helper_0_0(helper_fmul8x16au);
3714
                    gen_op_store_DT0_fpr(DFPREG(rd));
3715
                    break;
3716
                case 0x035: /* VIS I fmul8x16al */
3717
                    CHECK_FPU_FEATURE(dc, VIS1);
3718
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3719
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3720
                    tcg_gen_helper_0_0(helper_fmul8x16al);
3721
                    gen_op_store_DT0_fpr(DFPREG(rd));
3722
                    break;
3723
                case 0x036: /* VIS I fmul8sux16 */
3724
                    CHECK_FPU_FEATURE(dc, VIS1);
3725
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3726
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3727
                    tcg_gen_helper_0_0(helper_fmul8sux16);
3728
                    gen_op_store_DT0_fpr(DFPREG(rd));
3729
                    break;
3730
                case 0x037: /* VIS I fmul8ulx16 */
3731
                    CHECK_FPU_FEATURE(dc, VIS1);
3732
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3733
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3734
                    tcg_gen_helper_0_0(helper_fmul8ulx16);
3735
                    gen_op_store_DT0_fpr(DFPREG(rd));
3736
                    break;
3737
                case 0x038: /* VIS I fmuld8sux16 */
3738
                    CHECK_FPU_FEATURE(dc, VIS1);
3739
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3740
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3741
                    tcg_gen_helper_0_0(helper_fmuld8sux16);
3742
                    gen_op_store_DT0_fpr(DFPREG(rd));
3743
                    break;
3744
                case 0x039: /* VIS I fmuld8ulx16 */
3745
                    CHECK_FPU_FEATURE(dc, VIS1);
3746
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3747
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3748
                    tcg_gen_helper_0_0(helper_fmuld8ulx16);
3749
                    gen_op_store_DT0_fpr(DFPREG(rd));
3750
                    break;
3751
                case 0x03a: /* VIS I fpack32 */
3752
                case 0x03b: /* VIS I fpack16 */
3753
                case 0x03d: /* VIS I fpackfix */
3754
                case 0x03e: /* VIS I pdist */
3755
                    // XXX
3756
                    goto illegal_insn;
3757
                case 0x048: /* VIS I faligndata */
3758
                    CHECK_FPU_FEATURE(dc, VIS1);
3759
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3760
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3761
                    tcg_gen_helper_0_0(helper_faligndata);
3762
                    gen_op_store_DT0_fpr(DFPREG(rd));
3763
                    break;
3764
                case 0x04b: /* VIS I fpmerge */
3765
                    CHECK_FPU_FEATURE(dc, VIS1);
3766
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3767
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3768
                    tcg_gen_helper_0_0(helper_fpmerge);
3769
                    gen_op_store_DT0_fpr(DFPREG(rd));
3770
                    break;
3771
                case 0x04c: /* VIS II bshuffle */
3772
                    // XXX
3773
                    goto illegal_insn;
3774
                case 0x04d: /* VIS I fexpand */
3775
                    CHECK_FPU_FEATURE(dc, VIS1);
3776
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3777
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3778
                    tcg_gen_helper_0_0(helper_fexpand);
3779
                    gen_op_store_DT0_fpr(DFPREG(rd));
3780
                    break;
3781
                case 0x050: /* VIS I fpadd16 */
3782
                    CHECK_FPU_FEATURE(dc, VIS1);
3783
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3784
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3785
                    tcg_gen_helper_0_0(helper_fpadd16);
3786
                    gen_op_store_DT0_fpr(DFPREG(rd));
3787
                    break;
3788
                case 0x051: /* VIS I fpadd16s */
3789
                    CHECK_FPU_FEATURE(dc, VIS1);
3790
                    gen_op_load_fpr_FT0(rs1);
3791
                    gen_op_load_fpr_FT1(rs2);
3792
                    tcg_gen_helper_0_0(helper_fpadd16s);
3793
                    gen_op_store_FT0_fpr(rd);
3794
                    break;
3795
                case 0x052: /* VIS I fpadd32 */
3796
                    CHECK_FPU_FEATURE(dc, VIS1);
3797
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3798
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3799
                    tcg_gen_helper_0_0(helper_fpadd32);
3800
                    gen_op_store_DT0_fpr(DFPREG(rd));
3801
                    break;
3802
                case 0x053: /* VIS I fpadd32s */
3803
                    CHECK_FPU_FEATURE(dc, VIS1);
3804
                    gen_op_load_fpr_FT0(rs1);
3805
                    gen_op_load_fpr_FT1(rs2);
3806
                    tcg_gen_helper_0_0(helper_fpadd32s);
3807
                    gen_op_store_FT0_fpr(rd);
3808
                    break;
3809
                case 0x054: /* VIS I fpsub16 */
3810
                    CHECK_FPU_FEATURE(dc, VIS1);
3811
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3812
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3813
                    tcg_gen_helper_0_0(helper_fpsub16);
3814
                    gen_op_store_DT0_fpr(DFPREG(rd));
3815
                    break;
3816
                case 0x055: /* VIS I fpsub16s */
3817
                    CHECK_FPU_FEATURE(dc, VIS1);
3818
                    gen_op_load_fpr_FT0(rs1);
3819
                    gen_op_load_fpr_FT1(rs2);
3820
                    tcg_gen_helper_0_0(helper_fpsub16s);
3821
                    gen_op_store_FT0_fpr(rd);
3822
                    break;
3823
                case 0x056: /* VIS I fpsub32 */
3824
                    CHECK_FPU_FEATURE(dc, VIS1);
3825
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3826
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3827
                    tcg_gen_helper_0_0(helper_fpadd32);
3828
                    gen_op_store_DT0_fpr(DFPREG(rd));
3829
                    break;
3830
                case 0x057: /* VIS I fpsub32s */
3831
                    CHECK_FPU_FEATURE(dc, VIS1);
3832
                    gen_op_load_fpr_FT0(rs1);
3833
                    gen_op_load_fpr_FT1(rs2);
3834
                    tcg_gen_helper_0_0(helper_fpsub32s);
3835
                    gen_op_store_FT0_fpr(rd);
3836
                    break;
3837
                case 0x060: /* VIS I fzero */
3838
                    CHECK_FPU_FEATURE(dc, VIS1);
3839
                    tcg_gen_helper_0_0(helper_movl_DT0_0);
3840
                    gen_op_store_DT0_fpr(DFPREG(rd));
3841
                    break;
3842
                case 0x061: /* VIS I fzeros */
3843
                    CHECK_FPU_FEATURE(dc, VIS1);
3844
                    tcg_gen_helper_0_0(helper_movl_FT0_0);
3845
                    gen_op_store_FT0_fpr(rd);
3846
                    break;
3847
                case 0x062: /* VIS I fnor */
3848
                    CHECK_FPU_FEATURE(dc, VIS1);
3849
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3850
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3851
                    tcg_gen_helper_0_0(helper_fnor);
3852
                    gen_op_store_DT0_fpr(DFPREG(rd));
3853
                    break;
3854
                case 0x063: /* VIS I fnors */
3855
                    CHECK_FPU_FEATURE(dc, VIS1);
3856
                    gen_op_load_fpr_FT0(rs1);
3857
                    gen_op_load_fpr_FT1(rs2);
3858
                    tcg_gen_helper_0_0(helper_fnors);
3859
                    gen_op_store_FT0_fpr(rd);
3860
                    break;
3861
                case 0x064: /* VIS I fandnot2 */
3862
                    CHECK_FPU_FEATURE(dc, VIS1);
3863
                    gen_op_load_fpr_DT1(DFPREG(rs1));
3864
                    gen_op_load_fpr_DT0(DFPREG(rs2));
3865
                    tcg_gen_helper_0_0(helper_fandnot);
3866
                    gen_op_store_DT0_fpr(DFPREG(rd));
3867
                    break;
3868
                case 0x065: /* VIS I fandnot2s */
3869
                    CHECK_FPU_FEATURE(dc, VIS1);
3870
                    gen_op_load_fpr_FT1(rs1);
3871
                    gen_op_load_fpr_FT0(rs2);
3872
                    tcg_gen_helper_0_0(helper_fandnots);
3873
                    gen_op_store_FT0_fpr(rd);
3874
                    break;
3875
                case 0x066: /* VIS I fnot2 */
3876
                    CHECK_FPU_FEATURE(dc, VIS1);
3877
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3878
                    tcg_gen_helper_0_0(helper_fnot);
3879
                    gen_op_store_DT0_fpr(DFPREG(rd));
3880
                    break;
3881
                case 0x067: /* VIS I fnot2s */
3882
                    CHECK_FPU_FEATURE(dc, VIS1);
3883
                    gen_op_load_fpr_FT1(rs2);
3884
                    tcg_gen_helper_0_0(helper_fnot);
3885
                    gen_op_store_FT0_fpr(rd);
3886
                    break;
3887
                case 0x068: /* VIS I fandnot1 */
3888
                    CHECK_FPU_FEATURE(dc, VIS1);
3889
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3890
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3891
                    tcg_gen_helper_0_0(helper_fandnot);
3892
                    gen_op_store_DT0_fpr(DFPREG(rd));
3893
                    break;
3894
                case 0x069: /* VIS I fandnot1s */
3895
                    CHECK_FPU_FEATURE(dc, VIS1);
3896
                    gen_op_load_fpr_FT0(rs1);
3897
                    gen_op_load_fpr_FT1(rs2);
3898
                    tcg_gen_helper_0_0(helper_fandnots);
3899
                    gen_op_store_FT0_fpr(rd);
3900
                    break;
3901
                case 0x06a: /* VIS I fnot1 */
3902
                    CHECK_FPU_FEATURE(dc, VIS1);
3903
                    gen_op_load_fpr_DT1(DFPREG(rs1));
3904
                    tcg_gen_helper_0_0(helper_fnot);
3905
                    gen_op_store_DT0_fpr(DFPREG(rd));
3906
                    break;
3907
                case 0x06b: /* VIS I fnot1s */
3908
                    CHECK_FPU_FEATURE(dc, VIS1);
3909
                    gen_op_load_fpr_FT1(rs1);
3910
                    tcg_gen_helper_0_0(helper_fnot);
3911
                    gen_op_store_FT0_fpr(rd);
3912
                    break;
3913
                case 0x06c: /* VIS I fxor */
3914
                    CHECK_FPU_FEATURE(dc, VIS1);
3915
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3916
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3917
                    tcg_gen_helper_0_0(helper_fxor);
3918
                    gen_op_store_DT0_fpr(DFPREG(rd));
3919
                    break;
3920
                case 0x06d: /* VIS I fxors */
3921
                    CHECK_FPU_FEATURE(dc, VIS1);
3922
                    gen_op_load_fpr_FT0(rs1);
3923
                    gen_op_load_fpr_FT1(rs2);
3924
                    tcg_gen_helper_0_0(helper_fxors);
3925
                    gen_op_store_FT0_fpr(rd);
3926
                    break;
3927
                case 0x06e: /* VIS I fnand */
3928
                    CHECK_FPU_FEATURE(dc, VIS1);
3929
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3930
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3931
                    tcg_gen_helper_0_0(helper_fnand);
3932
                    gen_op_store_DT0_fpr(DFPREG(rd));
3933
                    break;
3934
                case 0x06f: /* VIS I fnands */
3935
                    CHECK_FPU_FEATURE(dc, VIS1);
3936
                    gen_op_load_fpr_FT0(rs1);
3937
                    gen_op_load_fpr_FT1(rs2);
3938
                    tcg_gen_helper_0_0(helper_fnands);
3939
                    gen_op_store_FT0_fpr(rd);
3940
                    break;
3941
                case 0x070: /* VIS I fand */
3942
                    CHECK_FPU_FEATURE(dc, VIS1);
3943
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3944
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3945
                    tcg_gen_helper_0_0(helper_fand);
3946
                    gen_op_store_DT0_fpr(DFPREG(rd));
3947
                    break;
3948
                case 0x071: /* VIS I fands */
3949
                    CHECK_FPU_FEATURE(dc, VIS1);
3950
                    gen_op_load_fpr_FT0(rs1);
3951
                    gen_op_load_fpr_FT1(rs2);
3952
                    tcg_gen_helper_0_0(helper_fands);
3953
                    gen_op_store_FT0_fpr(rd);
3954
                    break;
3955
                case 0x072: /* VIS I fxnor */
3956
                    CHECK_FPU_FEATURE(dc, VIS1);
3957
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3958
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3959
                    tcg_gen_helper_0_0(helper_fxnor);
3960
                    gen_op_store_DT0_fpr(DFPREG(rd));
3961
                    break;
3962
                case 0x073: /* VIS I fxnors */
3963
                    CHECK_FPU_FEATURE(dc, VIS1);
3964
                    gen_op_load_fpr_FT0(rs1);
3965
                    gen_op_load_fpr_FT1(rs2);
3966
                    tcg_gen_helper_0_0(helper_fxnors);
3967
                    gen_op_store_FT0_fpr(rd);
3968
                    break;
3969
                case 0x074: /* VIS I fsrc1 */
3970
                    CHECK_FPU_FEATURE(dc, VIS1);
3971
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3972
                    gen_op_store_DT0_fpr(DFPREG(rd));
3973
                    break;
3974
                case 0x075: /* VIS I fsrc1s */
3975
                    CHECK_FPU_FEATURE(dc, VIS1);
3976
                    gen_op_load_fpr_FT0(rs1);
3977
                    gen_op_store_FT0_fpr(rd);
3978
                    break;
3979
                case 0x076: /* VIS I fornot2 */
3980
                    CHECK_FPU_FEATURE(dc, VIS1);
3981
                    gen_op_load_fpr_DT1(DFPREG(rs1));
3982
                    gen_op_load_fpr_DT0(DFPREG(rs2));
3983
                    tcg_gen_helper_0_0(helper_fornot);
3984
                    gen_op_store_DT0_fpr(DFPREG(rd));
3985
                    break;
3986
                case 0x077: /* VIS I fornot2s */
3987
                    CHECK_FPU_FEATURE(dc, VIS1);
3988
                    gen_op_load_fpr_FT1(rs1);
3989
                    gen_op_load_fpr_FT0(rs2);
3990
                    tcg_gen_helper_0_0(helper_fornots);
3991
                    gen_op_store_FT0_fpr(rd);
3992
                    break;
3993
                case 0x078: /* VIS I fsrc2 */
3994
                    CHECK_FPU_FEATURE(dc, VIS1);
3995
                    gen_op_load_fpr_DT0(DFPREG(rs2));
3996
                    gen_op_store_DT0_fpr(DFPREG(rd));
3997
                    break;
3998
                case 0x079: /* VIS I fsrc2s */
3999
                    CHECK_FPU_FEATURE(dc, VIS1);
4000
                    gen_op_load_fpr_FT0(rs2);
4001
                    gen_op_store_FT0_fpr(rd);
4002
                    break;
4003
                case 0x07a: /* VIS I fornot1 */
4004
                    CHECK_FPU_FEATURE(dc, VIS1);
4005
                    gen_op_load_fpr_DT0(DFPREG(rs1));
4006
                    gen_op_load_fpr_DT1(DFPREG(rs2));
4007
                    tcg_gen_helper_0_0(helper_fornot);
4008
                    gen_op_store_DT0_fpr(DFPREG(rd));
4009
                    break;
4010
                case 0x07b: /* VIS I fornot1s */
4011
                    CHECK_FPU_FEATURE(dc, VIS1);
4012
                    gen_op_load_fpr_FT0(rs1);
4013
                    gen_op_load_fpr_FT1(rs2);
4014
                    tcg_gen_helper_0_0(helper_fornots);
4015
                    gen_op_store_FT0_fpr(rd);
4016
                    break;
4017
                case 0x07c: /* VIS I for */
4018
                    CHECK_FPU_FEATURE(dc, VIS1);
4019
                    gen_op_load_fpr_DT0(DFPREG(rs1));
4020
                    gen_op_load_fpr_DT1(DFPREG(rs2));
4021
                    tcg_gen_helper_0_0(helper_for);
4022
                    gen_op_store_DT0_fpr(DFPREG(rd));
4023
                    break;
4024
                case 0x07d: /* VIS I fors */
4025
                    CHECK_FPU_FEATURE(dc, VIS1);
4026
                    gen_op_load_fpr_FT0(rs1);
4027
                    gen_op_load_fpr_FT1(rs2);
4028
                    tcg_gen_helper_0_0(helper_fors);
4029
                    gen_op_store_FT0_fpr(rd);
4030
                    break;
4031
                case 0x07e: /* VIS I fone */
4032
                    CHECK_FPU_FEATURE(dc, VIS1);
4033
                    tcg_gen_helper_0_0(helper_movl_DT0_1);
4034
                    gen_op_store_DT0_fpr(DFPREG(rd));
4035
                    break;
4036
                case 0x07f: /* VIS I fones */
4037
                    CHECK_FPU_FEATURE(dc, VIS1);
4038
                    tcg_gen_helper_0_0(helper_movl_FT0_1);
4039
                    gen_op_store_FT0_fpr(rd);
4040
                    break;
4041
                case 0x080: /* VIS I shutdown */
4042
                case 0x081: /* VIS II siam */
4043
                    // XXX
4044
                    goto illegal_insn;
4045
                default:
4046
                    goto illegal_insn;
4047
                }
4048
#else
4049
                goto ncp_insn;
4050
#endif
4051
            } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
4052
#ifdef TARGET_SPARC64
4053
                goto illegal_insn;
4054
#else
4055
                goto ncp_insn;
4056
#endif
4057
#ifdef TARGET_SPARC64
4058
            } else if (xop == 0x39) { /* V9 return */
4059
                TCGv r_const;
4060

    
4061
                save_state(dc, cpu_cond);
4062
                cpu_src1 = get_src1(insn, cpu_src1);
4063
                if (IS_IMM) {   /* immediate */
4064
                    rs2 = GET_FIELDs(insn, 19, 31);
4065
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, (int)rs2);
4066
                } else {                /* register */
4067
                    rs2 = GET_FIELD(insn, 27, 31);
4068
                    if (rs2) {
4069
                        gen_movl_reg_TN(rs2, cpu_src2);
4070
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
4071
                    } else
4072
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
4073
                }
4074
                tcg_gen_helper_0_0(helper_restore);
4075
                gen_mov_pc_npc(dc, cpu_cond);
4076
                r_const = tcg_const_i32(3);
4077
                tcg_gen_helper_0_2(helper_check_align, cpu_dst, r_const);
4078
                tcg_temp_free(r_const);
4079
                tcg_gen_mov_tl(cpu_npc, cpu_dst);
4080
                dc->npc = DYNAMIC_PC;
4081
                goto jmp_insn;
4082
#endif
4083
            } else {
4084
                cpu_src1 = get_src1(insn, cpu_src1);
4085
                if (IS_IMM) {   /* immediate */
4086
                    rs2 = GET_FIELDs(insn, 19, 31);
4087
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, (int)rs2);
4088
                } else {                /* register */
4089
                    rs2 = GET_FIELD(insn, 27, 31);
4090
                    if (rs2) {
4091
                        gen_movl_reg_TN(rs2, cpu_src2);
4092
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
4093
                    } else
4094
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
4095
                }
4096
                switch (xop) {
4097
                case 0x38:      /* jmpl */
4098
                    {
4099
                        TCGv r_const;
4100

    
4101
                        r_const = tcg_const_tl(dc->pc);
4102
                        gen_movl_TN_reg(rd, r_const);
4103
                        tcg_temp_free(r_const);
4104
                        gen_mov_pc_npc(dc, cpu_cond);
4105
                        r_const = tcg_const_i32(3);
4106
                        tcg_gen_helper_0_2(helper_check_align, cpu_dst,
4107
                                           r_const);
4108
                        tcg_temp_free(r_const);
4109
                        tcg_gen_mov_tl(cpu_npc, cpu_dst);
4110
                        dc->npc = DYNAMIC_PC;
4111
                    }
4112
                    goto jmp_insn;
4113
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
4114
                case 0x39:      /* rett, V9 return */
4115
                    {
4116
                        TCGv r_const;
4117

    
4118
                        if (!supervisor(dc))
4119
                            goto priv_insn;
4120
                        gen_mov_pc_npc(dc, cpu_cond);
4121
                        r_const = tcg_const_i32(3);
4122
                        tcg_gen_helper_0_2(helper_check_align, cpu_dst,
4123
                                           r_const);
4124
                        tcg_temp_free(r_const);
4125
                        tcg_gen_mov_tl(cpu_npc, cpu_dst);
4126
                        dc->npc = DYNAMIC_PC;
4127
                        tcg_gen_helper_0_0(helper_rett);
4128
                    }
4129
                    goto jmp_insn;
4130
#endif
4131
                case 0x3b: /* flush */
4132
                    if (!((dc)->features & CPU_FEATURE_FLUSH))
4133
                        goto unimp_flush;
4134
                    tcg_gen_helper_0_1(helper_flush, cpu_dst);
4135
                    break;
4136
                case 0x3c:      /* save */
4137
                    save_state(dc, cpu_cond);
4138
                    tcg_gen_helper_0_0(helper_save);
4139
                    gen_movl_TN_reg(rd, cpu_dst);
4140
                    break;
4141
                case 0x3d:      /* restore */
4142
                    save_state(dc, cpu_cond);
4143
                    tcg_gen_helper_0_0(helper_restore);
4144
                    gen_movl_TN_reg(rd, cpu_dst);
4145
                    break;
4146
#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
4147
                case 0x3e:      /* V9 done/retry */
4148
                    {
4149
                        switch (rd) {
4150
                        case 0:
4151
                            if (!supervisor(dc))
4152
                                goto priv_insn;
4153
                            dc->npc = DYNAMIC_PC;
4154
                            dc->pc = DYNAMIC_PC;
4155
                            tcg_gen_helper_0_0(helper_done);
4156
                            goto jmp_insn;
4157
                        case 1:
4158
                            if (!supervisor(dc))
4159
                                goto priv_insn;
4160
                            dc->npc = DYNAMIC_PC;
4161
                            dc->pc = DYNAMIC_PC;
4162
                            tcg_gen_helper_0_0(helper_retry);
4163
                            goto jmp_insn;
4164
                        default:
4165
                            goto illegal_insn;
4166
                        }
4167
                    }
4168
                    break;
4169
#endif
4170
                default:
4171
                    goto illegal_insn;
4172
                }
4173
            }
4174
            break;
4175
        }
4176
        break;
4177
    case 3:                     /* load/store instructions */
4178
        {
4179
            unsigned int xop = GET_FIELD(insn, 7, 12);
4180

    
4181
            cpu_src1 = get_src1(insn, cpu_src1);
4182
            if (xop == 0x3c || xop == 0x3e) { // V9 casa/casxa
4183
                rs2 = GET_FIELD(insn, 27, 31);
4184
                gen_movl_reg_TN(rs2, cpu_src2);
4185
                tcg_gen_mov_tl(cpu_addr, cpu_src1);
4186
            } else if (IS_IMM) {     /* immediate */
4187
                rs2 = GET_FIELDs(insn, 19, 31);
4188
                tcg_gen_addi_tl(cpu_addr, cpu_src1, (int)rs2);
4189
            } else {            /* register */
4190
                rs2 = GET_FIELD(insn, 27, 31);
4191
                if (rs2 != 0) {
4192
                    gen_movl_reg_TN(rs2, cpu_src2);
4193
                    tcg_gen_add_tl(cpu_addr, cpu_src1, cpu_src2);
4194
                } else
4195
                    tcg_gen_mov_tl(cpu_addr, cpu_src1);
4196
            }
4197
            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
4198
                (xop > 0x17 && xop <= 0x1d ) ||
4199
                (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
4200
                switch (xop) {
4201
                case 0x0:       /* load unsigned word */
4202
                    ABI32_MASK(cpu_addr);
4203
                    tcg_gen_qemu_ld32u(cpu_val, cpu_addr, dc->mem_idx);
4204
                    break;
4205
                case 0x1:       /* load unsigned byte */
4206
                    ABI32_MASK(cpu_addr);
4207
                    tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx);
4208
                    break;
4209
                case 0x2:       /* load unsigned halfword */
4210
                    ABI32_MASK(cpu_addr);
4211
                    tcg_gen_qemu_ld16u(cpu_val, cpu_addr, dc->mem_idx);
4212
                    break;
4213
                case 0x3:       /* load double word */
4214
                    if (rd & 1)
4215
                        goto illegal_insn;
4216
                    else {
4217
                        TCGv r_const;
4218

    
4219
                        save_state(dc, cpu_cond);
4220
                        r_const = tcg_const_i32(7);
4221
                        tcg_gen_helper_0_2(helper_check_align, cpu_addr,
4222
                                           r_const); // XXX remove
4223
                        tcg_temp_free(r_const);
4224
                        ABI32_MASK(cpu_addr);
4225
                        tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
4226
                        tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
4227
                        tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffffULL);
4228
                        gen_movl_TN_reg(rd + 1, cpu_tmp0);
4229
                        tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
4230
                        tcg_gen_trunc_i64_tl(cpu_val, cpu_tmp64);
4231
                        tcg_gen_andi_tl(cpu_val, cpu_val, 0xffffffffULL);
4232
                    }
4233
                    break;
4234
                case 0x9:       /* load signed byte */
4235
                    ABI32_MASK(cpu_addr);
4236
                    tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
4237
                    break;
4238
                case 0xa:       /* load signed halfword */
4239
                    ABI32_MASK(cpu_addr);
4240
                    tcg_gen_qemu_ld16s(cpu_val, cpu_addr, dc->mem_idx);
4241
                    break;
4242
                case 0xd:       /* ldstub -- XXX: should be atomically */
4243
                    {
4244
                        TCGv r_const;
4245

    
4246
                        ABI32_MASK(cpu_addr);
4247
                        tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
4248
                        r_const = tcg_const_tl(0xff);
4249
                        tcg_gen_qemu_st8(r_const, cpu_addr, dc->mem_idx);
4250
                        tcg_temp_free(r_const);
4251
                    }
4252
                    break;
4253
                case 0x0f:      /* swap register with memory. Also
4254
                                   atomically */
4255
                    CHECK_IU_FEATURE(dc, SWAP);
4256
                    gen_movl_reg_TN(rd, cpu_val);
4257
                    ABI32_MASK(cpu_addr);
4258
                    tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
4259
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
4260
                    tcg_gen_extu_i32_tl(cpu_val, cpu_tmp32);
4261
                    break;
4262
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4263
                case 0x10:      /* load word alternate */
4264
#ifndef TARGET_SPARC64
4265
                    if (IS_IMM)
4266
                        goto illegal_insn;
4267
                    if (!supervisor(dc))
4268
                        goto priv_insn;
4269
#endif
4270
                    save_state(dc, cpu_cond);
4271
                    gen_ld_asi(cpu_val, cpu_addr, insn, 4, 0);
4272
                    break;
4273
                case 0x11:      /* load unsigned byte alternate */
4274
#ifndef TARGET_SPARC64
4275
                    if (IS_IMM)
4276
                        goto illegal_insn;
4277
                    if (!supervisor(dc))
4278
                        goto priv_insn;
4279
#endif
4280
                    save_state(dc, cpu_cond);
4281
                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 0);
4282
                    break;
4283
                case 0x12:      /* load unsigned halfword alternate */
4284
#ifndef TARGET_SPARC64
4285
                    if (IS_IMM)
4286
                        goto illegal_insn;
4287
                    if (!supervisor(dc))
4288
                        goto priv_insn;
4289
#endif
4290
                    save_state(dc, cpu_cond);
4291
                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 0);
4292
                    break;
4293
                case 0x13:      /* load double word alternate */
4294
#ifndef TARGET_SPARC64
4295
                    if (IS_IMM)
4296
                        goto illegal_insn;
4297
                    if (!supervisor(dc))
4298
                        goto priv_insn;
4299
#endif
4300
                    if (rd & 1)
4301
                        goto illegal_insn;
4302
                    save_state(dc, cpu_cond);
4303
                    gen_ldda_asi(cpu_tmp0, cpu_val, cpu_addr, insn);
4304
                    gen_movl_TN_reg(rd + 1, cpu_tmp0);
4305
                    break;
4306
                case 0x19:      /* load signed byte alternate */
4307
#ifndef TARGET_SPARC64
4308
                    if (IS_IMM)
4309
                        goto illegal_insn;
4310
                    if (!supervisor(dc))
4311
                        goto priv_insn;
4312
#endif
4313
                    save_state(dc, cpu_cond);
4314
                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 1);
4315
                    break;
4316
                case 0x1a:      /* load signed halfword alternate */
4317
#ifndef TARGET_SPARC64
4318
                    if (IS_IMM)
4319
                        goto illegal_insn;
4320
                    if (!supervisor(dc))
4321
                        goto priv_insn;
4322
#endif
4323
                    save_state(dc, cpu_cond);
4324
                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 1);
4325
                    break;
4326
                case 0x1d:      /* ldstuba -- XXX: should be atomically */
4327
#ifndef TARGET_SPARC64
4328
                    if (IS_IMM)
4329
                        goto illegal_insn;
4330
                    if (!supervisor(dc))
4331
                        goto priv_insn;
4332
#endif
4333
                    save_state(dc, cpu_cond);
4334
                    gen_ldstub_asi(cpu_val, cpu_addr, insn);
4335
                    break;
4336
                case 0x1f:      /* swap reg with alt. memory. Also
4337
                                   atomically */
4338
                    CHECK_IU_FEATURE(dc, SWAP);
4339
#ifndef TARGET_SPARC64
4340
                    if (IS_IMM)
4341
                        goto illegal_insn;
4342
                    if (!supervisor(dc))
4343
                        goto priv_insn;
4344
#endif
4345
                    save_state(dc, cpu_cond);
4346
                    gen_movl_reg_TN(rd, cpu_val);
4347
                    gen_swap_asi(cpu_val, cpu_addr, insn);
4348
                    break;
4349

    
4350
#ifndef TARGET_SPARC64
4351
                case 0x30: /* ldc */
4352
                case 0x31: /* ldcsr */
4353
                case 0x33: /* lddc */
4354
                    goto ncp_insn;
4355
#endif
4356
#endif
4357
#ifdef TARGET_SPARC64
4358
                case 0x08: /* V9 ldsw */
4359
                    ABI32_MASK(cpu_addr);
4360
                    tcg_gen_qemu_ld32s(cpu_val, cpu_addr, dc->mem_idx);
4361
                    break;
4362
                case 0x0b: /* V9 ldx */
4363
                    ABI32_MASK(cpu_addr);
4364
                    tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx);
4365
                    break;
4366
                case 0x18: /* V9 ldswa */
4367
                    save_state(dc, cpu_cond);
4368
                    gen_ld_asi(cpu_val, cpu_addr, insn, 4, 1);
4369
                    break;
4370
                case 0x1b: /* V9 ldxa */
4371
                    save_state(dc, cpu_cond);
4372
                    gen_ld_asi(cpu_val, cpu_addr, insn, 8, 0);
4373
                    break;
4374
                case 0x2d: /* V9 prefetch, no effect */
4375
                    goto skip_move;
4376
                case 0x30: /* V9 ldfa */
4377
                    save_state(dc, cpu_cond);
4378
                    gen_ldf_asi(cpu_addr, insn, 4, rd);
4379
                    goto skip_move;
4380
                case 0x33: /* V9 lddfa */
4381
                    save_state(dc, cpu_cond);
4382
                    gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd));
4383
                    goto skip_move;
4384
                case 0x3d: /* V9 prefetcha, no effect */
4385
                    goto skip_move;
4386
                case 0x32: /* V9 ldqfa */
4387
                    CHECK_FPU_FEATURE(dc, FLOAT128);
4388
                    save_state(dc, cpu_cond);
4389
                    gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd));
4390
                    goto skip_move;
4391
#endif
4392
                default:
4393
                    goto illegal_insn;
4394
                }
4395
                gen_movl_TN_reg(rd, cpu_val);
4396
#ifdef TARGET_SPARC64
4397
            skip_move: ;
4398
#endif
4399
            } else if (xop >= 0x20 && xop < 0x24) {
4400
                if (gen_trap_ifnofpu(dc, cpu_cond))
4401
                    goto jmp_insn;
4402
                save_state(dc, cpu_cond);
4403
                switch (xop) {
4404
                case 0x20:      /* load fpreg */
4405
                    ABI32_MASK(cpu_addr);
4406
                    tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
4407
                    tcg_gen_st_i32(cpu_tmp32, cpu_env,
4408
                                   offsetof(CPUState, fpr[rd]));
4409
                    break;
4410
                case 0x21:      /* load fsr */
4411
                    ABI32_MASK(cpu_addr);
4412
                    tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
4413
                    tcg_gen_st_i32(cpu_tmp32, cpu_env,
4414
                                   offsetof(CPUState, ft0));
4415
                    tcg_gen_helper_0_0(helper_ldfsr);
4416
                    break;
4417
                case 0x22:      /* load quad fpreg */
4418
                    {
4419
                        TCGv r_const;
4420

    
4421
                        CHECK_FPU_FEATURE(dc, FLOAT128);
4422
                        r_const = tcg_const_i32(dc->mem_idx);
4423
                        tcg_gen_helper_0_2(helper_ldqf, cpu_addr, r_const);
4424
                        tcg_temp_free(r_const);
4425
                        gen_op_store_QT0_fpr(QFPREG(rd));
4426
                    }
4427
                    break;
4428
                case 0x23:      /* load double fpreg */
4429
                    {
4430
                        TCGv r_const;
4431

    
4432
                        r_const = tcg_const_i32(dc->mem_idx);
4433
                        tcg_gen_helper_0_2(helper_lddf, cpu_addr, r_const);
4434
                        tcg_temp_free(r_const);
4435
                        gen_op_store_DT0_fpr(DFPREG(rd));
4436
                    }
4437
                    break;
4438
                default:
4439
                    goto illegal_insn;
4440
                }
4441
            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) || \
4442
                       xop == 0xe || xop == 0x1e) {
4443
                gen_movl_reg_TN(rd, cpu_val);
4444
                switch (xop) {
4445
                case 0x4: /* store word */
4446
                    ABI32_MASK(cpu_addr);
4447
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
4448
                    break;
4449
                case 0x5: /* store byte */
4450
                    ABI32_MASK(cpu_addr);
4451
                    tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx);
4452
                    break;
4453
                case 0x6: /* store halfword */
4454
                    ABI32_MASK(cpu_addr);
4455
                    tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx);
4456
                    break;
4457
                case 0x7: /* store double word */
4458
                    if (rd & 1)
4459
                        goto illegal_insn;
4460
                    else {
4461
                        TCGv r_low, r_const;
4462

    
4463
                        save_state(dc, cpu_cond);
4464
                        ABI32_MASK(cpu_addr);
4465
                        r_const = tcg_const_i32(7);
4466
                        tcg_gen_helper_0_2(helper_check_align, cpu_addr,
4467
                                           r_const); // XXX remove
4468
                        tcg_temp_free(r_const);
4469
                        r_low = tcg_temp_new(TCG_TYPE_TL);
4470
                        gen_movl_reg_TN(rd + 1, r_low);
4471
                        tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, cpu_val,
4472
                                           r_low);
4473
                        tcg_temp_free(r_low);
4474
                        tcg_gen_qemu_st64(cpu_tmp64, cpu_addr, dc->mem_idx);
4475
                    }
4476
                    break;
4477
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4478
                case 0x14: /* store word alternate */
4479
#ifndef TARGET_SPARC64
4480
                    if (IS_IMM)
4481
                        goto illegal_insn;
4482
                    if (!supervisor(dc))
4483
                        goto priv_insn;
4484
#endif
4485
                    save_state(dc, cpu_cond);
4486
                    gen_st_asi(cpu_val, cpu_addr, insn, 4);
4487
                    break;
4488
                case 0x15: /* store byte alternate */
4489
#ifndef TARGET_SPARC64
4490
                    if (IS_IMM)
4491
                        goto illegal_insn;
4492
                    if (!supervisor(dc))
4493
                        goto priv_insn;
4494
#endif
4495
                    save_state(dc, cpu_cond);
4496
                    gen_st_asi(cpu_val, cpu_addr, insn, 1);
4497
                    break;
4498
                case 0x16: /* store halfword alternate */
4499
#ifndef TARGET_SPARC64
4500
                    if (IS_IMM)
4501
                        goto illegal_insn;
4502
                    if (!supervisor(dc))
4503
                        goto priv_insn;
4504
#endif
4505
                    save_state(dc, cpu_cond);
4506
                    gen_st_asi(cpu_val, cpu_addr, insn, 2);
4507
                    break;
4508
                case 0x17: /* store double word alternate */
4509
#ifndef TARGET_SPARC64
4510
                    if (IS_IMM)
4511
                        goto illegal_insn;
4512
                    if (!supervisor(dc))
4513
                        goto priv_insn;
4514
#endif
4515
                    if (rd & 1)
4516
                        goto illegal_insn;
4517
                    else {
4518
                        save_state(dc, cpu_cond);
4519
                        gen_stda_asi(cpu_val, cpu_addr, insn, rd);
4520
                    }
4521
                    break;
4522
#endif
4523
#ifdef TARGET_SPARC64
4524
                case 0x0e: /* V9 stx */
4525
                    ABI32_MASK(cpu_addr);
4526
                    tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx);
4527
                    break;
4528
                case 0x1e: /* V9 stxa */
4529
                    save_state(dc, cpu_cond);
4530
                    gen_st_asi(cpu_val, cpu_addr, insn, 8);
4531
                    break;
4532
#endif
4533
                default:
4534
                    goto illegal_insn;
4535
                }
4536
            } else if (xop > 0x23 && xop < 0x28) {
4537
                if (gen_trap_ifnofpu(dc, cpu_cond))
4538
                    goto jmp_insn;
4539
                save_state(dc, cpu_cond);
4540
                switch (xop) {
4541
                case 0x24: /* store fpreg */
4542
                    ABI32_MASK(cpu_addr);
4543
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
4544
                                   offsetof(CPUState, fpr[rd]));
4545
                    tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx);
4546
                    break;
4547
                case 0x25: /* stfsr, V9 stxfsr */
4548
                    ABI32_MASK(cpu_addr);
4549
                    tcg_gen_helper_0_0(helper_stfsr);
4550
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
4551
                                   offsetof(CPUState, ft0));
4552
                    tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx);
4553
                    break;
4554
                case 0x26:
4555
#ifdef TARGET_SPARC64
4556
                    /* V9 stqf, store quad fpreg */
4557
                    {
4558
                        TCGv r_const;
4559

    
4560
                        CHECK_FPU_FEATURE(dc, FLOAT128);
4561
                        gen_op_load_fpr_QT0(QFPREG(rd));
4562
                        r_const = tcg_const_i32(dc->mem_idx);
4563
                        tcg_gen_helper_0_2(helper_stqf, cpu_addr, r_const);
4564
                        tcg_temp_free(r_const);
4565
                    }
4566
                    break;
4567
#else /* !TARGET_SPARC64 */
4568
                    /* stdfq, store floating point queue */
4569
#if defined(CONFIG_USER_ONLY)
4570
                    goto illegal_insn;
4571
#else
4572
                    if (!supervisor(dc))
4573
                        goto priv_insn;
4574
                    if (gen_trap_ifnofpu(dc, cpu_cond))
4575
                        goto jmp_insn;
4576
                    goto nfq_insn;
4577
#endif
4578
#endif
4579
                case 0x27: /* store double fpreg */
4580
                    {
4581
                        TCGv r_const;
4582

    
4583
                        gen_op_load_fpr_DT0(DFPREG(rd));
4584
                        r_const = tcg_const_i32(dc->mem_idx);
4585
                        tcg_gen_helper_0_2(helper_stdf, cpu_addr, r_const);
4586
                        tcg_temp_free(r_const);
4587
                    }
4588
                    break;
4589
                default:
4590
                    goto illegal_insn;
4591
                }
4592
            } else if (xop > 0x33 && xop < 0x3f) {
4593
                save_state(dc, cpu_cond);
4594
                switch (xop) {
4595
#ifdef TARGET_SPARC64
4596
                case 0x34: /* V9 stfa */
4597
                    gen_op_load_fpr_FT0(rd);
4598
                    gen_stf_asi(cpu_addr, insn, 4, rd);
4599
                    break;
4600
                case 0x36: /* V9 stqfa */
4601
                    {
4602
                        TCGv r_const;
4603

    
4604
                        CHECK_FPU_FEATURE(dc, FLOAT128);
4605
                        r_const = tcg_const_i32(7);
4606
                        tcg_gen_helper_0_2(helper_check_align, cpu_addr,
4607
                                           r_const);
4608
                        tcg_temp_free(r_const);
4609
                        gen_op_load_fpr_QT0(QFPREG(rd));
4610
                        gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd));
4611
                    }
4612
                    break;
4613
                case 0x37: /* V9 stdfa */
4614
                    gen_op_load_fpr_DT0(DFPREG(rd));
4615
                    gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
4616
                    break;
4617
                case 0x3c: /* V9 casa */
4618
                    gen_cas_asi(cpu_val, cpu_addr, cpu_src2, insn, rd);
4619
                    gen_movl_TN_reg(rd, cpu_val);
4620
                    break;
4621
                case 0x3e: /* V9 casxa */
4622
                    gen_casx_asi(cpu_val, cpu_addr, cpu_src2, insn, rd);
4623
                    gen_movl_TN_reg(rd, cpu_val);
4624
                    break;
4625
#else
4626
                case 0x34: /* stc */
4627
                case 0x35: /* stcsr */
4628
                case 0x36: /* stdcq */
4629
                case 0x37: /* stdc */
4630
                    goto ncp_insn;
4631
#endif
4632
                default:
4633
                    goto illegal_insn;
4634
                }
4635
            }
4636
            else
4637
                goto illegal_insn;
4638
        }
4639
        break;
4640
    }
4641
    /* default case for non jump instructions */
4642
    if (dc->npc == DYNAMIC_PC) {
4643
        dc->pc = DYNAMIC_PC;
4644
        gen_op_next_insn();
4645
    } else if (dc->npc == JUMP_PC) {
4646
        /* we can do a static jump */
4647
        gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
4648
        dc->is_br = 1;
4649
    } else {
4650
        dc->pc = dc->npc;
4651
        dc->npc = dc->npc + 4;
4652
    }
4653
 jmp_insn:
4654
    return;
4655
 illegal_insn:
4656
    {
4657
        TCGv r_const;
4658

    
4659
        save_state(dc, cpu_cond);
4660
        r_const = tcg_const_i32(TT_ILL_INSN);
4661
        tcg_gen_helper_0_1(raise_exception, r_const);
4662
        tcg_temp_free(r_const);
4663
        dc->is_br = 1;
4664
    }
4665
    return;
4666
 unimp_flush:
4667
    {
4668
        TCGv r_const;
4669

    
4670
        save_state(dc, cpu_cond);
4671
        r_const = tcg_const_i32(TT_UNIMP_FLUSH);
4672
        tcg_gen_helper_0_1(raise_exception, r_const);
4673
        tcg_temp_free(r_const);
4674
        dc->is_br = 1;
4675
    }
4676
    return;
4677
#if !defined(CONFIG_USER_ONLY)
4678
 priv_insn:
4679
    {
4680
        TCGv r_const;
4681

    
4682
        save_state(dc, cpu_cond);
4683
        r_const = tcg_const_i32(TT_PRIV_INSN);
4684
        tcg_gen_helper_0_1(raise_exception, r_const);
4685
        tcg_temp_free(r_const);
4686
        dc->is_br = 1;
4687
    }
4688
    return;
4689
#endif
4690
 nfpu_insn:
4691
    save_state(dc, cpu_cond);
4692
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
4693
    dc->is_br = 1;
4694
    return;
4695
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
4696
 nfq_insn:
4697
    save_state(dc, cpu_cond);
4698
    gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
4699
    dc->is_br = 1;
4700
    return;
4701
#endif
4702
#ifndef TARGET_SPARC64
4703
 ncp_insn:
4704
    {
4705
        TCGv r_const;
4706

    
4707
        save_state(dc, cpu_cond);
4708
        r_const = tcg_const_i32(TT_NCP_INSN);
4709
        tcg_gen_helper_0_1(raise_exception, r_const);
4710
        tcg_temp_free(r_const);
4711
        dc->is_br = 1;
4712
    }
4713
    return;
4714
#endif
4715
}
4716

    
4717
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
4718
                                                 int spc, CPUSPARCState *env)
4719
{
4720
    target_ulong pc_start, last_pc;
4721
    uint16_t *gen_opc_end;
4722
    DisasContext dc1, *dc = &dc1;
4723
    int j, lj = -1;
4724
    int num_insns;
4725
    int max_insns;
4726

    
4727
    memset(dc, 0, sizeof(DisasContext));
4728
    dc->tb = tb;
4729
    pc_start = tb->pc;
4730
    dc->pc = pc_start;
4731
    last_pc = dc->pc;
4732
    dc->npc = (target_ulong) tb->cs_base;
4733
    dc->mem_idx = cpu_mmu_index(env);
4734
    dc->features = env->features;
4735
    if ((dc->features & CPU_FEATURE_FLOAT)) {
4736
        dc->fpu_enabled = cpu_fpu_enabled(env);
4737
#if defined(CONFIG_USER_ONLY)
4738
        dc->features |= CPU_FEATURE_FLOAT128;
4739
#endif
4740
    } else
4741
        dc->fpu_enabled = 0;
4742
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4743

    
4744
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
4745
    cpu_tmp32 = tcg_temp_new(TCG_TYPE_I32);
4746
    cpu_tmp64 = tcg_temp_new(TCG_TYPE_I64);
4747

    
4748
    cpu_dst = tcg_temp_local_new(TCG_TYPE_TL);
4749

    
4750
    // loads and stores
4751
    cpu_val = tcg_temp_local_new(TCG_TYPE_TL);
4752
    cpu_addr = tcg_temp_local_new(TCG_TYPE_TL);
4753

    
4754
    num_insns = 0;
4755
    max_insns = tb->cflags & CF_COUNT_MASK;
4756
    if (max_insns == 0)
4757
        max_insns = CF_COUNT_MASK;
4758
    gen_icount_start();
4759
    do {
4760
        if (env->nb_breakpoints > 0) {
4761
            for(j = 0; j < env->nb_breakpoints; j++) {
4762
                if (env->breakpoints[j] == dc->pc) {
4763
                    if (dc->pc != pc_start)
4764
                        save_state(dc, cpu_cond);
4765
                    tcg_gen_helper_0_0(helper_debug);
4766
                    tcg_gen_exit_tb(0);
4767
                    dc->is_br = 1;
4768
                    goto exit_gen_loop;
4769
                }
4770
            }
4771
        }
4772
        if (spc) {
4773
            if (loglevel > 0)
4774
                fprintf(logfile, "Search PC...\n");
4775
            j = gen_opc_ptr - gen_opc_buf;
4776
            if (lj < j) {
4777
                lj++;
4778
                while (lj < j)
4779
                    gen_opc_instr_start[lj++] = 0;
4780
                gen_opc_pc[lj] = dc->pc;
4781
                gen_opc_npc[lj] = dc->npc;
4782
                gen_opc_instr_start[lj] = 1;
4783
                gen_opc_icount[lj] = num_insns;
4784
            }
4785
        }
4786
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
4787
            gen_io_start();
4788
        last_pc = dc->pc;
4789
        disas_sparc_insn(dc);
4790
        num_insns++;
4791

    
4792
        if (dc->is_br)
4793
            break;
4794
        /* if the next PC is different, we abort now */
4795
        if (dc->pc != (last_pc + 4))
4796
            break;
4797
        /* if we reach a page boundary, we stop generation so that the
4798
           PC of a TT_TFAULT exception is always in the right page */
4799
        if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
4800
            break;
4801
        /* if single step mode, we generate only one instruction and
4802
           generate an exception */
4803
        if (env->singlestep_enabled) {
4804
            tcg_gen_movi_tl(cpu_pc, dc->pc);
4805
            tcg_gen_exit_tb(0);
4806
            break;
4807
        }
4808
    } while ((gen_opc_ptr < gen_opc_end) &&
4809
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32) &&
4810
             num_insns < max_insns);
4811

    
4812
 exit_gen_loop:
4813
    tcg_temp_free(cpu_addr);
4814
    tcg_temp_free(cpu_val);
4815
    tcg_temp_free(cpu_dst);
4816
    tcg_temp_free(cpu_tmp64);
4817
    tcg_temp_free(cpu_tmp32);
4818
    tcg_temp_free(cpu_tmp0);
4819
    if (tb->cflags & CF_LAST_IO)
4820
        gen_io_end();
4821
    if (!dc->is_br) {
4822
        if (dc->pc != DYNAMIC_PC &&
4823
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
4824
            /* static PC and NPC: we can use direct chaining */
4825
            gen_goto_tb(dc, 0, dc->pc, dc->npc);
4826
        } else {
4827
            if (dc->pc != DYNAMIC_PC)
4828
                tcg_gen_movi_tl(cpu_pc, dc->pc);
4829
            save_npc(dc, cpu_cond);
4830
            tcg_gen_exit_tb(0);
4831
        }
4832
    }
4833
    gen_icount_end(tb, num_insns);
4834
    *gen_opc_ptr = INDEX_op_end;
4835
    if (spc) {
4836
        j = gen_opc_ptr - gen_opc_buf;
4837
        lj++;
4838
        while (lj <= j)
4839
            gen_opc_instr_start[lj++] = 0;
4840
#if 0
4841
        if (loglevel > 0) {
4842
            page_dump(logfile);
4843
        }
4844
#endif
4845
        gen_opc_jump_pc[0] = dc->jump_pc[0];
4846
        gen_opc_jump_pc[1] = dc->jump_pc[1];
4847
    } else {
4848
        tb->size = last_pc + 4 - pc_start;
4849
        tb->icount = num_insns;
4850
    }
4851
#ifdef DEBUG_DISAS
4852
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4853
        fprintf(logfile, "--------------\n");
4854
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
4855
        target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
4856
        fprintf(logfile, "\n");
4857
    }
4858
#endif
4859
    return 0;
4860
}
4861

    
4862
int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
4863
{
4864
    return gen_intermediate_code_internal(tb, 0, env);
4865
}
4866

    
4867
int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
4868
{
4869
    return gen_intermediate_code_internal(tb, 1, env);
4870
}
4871

    
4872
void gen_intermediate_code_init(CPUSPARCState *env)
4873
{
4874
    unsigned int i;
4875
    static int inited;
4876
    static const char * const gregnames[8] = {
4877
        NULL, // g0 not used
4878
        "g1",
4879
        "g2",
4880
        "g3",
4881
        "g4",
4882
        "g5",
4883
        "g6",
4884
        "g7",
4885
    };
4886

    
4887
    /* init various static tables */
4888
    if (!inited) {
4889
        inited = 1;
4890

    
4891
        cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
4892
        cpu_regwptr = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
4893
                                         offsetof(CPUState, regwptr),
4894
                                         "regwptr");
4895
#ifdef TARGET_SPARC64
4896
        cpu_xcc = tcg_global_mem_new(TCG_TYPE_I32,
4897
                                     TCG_AREG0, offsetof(CPUState, xcc),
4898
                                     "xcc");
4899
#endif
4900
        cpu_cond = tcg_global_mem_new(TCG_TYPE_TL,
4901
                                      TCG_AREG0, offsetof(CPUState, cond),
4902
                                      "cond");
4903
        cpu_cc_src = tcg_global_mem_new(TCG_TYPE_TL,
4904
                                        TCG_AREG0, offsetof(CPUState, cc_src),
4905
                                        "cc_src");
4906
        cpu_cc_src2 = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4907
                                         offsetof(CPUState, cc_src2),
4908
                                         "cc_src2");
4909
        cpu_cc_dst = tcg_global_mem_new(TCG_TYPE_TL,
4910
                                        TCG_AREG0, offsetof(CPUState, cc_dst),
4911
                                        "cc_dst");
4912
        cpu_psr = tcg_global_mem_new(TCG_TYPE_I32,
4913
                                     TCG_AREG0, offsetof(CPUState, psr),
4914
                                     "psr");
4915
        cpu_fsr = tcg_global_mem_new(TCG_TYPE_TL,
4916
                                     TCG_AREG0, offsetof(CPUState, fsr),
4917
                                     "fsr");
4918
        cpu_pc = tcg_global_mem_new(TCG_TYPE_TL,
4919
                                    TCG_AREG0, offsetof(CPUState, pc),
4920
                                    "pc");
4921
        cpu_npc = tcg_global_mem_new(TCG_TYPE_TL,
4922
                                    TCG_AREG0, offsetof(CPUState, npc),
4923
                                    "npc");
4924
        for (i = 1; i < 8; i++)
4925
            cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4926
                                              offsetof(CPUState, gregs[i]),
4927
                                              gregnames[i]);
4928
        /* register helpers */
4929

    
4930
#undef DEF_HELPER
4931
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
4932
#include "helper.h"
4933
    }
4934
}
4935

    
4936
void gen_pc_load(CPUState *env, TranslationBlock *tb,
4937
                unsigned long searched_pc, int pc_pos, void *puc)
4938
{
4939
    target_ulong npc;
4940
    env->pc = gen_opc_pc[pc_pos];
4941
    npc = gen_opc_npc[pc_pos];
4942
    if (npc == 1) {
4943
        /* dynamic NPC: already stored */
4944
    } else if (npc == 2) {
4945
        target_ulong t2 = (target_ulong)(unsigned long)puc;
4946
        /* jump PC: use T2 and the jump targets of the translation */
4947
        if (t2)
4948
            env->npc = gen_opc_jump_pc[0];
4949
        else
4950
            env->npc = gen_opc_jump_pc[1];
4951
    } else {
4952
        env->npc = npc;
4953
    }
4954
}