Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ ba6a9d8c

History | View | Annotate | Download (184.8 kB)

1
/*
2
   SPARC translation
3

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

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

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

17
   You should have received a copy of the GNU Lesser General Public
18
   License along with this library; if not, write to the Free Software
19
   Foundation, Inc., 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
    int address_mask_32bit;
61
    struct TranslationBlock *tb;
62
    sparc_def_t *def;
63
} DisasContext;
64

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
205
#ifdef TARGET_SPARC64
206
#ifndef TARGET_ABI32
207
#define AM_CHECK(dc) ((dc)->address_mask_32bit)
208
#else
209
#define AM_CHECK(dc) (1)
210
#endif
211
#endif
212

    
213
static inline void gen_address_mask(DisasContext *dc, TCGv addr)
214
{
215
#ifdef TARGET_SPARC64
216
    if (AM_CHECK(dc))
217
        tcg_gen_andi_tl(addr, addr, 0xffffffffULL);
218
#endif
219
}
220

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

    
232
static inline void gen_movl_TN_reg(int reg, TCGv tn)
233
{
234
    if (reg == 0)
235
        return;
236
    else if (reg < 8)
237
        tcg_gen_mov_tl(cpu_gregs[reg], tn);
238
    else {
239
        tcg_gen_st_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
240
    }
241
}
242

    
243
static inline void gen_goto_tb(DisasContext *s, int tb_num,
244
                               target_ulong pc, target_ulong npc)
245
{
246
    TranslationBlock *tb;
247

    
248
    tb = s->tb;
249
    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
250
        (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK))  {
251
        /* jump to same page: we can use a direct jump */
252
        tcg_gen_goto_tb(tb_num);
253
        tcg_gen_movi_tl(cpu_pc, pc);
254
        tcg_gen_movi_tl(cpu_npc, npc);
255
        tcg_gen_exit_tb((long)tb + tb_num);
256
    } else {
257
        /* jump to another page: currently not optimized */
258
        tcg_gen_movi_tl(cpu_pc, pc);
259
        tcg_gen_movi_tl(cpu_npc, npc);
260
        tcg_gen_exit_tb(0);
261
    }
262
}
263

    
264
// XXX suboptimal
265
static inline void gen_mov_reg_N(TCGv reg, TCGv src)
266
{
267
    tcg_gen_extu_i32_tl(reg, src);
268
    tcg_gen_shri_tl(reg, reg, PSR_NEG_SHIFT);
269
    tcg_gen_andi_tl(reg, reg, 0x1);
270
}
271

    
272
static inline void gen_mov_reg_Z(TCGv reg, TCGv src)
273
{
274
    tcg_gen_extu_i32_tl(reg, src);
275
    tcg_gen_shri_tl(reg, reg, PSR_ZERO_SHIFT);
276
    tcg_gen_andi_tl(reg, reg, 0x1);
277
}
278

    
279
static inline void gen_mov_reg_V(TCGv reg, TCGv src)
280
{
281
    tcg_gen_extu_i32_tl(reg, src);
282
    tcg_gen_shri_tl(reg, reg, PSR_OVF_SHIFT);
283
    tcg_gen_andi_tl(reg, reg, 0x1);
284
}
285

    
286
static inline void gen_mov_reg_C(TCGv reg, TCGv src)
287
{
288
    tcg_gen_extu_i32_tl(reg, src);
289
    tcg_gen_shri_tl(reg, reg, PSR_CARRY_SHIFT);
290
    tcg_gen_andi_tl(reg, reg, 0x1);
291
}
292

    
293
static inline void gen_cc_clear_icc(void)
294
{
295
    tcg_gen_movi_i32(cpu_psr, 0);
296
}
297

    
298
#ifdef TARGET_SPARC64
299
static inline void gen_cc_clear_xcc(void)
300
{
301
    tcg_gen_movi_i32(cpu_xcc, 0);
302
}
303
#endif
304

    
305
/* old op:
306
    if (!T0)
307
        env->psr |= PSR_ZERO;
308
    if ((int32_t) T0 < 0)
309
        env->psr |= PSR_NEG;
310
*/
311
static inline void gen_cc_NZ_icc(TCGv dst)
312
{
313
    TCGv r_temp;
314
    int l1, l2;
315

    
316
    l1 = gen_new_label();
317
    l2 = gen_new_label();
318
    r_temp = tcg_temp_new(TCG_TYPE_TL);
319
    tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
320
    tcg_gen_brcondi_tl(TCG_COND_NE, r_temp, 0, l1);
321
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_ZERO);
322
    gen_set_label(l1);
323
    tcg_gen_ext_i32_tl(r_temp, dst);
324
    tcg_gen_brcondi_tl(TCG_COND_GE, r_temp, 0, l2);
325
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_NEG);
326
    gen_set_label(l2);
327
    tcg_temp_free(r_temp);
328
}
329

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

    
335
    l1 = gen_new_label();
336
    l2 = gen_new_label();
337
    tcg_gen_brcondi_tl(TCG_COND_NE, dst, 0, l1);
338
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_ZERO);
339
    gen_set_label(l1);
340
    tcg_gen_brcondi_tl(TCG_COND_GE, dst, 0, l2);
341
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_NEG);
342
    gen_set_label(l2);
343
}
344
#endif
345

    
346
/* old op:
347
    if (T0 < src1)
348
        env->psr |= PSR_CARRY;
349
*/
350
static inline void gen_cc_C_add_icc(TCGv dst, TCGv src1)
351
{
352
    TCGv r_temp1, r_temp2;
353
    int l1;
354

    
355
    l1 = gen_new_label();
356
    r_temp1 = tcg_temp_new(TCG_TYPE_TL);
357
    r_temp2 = tcg_temp_new(TCG_TYPE_TL);
358
    tcg_gen_andi_tl(r_temp1, dst, 0xffffffffULL);
359
    tcg_gen_andi_tl(r_temp2, src1, 0xffffffffULL);
360
    tcg_gen_brcond_tl(TCG_COND_GEU, r_temp1, r_temp2, l1);
361
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
362
    gen_set_label(l1);
363
    tcg_temp_free(r_temp1);
364
    tcg_temp_free(r_temp2);
365
}
366

    
367
#ifdef TARGET_SPARC64
368
static inline void gen_cc_C_add_xcc(TCGv dst, TCGv src1)
369
{
370
    int l1;
371

    
372
    l1 = gen_new_label();
373
    tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l1);
374
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
375
    gen_set_label(l1);
376
}
377
#endif
378

    
379
/* old op:
380
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
381
        env->psr |= PSR_OVF;
382
*/
383
static inline void gen_cc_V_add_icc(TCGv dst, TCGv src1, TCGv src2)
384
{
385
    TCGv r_temp;
386

    
387
    r_temp = tcg_temp_new(TCG_TYPE_TL);
388
    tcg_gen_xor_tl(r_temp, src1, src2);
389
    tcg_gen_xori_tl(r_temp, r_temp, -1);
390
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
391
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
392
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
393
    tcg_gen_shri_tl(r_temp, r_temp, 31 - PSR_OVF_SHIFT);
394
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
395
    tcg_temp_free(r_temp);
396
    tcg_gen_or_i32(cpu_psr, cpu_psr, cpu_tmp32);
397
}
398

    
399
#ifdef TARGET_SPARC64
400
static inline void gen_cc_V_add_xcc(TCGv dst, TCGv src1, TCGv src2)
401
{
402
    TCGv r_temp;
403

    
404
    r_temp = tcg_temp_new(TCG_TYPE_TL);
405
    tcg_gen_xor_tl(r_temp, src1, src2);
406
    tcg_gen_xori_tl(r_temp, r_temp, -1);
407
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
408
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
409
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
410
    tcg_gen_shri_tl(r_temp, r_temp, 63 - PSR_OVF_SHIFT);
411
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
412
    tcg_temp_free(r_temp);
413
    tcg_gen_or_i32(cpu_xcc, cpu_xcc, cpu_tmp32);
414
}
415
#endif
416

    
417
static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
418
{
419
    TCGv r_temp, r_const;
420
    int l1;
421

    
422
    l1 = gen_new_label();
423

    
424
    r_temp = tcg_temp_new(TCG_TYPE_TL);
425
    tcg_gen_xor_tl(r_temp, src1, src2);
426
    tcg_gen_xori_tl(r_temp, r_temp, -1);
427
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
428
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
429
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
430
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
431
    r_const = tcg_const_i32(TT_TOVF);
432
    tcg_gen_helper_0_1(raise_exception, r_const);
433
    tcg_temp_free(r_const);
434
    gen_set_label(l1);
435
    tcg_temp_free(r_temp);
436
}
437

    
438
static inline void gen_cc_V_tag(TCGv src1, TCGv src2)
439
{
440
    int l1;
441

    
442
    l1 = gen_new_label();
443
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
444
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
445
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
446
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
447
    gen_set_label(l1);
448
}
449

    
450
static inline void gen_tag_tv(TCGv src1, TCGv src2)
451
{
452
    int l1;
453
    TCGv r_const;
454

    
455
    l1 = gen_new_label();
456
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
457
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
458
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
459
    r_const = tcg_const_i32(TT_TOVF);
460
    tcg_gen_helper_0_1(raise_exception, r_const);
461
    tcg_temp_free(r_const);
462
    gen_set_label(l1);
463
}
464

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

    
483
static inline void gen_op_addx_cc(TCGv dst, TCGv src1, TCGv src2)
484
{
485
    tcg_gen_mov_tl(cpu_cc_src, src1);
486
    tcg_gen_mov_tl(cpu_cc_src2, src2);
487
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
488
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_tmp0);
489
    gen_cc_clear_icc();
490
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
491
#ifdef TARGET_SPARC64
492
    gen_cc_clear_xcc();
493
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
494
#endif
495
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_dst, cpu_cc_src2);
496
    gen_cc_NZ_icc(cpu_cc_dst);
497
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
498
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
499
#ifdef TARGET_SPARC64
500
    gen_cc_NZ_xcc(cpu_cc_dst);
501
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
502
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
503
#endif
504
    tcg_gen_mov_tl(dst, cpu_cc_dst);
505
}
506

    
507
static inline void gen_op_tadd_cc(TCGv dst, TCGv src1, TCGv src2)
508
{
509
    tcg_gen_mov_tl(cpu_cc_src, src1);
510
    tcg_gen_mov_tl(cpu_cc_src2, src2);
511
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
512
    gen_cc_clear_icc();
513
    gen_cc_NZ_icc(cpu_cc_dst);
514
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
515
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
516
    gen_cc_V_tag(cpu_cc_src, cpu_cc_src2);
517
#ifdef TARGET_SPARC64
518
    gen_cc_clear_xcc();
519
    gen_cc_NZ_xcc(cpu_cc_dst);
520
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
521
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
522
#endif
523
    tcg_gen_mov_tl(dst, cpu_cc_dst);
524
}
525

    
526
static inline void gen_op_tadd_ccTV(TCGv dst, TCGv src1, TCGv src2)
527
{
528
    tcg_gen_mov_tl(cpu_cc_src, src1);
529
    tcg_gen_mov_tl(cpu_cc_src2, src2);
530
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
531
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
532
    gen_add_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
533
    gen_cc_clear_icc();
534
    gen_cc_NZ_icc(cpu_cc_dst);
535
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
536
#ifdef TARGET_SPARC64
537
    gen_cc_clear_xcc();
538
    gen_cc_NZ_xcc(cpu_cc_dst);
539
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
540
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
541
#endif
542
    tcg_gen_mov_tl(dst, cpu_cc_dst);
543
}
544

    
545
/* old op:
546
    if (src1 < T1)
547
        env->psr |= PSR_CARRY;
548
*/
549
static inline void gen_cc_C_sub_icc(TCGv src1, TCGv src2)
550
{
551
    TCGv r_temp1, r_temp2;
552
    int l1;
553

    
554
    l1 = gen_new_label();
555
    r_temp1 = tcg_temp_new(TCG_TYPE_TL);
556
    r_temp2 = tcg_temp_new(TCG_TYPE_TL);
557
    tcg_gen_andi_tl(r_temp1, src1, 0xffffffffULL);
558
    tcg_gen_andi_tl(r_temp2, src2, 0xffffffffULL);
559
    tcg_gen_brcond_tl(TCG_COND_GEU, r_temp1, r_temp2, l1);
560
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
561
    gen_set_label(l1);
562
    tcg_temp_free(r_temp1);
563
    tcg_temp_free(r_temp2);
564
}
565

    
566
#ifdef TARGET_SPARC64
567
static inline void gen_cc_C_sub_xcc(TCGv src1, TCGv src2)
568
{
569
    int l1;
570

    
571
    l1 = gen_new_label();
572
    tcg_gen_brcond_tl(TCG_COND_GEU, src1, src2, l1);
573
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
574
    gen_set_label(l1);
575
}
576
#endif
577

    
578
/* old op:
579
    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
580
        env->psr |= PSR_OVF;
581
*/
582
static inline void gen_cc_V_sub_icc(TCGv dst, TCGv src1, TCGv src2)
583
{
584
    TCGv r_temp;
585

    
586
    r_temp = tcg_temp_new(TCG_TYPE_TL);
587
    tcg_gen_xor_tl(r_temp, src1, src2);
588
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
589
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
590
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
591
    tcg_gen_shri_tl(r_temp, r_temp, 31 - PSR_OVF_SHIFT);
592
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
593
    tcg_gen_or_i32(cpu_psr, cpu_psr, cpu_tmp32);
594
    tcg_temp_free(r_temp);
595
}
596

    
597
#ifdef TARGET_SPARC64
598
static inline void gen_cc_V_sub_xcc(TCGv dst, TCGv src1, TCGv src2)
599
{
600
    TCGv r_temp;
601

    
602
    r_temp = tcg_temp_new(TCG_TYPE_TL);
603
    tcg_gen_xor_tl(r_temp, src1, src2);
604
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
605
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
606
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
607
    tcg_gen_shri_tl(r_temp, r_temp, 63 - PSR_OVF_SHIFT);
608
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
609
    tcg_gen_or_i32(cpu_xcc, cpu_xcc, cpu_tmp32);
610
    tcg_temp_free(r_temp);
611
}
612
#endif
613

    
614
static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
615
{
616
    TCGv r_temp, r_const;
617
    int l1;
618

    
619
    l1 = gen_new_label();
620

    
621
    r_temp = tcg_temp_new(TCG_TYPE_TL);
622
    tcg_gen_xor_tl(r_temp, src1, src2);
623
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
624
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
625
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
626
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
627
    r_const = tcg_const_i32(TT_TOVF);
628
    tcg_gen_helper_0_1(raise_exception, r_const);
629
    tcg_temp_free(r_const);
630
    gen_set_label(l1);
631
    tcg_temp_free(r_temp);
632
}
633

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

    
652
static inline void gen_op_subx_cc(TCGv dst, TCGv src1, TCGv src2)
653
{
654
    tcg_gen_mov_tl(cpu_cc_src, src1);
655
    tcg_gen_mov_tl(cpu_cc_src2, src2);
656
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
657
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_tmp0);
658
    gen_cc_clear_icc();
659
    gen_cc_C_sub_icc(cpu_cc_dst, cpu_cc_src);
660
#ifdef TARGET_SPARC64
661
    gen_cc_clear_xcc();
662
    gen_cc_C_sub_xcc(cpu_cc_dst, cpu_cc_src);
663
#endif
664
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_dst, cpu_cc_src2);
665
    gen_cc_NZ_icc(cpu_cc_dst);
666
    gen_cc_C_sub_icc(cpu_cc_dst, cpu_cc_src);
667
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
668
#ifdef TARGET_SPARC64
669
    gen_cc_NZ_xcc(cpu_cc_dst);
670
    gen_cc_C_sub_xcc(cpu_cc_dst, cpu_cc_src);
671
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
672
#endif
673
    tcg_gen_mov_tl(dst, cpu_cc_dst);
674
}
675

    
676
static inline void gen_op_tsub_cc(TCGv dst, TCGv src1, TCGv src2)
677
{
678
    tcg_gen_mov_tl(cpu_cc_src, src1);
679
    tcg_gen_mov_tl(cpu_cc_src2, src2);
680
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
681
    gen_cc_clear_icc();
682
    gen_cc_NZ_icc(cpu_cc_dst);
683
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
684
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
685
    gen_cc_V_tag(cpu_cc_src, cpu_cc_src2);
686
#ifdef TARGET_SPARC64
687
    gen_cc_clear_xcc();
688
    gen_cc_NZ_xcc(cpu_cc_dst);
689
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
690
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
691
#endif
692
    tcg_gen_mov_tl(dst, cpu_cc_dst);
693
}
694

    
695
static inline void gen_op_tsub_ccTV(TCGv dst, TCGv src1, TCGv src2)
696
{
697
    tcg_gen_mov_tl(cpu_cc_src, src1);
698
    tcg_gen_mov_tl(cpu_cc_src2, src2);
699
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
700
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
701
    gen_sub_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
702
    gen_cc_clear_icc();
703
    gen_cc_NZ_icc(cpu_cc_dst);
704
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
705
#ifdef TARGET_SPARC64
706
    gen_cc_clear_xcc();
707
    gen_cc_NZ_xcc(cpu_cc_dst);
708
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
709
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
710
#endif
711
    tcg_gen_mov_tl(dst, cpu_cc_dst);
712
}
713

    
714
static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
715
{
716
    TCGv r_temp, r_temp2;
717
    int l1;
718

    
719
    l1 = gen_new_label();
720
    r_temp = tcg_temp_new(TCG_TYPE_TL);
721
    r_temp2 = tcg_temp_new(TCG_TYPE_I32);
722

    
723
    /* old op:
724
    if (!(env->y & 1))
725
        T1 = 0;
726
    */
727
    tcg_gen_mov_tl(cpu_cc_src, src1);
728
    tcg_gen_ld32u_tl(r_temp, cpu_env, offsetof(CPUSPARCState, y));
729
    tcg_gen_trunc_tl_i32(r_temp2, r_temp);
730
    tcg_gen_andi_i32(r_temp2, r_temp2, 0x1);
731
    tcg_gen_mov_tl(cpu_cc_src2, src2);
732
    tcg_gen_brcondi_i32(TCG_COND_NE, r_temp2, 0, l1);
733
    tcg_gen_movi_tl(cpu_cc_src2, 0);
734
    gen_set_label(l1);
735

    
736
    // b2 = T0 & 1;
737
    // env->y = (b2 << 31) | (env->y >> 1);
738
    tcg_gen_trunc_tl_i32(r_temp2, cpu_cc_src);
739
    tcg_gen_andi_i32(r_temp2, r_temp2, 0x1);
740
    tcg_gen_shli_i32(r_temp2, r_temp2, 31);
741
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, y));
742
    tcg_gen_shri_i32(cpu_tmp32, cpu_tmp32, 1);
743
    tcg_gen_or_i32(cpu_tmp32, cpu_tmp32, r_temp2);
744
    tcg_temp_free(r_temp2);
745
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, y));
746

    
747
    // b1 = N ^ V;
748
    gen_mov_reg_N(cpu_tmp0, cpu_psr);
749
    gen_mov_reg_V(r_temp, cpu_psr);
750
    tcg_gen_xor_tl(cpu_tmp0, cpu_tmp0, r_temp);
751
    tcg_temp_free(r_temp);
752

    
753
    // T0 = (b1 << 31) | (T0 >> 1);
754
    // src1 = T0;
755
    tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
756
    tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
757
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
758

    
759
    /* do addition and update flags */
760
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
761

    
762
    gen_cc_clear_icc();
763
    gen_cc_NZ_icc(cpu_cc_dst);
764
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
765
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
766
    tcg_gen_mov_tl(dst, cpu_cc_dst);
767
}
768

    
769
static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
770
{
771
    TCGv r_temp, r_temp2;
772

    
773
    r_temp = tcg_temp_new(TCG_TYPE_I64);
774
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);
775

    
776
    tcg_gen_extu_tl_i64(r_temp, src2);
777
    tcg_gen_extu_tl_i64(r_temp2, src1);
778
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
779

    
780
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
781
    tcg_gen_trunc_i64_i32(r_temp, r_temp);
782
    tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
783
    tcg_temp_free(r_temp);
784
#ifdef TARGET_SPARC64
785
    tcg_gen_mov_i64(dst, r_temp2);
786
#else
787
    tcg_gen_trunc_i64_tl(dst, r_temp2);
788
#endif
789
    tcg_temp_free(r_temp2);
790
}
791

    
792
static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
793
{
794
    TCGv r_temp, r_temp2;
795

    
796
    r_temp = tcg_temp_new(TCG_TYPE_I64);
797
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);
798

    
799
    tcg_gen_ext_tl_i64(r_temp, src2);
800
    tcg_gen_ext_tl_i64(r_temp2, src1);
801
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
802

    
803
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
804
    tcg_gen_trunc_i64_i32(r_temp, r_temp);
805
    tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
806
    tcg_temp_free(r_temp);
807
#ifdef TARGET_SPARC64
808
    tcg_gen_mov_i64(dst, r_temp2);
809
#else
810
    tcg_gen_trunc_i64_tl(dst, r_temp2);
811
#endif
812
    tcg_temp_free(r_temp2);
813
}
814

    
815
#ifdef TARGET_SPARC64
816
static inline void gen_trap_ifdivzero_tl(TCGv divisor)
817
{
818
    TCGv r_const;
819
    int l1;
820

    
821
    l1 = gen_new_label();
822
    tcg_gen_brcondi_tl(TCG_COND_NE, divisor, 0, l1);
823
    r_const = tcg_const_i32(TT_DIV_ZERO);
824
    tcg_gen_helper_0_1(raise_exception, r_const);
825
    tcg_temp_free(r_const);
826
    gen_set_label(l1);
827
}
828

    
829
static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
830
{
831
    int l1, l2;
832

    
833
    l1 = gen_new_label();
834
    l2 = gen_new_label();
835
    tcg_gen_mov_tl(cpu_cc_src, src1);
836
    tcg_gen_mov_tl(cpu_cc_src2, src2);
837
    gen_trap_ifdivzero_tl(cpu_cc_src2);
838
    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc_src, INT64_MIN, l1);
839
    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc_src2, -1, l1);
840
    tcg_gen_movi_i64(dst, INT64_MIN);
841
    tcg_gen_br(l2);
842
    gen_set_label(l1);
843
    tcg_gen_div_i64(dst, cpu_cc_src, cpu_cc_src2);
844
    gen_set_label(l2);
845
}
846
#endif
847

    
848
static inline void gen_op_div_cc(TCGv dst)
849
{
850
    int l1;
851

    
852
    tcg_gen_mov_tl(cpu_cc_dst, dst);
853
    gen_cc_clear_icc();
854
    gen_cc_NZ_icc(cpu_cc_dst);
855
    l1 = gen_new_label();
856
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cc_src2, 0, l1);
857
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
858
    gen_set_label(l1);
859
}
860

    
861
static inline void gen_op_logic_cc(TCGv dst)
862
{
863
    tcg_gen_mov_tl(cpu_cc_dst, dst);
864

    
865
    gen_cc_clear_icc();
866
    gen_cc_NZ_icc(cpu_cc_dst);
867
#ifdef TARGET_SPARC64
868
    gen_cc_clear_xcc();
869
    gen_cc_NZ_xcc(cpu_cc_dst);
870
#endif
871
}
872

    
873
// 1
874
static inline void gen_op_eval_ba(TCGv dst)
875
{
876
    tcg_gen_movi_tl(dst, 1);
877
}
878

    
879
// Z
880
static inline void gen_op_eval_be(TCGv dst, TCGv src)
881
{
882
    gen_mov_reg_Z(dst, src);
883
}
884

    
885
// Z | (N ^ V)
886
static inline void gen_op_eval_ble(TCGv dst, TCGv src)
887
{
888
    gen_mov_reg_N(cpu_tmp0, src);
889
    gen_mov_reg_V(dst, src);
890
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
891
    gen_mov_reg_Z(cpu_tmp0, src);
892
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
893
}
894

    
895
// N ^ V
896
static inline void gen_op_eval_bl(TCGv dst, TCGv src)
897
{
898
    gen_mov_reg_V(cpu_tmp0, src);
899
    gen_mov_reg_N(dst, src);
900
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
901
}
902

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

    
911
// C
912
static inline void gen_op_eval_bcs(TCGv dst, TCGv src)
913
{
914
    gen_mov_reg_C(dst, src);
915
}
916

    
917
// V
918
static inline void gen_op_eval_bvs(TCGv dst, TCGv src)
919
{
920
    gen_mov_reg_V(dst, src);
921
}
922

    
923
// 0
924
static inline void gen_op_eval_bn(TCGv dst)
925
{
926
    tcg_gen_movi_tl(dst, 0);
927
}
928

    
929
// N
930
static inline void gen_op_eval_bneg(TCGv dst, TCGv src)
931
{
932
    gen_mov_reg_N(dst, src);
933
}
934

    
935
// !Z
936
static inline void gen_op_eval_bne(TCGv dst, TCGv src)
937
{
938
    gen_mov_reg_Z(dst, src);
939
    tcg_gen_xori_tl(dst, dst, 0x1);
940
}
941

    
942
// !(Z | (N ^ V))
943
static inline void gen_op_eval_bg(TCGv dst, TCGv src)
944
{
945
    gen_mov_reg_N(cpu_tmp0, src);
946
    gen_mov_reg_V(dst, src);
947
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
948
    gen_mov_reg_Z(cpu_tmp0, src);
949
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
950
    tcg_gen_xori_tl(dst, dst, 0x1);
951
}
952

    
953
// !(N ^ V)
954
static inline void gen_op_eval_bge(TCGv dst, TCGv src)
955
{
956
    gen_mov_reg_V(cpu_tmp0, src);
957
    gen_mov_reg_N(dst, src);
958
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
959
    tcg_gen_xori_tl(dst, dst, 0x1);
960
}
961

    
962
// !(C | Z)
963
static inline void gen_op_eval_bgu(TCGv dst, TCGv src)
964
{
965
    gen_mov_reg_Z(cpu_tmp0, src);
966
    gen_mov_reg_C(dst, src);
967
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
968
    tcg_gen_xori_tl(dst, dst, 0x1);
969
}
970

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

    
978
// !N
979
static inline void gen_op_eval_bpos(TCGv dst, TCGv src)
980
{
981
    gen_mov_reg_N(dst, src);
982
    tcg_gen_xori_tl(dst, dst, 0x1);
983
}
984

    
985
// !V
986
static inline void gen_op_eval_bvc(TCGv dst, TCGv src)
987
{
988
    gen_mov_reg_V(dst, src);
989
    tcg_gen_xori_tl(dst, dst, 0x1);
990
}
991

    
992
/*
993
  FPSR bit field FCC1 | FCC0:
994
   0 =
995
   1 <
996
   2 >
997
   3 unordered
998
*/
999
static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src,
1000
                                    unsigned int fcc_offset)
1001
{
1002
    tcg_gen_shri_tl(reg, src, FSR_FCC0_SHIFT + fcc_offset);
1003
    tcg_gen_andi_tl(reg, reg, 0x1);
1004
}
1005

    
1006
static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
1007
                                    unsigned int fcc_offset)
1008
{
1009
    tcg_gen_shri_tl(reg, src, FSR_FCC1_SHIFT + fcc_offset);
1010
    tcg_gen_andi_tl(reg, reg, 0x1);
1011
}
1012

    
1013
// !0: FCC0 | FCC1
1014
static inline void gen_op_eval_fbne(TCGv dst, TCGv src,
1015
                                    unsigned int fcc_offset)
1016
{
1017
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1018
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1019
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
1020
}
1021

    
1022
// 1 or 2: FCC0 ^ FCC1
1023
static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
1024
                                    unsigned int fcc_offset)
1025
{
1026
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1027
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1028
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1029
}
1030

    
1031
// 1 or 3: FCC0
1032
static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
1033
                                    unsigned int fcc_offset)
1034
{
1035
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1036
}
1037

    
1038
// 1: FCC0 & !FCC1
1039
static inline void gen_op_eval_fbl(TCGv dst, TCGv src,
1040
                                    unsigned int fcc_offset)
1041
{
1042
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1043
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1044
    tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
1045
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1046
}
1047

    
1048
// 2 or 3: FCC1
1049
static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
1050
                                    unsigned int fcc_offset)
1051
{
1052
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1053
}
1054

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

    
1065
// 3: FCC0 & FCC1
1066
static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
1067
                                    unsigned int fcc_offset)
1068
{
1069
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1070
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1071
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1072
}
1073

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

    
1084
// 0 or 3: !(FCC0 ^ FCC1)
1085
static inline void gen_op_eval_fbue(TCGv dst, TCGv src,
1086
                                    unsigned int fcc_offset)
1087
{
1088
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1089
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1090
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1091
    tcg_gen_xori_tl(dst, dst, 0x1);
1092
}
1093

    
1094
// 0 or 2: !FCC0
1095
static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
1096
                                    unsigned int fcc_offset)
1097
{
1098
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1099
    tcg_gen_xori_tl(dst, dst, 0x1);
1100
}
1101

    
1102
// !1: !(FCC0 & !FCC1)
1103
static inline void gen_op_eval_fbuge(TCGv dst, TCGv src,
1104
                                    unsigned int fcc_offset)
1105
{
1106
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1107
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1108
    tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
1109
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1110
    tcg_gen_xori_tl(dst, dst, 0x1);
1111
}
1112

    
1113
// 0 or 1: !FCC1
1114
static inline void gen_op_eval_fble(TCGv dst, TCGv src,
1115
                                    unsigned int fcc_offset)
1116
{
1117
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1118
    tcg_gen_xori_tl(dst, dst, 0x1);
1119
}
1120

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

    
1132
// !3: !(FCC0 & FCC1)
1133
static inline void gen_op_eval_fbo(TCGv dst, TCGv src,
1134
                                    unsigned int fcc_offset)
1135
{
1136
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1137
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1138
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1139
    tcg_gen_xori_tl(dst, dst, 0x1);
1140
}
1141

    
1142
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
1143
                               target_ulong pc2, TCGv r_cond)
1144
{
1145
    int l1;
1146

    
1147
    l1 = gen_new_label();
1148

    
1149
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
1150

    
1151
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
1152

    
1153
    gen_set_label(l1);
1154
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
1155
}
1156

    
1157
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
1158
                                target_ulong pc2, TCGv r_cond)
1159
{
1160
    int l1;
1161

    
1162
    l1 = gen_new_label();
1163

    
1164
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
1165

    
1166
    gen_goto_tb(dc, 0, pc2, pc1);
1167

    
1168
    gen_set_label(l1);
1169
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
1170
}
1171

    
1172
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
1173
                                      TCGv r_cond)
1174
{
1175
    int l1, l2;
1176

    
1177
    l1 = gen_new_label();
1178
    l2 = gen_new_label();
1179

    
1180
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
1181

    
1182
    tcg_gen_movi_tl(cpu_npc, npc1);
1183
    tcg_gen_br(l2);
1184

    
1185
    gen_set_label(l1);
1186
    tcg_gen_movi_tl(cpu_npc, npc2);
1187
    gen_set_label(l2);
1188
}
1189

    
1190
/* call this function before using the condition register as it may
1191
   have been set for a jump */
1192
static inline void flush_cond(DisasContext *dc, TCGv cond)
1193
{
1194
    if (dc->npc == JUMP_PC) {
1195
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1196
        dc->npc = DYNAMIC_PC;
1197
    }
1198
}
1199

    
1200
static inline void save_npc(DisasContext *dc, TCGv cond)
1201
{
1202
    if (dc->npc == JUMP_PC) {
1203
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1204
        dc->npc = DYNAMIC_PC;
1205
    } else if (dc->npc != DYNAMIC_PC) {
1206
        tcg_gen_movi_tl(cpu_npc, dc->npc);
1207
    }
1208
}
1209

    
1210
static inline void save_state(DisasContext *dc, TCGv cond)
1211
{
1212
    tcg_gen_movi_tl(cpu_pc, dc->pc);
1213
    save_npc(dc, cond);
1214
}
1215

    
1216
static inline void gen_mov_pc_npc(DisasContext *dc, TCGv cond)
1217
{
1218
    if (dc->npc == JUMP_PC) {
1219
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1220
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1221
        dc->pc = DYNAMIC_PC;
1222
    } else if (dc->npc == DYNAMIC_PC) {
1223
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1224
        dc->pc = DYNAMIC_PC;
1225
    } else {
1226
        dc->pc = dc->npc;
1227
    }
1228
}
1229

    
1230
static inline void gen_op_next_insn(void)
1231
{
1232
    tcg_gen_mov_tl(cpu_pc, cpu_npc);
1233
    tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
1234
}
1235

    
1236
static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond)
1237
{
1238
    TCGv r_src;
1239

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

    
1300
static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
1301
{
1302
    unsigned int offset;
1303

    
1304
    switch (cc) {
1305
    default:
1306
    case 0x0:
1307
        offset = 0;
1308
        break;
1309
    case 0x1:
1310
        offset = 32 - 10;
1311
        break;
1312
    case 0x2:
1313
        offset = 34 - 10;
1314
        break;
1315
    case 0x3:
1316
        offset = 36 - 10;
1317
        break;
1318
    }
1319

    
1320
    switch (cond) {
1321
    case 0x0:
1322
        gen_op_eval_bn(r_dst);
1323
        break;
1324
    case 0x1:
1325
        gen_op_eval_fbne(r_dst, cpu_fsr, offset);
1326
        break;
1327
    case 0x2:
1328
        gen_op_eval_fblg(r_dst, cpu_fsr, offset);
1329
        break;
1330
    case 0x3:
1331
        gen_op_eval_fbul(r_dst, cpu_fsr, offset);
1332
        break;
1333
    case 0x4:
1334
        gen_op_eval_fbl(r_dst, cpu_fsr, offset);
1335
        break;
1336
    case 0x5:
1337
        gen_op_eval_fbug(r_dst, cpu_fsr, offset);
1338
        break;
1339
    case 0x6:
1340
        gen_op_eval_fbg(r_dst, cpu_fsr, offset);
1341
        break;
1342
    case 0x7:
1343
        gen_op_eval_fbu(r_dst, cpu_fsr, offset);
1344
        break;
1345
    case 0x8:
1346
        gen_op_eval_ba(r_dst);
1347
        break;
1348
    case 0x9:
1349
        gen_op_eval_fbe(r_dst, cpu_fsr, offset);
1350
        break;
1351
    case 0xa:
1352
        gen_op_eval_fbue(r_dst, cpu_fsr, offset);
1353
        break;
1354
    case 0xb:
1355
        gen_op_eval_fbge(r_dst, cpu_fsr, offset);
1356
        break;
1357
    case 0xc:
1358
        gen_op_eval_fbuge(r_dst, cpu_fsr, offset);
1359
        break;
1360
    case 0xd:
1361
        gen_op_eval_fble(r_dst, cpu_fsr, offset);
1362
        break;
1363
    case 0xe:
1364
        gen_op_eval_fbule(r_dst, cpu_fsr, offset);
1365
        break;
1366
    case 0xf:
1367
        gen_op_eval_fbo(r_dst, cpu_fsr, offset);
1368
        break;
1369
    }
1370
}
1371

    
1372
#ifdef TARGET_SPARC64
1373
// Inverted logic
1374
static const int gen_tcg_cond_reg[8] = {
1375
    -1,
1376
    TCG_COND_NE,
1377
    TCG_COND_GT,
1378
    TCG_COND_GE,
1379
    -1,
1380
    TCG_COND_EQ,
1381
    TCG_COND_LE,
1382
    TCG_COND_LT,
1383
};
1384

    
1385
static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
1386
{
1387
    int l1;
1388

    
1389
    l1 = gen_new_label();
1390
    tcg_gen_movi_tl(r_dst, 0);
1391
    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], r_src, 0, l1);
1392
    tcg_gen_movi_tl(r_dst, 1);
1393
    gen_set_label(l1);
1394
}
1395
#endif
1396

    
1397
/* XXX: potentially incorrect if dynamic npc */
1398
static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1399
                      TCGv r_cond)
1400
{
1401
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1402
    target_ulong target = dc->pc + offset;
1403

    
1404
    if (cond == 0x0) {
1405
        /* unconditional not taken */
1406
        if (a) {
1407
            dc->pc = dc->npc + 4;
1408
            dc->npc = dc->pc + 4;
1409
        } else {
1410
            dc->pc = dc->npc;
1411
            dc->npc = dc->pc + 4;
1412
        }
1413
    } else if (cond == 0x8) {
1414
        /* unconditional taken */
1415
        if (a) {
1416
            dc->pc = target;
1417
            dc->npc = dc->pc + 4;
1418
        } else {
1419
            dc->pc = dc->npc;
1420
            dc->npc = target;
1421
        }
1422
    } else {
1423
        flush_cond(dc, r_cond);
1424
        gen_cond(r_cond, cc, cond);
1425
        if (a) {
1426
            gen_branch_a(dc, target, dc->npc, r_cond);
1427
            dc->is_br = 1;
1428
        } else {
1429
            dc->pc = dc->npc;
1430
            dc->jump_pc[0] = target;
1431
            dc->jump_pc[1] = dc->npc + 4;
1432
            dc->npc = JUMP_PC;
1433
        }
1434
    }
1435
}
1436

    
1437
/* XXX: potentially incorrect if dynamic npc */
1438
static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1439
                      TCGv r_cond)
1440
{
1441
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1442
    target_ulong target = dc->pc + offset;
1443

    
1444
    if (cond == 0x0) {
1445
        /* unconditional not taken */
1446
        if (a) {
1447
            dc->pc = dc->npc + 4;
1448
            dc->npc = dc->pc + 4;
1449
        } else {
1450
            dc->pc = dc->npc;
1451
            dc->npc = dc->pc + 4;
1452
        }
1453
    } else if (cond == 0x8) {
1454
        /* unconditional taken */
1455
        if (a) {
1456
            dc->pc = target;
1457
            dc->npc = dc->pc + 4;
1458
        } else {
1459
            dc->pc = dc->npc;
1460
            dc->npc = target;
1461
        }
1462
    } else {
1463
        flush_cond(dc, r_cond);
1464
        gen_fcond(r_cond, cc, cond);
1465
        if (a) {
1466
            gen_branch_a(dc, target, dc->npc, r_cond);
1467
            dc->is_br = 1;
1468
        } else {
1469
            dc->pc = dc->npc;
1470
            dc->jump_pc[0] = target;
1471
            dc->jump_pc[1] = dc->npc + 4;
1472
            dc->npc = JUMP_PC;
1473
        }
1474
    }
1475
}
1476

    
1477
#ifdef TARGET_SPARC64
1478
/* XXX: potentially incorrect if dynamic npc */
1479
static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
1480
                          TCGv r_cond, TCGv r_reg)
1481
{
1482
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1483
    target_ulong target = dc->pc + offset;
1484

    
1485
    flush_cond(dc, r_cond);
1486
    gen_cond_reg(r_cond, cond, r_reg);
1487
    if (a) {
1488
        gen_branch_a(dc, target, dc->npc, r_cond);
1489
        dc->is_br = 1;
1490
    } else {
1491
        dc->pc = dc->npc;
1492
        dc->jump_pc[0] = target;
1493
        dc->jump_pc[1] = dc->npc + 4;
1494
        dc->npc = JUMP_PC;
1495
    }
1496
}
1497

    
1498
static GenOpFunc * const gen_fcmps[4] = {
1499
    helper_fcmps,
1500
    helper_fcmps_fcc1,
1501
    helper_fcmps_fcc2,
1502
    helper_fcmps_fcc3,
1503
};
1504

    
1505
static GenOpFunc * const gen_fcmpd[4] = {
1506
    helper_fcmpd,
1507
    helper_fcmpd_fcc1,
1508
    helper_fcmpd_fcc2,
1509
    helper_fcmpd_fcc3,
1510
};
1511

    
1512
static GenOpFunc * const gen_fcmpq[4] = {
1513
    helper_fcmpq,
1514
    helper_fcmpq_fcc1,
1515
    helper_fcmpq_fcc2,
1516
    helper_fcmpq_fcc3,
1517
};
1518

    
1519
static GenOpFunc * const gen_fcmpes[4] = {
1520
    helper_fcmpes,
1521
    helper_fcmpes_fcc1,
1522
    helper_fcmpes_fcc2,
1523
    helper_fcmpes_fcc3,
1524
};
1525

    
1526
static GenOpFunc * const gen_fcmped[4] = {
1527
    helper_fcmped,
1528
    helper_fcmped_fcc1,
1529
    helper_fcmped_fcc2,
1530
    helper_fcmped_fcc3,
1531
};
1532

    
1533
static GenOpFunc * const gen_fcmpeq[4] = {
1534
    helper_fcmpeq,
1535
    helper_fcmpeq_fcc1,
1536
    helper_fcmpeq_fcc2,
1537
    helper_fcmpeq_fcc3,
1538
};
1539

    
1540
static inline void gen_op_fcmps(int fccno)
1541
{
1542
    tcg_gen_helper_0_0(gen_fcmps[fccno]);
1543
}
1544

    
1545
static inline void gen_op_fcmpd(int fccno)
1546
{
1547
    tcg_gen_helper_0_0(gen_fcmpd[fccno]);
1548
}
1549

    
1550
static inline void gen_op_fcmpq(int fccno)
1551
{
1552
    tcg_gen_helper_0_0(gen_fcmpq[fccno]);
1553
}
1554

    
1555
static inline void gen_op_fcmpes(int fccno)
1556
{
1557
    tcg_gen_helper_0_0(gen_fcmpes[fccno]);
1558
}
1559

    
1560
static inline void gen_op_fcmped(int fccno)
1561
{
1562
    tcg_gen_helper_0_0(gen_fcmped[fccno]);
1563
}
1564

    
1565
static inline void gen_op_fcmpeq(int fccno)
1566
{
1567
    tcg_gen_helper_0_0(gen_fcmpeq[fccno]);
1568
}
1569

    
1570
#else
1571

    
1572
static inline void gen_op_fcmps(int fccno)
1573
{
1574
    tcg_gen_helper_0_0(helper_fcmps);
1575
}
1576

    
1577
static inline void gen_op_fcmpd(int fccno)
1578
{
1579
    tcg_gen_helper_0_0(helper_fcmpd);
1580
}
1581

    
1582
static inline void gen_op_fcmpq(int fccno)
1583
{
1584
    tcg_gen_helper_0_0(helper_fcmpq);
1585
}
1586

    
1587
static inline void gen_op_fcmpes(int fccno)
1588
{
1589
    tcg_gen_helper_0_0(helper_fcmpes);
1590
}
1591

    
1592
static inline void gen_op_fcmped(int fccno)
1593
{
1594
    tcg_gen_helper_0_0(helper_fcmped);
1595
}
1596

    
1597
static inline void gen_op_fcmpeq(int fccno)
1598
{
1599
    tcg_gen_helper_0_0(helper_fcmpeq);
1600
}
1601
#endif
1602

    
1603
static inline void gen_op_fpexception_im(int fsr_flags)
1604
{
1605
    TCGv r_const;
1606

    
1607
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~FSR_FTT_MASK);
1608
    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
1609
    r_const = tcg_const_i32(TT_FP_EXCP);
1610
    tcg_gen_helper_0_1(raise_exception, r_const);
1611
    tcg_temp_free(r_const);
1612
}
1613

    
1614
static int gen_trap_ifnofpu(DisasContext *dc, TCGv r_cond)
1615
{
1616
#if !defined(CONFIG_USER_ONLY)
1617
    if (!dc->fpu_enabled) {
1618
        TCGv r_const;
1619

    
1620
        save_state(dc, r_cond);
1621
        r_const = tcg_const_i32(TT_NFPU_INSN);
1622
        tcg_gen_helper_0_1(raise_exception, r_const);
1623
        tcg_temp_free(r_const);
1624
        dc->is_br = 1;
1625
        return 1;
1626
    }
1627
#endif
1628
    return 0;
1629
}
1630

    
1631
static inline void gen_op_clear_ieee_excp_and_FTT(void)
1632
{
1633
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~(FSR_FTT_MASK | FSR_CEXC_MASK));
1634
}
1635

    
1636
static inline void gen_clear_float_exceptions(void)
1637
{
1638
    tcg_gen_helper_0_0(helper_clear_float_exceptions);
1639
}
1640

    
1641
/* asi moves */
1642
#ifdef TARGET_SPARC64
1643
static inline TCGv gen_get_asi(int insn, TCGv r_addr)
1644
{
1645
    int asi;
1646
    TCGv r_asi;
1647

    
1648
    if (IS_IMM) {
1649
        r_asi = tcg_temp_new(TCG_TYPE_I32);
1650
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
1651
    } else {
1652
        asi = GET_FIELD(insn, 19, 26);
1653
        r_asi = tcg_const_i32(asi);
1654
    }
1655
    return r_asi;
1656
}
1657

    
1658
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
1659
                              int sign)
1660
{
1661
    TCGv r_asi, r_size, r_sign;
1662

    
1663
    r_asi = gen_get_asi(insn, addr);
1664
    r_size = tcg_const_i32(size);
1665
    r_sign = tcg_const_i32(sign);
1666
    tcg_gen_helper_1_4(helper_ld_asi, dst, addr, r_asi, r_size, r_sign);
1667
    tcg_temp_free(r_sign);
1668
    tcg_temp_free(r_size);
1669
    tcg_temp_free(r_asi);
1670
}
1671

    
1672
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1673
{
1674
    TCGv r_asi, r_size;
1675

    
1676
    r_asi = gen_get_asi(insn, addr);
1677
    r_size = tcg_const_i32(size);
1678
    tcg_gen_helper_0_4(helper_st_asi, addr, src, r_asi, r_size);
1679
    tcg_temp_free(r_size);
1680
    tcg_temp_free(r_asi);
1681
}
1682

    
1683
static inline void gen_ldf_asi(TCGv addr, int insn, int size, int rd)
1684
{
1685
    TCGv r_asi, r_size, r_rd;
1686

    
1687
    r_asi = gen_get_asi(insn, addr);
1688
    r_size = tcg_const_i32(size);
1689
    r_rd = tcg_const_i32(rd);
1690
    tcg_gen_helper_0_4(helper_ldf_asi, addr, r_asi, r_size, r_rd);
1691
    tcg_temp_free(r_rd);
1692
    tcg_temp_free(r_size);
1693
    tcg_temp_free(r_asi);
1694
}
1695

    
1696
static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
1697
{
1698
    TCGv r_asi, r_size, r_rd;
1699

    
1700
    r_asi = gen_get_asi(insn, addr);
1701
    r_size = tcg_const_i32(size);
1702
    r_rd = tcg_const_i32(rd);
1703
    tcg_gen_helper_0_4(helper_stf_asi, addr, r_asi, r_size, r_rd);
1704
    tcg_temp_free(r_rd);
1705
    tcg_temp_free(r_size);
1706
    tcg_temp_free(r_asi);
1707
}
1708

    
1709
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1710
{
1711
    TCGv r_asi, r_size, r_sign;
1712

    
1713
    r_asi = gen_get_asi(insn, addr);
1714
    r_size = tcg_const_i32(4);
1715
    r_sign = tcg_const_i32(0);
1716
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
1717
    tcg_temp_free(r_sign);
1718
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, r_asi, r_size);
1719
    tcg_temp_free(r_size);
1720
    tcg_temp_free(r_asi);
1721
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1722
}
1723

    
1724
static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
1725
{
1726
    TCGv r_asi, r_rd;
1727

    
1728
    r_asi = gen_get_asi(insn, addr);
1729
    r_rd = tcg_const_i32(rd);
1730
    tcg_gen_helper_0_3(helper_ldda_asi, addr, r_asi, r_rd);
1731
    tcg_temp_free(r_rd);
1732
    tcg_temp_free(r_asi);
1733
}
1734

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

    
1739
    r_temp = tcg_temp_new(TCG_TYPE_TL);
1740
    gen_movl_reg_TN(rd + 1, r_temp);
1741
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi,
1742
                       r_temp);
1743
    tcg_temp_free(r_temp);
1744
    r_asi = gen_get_asi(insn, addr);
1745
    r_size = tcg_const_i32(8);
1746
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi, r_size);
1747
    tcg_temp_free(r_size);
1748
    tcg_temp_free(r_asi);
1749
}
1750

    
1751
static inline void gen_cas_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
1752
                               int rd)
1753
{
1754
    TCGv r_val1, r_asi;
1755

    
1756
    r_val1 = tcg_temp_new(TCG_TYPE_TL);
1757
    gen_movl_reg_TN(rd, r_val1);
1758
    r_asi = gen_get_asi(insn, addr);
1759
    tcg_gen_helper_1_4(helper_cas_asi, dst, addr, r_val1, val2, r_asi);
1760
    tcg_temp_free(r_asi);
1761
    tcg_temp_free(r_val1);
1762
}
1763

    
1764
static inline void gen_casx_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
1765
                                int rd)
1766
{
1767
    TCGv r_asi;
1768

    
1769
    gen_movl_reg_TN(rd, cpu_tmp64);
1770
    r_asi = gen_get_asi(insn, addr);
1771
    tcg_gen_helper_1_4(helper_casx_asi, dst, addr, cpu_tmp64, val2, r_asi);
1772
    tcg_temp_free(r_asi);
1773
}
1774

    
1775
#elif !defined(CONFIG_USER_ONLY)
1776

    
1777
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
1778
                              int sign)
1779
{
1780
    TCGv r_asi, r_size, r_sign;
1781

    
1782
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1783
    r_size = tcg_const_i32(size);
1784
    r_sign = tcg_const_i32(sign);
1785
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
1786
    tcg_temp_free(r_sign);
1787
    tcg_temp_free(r_size);
1788
    tcg_temp_free(r_asi);
1789
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1790
}
1791

    
1792
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1793
{
1794
    TCGv r_asi, r_size;
1795

    
1796
    tcg_gen_extu_tl_i64(cpu_tmp64, src);
1797
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1798
    r_size = tcg_const_i32(size);
1799
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi, r_size);
1800
    tcg_temp_free(r_size);
1801
    tcg_temp_free(r_asi);
1802
}
1803

    
1804
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1805
{
1806
    TCGv r_asi, r_size, r_sign;
1807

    
1808
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1809
    r_size = tcg_const_i32(4);
1810
    r_sign = tcg_const_i32(0);
1811
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
1812
    tcg_temp_free(r_sign);
1813
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, r_asi, r_size);
1814
    tcg_temp_free(r_size);
1815
    tcg_temp_free(r_asi);
1816
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1817
}
1818

    
1819
static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
1820
{
1821
    TCGv r_asi, r_size, r_sign;
1822

    
1823
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1824
    r_size = tcg_const_i32(8);
1825
    r_sign = tcg_const_i32(0);
1826
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
1827
    tcg_temp_free(r_sign);
1828
    tcg_temp_free(r_size);
1829
    tcg_temp_free(r_asi);
1830
    tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
1831
    gen_movl_TN_reg(rd + 1, cpu_tmp0);
1832
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1833
    tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
1834
    gen_movl_TN_reg(rd, hi);
1835
}
1836

    
1837
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1838
{
1839
    TCGv r_temp, r_asi, r_size;
1840

    
1841
    r_temp = tcg_temp_new(TCG_TYPE_TL);
1842
    gen_movl_reg_TN(rd + 1, r_temp);
1843
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi, r_temp);
1844
    tcg_temp_free(r_temp);
1845
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1846
    r_size = tcg_const_i32(8);
1847
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi, r_size);
1848
    tcg_temp_free(r_size);
1849
    tcg_temp_free(r_asi);
1850
}
1851
#endif
1852

    
1853
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1854
static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
1855
{
1856
    TCGv r_val, r_asi, r_size;
1857

    
1858
    gen_ld_asi(dst, addr, insn, 1, 0);
1859

    
1860
    r_val = tcg_const_i64(0xffULL);
1861
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1862
    r_size = tcg_const_i32(1);
1863
    tcg_gen_helper_0_4(helper_st_asi, addr, r_val, r_asi, r_size);
1864
    tcg_temp_free(r_size);
1865
    tcg_temp_free(r_asi);
1866
    tcg_temp_free(r_val);
1867
}
1868
#endif
1869

    
1870
static inline TCGv get_src1(unsigned int insn, TCGv def)
1871
{
1872
    TCGv r_rs1 = def;
1873
    unsigned int rs1;
1874

    
1875
    rs1 = GET_FIELD(insn, 13, 17);
1876
    if (rs1 == 0)
1877
        r_rs1 = tcg_const_tl(0); // XXX how to free?
1878
    else if (rs1 < 8)
1879
        r_rs1 = cpu_gregs[rs1];
1880
    else
1881
        tcg_gen_ld_tl(def, cpu_regwptr, (rs1 - 8) * sizeof(target_ulong));
1882
    return r_rs1;
1883
}
1884

    
1885
static inline TCGv get_src2(unsigned int insn, TCGv def)
1886
{
1887
    TCGv r_rs2 = def;
1888
    unsigned int rs2;
1889

    
1890
    if (IS_IMM) { /* immediate */
1891
        rs2 = GET_FIELDs(insn, 19, 31);
1892
        r_rs2 = tcg_const_tl((int)rs2); // XXX how to free?
1893
    } else { /* register */
1894
        rs2 = GET_FIELD(insn, 27, 31);
1895
        if (rs2 == 0)
1896
            r_rs2 = tcg_const_tl(0); // XXX how to free?
1897
        else if (rs2 < 8)
1898
            r_rs2 = cpu_gregs[rs2];
1899
        else
1900
            tcg_gen_ld_tl(def, cpu_regwptr, (rs2 - 8) * sizeof(target_ulong));
1901
    }
1902
    return r_rs2;
1903
}
1904

    
1905
#define CHECK_IU_FEATURE(dc, FEATURE)                      \
1906
    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
1907
        goto illegal_insn;
1908
#define CHECK_FPU_FEATURE(dc, FEATURE)                     \
1909
    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
1910
        goto nfpu_insn;
1911

    
1912
/* before an instruction, dc->pc must be static */
1913
static void disas_sparc_insn(DisasContext * dc)
1914
{
1915
    unsigned int insn, opc, rs1, rs2, rd;
1916

    
1917
    if (unlikely(loglevel & CPU_LOG_TB_OP))
1918
        tcg_gen_debug_insn_start(dc->pc);
1919
    insn = ldl_code(dc->pc);
1920
    opc = GET_FIELD(insn, 0, 1);
1921

    
1922
    rd = GET_FIELD(insn, 2, 6);
1923

    
1924
    cpu_src1 = tcg_temp_new(TCG_TYPE_TL); // const
1925
    cpu_src2 = tcg_temp_new(TCG_TYPE_TL); // const
1926

    
1927
    switch (opc) {
1928
    case 0:                     /* branches/sethi */
1929
        {
1930
            unsigned int xop = GET_FIELD(insn, 7, 9);
1931
            int32_t target;
1932
            switch (xop) {
1933
#ifdef TARGET_SPARC64
1934
            case 0x1:           /* V9 BPcc */
1935
                {
1936
                    int cc;
1937

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

    
2000
                    r_const = tcg_const_tl(value << 10);
2001
                    gen_movl_TN_reg(rd, r_const);
2002
                    tcg_temp_free(r_const);
2003
                }
2004
                break;
2005
            case 0x0:           /* UNIMPL */
2006
            default:
2007
                goto illegal_insn;
2008
            }
2009
            break;
2010
        }
2011
        break;
2012
    case 1:
2013
        /*CALL*/ {
2014
            target_long target = GET_FIELDs(insn, 2, 31) << 2;
2015
            TCGv r_const;
2016

    
2017
            r_const = tcg_const_tl(dc->pc);
2018
            gen_movl_TN_reg(15, r_const);
2019
            tcg_temp_free(r_const);
2020
            target += dc->pc;
2021
            gen_mov_pc_npc(dc, cpu_cond);
2022
            dc->npc = target;
2023
        }
2024
        goto jmp_insn;
2025
    case 2:                     /* FPU & Logical Operations */
2026
        {
2027
            unsigned int xop = GET_FIELD(insn, 7, 12);
2028
            if (xop == 0x3a) {  /* generate trap */
2029
                int cond;
2030

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

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

    
2104
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2105
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2106
                                       offsetof(CPUState, tick));
2107
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst,
2108
                                           r_tickptr);
2109
                        tcg_temp_free(r_tickptr);
2110
                        gen_movl_TN_reg(rd, cpu_dst);
2111
                    }
2112
                    break;
2113
                case 0x5: /* V9 rdpc */
2114
                    {
2115
                        TCGv r_const;
2116

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

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

    
2223
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2224
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2225
                                       offsetof(CPUState, tsptr));
2226
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2227
                                      offsetof(trap_state, tpc));
2228
                        tcg_temp_free(r_tsptr);
2229
                    }
2230
                    break;
2231
                case 1: // tnpc
2232
                    {
2233
                        TCGv r_tsptr;
2234

    
2235
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2236
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2237
                                       offsetof(CPUState, tsptr));
2238
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2239
                                      offsetof(trap_state, tnpc));
2240
                        tcg_temp_free(r_tsptr);
2241
                    }
2242
                    break;
2243
                case 2: // tstate
2244
                    {
2245
                        TCGv r_tsptr;
2246

    
2247
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2248
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2249
                                       offsetof(CPUState, tsptr));
2250
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2251
                                      offsetof(trap_state, tstate));
2252
                        tcg_temp_free(r_tsptr);
2253
                    }
2254
                    break;
2255
                case 3: // tt
2256
                    {
2257
                        TCGv r_tsptr;
2258

    
2259
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2260
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2261
                                       offsetof(CPUState, tsptr));
2262
                        tcg_gen_ld_i32(cpu_tmp0, r_tsptr,
2263
                                       offsetof(trap_state, tt));
2264
                        tcg_temp_free(r_tsptr);
2265
                    }
2266
                    break;
2267
                case 4: // tick
2268
                    {
2269
                        TCGv r_tickptr;
2270

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

    
2709
                    l1 = gen_new_label();
2710
                    cond = GET_FIELD_SP(insn, 14, 17);
2711
                    cpu_src1 = get_src1(insn, cpu_src1);
2712
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2713
                                       0, l1);
2714
                    gen_op_load_fpr_FT0(rs2);
2715
                    gen_op_store_FT0_fpr(rd);
2716
                    gen_set_label(l1);
2717
                    break;
2718
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
2719
                    int l1;
2720

    
2721
                    l1 = gen_new_label();
2722
                    cond = GET_FIELD_SP(insn, 14, 17);
2723
                    cpu_src1 = get_src1(insn, cpu_src1);
2724
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2725
                                       0, l1);
2726
                    gen_op_load_fpr_DT0(DFPREG(rs2));
2727
                    gen_op_store_DT0_fpr(DFPREG(rd));
2728
                    gen_set_label(l1);
2729
                    break;
2730
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
2731
                    int l1;
2732

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

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

    
2884
                rs1 = GET_FIELD(insn, 13, 17);
2885
                if (rs1 == 0) {
2886
                    // or %g0, x, y -> mov T0, x; mov y, T0
2887
                    if (IS_IMM) {       /* immediate */
2888
                        TCGv r_const;
2889

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

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

    
3234
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
3235
                                                   cpu_src2);
3236
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3237
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3238
                                                   offsetof(CPUState, stick));
3239
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3240
                                                       r_tickptr, cpu_dst);
3241
                                    tcg_temp_free(r_tickptr);
3242
                                }
3243
                                break;
3244
                            case 0x19: /* System tick compare */
3245
#if !defined(CONFIG_USER_ONLY)
3246
                                if (!supervisor(dc))
3247
                                    goto illegal_insn;
3248
#endif
3249
                                {
3250
                                    TCGv r_tickptr;
3251

    
3252
                                    tcg_gen_xor_tl(cpu_tmp0, cpu_src1,
3253
                                                   cpu_src2);
3254
                                    tcg_gen_st_tl(cpu_tmp0, cpu_env,
3255
                                                  offsetof(CPUSPARCState,
3256
                                                           stick_cmpr));
3257
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3258
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3259
                                                   offsetof(CPUState, stick));
3260
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3261
                                                       r_tickptr, cpu_tmp0);
3262
                                    tcg_temp_free(r_tickptr);
3263
                                }
3264
                                break;
3265

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

    
3321
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3322
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3323
                                                   offsetof(CPUState, tsptr));
3324
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3325
                                                  offsetof(trap_state, tpc));
3326
                                    tcg_temp_free(r_tsptr);
3327
                                }
3328
                                break;
3329
                            case 1: // tnpc
3330
                                {
3331
                                    TCGv r_tsptr;
3332

    
3333
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3334
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3335
                                                   offsetof(CPUState, tsptr));
3336
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3337
                                                  offsetof(trap_state, tnpc));
3338
                                    tcg_temp_free(r_tsptr);
3339
                                }
3340
                                break;
3341
                            case 2: // tstate
3342
                                {
3343
                                    TCGv r_tsptr;
3344

    
3345
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3346
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3347
                                                   offsetof(CPUState, tsptr));
3348
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3349
                                                  offsetof(trap_state,
3350
                                                           tstate));
3351
                                    tcg_temp_free(r_tsptr);
3352
                                }
3353
                                break;
3354
                            case 3: // tt
3355
                                {
3356
                                    TCGv r_tsptr;
3357

    
3358
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3359
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3360
                                                   offsetof(CPUState, tsptr));
3361
                                    tcg_gen_st_i32(cpu_tmp0, r_tsptr,
3362
                                                   offsetof(trap_state, tt));
3363
                                    tcg_temp_free(r_tsptr);
3364
                                }
3365
                                break;
3366
                            case 4: // tick
3367
                                {
3368
                                    TCGv r_tickptr;
3369

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

    
3498
                                    tcg_gen_st_tl(cpu_tmp0, cpu_env,
3499
                                                  offsetof(CPUSPARCState,
3500
                                                           hstick_cmpr));
3501
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3502
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3503
                                                   offsetof(CPUState, hstick));
3504
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3505
                                                       r_tickptr, cpu_tmp0);
3506
                                    tcg_temp_free(r_tickptr);
3507
                                }
3508
                                break;
3509
                            case 6: // hver readonly
3510
                            default:
3511
                                goto illegal_insn;
3512
                            }
3513
#endif
3514
                        }
3515
                        break;
3516
#endif
3517
#ifdef TARGET_SPARC64
3518
                    case 0x2c: /* V9 movcc */
3519
                        {
3520
                            int cc = GET_FIELD_SP(insn, 11, 12);
3521
                            int cond = GET_FIELD_SP(insn, 14, 17);
3522
                            TCGv r_cond;
3523
                            int l1;
3524

    
3525
                            r_cond = tcg_temp_new(TCG_TYPE_TL);
3526
                            if (insn & (1 << 18)) {
3527
                                if (cc == 0)
3528
                                    gen_cond(r_cond, 0, cond);
3529
                                else if (cc == 2)
3530
                                    gen_cond(r_cond, 1, cond);
3531
                                else
3532
                                    goto illegal_insn;
3533
                            } else {
3534
                                gen_fcond(r_cond, cc, cond);
3535
                            }
3536

    
3537
                            l1 = gen_new_label();
3538

    
3539
                            tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
3540
                            if (IS_IMM) {       /* immediate */
3541
                                TCGv r_const;
3542

    
3543
                                rs2 = GET_FIELD_SPs(insn, 0, 10);
3544
                                r_const = tcg_const_tl((int)rs2);
3545
                                gen_movl_TN_reg(rd, r_const);
3546
                                tcg_temp_free(r_const);
3547
                            } else {
3548
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3549
                                gen_movl_reg_TN(rs2, cpu_tmp0);
3550
                                gen_movl_TN_reg(rd, cpu_tmp0);
3551
                            }
3552
                            gen_set_label(l1);
3553
                            tcg_temp_free(r_cond);
3554
                            break;
3555
                        }
3556
                    case 0x2d: /* V9 sdivx */
3557
                        gen_op_sdivx(cpu_dst, cpu_src1, cpu_src2);
3558
                        gen_movl_TN_reg(rd, cpu_dst);
3559
                        break;
3560
                    case 0x2e: /* V9 popc */
3561
                        {
3562
                            cpu_src2 = get_src2(insn, cpu_src2);
3563
                            tcg_gen_helper_1_1(helper_popc, cpu_dst,
3564
                                               cpu_src2);
3565
                            gen_movl_TN_reg(rd, cpu_dst);
3566
                        }
3567
                    case 0x2f: /* V9 movr */
3568
                        {
3569
                            int cond = GET_FIELD_SP(insn, 10, 12);
3570
                            int l1;
3571

    
3572
                            cpu_src1 = get_src1(insn, cpu_src1);
3573

    
3574
                            l1 = gen_new_label();
3575

    
3576
                            tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond],
3577
                                              cpu_src1, 0, l1);
3578
                            if (IS_IMM) {       /* immediate */
3579
                                TCGv r_const;
3580

    
3581
                                rs2 = GET_FIELD_SPs(insn, 0, 9);
3582
                                r_const = tcg_const_tl((int)rs2);
3583
                                gen_movl_TN_reg(rd, r_const);
3584
                                tcg_temp_free(r_const);
3585
                            } else {
3586
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3587
                                gen_movl_reg_TN(rs2, cpu_tmp0);
3588
                                gen_movl_TN_reg(rd, cpu_tmp0);
3589
                            }
3590
                            gen_set_label(l1);
3591
                            break;
3592
                        }
3593
#endif
3594
                    default:
3595
                        goto illegal_insn;
3596
                    }
3597
                }
3598
            } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
3599
#ifdef TARGET_SPARC64
3600
                int opf = GET_FIELD_SP(insn, 5, 13);
3601
                rs1 = GET_FIELD(insn, 13, 17);
3602
                rs2 = GET_FIELD(insn, 27, 31);
3603
                if (gen_trap_ifnofpu(dc, cpu_cond))
3604
                    goto jmp_insn;
3605

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

    
4074
                save_state(dc, cpu_cond);
4075
                cpu_src1 = get_src1(insn, cpu_src1);
4076
                if (IS_IMM) {   /* immediate */
4077
                    rs2 = GET_FIELDs(insn, 19, 31);
4078
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, (int)rs2);
4079
                } else {                /* register */
4080
                    rs2 = GET_FIELD(insn, 27, 31);
4081
                    if (rs2) {
4082
                        gen_movl_reg_TN(rs2, cpu_src2);
4083
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
4084
                    } else
4085
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
4086
                }
4087
                tcg_gen_helper_0_0(helper_restore);
4088
                gen_mov_pc_npc(dc, cpu_cond);
4089
                r_const = tcg_const_i32(3);
4090
                tcg_gen_helper_0_2(helper_check_align, cpu_dst, r_const);
4091
                tcg_temp_free(r_const);
4092
                tcg_gen_mov_tl(cpu_npc, cpu_dst);
4093
                dc->npc = DYNAMIC_PC;
4094
                goto jmp_insn;
4095
#endif
4096
            } else {
4097
                cpu_src1 = get_src1(insn, cpu_src1);
4098
                if (IS_IMM) {   /* immediate */
4099
                    rs2 = GET_FIELDs(insn, 19, 31);
4100
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, (int)rs2);
4101
                } else {                /* register */
4102
                    rs2 = GET_FIELD(insn, 27, 31);
4103
                    if (rs2) {
4104
                        gen_movl_reg_TN(rs2, cpu_src2);
4105
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
4106
                    } else
4107
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
4108
                }
4109
                switch (xop) {
4110
                case 0x38:      /* jmpl */
4111
                    {
4112
                        TCGv r_const;
4113

    
4114
                        r_const = tcg_const_tl(dc->pc);
4115
                        gen_movl_TN_reg(rd, r_const);
4116
                        tcg_temp_free(r_const);
4117
                        gen_mov_pc_npc(dc, cpu_cond);
4118
                        r_const = tcg_const_i32(3);
4119
                        tcg_gen_helper_0_2(helper_check_align, cpu_dst,
4120
                                           r_const);
4121
                        tcg_temp_free(r_const);
4122
                        tcg_gen_mov_tl(cpu_npc, cpu_dst);
4123
                        dc->npc = DYNAMIC_PC;
4124
                    }
4125
                    goto jmp_insn;
4126
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
4127
                case 0x39:      /* rett, V9 return */
4128
                    {
4129
                        TCGv r_const;
4130

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

    
4194
            cpu_src1 = get_src1(insn, cpu_src1);
4195
            if (xop == 0x3c || xop == 0x3e) { // V9 casa/casxa
4196
                rs2 = GET_FIELD(insn, 27, 31);
4197
                gen_movl_reg_TN(rs2, cpu_src2);
4198
                tcg_gen_mov_tl(cpu_addr, cpu_src1);
4199
            } else if (IS_IMM) {     /* immediate */
4200
                rs2 = GET_FIELDs(insn, 19, 31);
4201
                tcg_gen_addi_tl(cpu_addr, cpu_src1, (int)rs2);
4202
            } else {            /* register */
4203
                rs2 = GET_FIELD(insn, 27, 31);
4204
                if (rs2 != 0) {
4205
                    gen_movl_reg_TN(rs2, cpu_src2);
4206
                    tcg_gen_add_tl(cpu_addr, cpu_src1, cpu_src2);
4207
                } else
4208
                    tcg_gen_mov_tl(cpu_addr, cpu_src1);
4209
            }
4210
            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
4211
                (xop > 0x17 && xop <= 0x1d ) ||
4212
                (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
4213
                switch (xop) {
4214
                case 0x0:       /* load unsigned word */
4215
                    gen_address_mask(dc, cpu_addr);
4216
                    tcg_gen_qemu_ld32u(cpu_val, cpu_addr, dc->mem_idx);
4217
                    break;
4218
                case 0x1:       /* load unsigned byte */
4219
                    gen_address_mask(dc, cpu_addr);
4220
                    tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx);
4221
                    break;
4222
                case 0x2:       /* load unsigned halfword */
4223
                    gen_address_mask(dc, cpu_addr);
4224
                    tcg_gen_qemu_ld16u(cpu_val, cpu_addr, dc->mem_idx);
4225
                    break;
4226
                case 0x3:       /* load double word */
4227
                    if (rd & 1)
4228
                        goto illegal_insn;
4229
                    else {
4230
                        TCGv r_const;
4231

    
4232
                        save_state(dc, cpu_cond);
4233
                        r_const = tcg_const_i32(7);
4234
                        tcg_gen_helper_0_2(helper_check_align, cpu_addr,
4235
                                           r_const); // XXX remove
4236
                        tcg_temp_free(r_const);
4237
                        gen_address_mask(dc, cpu_addr);
4238
                        tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
4239
                        tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
4240
                        tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffffULL);
4241
                        gen_movl_TN_reg(rd + 1, cpu_tmp0);
4242
                        tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
4243
                        tcg_gen_trunc_i64_tl(cpu_val, cpu_tmp64);
4244
                        tcg_gen_andi_tl(cpu_val, cpu_val, 0xffffffffULL);
4245
                    }
4246
                    break;
4247
                case 0x9:       /* load signed byte */
4248
                    gen_address_mask(dc, cpu_addr);
4249
                    tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
4250
                    break;
4251
                case 0xa:       /* load signed halfword */
4252
                    gen_address_mask(dc, cpu_addr);
4253
                    tcg_gen_qemu_ld16s(cpu_val, cpu_addr, dc->mem_idx);
4254
                    break;
4255
                case 0xd:       /* ldstub -- XXX: should be atomically */
4256
                    {
4257
                        TCGv r_const;
4258

    
4259
                        gen_address_mask(dc, cpu_addr);
4260
                        tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
4261
                        r_const = tcg_const_tl(0xff);
4262
                        tcg_gen_qemu_st8(r_const, cpu_addr, dc->mem_idx);
4263
                        tcg_temp_free(r_const);
4264
                    }
4265
                    break;
4266
                case 0x0f:      /* swap register with memory. Also
4267
                                   atomically */
4268
                    CHECK_IU_FEATURE(dc, SWAP);
4269
                    gen_movl_reg_TN(rd, cpu_val);
4270
                    gen_address_mask(dc, cpu_addr);
4271
                    tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
4272
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
4273
                    tcg_gen_extu_i32_tl(cpu_val, cpu_tmp32);
4274
                    break;
4275
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4276
                case 0x10:      /* load word alternate */
4277
#ifndef TARGET_SPARC64
4278
                    if (IS_IMM)
4279
                        goto illegal_insn;
4280
                    if (!supervisor(dc))
4281
                        goto priv_insn;
4282
#endif
4283
                    save_state(dc, cpu_cond);
4284
                    gen_ld_asi(cpu_val, cpu_addr, insn, 4, 0);
4285
                    break;
4286
                case 0x11:      /* load unsigned byte alternate */
4287
#ifndef TARGET_SPARC64
4288
                    if (IS_IMM)
4289
                        goto illegal_insn;
4290
                    if (!supervisor(dc))
4291
                        goto priv_insn;
4292
#endif
4293
                    save_state(dc, cpu_cond);
4294
                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 0);
4295
                    break;
4296
                case 0x12:      /* load unsigned halfword alternate */
4297
#ifndef TARGET_SPARC64
4298
                    if (IS_IMM)
4299
                        goto illegal_insn;
4300
                    if (!supervisor(dc))
4301
                        goto priv_insn;
4302
#endif
4303
                    save_state(dc, cpu_cond);
4304
                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 0);
4305
                    break;
4306
                case 0x13:      /* load double word alternate */
4307
#ifndef TARGET_SPARC64
4308
                    if (IS_IMM)
4309
                        goto illegal_insn;
4310
                    if (!supervisor(dc))
4311
                        goto priv_insn;
4312
#endif
4313
                    if (rd & 1)
4314
                        goto illegal_insn;
4315
                    save_state(dc, cpu_cond);
4316
                    gen_ldda_asi(cpu_val, cpu_addr, insn, rd);
4317
                    goto skip_move;
4318
                case 0x19:      /* load signed byte alternate */
4319
#ifndef TARGET_SPARC64
4320
                    if (IS_IMM)
4321
                        goto illegal_insn;
4322
                    if (!supervisor(dc))
4323
                        goto priv_insn;
4324
#endif
4325
                    save_state(dc, cpu_cond);
4326
                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 1);
4327
                    break;
4328
                case 0x1a:      /* load signed halfword alternate */
4329
#ifndef TARGET_SPARC64
4330
                    if (IS_IMM)
4331
                        goto illegal_insn;
4332
                    if (!supervisor(dc))
4333
                        goto priv_insn;
4334
#endif
4335
                    save_state(dc, cpu_cond);
4336
                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 1);
4337
                    break;
4338
                case 0x1d:      /* ldstuba -- XXX: should be atomically */
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_ldstub_asi(cpu_val, cpu_addr, insn);
4347
                    break;
4348
                case 0x1f:      /* swap reg with alt. memory. Also
4349
                                   atomically */
4350
                    CHECK_IU_FEATURE(dc, SWAP);
4351
#ifndef TARGET_SPARC64
4352
                    if (IS_IMM)
4353
                        goto illegal_insn;
4354
                    if (!supervisor(dc))
4355
                        goto priv_insn;
4356
#endif
4357
                    save_state(dc, cpu_cond);
4358
                    gen_movl_reg_TN(rd, cpu_val);
4359
                    gen_swap_asi(cpu_val, cpu_addr, insn);
4360
                    break;
4361

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

    
4433
                        CHECK_FPU_FEATURE(dc, FLOAT128);
4434
                        r_const = tcg_const_i32(dc->mem_idx);
4435
                        tcg_gen_helper_0_2(helper_ldqf, cpu_addr, r_const);
4436
                        tcg_temp_free(r_const);
4437
                        gen_op_store_QT0_fpr(QFPREG(rd));
4438
                    }
4439
                    break;
4440
                case 0x23:      /* load double fpreg */
4441
                    {
4442
                        TCGv r_const;
4443

    
4444
                        r_const = tcg_const_i32(dc->mem_idx);
4445
                        tcg_gen_helper_0_2(helper_lddf, cpu_addr, r_const);
4446
                        tcg_temp_free(r_const);
4447
                        gen_op_store_DT0_fpr(DFPREG(rd));
4448
                    }
4449
                    break;
4450
                default:
4451
                    goto illegal_insn;
4452
                }
4453
            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) || \
4454
                       xop == 0xe || xop == 0x1e) {
4455
                gen_movl_reg_TN(rd, cpu_val);
4456
                switch (xop) {
4457
                case 0x4: /* store word */
4458
                    gen_address_mask(dc, cpu_addr);
4459
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
4460
                    break;
4461
                case 0x5: /* store byte */
4462
                    gen_address_mask(dc, cpu_addr);
4463
                    tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx);
4464
                    break;
4465
                case 0x6: /* store halfword */
4466
                    gen_address_mask(dc, cpu_addr);
4467
                    tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx);
4468
                    break;
4469
                case 0x7: /* store double word */
4470
                    if (rd & 1)
4471
                        goto illegal_insn;
4472
                    else {
4473
                        TCGv r_low, r_const;
4474

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

    
4572
                        CHECK_FPU_FEATURE(dc, FLOAT128);
4573
                        gen_op_load_fpr_QT0(QFPREG(rd));
4574
                        r_const = tcg_const_i32(dc->mem_idx);
4575
                        tcg_gen_helper_0_2(helper_stqf, cpu_addr, r_const);
4576
                        tcg_temp_free(r_const);
4577
                    }
4578
                    break;
4579
#else /* !TARGET_SPARC64 */
4580
                    /* stdfq, store floating point queue */
4581
#if defined(CONFIG_USER_ONLY)
4582
                    goto illegal_insn;
4583
#else
4584
                    if (!supervisor(dc))
4585
                        goto priv_insn;
4586
                    if (gen_trap_ifnofpu(dc, cpu_cond))
4587
                        goto jmp_insn;
4588
                    goto nfq_insn;
4589
#endif
4590
#endif
4591
                case 0x27: /* store double fpreg */
4592
                    {
4593
                        TCGv r_const;
4594

    
4595
                        gen_op_load_fpr_DT0(DFPREG(rd));
4596
                        r_const = tcg_const_i32(dc->mem_idx);
4597
                        tcg_gen_helper_0_2(helper_stdf, cpu_addr, r_const);
4598
                        tcg_temp_free(r_const);
4599
                    }
4600
                    break;
4601
                default:
4602
                    goto illegal_insn;
4603
                }
4604
            } else if (xop > 0x33 && xop < 0x3f) {
4605
                save_state(dc, cpu_cond);
4606
                switch (xop) {
4607
#ifdef TARGET_SPARC64
4608
                case 0x34: /* V9 stfa */
4609
                    gen_op_load_fpr_FT0(rd);
4610
                    gen_stf_asi(cpu_addr, insn, 4, rd);
4611
                    break;
4612
                case 0x36: /* V9 stqfa */
4613
                    {
4614
                        TCGv r_const;
4615

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

    
4671
        save_state(dc, cpu_cond);
4672
        r_const = tcg_const_i32(TT_ILL_INSN);
4673
        tcg_gen_helper_0_1(raise_exception, r_const);
4674
        tcg_temp_free(r_const);
4675
        dc->is_br = 1;
4676
    }
4677
    return;
4678
 unimp_flush:
4679
    {
4680
        TCGv r_const;
4681

    
4682
        save_state(dc, cpu_cond);
4683
        r_const = tcg_const_i32(TT_UNIMP_FLUSH);
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
#if !defined(CONFIG_USER_ONLY)
4690
 priv_insn:
4691
    {
4692
        TCGv r_const;
4693

    
4694
        save_state(dc, cpu_cond);
4695
        r_const = tcg_const_i32(TT_PRIV_INSN);
4696
        tcg_gen_helper_0_1(raise_exception, r_const);
4697
        tcg_temp_free(r_const);
4698
        dc->is_br = 1;
4699
    }
4700
    return;
4701
#endif
4702
 nfpu_insn:
4703
    save_state(dc, cpu_cond);
4704
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
4705
    dc->is_br = 1;
4706
    return;
4707
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
4708
 nfq_insn:
4709
    save_state(dc, cpu_cond);
4710
    gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
4711
    dc->is_br = 1;
4712
    return;
4713
#endif
4714
#ifndef TARGET_SPARC64
4715
 ncp_insn:
4716
    {
4717
        TCGv r_const;
4718

    
4719
        save_state(dc, cpu_cond);
4720
        r_const = tcg_const_i32(TT_NCP_INSN);
4721
        tcg_gen_helper_0_1(raise_exception, r_const);
4722
        tcg_temp_free(r_const);
4723
        dc->is_br = 1;
4724
    }
4725
    return;
4726
#endif
4727
}
4728

    
4729
static inline void gen_intermediate_code_internal(TranslationBlock * tb,
4730
                                                  int spc, CPUSPARCState *env)
4731
{
4732
    target_ulong pc_start, last_pc;
4733
    uint16_t *gen_opc_end;
4734
    DisasContext dc1, *dc = &dc1;
4735
    int j, lj = -1;
4736
    int num_insns;
4737
    int max_insns;
4738

    
4739
    memset(dc, 0, sizeof(DisasContext));
4740
    dc->tb = tb;
4741
    pc_start = tb->pc;
4742
    dc->pc = pc_start;
4743
    last_pc = dc->pc;
4744
    dc->npc = (target_ulong) tb->cs_base;
4745
    dc->mem_idx = cpu_mmu_index(env);
4746
    dc->def = env->def;
4747
    if ((dc->def->features & CPU_FEATURE_FLOAT))
4748
        dc->fpu_enabled = cpu_fpu_enabled(env);
4749
    else
4750
        dc->fpu_enabled = 0;
4751
#ifdef TARGET_SPARC64
4752
    dc->address_mask_32bit = env->pstate & PS_AM;
4753
#endif
4754
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4755

    
4756
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
4757
    cpu_tmp32 = tcg_temp_new(TCG_TYPE_I32);
4758
    cpu_tmp64 = tcg_temp_new(TCG_TYPE_I64);
4759

    
4760
    cpu_dst = tcg_temp_local_new(TCG_TYPE_TL);
4761

    
4762
    // loads and stores
4763
    cpu_val = tcg_temp_local_new(TCG_TYPE_TL);
4764
    cpu_addr = tcg_temp_local_new(TCG_TYPE_TL);
4765

    
4766
    num_insns = 0;
4767
    max_insns = tb->cflags & CF_COUNT_MASK;
4768
    if (max_insns == 0)
4769
        max_insns = CF_COUNT_MASK;
4770
    gen_icount_start();
4771
    do {
4772
        if (env->nb_breakpoints > 0) {
4773
            for(j = 0; j < env->nb_breakpoints; j++) {
4774
                if (env->breakpoints[j] == dc->pc) {
4775
                    if (dc->pc != pc_start)
4776
                        save_state(dc, cpu_cond);
4777
                    tcg_gen_helper_0_0(helper_debug);
4778
                    tcg_gen_exit_tb(0);
4779
                    dc->is_br = 1;
4780
                    goto exit_gen_loop;
4781
                }
4782
            }
4783
        }
4784
        if (spc) {
4785
            if (loglevel > 0)
4786
                fprintf(logfile, "Search PC...\n");
4787
            j = gen_opc_ptr - gen_opc_buf;
4788
            if (lj < j) {
4789
                lj++;
4790
                while (lj < j)
4791
                    gen_opc_instr_start[lj++] = 0;
4792
                gen_opc_pc[lj] = dc->pc;
4793
                gen_opc_npc[lj] = dc->npc;
4794
                gen_opc_instr_start[lj] = 1;
4795
                gen_opc_icount[lj] = num_insns;
4796
            }
4797
        }
4798
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
4799
            gen_io_start();
4800
        last_pc = dc->pc;
4801
        disas_sparc_insn(dc);
4802
        num_insns++;
4803

    
4804
        if (dc->is_br)
4805
            break;
4806
        /* if the next PC is different, we abort now */
4807
        if (dc->pc != (last_pc + 4))
4808
            break;
4809
        /* if we reach a page boundary, we stop generation so that the
4810
           PC of a TT_TFAULT exception is always in the right page */
4811
        if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
4812
            break;
4813
        /* if single step mode, we generate only one instruction and
4814
           generate an exception */
4815
        if (env->singlestep_enabled) {
4816
            tcg_gen_movi_tl(cpu_pc, dc->pc);
4817
            tcg_gen_exit_tb(0);
4818
            break;
4819
        }
4820
    } while ((gen_opc_ptr < gen_opc_end) &&
4821
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32) &&
4822
             num_insns < max_insns);
4823

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

    
4873
void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
4874
{
4875
    gen_intermediate_code_internal(tb, 0, env);
4876
}
4877

    
4878
void gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
4879
{
4880
    gen_intermediate_code_internal(tb, 1, env);
4881
}
4882

    
4883
void gen_intermediate_code_init(CPUSPARCState *env)
4884
{
4885
    unsigned int i;
4886
    static int inited;
4887
    static const char * const gregnames[8] = {
4888
        NULL, // g0 not used
4889
        "g1",
4890
        "g2",
4891
        "g3",
4892
        "g4",
4893
        "g5",
4894
        "g6",
4895
        "g7",
4896
    };
4897

    
4898
    /* init various static tables */
4899
    if (!inited) {
4900
        inited = 1;
4901

    
4902
        cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
4903
        cpu_regwptr = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
4904
                                         offsetof(CPUState, regwptr),
4905
                                         "regwptr");
4906
#ifdef TARGET_SPARC64
4907
        cpu_xcc = tcg_global_mem_new(TCG_TYPE_I32,
4908
                                     TCG_AREG0, offsetof(CPUState, xcc),
4909
                                     "xcc");
4910
#endif
4911
        cpu_cond = tcg_global_mem_new(TCG_TYPE_TL,
4912
                                      TCG_AREG0, offsetof(CPUState, cond),
4913
                                      "cond");
4914
        cpu_cc_src = tcg_global_mem_new(TCG_TYPE_TL,
4915
                                        TCG_AREG0, offsetof(CPUState, cc_src),
4916
                                        "cc_src");
4917
        cpu_cc_src2 = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4918
                                         offsetof(CPUState, cc_src2),
4919
                                         "cc_src2");
4920
        cpu_cc_dst = tcg_global_mem_new(TCG_TYPE_TL,
4921
                                        TCG_AREG0, offsetof(CPUState, cc_dst),
4922
                                        "cc_dst");
4923
        cpu_psr = tcg_global_mem_new(TCG_TYPE_I32,
4924
                                     TCG_AREG0, offsetof(CPUState, psr),
4925
                                     "psr");
4926
        cpu_fsr = tcg_global_mem_new(TCG_TYPE_TL,
4927
                                     TCG_AREG0, offsetof(CPUState, fsr),
4928
                                     "fsr");
4929
        cpu_pc = tcg_global_mem_new(TCG_TYPE_TL,
4930
                                    TCG_AREG0, offsetof(CPUState, pc),
4931
                                    "pc");
4932
        cpu_npc = tcg_global_mem_new(TCG_TYPE_TL,
4933
                                    TCG_AREG0, offsetof(CPUState, npc),
4934
                                    "npc");
4935
        for (i = 1; i < 8; i++)
4936
            cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4937
                                              offsetof(CPUState, gregs[i]),
4938
                                              gregnames[i]);
4939
        /* register helpers */
4940

    
4941
#undef DEF_HELPER
4942
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
4943
#include "helper.h"
4944
    }
4945
}
4946

    
4947
void gen_pc_load(CPUState *env, TranslationBlock *tb,
4948
                unsigned long searched_pc, int pc_pos, void *puc)
4949
{
4950
    target_ulong npc;
4951
    env->pc = gen_opc_pc[pc_pos];
4952
    npc = gen_opc_npc[pc_pos];
4953
    if (npc == 1) {
4954
        /* dynamic NPC: already stored */
4955
    } else if (npc == 2) {
4956
        target_ulong t2 = (target_ulong)(unsigned long)puc;
4957
        /* jump PC: use T2 and the jump targets of the translation */
4958
        if (t2)
4959
            env->npc = gen_opc_jump_pc[0];
4960
        else
4961
            env->npc = gen_opc_jump_pc[1];
4962
    } else {
4963
        env->npc = npc;
4964
    }
4965
}