Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ 5068cbd9

History | View | Annotate | Download (191.4 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_y;
45
#ifndef CONFIG_USER_ONLY
46
static TCGv cpu_tbr;
47
#endif
48
static TCGv cpu_cond, cpu_src1, cpu_src2, cpu_dst, cpu_addr, cpu_val;
49
#ifdef TARGET_SPARC64
50
static TCGv cpu_xcc, cpu_asi, cpu_fprs, cpu_gsr;
51
static TCGv cpu_tick_cmpr, cpu_stick_cmpr, cpu_hstick_cmpr;
52
static TCGv cpu_hintp, cpu_htba, cpu_hver, cpu_ssr, cpu_ver;
53
#else
54
static TCGv cpu_wim;
55
#endif
56
/* local register indexes (only used inside old micro ops) */
57
static TCGv cpu_tmp0, cpu_tmp32, cpu_tmp64;
58
/* Floating point registers */
59
static TCGv cpu_fpr[TARGET_FPREGS];
60

    
61
#include "gen-icount.h"
62

    
63
typedef struct DisasContext {
64
    target_ulong pc;    /* current Program Counter: integer or DYNAMIC_PC */
65
    target_ulong npc;   /* next PC: integer or DYNAMIC_PC or JUMP_PC */
66
    target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
67
    int is_br;
68
    int mem_idx;
69
    int fpu_enabled;
70
    int address_mask_32bit;
71
    struct TranslationBlock *tb;
72
    sparc_def_t *def;
73
} DisasContext;
74

    
75
// This function uses non-native bit order
76
#define GET_FIELD(X, FROM, TO) \
77
  ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
78

    
79
// This function uses the order in the manuals, i.e. bit 0 is 2^0
80
#define GET_FIELD_SP(X, FROM, TO) \
81
    GET_FIELD(X, 31 - (TO), 31 - (FROM))
82

    
83
#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
84
#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
85

    
86
#ifdef TARGET_SPARC64
87
#define FFPREG(r) (r)
88
#define DFPREG(r) (((r & 1) << 5) | (r & 0x1e))
89
#define QFPREG(r) (((r & 1) << 5) | (r & 0x1c))
90
#else
91
#define FFPREG(r) (r)
92
#define DFPREG(r) (r & 0x1e)
93
#define QFPREG(r) (r & 0x1c)
94
#endif
95

    
96
static int sign_extend(int x, int len)
97
{
98
    len = 32 - len;
99
    return (x << len) >> len;
100
}
101

    
102
#define IS_IMM (insn & (1<<13))
103

    
104
/* floating point registers moves */
105
static void gen_op_load_fpr_DT0(unsigned int src)
106
{
107
    tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, dt0) +
108
                   offsetof(CPU_DoubleU, l.upper));
109
    tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, dt0) +
110
                   offsetof(CPU_DoubleU, l.lower));
111
}
112

    
113
static void gen_op_load_fpr_DT1(unsigned int src)
114
{
115
    tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, dt1) +
116
                   offsetof(CPU_DoubleU, l.upper));
117
    tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, dt1) +
118
                   offsetof(CPU_DoubleU, l.lower));
119
}
120

    
121
static void gen_op_store_DT0_fpr(unsigned int dst)
122
{
123
    tcg_gen_ld_i32(cpu_fpr[dst], cpu_env, offsetof(CPUSPARCState, dt0) +
124
                   offsetof(CPU_DoubleU, l.upper));
125
    tcg_gen_ld_i32(cpu_fpr[dst + 1], cpu_env, offsetof(CPUSPARCState, dt0) +
126
                   offsetof(CPU_DoubleU, l.lower));
127
}
128

    
129
static void gen_op_load_fpr_QT0(unsigned int src)
130
{
131
    tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, qt0) +
132
                   offsetof(CPU_QuadU, l.upmost));
133
    tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, qt0) +
134
                   offsetof(CPU_QuadU, l.upper));
135
    tcg_gen_st_i32(cpu_fpr[src + 2], cpu_env, offsetof(CPUSPARCState, qt0) +
136
                   offsetof(CPU_QuadU, l.lower));
137
    tcg_gen_st_i32(cpu_fpr[src + 3], cpu_env, offsetof(CPUSPARCState, qt0) +
138
                   offsetof(CPU_QuadU, l.lowest));
139
}
140

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

    
153
static void gen_op_store_QT0_fpr(unsigned int dst)
154
{
155
    tcg_gen_ld_i32(cpu_fpr[dst], cpu_env, offsetof(CPUSPARCState, qt0) +
156
                   offsetof(CPU_QuadU, l.upmost));
157
    tcg_gen_ld_i32(cpu_fpr[dst + 1], cpu_env, offsetof(CPUSPARCState, qt0) +
158
                   offsetof(CPU_QuadU, l.upper));
159
    tcg_gen_ld_i32(cpu_fpr[dst + 2], cpu_env, offsetof(CPUSPARCState, qt0) +
160
                   offsetof(CPU_QuadU, l.lower));
161
    tcg_gen_ld_i32(cpu_fpr[dst + 3], cpu_env, offsetof(CPUSPARCState, qt0) +
162
                   offsetof(CPU_QuadU, l.lowest));
163
}
164

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

    
179
#ifdef TARGET_SPARC64
180
#ifndef TARGET_ABI32
181
#define AM_CHECK(dc) ((dc)->address_mask_32bit)
182
#else
183
#define AM_CHECK(dc) (1)
184
#endif
185
#endif
186

    
187
static inline void gen_address_mask(DisasContext *dc, TCGv addr)
188
{
189
#ifdef TARGET_SPARC64
190
    if (AM_CHECK(dc))
191
        tcg_gen_andi_tl(addr, addr, 0xffffffffULL);
192
#endif
193
}
194

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
329
    l1 = gen_new_label();
330
    r_temp1 = tcg_temp_new(TCG_TYPE_TL);
331
    r_temp2 = tcg_temp_new(TCG_TYPE_TL);
332
    tcg_gen_andi_tl(r_temp1, dst, 0xffffffffULL);
333
    tcg_gen_andi_tl(r_temp2, src1, 0xffffffffULL);
334
    tcg_gen_brcond_tl(TCG_COND_GEU, r_temp1, r_temp2, l1);
335
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
336
    gen_set_label(l1);
337
    tcg_temp_free(r_temp1);
338
    tcg_temp_free(r_temp2);
339
}
340

    
341
#ifdef TARGET_SPARC64
342
static inline void gen_cc_C_add_xcc(TCGv dst, TCGv src1)
343
{
344
    int l1;
345

    
346
    l1 = gen_new_label();
347
    tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l1);
348
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
349
    gen_set_label(l1);
350
}
351
#endif
352

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

    
361
    r_temp = tcg_temp_new(TCG_TYPE_TL);
362
    tcg_gen_xor_tl(r_temp, src1, src2);
363
    tcg_gen_xori_tl(r_temp, r_temp, -1);
364
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
365
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
366
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
367
    tcg_gen_shri_tl(r_temp, r_temp, 31 - PSR_OVF_SHIFT);
368
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
369
    tcg_temp_free(r_temp);
370
    tcg_gen_or_i32(cpu_psr, cpu_psr, cpu_tmp32);
371
}
372

    
373
#ifdef TARGET_SPARC64
374
static inline void gen_cc_V_add_xcc(TCGv dst, TCGv src1, TCGv src2)
375
{
376
    TCGv r_temp;
377

    
378
    r_temp = tcg_temp_new(TCG_TYPE_TL);
379
    tcg_gen_xor_tl(r_temp, src1, src2);
380
    tcg_gen_xori_tl(r_temp, r_temp, -1);
381
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
382
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
383
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
384
    tcg_gen_shri_tl(r_temp, r_temp, 63 - PSR_OVF_SHIFT);
385
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
386
    tcg_temp_free(r_temp);
387
    tcg_gen_or_i32(cpu_xcc, cpu_xcc, cpu_tmp32);
388
}
389
#endif
390

    
391
static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
392
{
393
    TCGv r_temp, r_const;
394
    int l1;
395

    
396
    l1 = gen_new_label();
397

    
398
    r_temp = tcg_temp_new(TCG_TYPE_TL);
399
    tcg_gen_xor_tl(r_temp, src1, src2);
400
    tcg_gen_xori_tl(r_temp, r_temp, -1);
401
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
402
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
403
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
404
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
405
    r_const = tcg_const_i32(TT_TOVF);
406
    tcg_gen_helper_0_1(raise_exception, r_const);
407
    tcg_temp_free(r_const);
408
    gen_set_label(l1);
409
    tcg_temp_free(r_temp);
410
}
411

    
412
static inline void gen_cc_V_tag(TCGv src1, TCGv src2)
413
{
414
    int l1;
415

    
416
    l1 = gen_new_label();
417
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
418
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
419
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
420
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
421
    gen_set_label(l1);
422
}
423

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

    
429
    l1 = gen_new_label();
430
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
431
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
432
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
433
    r_const = tcg_const_i32(TT_TOVF);
434
    tcg_gen_helper_0_1(raise_exception, r_const);
435
    tcg_temp_free(r_const);
436
    gen_set_label(l1);
437
}
438

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

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

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

    
500
static inline void gen_op_tadd_ccTV(TCGv dst, TCGv src1, TCGv src2)
501
{
502
    tcg_gen_mov_tl(cpu_cc_src, src1);
503
    tcg_gen_mov_tl(cpu_cc_src2, src2);
504
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
505
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
506
    gen_add_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
507
    gen_cc_clear_icc();
508
    gen_cc_NZ_icc(cpu_cc_dst);
509
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
510
#ifdef TARGET_SPARC64
511
    gen_cc_clear_xcc();
512
    gen_cc_NZ_xcc(cpu_cc_dst);
513
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
514
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
515
#endif
516
    tcg_gen_mov_tl(dst, cpu_cc_dst);
517
}
518

    
519
/* old op:
520
    if (src1 < T1)
521
        env->psr |= PSR_CARRY;
522
*/
523
static inline void gen_cc_C_sub_icc(TCGv src1, TCGv src2)
524
{
525
    TCGv r_temp1, r_temp2;
526
    int l1;
527

    
528
    l1 = gen_new_label();
529
    r_temp1 = tcg_temp_new(TCG_TYPE_TL);
530
    r_temp2 = tcg_temp_new(TCG_TYPE_TL);
531
    tcg_gen_andi_tl(r_temp1, src1, 0xffffffffULL);
532
    tcg_gen_andi_tl(r_temp2, src2, 0xffffffffULL);
533
    tcg_gen_brcond_tl(TCG_COND_GEU, r_temp1, r_temp2, l1);
534
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
535
    gen_set_label(l1);
536
    tcg_temp_free(r_temp1);
537
    tcg_temp_free(r_temp2);
538
}
539

    
540
#ifdef TARGET_SPARC64
541
static inline void gen_cc_C_sub_xcc(TCGv src1, TCGv src2)
542
{
543
    int l1;
544

    
545
    l1 = gen_new_label();
546
    tcg_gen_brcond_tl(TCG_COND_GEU, src1, src2, l1);
547
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
548
    gen_set_label(l1);
549
}
550
#endif
551

    
552
/* old op:
553
    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
554
        env->psr |= PSR_OVF;
555
*/
556
static inline void gen_cc_V_sub_icc(TCGv dst, TCGv src1, TCGv src2)
557
{
558
    TCGv r_temp;
559

    
560
    r_temp = tcg_temp_new(TCG_TYPE_TL);
561
    tcg_gen_xor_tl(r_temp, src1, src2);
562
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
563
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
564
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
565
    tcg_gen_shri_tl(r_temp, r_temp, 31 - PSR_OVF_SHIFT);
566
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
567
    tcg_gen_or_i32(cpu_psr, cpu_psr, cpu_tmp32);
568
    tcg_temp_free(r_temp);
569
}
570

    
571
#ifdef TARGET_SPARC64
572
static inline void gen_cc_V_sub_xcc(TCGv dst, TCGv src1, TCGv src2)
573
{
574
    TCGv r_temp;
575

    
576
    r_temp = tcg_temp_new(TCG_TYPE_TL);
577
    tcg_gen_xor_tl(r_temp, src1, src2);
578
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
579
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
580
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
581
    tcg_gen_shri_tl(r_temp, r_temp, 63 - PSR_OVF_SHIFT);
582
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
583
    tcg_gen_or_i32(cpu_xcc, cpu_xcc, cpu_tmp32);
584
    tcg_temp_free(r_temp);
585
}
586
#endif
587

    
588
static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
589
{
590
    TCGv r_temp, r_const;
591
    int l1;
592

    
593
    l1 = gen_new_label();
594

    
595
    r_temp = tcg_temp_new(TCG_TYPE_TL);
596
    tcg_gen_xor_tl(r_temp, src1, src2);
597
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
598
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
599
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
600
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
601
    r_const = tcg_const_i32(TT_TOVF);
602
    tcg_gen_helper_0_1(raise_exception, r_const);
603
    tcg_temp_free(r_const);
604
    gen_set_label(l1);
605
    tcg_temp_free(r_temp);
606
}
607

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

    
626
static inline void gen_op_subx_cc(TCGv dst, TCGv src1, TCGv src2)
627
{
628
    tcg_gen_mov_tl(cpu_cc_src, src1);
629
    tcg_gen_mov_tl(cpu_cc_src2, src2);
630
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
631
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_tmp0);
632
    gen_cc_clear_icc();
633
    gen_cc_C_sub_icc(cpu_cc_dst, cpu_cc_src);
634
#ifdef TARGET_SPARC64
635
    gen_cc_clear_xcc();
636
    gen_cc_C_sub_xcc(cpu_cc_dst, cpu_cc_src);
637
#endif
638
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_dst, cpu_cc_src2);
639
    gen_cc_NZ_icc(cpu_cc_dst);
640
    gen_cc_C_sub_icc(cpu_cc_dst, cpu_cc_src);
641
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
642
#ifdef TARGET_SPARC64
643
    gen_cc_NZ_xcc(cpu_cc_dst);
644
    gen_cc_C_sub_xcc(cpu_cc_dst, cpu_cc_src);
645
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
646
#endif
647
    tcg_gen_mov_tl(dst, cpu_cc_dst);
648
}
649

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

    
669
static inline void gen_op_tsub_ccTV(TCGv dst, TCGv src1, TCGv src2)
670
{
671
    tcg_gen_mov_tl(cpu_cc_src, src1);
672
    tcg_gen_mov_tl(cpu_cc_src2, src2);
673
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
674
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
675
    gen_sub_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
676
    gen_cc_clear_icc();
677
    gen_cc_NZ_icc(cpu_cc_dst);
678
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
679
#ifdef TARGET_SPARC64
680
    gen_cc_clear_xcc();
681
    gen_cc_NZ_xcc(cpu_cc_dst);
682
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
683
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
684
#endif
685
    tcg_gen_mov_tl(dst, cpu_cc_dst);
686
}
687

    
688
static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
689
{
690
    TCGv r_temp;
691
    int l1;
692

    
693
    l1 = gen_new_label();
694
    r_temp = tcg_temp_new(TCG_TYPE_TL);
695

    
696
    /* old op:
697
    if (!(env->y & 1))
698
        T1 = 0;
699
    */
700
    tcg_gen_mov_tl(cpu_cc_src, src1);
701
    tcg_gen_andi_tl(r_temp, cpu_y, 0x1);
702
    tcg_gen_mov_tl(cpu_cc_src2, src2);
703
    tcg_gen_brcondi_tl(TCG_COND_NE, r_temp, 0, l1);
704
    tcg_gen_movi_tl(cpu_cc_src2, 0);
705
    gen_set_label(l1);
706

    
707
    // b2 = T0 & 1;
708
    // env->y = (b2 << 31) | (env->y >> 1);
709
    tcg_gen_andi_tl(r_temp, cpu_cc_src, 0x1);
710
    tcg_gen_shli_tl(r_temp, r_temp, 31);
711
    tcg_gen_shri_tl(cpu_tmp0, cpu_y, 1);
712
    tcg_gen_or_tl(cpu_tmp0, cpu_tmp0, r_temp);
713
    tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
714

    
715
    // b1 = N ^ V;
716
    gen_mov_reg_N(cpu_tmp0, cpu_psr);
717
    gen_mov_reg_V(r_temp, cpu_psr);
718
    tcg_gen_xor_tl(cpu_tmp0, cpu_tmp0, r_temp);
719
    tcg_temp_free(r_temp);
720

    
721
    // T0 = (b1 << 31) | (T0 >> 1);
722
    // src1 = T0;
723
    tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
724
    tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
725
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
726

    
727
    /* do addition and update flags */
728
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
729

    
730
    gen_cc_clear_icc();
731
    gen_cc_NZ_icc(cpu_cc_dst);
732
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
733
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
734
    tcg_gen_mov_tl(dst, cpu_cc_dst);
735
}
736

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

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

    
744
    tcg_gen_extu_i32_i64(r_temp, src2);
745
    tcg_gen_extu_i32_i64(r_temp2, src1);
746
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
747

    
748
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
749
    tcg_gen_trunc_i64_tl(cpu_tmp0, r_temp);
750
    tcg_temp_free(r_temp);
751
    tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
752
#ifdef TARGET_SPARC64
753
    tcg_gen_mov_i64(dst, r_temp2);
754
#else
755
    tcg_gen_trunc_i64_tl(dst, r_temp2);
756
#endif
757
    tcg_temp_free(r_temp2);
758
}
759

    
760
static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
761
{
762
    TCGv r_temp, r_temp2;
763

    
764
    r_temp = tcg_temp_new(TCG_TYPE_I64);
765
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);
766

    
767
    tcg_gen_ext_i32_i64(r_temp, src2);
768
    tcg_gen_ext_i32_i64(r_temp2, src1);
769
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
770

    
771
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
772
    tcg_gen_trunc_i64_tl(cpu_tmp0, r_temp);
773
    tcg_temp_free(r_temp);
774
    tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
775
#ifdef TARGET_SPARC64
776
    tcg_gen_mov_i64(dst, r_temp2);
777
#else
778
    tcg_gen_trunc_i64_tl(dst, r_temp2);
779
#endif
780
    tcg_temp_free(r_temp2);
781
}
782

    
783
#ifdef TARGET_SPARC64
784
static inline void gen_trap_ifdivzero_tl(TCGv divisor)
785
{
786
    TCGv r_const;
787
    int l1;
788

    
789
    l1 = gen_new_label();
790
    tcg_gen_brcondi_tl(TCG_COND_NE, divisor, 0, l1);
791
    r_const = tcg_const_i32(TT_DIV_ZERO);
792
    tcg_gen_helper_0_1(raise_exception, r_const);
793
    tcg_temp_free(r_const);
794
    gen_set_label(l1);
795
}
796

    
797
static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
798
{
799
    int l1, l2;
800

    
801
    l1 = gen_new_label();
802
    l2 = gen_new_label();
803
    tcg_gen_mov_tl(cpu_cc_src, src1);
804
    tcg_gen_mov_tl(cpu_cc_src2, src2);
805
    gen_trap_ifdivzero_tl(cpu_cc_src2);
806
    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc_src, INT64_MIN, l1);
807
    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc_src2, -1, l1);
808
    tcg_gen_movi_i64(dst, INT64_MIN);
809
    tcg_gen_br(l2);
810
    gen_set_label(l1);
811
    tcg_gen_div_i64(dst, cpu_cc_src, cpu_cc_src2);
812
    gen_set_label(l2);
813
}
814
#endif
815

    
816
static inline void gen_op_div_cc(TCGv dst)
817
{
818
    int l1;
819

    
820
    tcg_gen_mov_tl(cpu_cc_dst, dst);
821
    gen_cc_clear_icc();
822
    gen_cc_NZ_icc(cpu_cc_dst);
823
    l1 = gen_new_label();
824
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cc_src2, 0, l1);
825
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
826
    gen_set_label(l1);
827
}
828

    
829
static inline void gen_op_logic_cc(TCGv dst)
830
{
831
    tcg_gen_mov_tl(cpu_cc_dst, dst);
832

    
833
    gen_cc_clear_icc();
834
    gen_cc_NZ_icc(cpu_cc_dst);
835
#ifdef TARGET_SPARC64
836
    gen_cc_clear_xcc();
837
    gen_cc_NZ_xcc(cpu_cc_dst);
838
#endif
839
}
840

    
841
// 1
842
static inline void gen_op_eval_ba(TCGv dst)
843
{
844
    tcg_gen_movi_tl(dst, 1);
845
}
846

    
847
// Z
848
static inline void gen_op_eval_be(TCGv dst, TCGv src)
849
{
850
    gen_mov_reg_Z(dst, src);
851
}
852

    
853
// Z | (N ^ V)
854
static inline void gen_op_eval_ble(TCGv dst, TCGv src)
855
{
856
    gen_mov_reg_N(cpu_tmp0, src);
857
    gen_mov_reg_V(dst, src);
858
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
859
    gen_mov_reg_Z(cpu_tmp0, src);
860
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
861
}
862

    
863
// N ^ V
864
static inline void gen_op_eval_bl(TCGv dst, TCGv src)
865
{
866
    gen_mov_reg_V(cpu_tmp0, src);
867
    gen_mov_reg_N(dst, src);
868
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
869
}
870

    
871
// C | Z
872
static inline void gen_op_eval_bleu(TCGv dst, TCGv src)
873
{
874
    gen_mov_reg_Z(cpu_tmp0, src);
875
    gen_mov_reg_C(dst, src);
876
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
877
}
878

    
879
// C
880
static inline void gen_op_eval_bcs(TCGv dst, TCGv src)
881
{
882
    gen_mov_reg_C(dst, src);
883
}
884

    
885
// V
886
static inline void gen_op_eval_bvs(TCGv dst, TCGv src)
887
{
888
    gen_mov_reg_V(dst, src);
889
}
890

    
891
// 0
892
static inline void gen_op_eval_bn(TCGv dst)
893
{
894
    tcg_gen_movi_tl(dst, 0);
895
}
896

    
897
// N
898
static inline void gen_op_eval_bneg(TCGv dst, TCGv src)
899
{
900
    gen_mov_reg_N(dst, src);
901
}
902

    
903
// !Z
904
static inline void gen_op_eval_bne(TCGv dst, TCGv src)
905
{
906
    gen_mov_reg_Z(dst, src);
907
    tcg_gen_xori_tl(dst, dst, 0x1);
908
}
909

    
910
// !(Z | (N ^ V))
911
static inline void gen_op_eval_bg(TCGv dst, TCGv src)
912
{
913
    gen_mov_reg_N(cpu_tmp0, src);
914
    gen_mov_reg_V(dst, src);
915
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
916
    gen_mov_reg_Z(cpu_tmp0, src);
917
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
918
    tcg_gen_xori_tl(dst, dst, 0x1);
919
}
920

    
921
// !(N ^ V)
922
static inline void gen_op_eval_bge(TCGv dst, TCGv src)
923
{
924
    gen_mov_reg_V(cpu_tmp0, src);
925
    gen_mov_reg_N(dst, src);
926
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
927
    tcg_gen_xori_tl(dst, dst, 0x1);
928
}
929

    
930
// !(C | Z)
931
static inline void gen_op_eval_bgu(TCGv dst, TCGv src)
932
{
933
    gen_mov_reg_Z(cpu_tmp0, src);
934
    gen_mov_reg_C(dst, src);
935
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
936
    tcg_gen_xori_tl(dst, dst, 0x1);
937
}
938

    
939
// !C
940
static inline void gen_op_eval_bcc(TCGv dst, TCGv src)
941
{
942
    gen_mov_reg_C(dst, src);
943
    tcg_gen_xori_tl(dst, dst, 0x1);
944
}
945

    
946
// !N
947
static inline void gen_op_eval_bpos(TCGv dst, TCGv src)
948
{
949
    gen_mov_reg_N(dst, src);
950
    tcg_gen_xori_tl(dst, dst, 0x1);
951
}
952

    
953
// !V
954
static inline void gen_op_eval_bvc(TCGv dst, TCGv src)
955
{
956
    gen_mov_reg_V(dst, src);
957
    tcg_gen_xori_tl(dst, dst, 0x1);
958
}
959

    
960
/*
961
  FPSR bit field FCC1 | FCC0:
962
   0 =
963
   1 <
964
   2 >
965
   3 unordered
966
*/
967
static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src,
968
                                    unsigned int fcc_offset)
969
{
970
    tcg_gen_shri_tl(reg, src, FSR_FCC0_SHIFT + fcc_offset);
971
    tcg_gen_andi_tl(reg, reg, 0x1);
972
}
973

    
974
static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
975
                                    unsigned int fcc_offset)
976
{
977
    tcg_gen_shri_tl(reg, src, FSR_FCC1_SHIFT + fcc_offset);
978
    tcg_gen_andi_tl(reg, reg, 0x1);
979
}
980

    
981
// !0: FCC0 | FCC1
982
static inline void gen_op_eval_fbne(TCGv dst, TCGv src,
983
                                    unsigned int fcc_offset)
984
{
985
    gen_mov_reg_FCC0(dst, src, fcc_offset);
986
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
987
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
988
}
989

    
990
// 1 or 2: FCC0 ^ FCC1
991
static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
992
                                    unsigned int fcc_offset)
993
{
994
    gen_mov_reg_FCC0(dst, src, fcc_offset);
995
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
996
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
997
}
998

    
999
// 1 or 3: FCC0
1000
static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
1001
                                    unsigned int fcc_offset)
1002
{
1003
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1004
}
1005

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

    
1016
// 2 or 3: FCC1
1017
static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
1018
                                    unsigned int fcc_offset)
1019
{
1020
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1021
}
1022

    
1023
// 2: !FCC0 & FCC1
1024
static inline void gen_op_eval_fbg(TCGv dst, TCGv src,
1025
                                    unsigned int fcc_offset)
1026
{
1027
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1028
    tcg_gen_xori_tl(dst, dst, 0x1);
1029
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1030
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1031
}
1032

    
1033
// 3: FCC0 & FCC1
1034
static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
1035
                                    unsigned int fcc_offset)
1036
{
1037
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1038
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1039
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1040
}
1041

    
1042
// 0: !(FCC0 | FCC1)
1043
static inline void gen_op_eval_fbe(TCGv dst, TCGv src,
1044
                                    unsigned int fcc_offset)
1045
{
1046
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1047
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1048
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
1049
    tcg_gen_xori_tl(dst, dst, 0x1);
1050
}
1051

    
1052
// 0 or 3: !(FCC0 ^ FCC1)
1053
static inline void gen_op_eval_fbue(TCGv dst, TCGv src,
1054
                                    unsigned int fcc_offset)
1055
{
1056
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1057
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1058
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1059
    tcg_gen_xori_tl(dst, dst, 0x1);
1060
}
1061

    
1062
// 0 or 2: !FCC0
1063
static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
1064
                                    unsigned int fcc_offset)
1065
{
1066
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1067
    tcg_gen_xori_tl(dst, dst, 0x1);
1068
}
1069

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

    
1081
// 0 or 1: !FCC1
1082
static inline void gen_op_eval_fble(TCGv dst, TCGv src,
1083
                                    unsigned int fcc_offset)
1084
{
1085
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1086
    tcg_gen_xori_tl(dst, dst, 0x1);
1087
}
1088

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

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

    
1110
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
1111
                               target_ulong pc2, TCGv r_cond)
1112
{
1113
    int l1;
1114

    
1115
    l1 = gen_new_label();
1116

    
1117
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
1118

    
1119
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
1120

    
1121
    gen_set_label(l1);
1122
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
1123
}
1124

    
1125
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
1126
                                target_ulong pc2, TCGv r_cond)
1127
{
1128
    int l1;
1129

    
1130
    l1 = gen_new_label();
1131

    
1132
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
1133

    
1134
    gen_goto_tb(dc, 0, pc2, pc1);
1135

    
1136
    gen_set_label(l1);
1137
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
1138
}
1139

    
1140
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
1141
                                      TCGv r_cond)
1142
{
1143
    int l1, l2;
1144

    
1145
    l1 = gen_new_label();
1146
    l2 = gen_new_label();
1147

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

    
1150
    tcg_gen_movi_tl(cpu_npc, npc1);
1151
    tcg_gen_br(l2);
1152

    
1153
    gen_set_label(l1);
1154
    tcg_gen_movi_tl(cpu_npc, npc2);
1155
    gen_set_label(l2);
1156
}
1157

    
1158
/* call this function before using the condition register as it may
1159
   have been set for a jump */
1160
static inline void flush_cond(DisasContext *dc, TCGv cond)
1161
{
1162
    if (dc->npc == JUMP_PC) {
1163
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1164
        dc->npc = DYNAMIC_PC;
1165
    }
1166
}
1167

    
1168
static inline void save_npc(DisasContext *dc, TCGv cond)
1169
{
1170
    if (dc->npc == JUMP_PC) {
1171
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1172
        dc->npc = DYNAMIC_PC;
1173
    } else if (dc->npc != DYNAMIC_PC) {
1174
        tcg_gen_movi_tl(cpu_npc, dc->npc);
1175
    }
1176
}
1177

    
1178
static inline void save_state(DisasContext *dc, TCGv cond)
1179
{
1180
    tcg_gen_movi_tl(cpu_pc, dc->pc);
1181
    save_npc(dc, cond);
1182
}
1183

    
1184
static inline void gen_mov_pc_npc(DisasContext *dc, TCGv cond)
1185
{
1186
    if (dc->npc == JUMP_PC) {
1187
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1188
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1189
        dc->pc = DYNAMIC_PC;
1190
    } else if (dc->npc == DYNAMIC_PC) {
1191
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1192
        dc->pc = DYNAMIC_PC;
1193
    } else {
1194
        dc->pc = dc->npc;
1195
    }
1196
}
1197

    
1198
static inline void gen_op_next_insn(void)
1199
{
1200
    tcg_gen_mov_tl(cpu_pc, cpu_npc);
1201
    tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
1202
}
1203

    
1204
static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond)
1205
{
1206
    TCGv r_src;
1207

    
1208
#ifdef TARGET_SPARC64
1209
    if (cc)
1210
        r_src = cpu_xcc;
1211
    else
1212
        r_src = cpu_psr;
1213
#else
1214
    r_src = cpu_psr;
1215
#endif
1216
    switch (cond) {
1217
    case 0x0:
1218
        gen_op_eval_bn(r_dst);
1219
        break;
1220
    case 0x1:
1221
        gen_op_eval_be(r_dst, r_src);
1222
        break;
1223
    case 0x2:
1224
        gen_op_eval_ble(r_dst, r_src);
1225
        break;
1226
    case 0x3:
1227
        gen_op_eval_bl(r_dst, r_src);
1228
        break;
1229
    case 0x4:
1230
        gen_op_eval_bleu(r_dst, r_src);
1231
        break;
1232
    case 0x5:
1233
        gen_op_eval_bcs(r_dst, r_src);
1234
        break;
1235
    case 0x6:
1236
        gen_op_eval_bneg(r_dst, r_src);
1237
        break;
1238
    case 0x7:
1239
        gen_op_eval_bvs(r_dst, r_src);
1240
        break;
1241
    case 0x8:
1242
        gen_op_eval_ba(r_dst);
1243
        break;
1244
    case 0x9:
1245
        gen_op_eval_bne(r_dst, r_src);
1246
        break;
1247
    case 0xa:
1248
        gen_op_eval_bg(r_dst, r_src);
1249
        break;
1250
    case 0xb:
1251
        gen_op_eval_bge(r_dst, r_src);
1252
        break;
1253
    case 0xc:
1254
        gen_op_eval_bgu(r_dst, r_src);
1255
        break;
1256
    case 0xd:
1257
        gen_op_eval_bcc(r_dst, r_src);
1258
        break;
1259
    case 0xe:
1260
        gen_op_eval_bpos(r_dst, r_src);
1261
        break;
1262
    case 0xf:
1263
        gen_op_eval_bvc(r_dst, r_src);
1264
        break;
1265
    }
1266
}
1267

    
1268
static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
1269
{
1270
    unsigned int offset;
1271

    
1272
    switch (cc) {
1273
    default:
1274
    case 0x0:
1275
        offset = 0;
1276
        break;
1277
    case 0x1:
1278
        offset = 32 - 10;
1279
        break;
1280
    case 0x2:
1281
        offset = 34 - 10;
1282
        break;
1283
    case 0x3:
1284
        offset = 36 - 10;
1285
        break;
1286
    }
1287

    
1288
    switch (cond) {
1289
    case 0x0:
1290
        gen_op_eval_bn(r_dst);
1291
        break;
1292
    case 0x1:
1293
        gen_op_eval_fbne(r_dst, cpu_fsr, offset);
1294
        break;
1295
    case 0x2:
1296
        gen_op_eval_fblg(r_dst, cpu_fsr, offset);
1297
        break;
1298
    case 0x3:
1299
        gen_op_eval_fbul(r_dst, cpu_fsr, offset);
1300
        break;
1301
    case 0x4:
1302
        gen_op_eval_fbl(r_dst, cpu_fsr, offset);
1303
        break;
1304
    case 0x5:
1305
        gen_op_eval_fbug(r_dst, cpu_fsr, offset);
1306
        break;
1307
    case 0x6:
1308
        gen_op_eval_fbg(r_dst, cpu_fsr, offset);
1309
        break;
1310
    case 0x7:
1311
        gen_op_eval_fbu(r_dst, cpu_fsr, offset);
1312
        break;
1313
    case 0x8:
1314
        gen_op_eval_ba(r_dst);
1315
        break;
1316
    case 0x9:
1317
        gen_op_eval_fbe(r_dst, cpu_fsr, offset);
1318
        break;
1319
    case 0xa:
1320
        gen_op_eval_fbue(r_dst, cpu_fsr, offset);
1321
        break;
1322
    case 0xb:
1323
        gen_op_eval_fbge(r_dst, cpu_fsr, offset);
1324
        break;
1325
    case 0xc:
1326
        gen_op_eval_fbuge(r_dst, cpu_fsr, offset);
1327
        break;
1328
    case 0xd:
1329
        gen_op_eval_fble(r_dst, cpu_fsr, offset);
1330
        break;
1331
    case 0xe:
1332
        gen_op_eval_fbule(r_dst, cpu_fsr, offset);
1333
        break;
1334
    case 0xf:
1335
        gen_op_eval_fbo(r_dst, cpu_fsr, offset);
1336
        break;
1337
    }
1338
}
1339

    
1340
#ifdef TARGET_SPARC64
1341
// Inverted logic
1342
static const int gen_tcg_cond_reg[8] = {
1343
    -1,
1344
    TCG_COND_NE,
1345
    TCG_COND_GT,
1346
    TCG_COND_GE,
1347
    -1,
1348
    TCG_COND_EQ,
1349
    TCG_COND_LE,
1350
    TCG_COND_LT,
1351
};
1352

    
1353
static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
1354
{
1355
    int l1;
1356

    
1357
    l1 = gen_new_label();
1358
    tcg_gen_movi_tl(r_dst, 0);
1359
    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], r_src, 0, l1);
1360
    tcg_gen_movi_tl(r_dst, 1);
1361
    gen_set_label(l1);
1362
}
1363
#endif
1364

    
1365
/* XXX: potentially incorrect if dynamic npc */
1366
static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1367
                      TCGv r_cond)
1368
{
1369
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1370
    target_ulong target = dc->pc + offset;
1371

    
1372
    if (cond == 0x0) {
1373
        /* unconditional not taken */
1374
        if (a) {
1375
            dc->pc = dc->npc + 4;
1376
            dc->npc = dc->pc + 4;
1377
        } else {
1378
            dc->pc = dc->npc;
1379
            dc->npc = dc->pc + 4;
1380
        }
1381
    } else if (cond == 0x8) {
1382
        /* unconditional taken */
1383
        if (a) {
1384
            dc->pc = target;
1385
            dc->npc = dc->pc + 4;
1386
        } else {
1387
            dc->pc = dc->npc;
1388
            dc->npc = target;
1389
        }
1390
    } else {
1391
        flush_cond(dc, r_cond);
1392
        gen_cond(r_cond, cc, cond);
1393
        if (a) {
1394
            gen_branch_a(dc, target, dc->npc, r_cond);
1395
            dc->is_br = 1;
1396
        } else {
1397
            dc->pc = dc->npc;
1398
            dc->jump_pc[0] = target;
1399
            dc->jump_pc[1] = dc->npc + 4;
1400
            dc->npc = JUMP_PC;
1401
        }
1402
    }
1403
}
1404

    
1405
/* XXX: potentially incorrect if dynamic npc */
1406
static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1407
                      TCGv r_cond)
1408
{
1409
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1410
    target_ulong target = dc->pc + offset;
1411

    
1412
    if (cond == 0x0) {
1413
        /* unconditional not taken */
1414
        if (a) {
1415
            dc->pc = dc->npc + 4;
1416
            dc->npc = dc->pc + 4;
1417
        } else {
1418
            dc->pc = dc->npc;
1419
            dc->npc = dc->pc + 4;
1420
        }
1421
    } else if (cond == 0x8) {
1422
        /* unconditional taken */
1423
        if (a) {
1424
            dc->pc = target;
1425
            dc->npc = dc->pc + 4;
1426
        } else {
1427
            dc->pc = dc->npc;
1428
            dc->npc = target;
1429
        }
1430
    } else {
1431
        flush_cond(dc, r_cond);
1432
        gen_fcond(r_cond, cc, cond);
1433
        if (a) {
1434
            gen_branch_a(dc, target, dc->npc, r_cond);
1435
            dc->is_br = 1;
1436
        } else {
1437
            dc->pc = dc->npc;
1438
            dc->jump_pc[0] = target;
1439
            dc->jump_pc[1] = dc->npc + 4;
1440
            dc->npc = JUMP_PC;
1441
        }
1442
    }
1443
}
1444

    
1445
#ifdef TARGET_SPARC64
1446
/* XXX: potentially incorrect if dynamic npc */
1447
static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
1448
                          TCGv r_cond, TCGv r_reg)
1449
{
1450
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1451
    target_ulong target = dc->pc + offset;
1452

    
1453
    flush_cond(dc, r_cond);
1454
    gen_cond_reg(r_cond, cond, r_reg);
1455
    if (a) {
1456
        gen_branch_a(dc, target, dc->npc, r_cond);
1457
        dc->is_br = 1;
1458
    } else {
1459
        dc->pc = dc->npc;
1460
        dc->jump_pc[0] = target;
1461
        dc->jump_pc[1] = dc->npc + 4;
1462
        dc->npc = JUMP_PC;
1463
    }
1464
}
1465

    
1466
static GenOpFunc * const gen_fcmpd[4] = {
1467
    helper_fcmpd,
1468
    helper_fcmpd_fcc1,
1469
    helper_fcmpd_fcc2,
1470
    helper_fcmpd_fcc3,
1471
};
1472

    
1473
static GenOpFunc * const gen_fcmpq[4] = {
1474
    helper_fcmpq,
1475
    helper_fcmpq_fcc1,
1476
    helper_fcmpq_fcc2,
1477
    helper_fcmpq_fcc3,
1478
};
1479

    
1480
static GenOpFunc * const gen_fcmped[4] = {
1481
    helper_fcmped,
1482
    helper_fcmped_fcc1,
1483
    helper_fcmped_fcc2,
1484
    helper_fcmped_fcc3,
1485
};
1486

    
1487
static GenOpFunc * const gen_fcmpeq[4] = {
1488
    helper_fcmpeq,
1489
    helper_fcmpeq_fcc1,
1490
    helper_fcmpeq_fcc2,
1491
    helper_fcmpeq_fcc3,
1492
};
1493

    
1494
static inline void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2)
1495
{
1496
    switch (fccno) {
1497
    case 0:
1498
        tcg_gen_helper_0_2(helper_fcmps, r_rs1, r_rs2);
1499
        break;
1500
    case 1:
1501
        tcg_gen_helper_0_2(helper_fcmps_fcc1, r_rs1, r_rs2);
1502
        break;
1503
    case 2:
1504
        tcg_gen_helper_0_2(helper_fcmps_fcc2, r_rs1, r_rs2);
1505
        break;
1506
    case 3:
1507
        tcg_gen_helper_0_2(helper_fcmps_fcc3, r_rs1, r_rs2);
1508
        break;
1509
    }
1510
}
1511

    
1512
static inline void gen_op_fcmpd(int fccno)
1513
{
1514
    tcg_gen_helper_0_0(gen_fcmpd[fccno]);
1515
}
1516

    
1517
static inline void gen_op_fcmpq(int fccno)
1518
{
1519
    tcg_gen_helper_0_0(gen_fcmpq[fccno]);
1520
}
1521

    
1522
static inline void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2)
1523
{
1524
    switch (fccno) {
1525
    case 0:
1526
        tcg_gen_helper_0_2(helper_fcmpes, r_rs1, r_rs2);
1527
        break;
1528
    case 1:
1529
        tcg_gen_helper_0_2(helper_fcmpes_fcc1, r_rs1, r_rs2);
1530
        break;
1531
    case 2:
1532
        tcg_gen_helper_0_2(helper_fcmpes_fcc2, r_rs1, r_rs2);
1533
        break;
1534
    case 3:
1535
        tcg_gen_helper_0_2(helper_fcmpes_fcc3, r_rs1, r_rs2);
1536
        break;
1537
    }
1538
}
1539

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

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

    
1550
#else
1551

    
1552
static inline void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2)
1553
{
1554
    tcg_gen_helper_0_2(helper_fcmps, r_rs1, r_rs2);
1555
}
1556

    
1557
static inline void gen_op_fcmpd(int fccno)
1558
{
1559
    tcg_gen_helper_0_0(helper_fcmpd);
1560
}
1561

    
1562
static inline void gen_op_fcmpq(int fccno)
1563
{
1564
    tcg_gen_helper_0_0(helper_fcmpq);
1565
}
1566

    
1567
static inline void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2)
1568
{
1569
    tcg_gen_helper_0_2(helper_fcmpes, r_rs1, r_rs2);
1570
}
1571

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

    
1577
static inline void gen_op_fcmpeq(int fccno)
1578
{
1579
    tcg_gen_helper_0_0(helper_fcmpeq);
1580
}
1581
#endif
1582

    
1583
static inline void gen_op_fpexception_im(int fsr_flags)
1584
{
1585
    TCGv r_const;
1586

    
1587
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_NMASK);
1588
    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
1589
    r_const = tcg_const_i32(TT_FP_EXCP);
1590
    tcg_gen_helper_0_1(raise_exception, r_const);
1591
    tcg_temp_free(r_const);
1592
}
1593

    
1594
static int gen_trap_ifnofpu(DisasContext *dc, TCGv r_cond)
1595
{
1596
#if !defined(CONFIG_USER_ONLY)
1597
    if (!dc->fpu_enabled) {
1598
        TCGv r_const;
1599

    
1600
        save_state(dc, r_cond);
1601
        r_const = tcg_const_i32(TT_NFPU_INSN);
1602
        tcg_gen_helper_0_1(raise_exception, r_const);
1603
        tcg_temp_free(r_const);
1604
        dc->is_br = 1;
1605
        return 1;
1606
    }
1607
#endif
1608
    return 0;
1609
}
1610

    
1611
static inline void gen_op_clear_ieee_excp_and_FTT(void)
1612
{
1613
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_CEXC_NMASK);
1614
}
1615

    
1616
static inline void gen_clear_float_exceptions(void)
1617
{
1618
    tcg_gen_helper_0_0(helper_clear_float_exceptions);
1619
}
1620

    
1621
/* asi moves */
1622
#ifdef TARGET_SPARC64
1623
static inline TCGv gen_get_asi(int insn, TCGv r_addr)
1624
{
1625
    int asi;
1626
    TCGv r_asi;
1627

    
1628
    if (IS_IMM) {
1629
        r_asi = tcg_temp_new(TCG_TYPE_I32);
1630
        tcg_gen_mov_i32(r_asi, cpu_asi);
1631
    } else {
1632
        asi = GET_FIELD(insn, 19, 26);
1633
        r_asi = tcg_const_i32(asi);
1634
    }
1635
    return r_asi;
1636
}
1637

    
1638
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
1639
                              int sign)
1640
{
1641
    TCGv r_asi, r_size, r_sign;
1642

    
1643
    r_asi = gen_get_asi(insn, addr);
1644
    r_size = tcg_const_i32(size);
1645
    r_sign = tcg_const_i32(sign);
1646
    tcg_gen_helper_1_4(helper_ld_asi, dst, addr, r_asi, r_size, r_sign);
1647
    tcg_temp_free(r_sign);
1648
    tcg_temp_free(r_size);
1649
    tcg_temp_free(r_asi);
1650
}
1651

    
1652
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1653
{
1654
    TCGv r_asi, r_size;
1655

    
1656
    r_asi = gen_get_asi(insn, addr);
1657
    r_size = tcg_const_i32(size);
1658
    tcg_gen_helper_0_4(helper_st_asi, addr, src, r_asi, r_size);
1659
    tcg_temp_free(r_size);
1660
    tcg_temp_free(r_asi);
1661
}
1662

    
1663
static inline void gen_ldf_asi(TCGv addr, int insn, int size, int rd)
1664
{
1665
    TCGv r_asi, r_size, r_rd;
1666

    
1667
    r_asi = gen_get_asi(insn, addr);
1668
    r_size = tcg_const_i32(size);
1669
    r_rd = tcg_const_i32(rd);
1670
    tcg_gen_helper_0_4(helper_ldf_asi, addr, r_asi, r_size, r_rd);
1671
    tcg_temp_free(r_rd);
1672
    tcg_temp_free(r_size);
1673
    tcg_temp_free(r_asi);
1674
}
1675

    
1676
static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
1677
{
1678
    TCGv r_asi, r_size, r_rd;
1679

    
1680
    r_asi = gen_get_asi(insn, addr);
1681
    r_size = tcg_const_i32(size);
1682
    r_rd = tcg_const_i32(rd);
1683
    tcg_gen_helper_0_4(helper_stf_asi, addr, r_asi, r_size, r_rd);
1684
    tcg_temp_free(r_rd);
1685
    tcg_temp_free(r_size);
1686
    tcg_temp_free(r_asi);
1687
}
1688

    
1689
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1690
{
1691
    TCGv r_asi, r_size, r_sign;
1692

    
1693
    r_asi = gen_get_asi(insn, addr);
1694
    r_size = tcg_const_i32(4);
1695
    r_sign = tcg_const_i32(0);
1696
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
1697
    tcg_temp_free(r_sign);
1698
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, r_asi, r_size);
1699
    tcg_temp_free(r_size);
1700
    tcg_temp_free(r_asi);
1701
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1702
}
1703

    
1704
static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
1705
{
1706
    TCGv r_asi, r_rd;
1707

    
1708
    r_asi = gen_get_asi(insn, addr);
1709
    r_rd = tcg_const_i32(rd);
1710
    tcg_gen_helper_0_3(helper_ldda_asi, addr, r_asi, r_rd);
1711
    tcg_temp_free(r_rd);
1712
    tcg_temp_free(r_asi);
1713
}
1714

    
1715
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1716
{
1717
    TCGv r_temp, r_asi, r_size;
1718

    
1719
    r_temp = tcg_temp_new(TCG_TYPE_TL);
1720
    gen_movl_reg_TN(rd + 1, r_temp);
1721
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi,
1722
                       r_temp);
1723
    tcg_temp_free(r_temp);
1724
    r_asi = gen_get_asi(insn, addr);
1725
    r_size = tcg_const_i32(8);
1726
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi, r_size);
1727
    tcg_temp_free(r_size);
1728
    tcg_temp_free(r_asi);
1729
}
1730

    
1731
static inline void gen_cas_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
1732
                               int rd)
1733
{
1734
    TCGv r_val1, r_asi;
1735

    
1736
    r_val1 = tcg_temp_new(TCG_TYPE_TL);
1737
    gen_movl_reg_TN(rd, r_val1);
1738
    r_asi = gen_get_asi(insn, addr);
1739
    tcg_gen_helper_1_4(helper_cas_asi, dst, addr, r_val1, val2, r_asi);
1740
    tcg_temp_free(r_asi);
1741
    tcg_temp_free(r_val1);
1742
}
1743

    
1744
static inline void gen_casx_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
1745
                                int rd)
1746
{
1747
    TCGv r_asi;
1748

    
1749
    gen_movl_reg_TN(rd, cpu_tmp64);
1750
    r_asi = gen_get_asi(insn, addr);
1751
    tcg_gen_helper_1_4(helper_casx_asi, dst, addr, cpu_tmp64, val2, r_asi);
1752
    tcg_temp_free(r_asi);
1753
}
1754

    
1755
#elif !defined(CONFIG_USER_ONLY)
1756

    
1757
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
1758
                              int sign)
1759
{
1760
    TCGv r_asi, r_size, r_sign;
1761

    
1762
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1763
    r_size = tcg_const_i32(size);
1764
    r_sign = tcg_const_i32(sign);
1765
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
1766
    tcg_temp_free(r_sign);
1767
    tcg_temp_free(r_size);
1768
    tcg_temp_free(r_asi);
1769
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1770
}
1771

    
1772
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1773
{
1774
    TCGv r_asi, r_size;
1775

    
1776
    tcg_gen_extu_tl_i64(cpu_tmp64, src);
1777
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1778
    r_size = tcg_const_i32(size);
1779
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi, r_size);
1780
    tcg_temp_free(r_size);
1781
    tcg_temp_free(r_asi);
1782
}
1783

    
1784
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1785
{
1786
    TCGv r_asi, r_size, r_sign;
1787

    
1788
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1789
    r_size = tcg_const_i32(4);
1790
    r_sign = tcg_const_i32(0);
1791
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
1792
    tcg_temp_free(r_sign);
1793
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, r_asi, r_size);
1794
    tcg_temp_free(r_size);
1795
    tcg_temp_free(r_asi);
1796
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1797
}
1798

    
1799
static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
1800
{
1801
    TCGv r_asi, r_size, r_sign;
1802

    
1803
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1804
    r_size = tcg_const_i32(8);
1805
    r_sign = tcg_const_i32(0);
1806
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
1807
    tcg_temp_free(r_sign);
1808
    tcg_temp_free(r_size);
1809
    tcg_temp_free(r_asi);
1810
    tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
1811
    gen_movl_TN_reg(rd + 1, cpu_tmp0);
1812
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1813
    tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
1814
    gen_movl_TN_reg(rd, hi);
1815
}
1816

    
1817
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1818
{
1819
    TCGv r_temp, r_asi, r_size;
1820

    
1821
    r_temp = tcg_temp_new(TCG_TYPE_TL);
1822
    gen_movl_reg_TN(rd + 1, r_temp);
1823
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi, r_temp);
1824
    tcg_temp_free(r_temp);
1825
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1826
    r_size = tcg_const_i32(8);
1827
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi, r_size);
1828
    tcg_temp_free(r_size);
1829
    tcg_temp_free(r_asi);
1830
}
1831
#endif
1832

    
1833
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1834
static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
1835
{
1836
    TCGv r_val, r_asi, r_size;
1837

    
1838
    gen_ld_asi(dst, addr, insn, 1, 0);
1839

    
1840
    r_val = tcg_const_i64(0xffULL);
1841
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1842
    r_size = tcg_const_i32(1);
1843
    tcg_gen_helper_0_4(helper_st_asi, addr, r_val, r_asi, r_size);
1844
    tcg_temp_free(r_size);
1845
    tcg_temp_free(r_asi);
1846
    tcg_temp_free(r_val);
1847
}
1848
#endif
1849

    
1850
static inline TCGv get_src1(unsigned int insn, TCGv def)
1851
{
1852
    TCGv r_rs1 = def;
1853
    unsigned int rs1;
1854

    
1855
    rs1 = GET_FIELD(insn, 13, 17);
1856
    if (rs1 == 0)
1857
        r_rs1 = tcg_const_tl(0); // XXX how to free?
1858
    else if (rs1 < 8)
1859
        r_rs1 = cpu_gregs[rs1];
1860
    else
1861
        tcg_gen_ld_tl(def, cpu_regwptr, (rs1 - 8) * sizeof(target_ulong));
1862
    return r_rs1;
1863
}
1864

    
1865
static inline TCGv get_src2(unsigned int insn, TCGv def)
1866
{
1867
    TCGv r_rs2 = def;
1868
    unsigned int rs2;
1869

    
1870
    if (IS_IMM) { /* immediate */
1871
        rs2 = GET_FIELDs(insn, 19, 31);
1872
        r_rs2 = tcg_const_tl((int)rs2); // XXX how to free?
1873
    } else { /* register */
1874
        rs2 = GET_FIELD(insn, 27, 31);
1875
        if (rs2 == 0)
1876
            r_rs2 = tcg_const_tl(0); // XXX how to free?
1877
        else if (rs2 < 8)
1878
            r_rs2 = cpu_gregs[rs2];
1879
        else
1880
            tcg_gen_ld_tl(def, cpu_regwptr, (rs2 - 8) * sizeof(target_ulong));
1881
    }
1882
    return r_rs2;
1883
}
1884

    
1885
#define CHECK_IU_FEATURE(dc, FEATURE)                      \
1886
    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
1887
        goto illegal_insn;
1888
#define CHECK_FPU_FEATURE(dc, FEATURE)                     \
1889
    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
1890
        goto nfpu_insn;
1891

    
1892
/* before an instruction, dc->pc must be static */
1893
static void disas_sparc_insn(DisasContext * dc)
1894
{
1895
    unsigned int insn, opc, rs1, rs2, rd;
1896

    
1897
    if (unlikely(loglevel & CPU_LOG_TB_OP))
1898
        tcg_gen_debug_insn_start(dc->pc);
1899
    insn = ldl_code(dc->pc);
1900
    opc = GET_FIELD(insn, 0, 1);
1901

    
1902
    rd = GET_FIELD(insn, 2, 6);
1903

    
1904
    cpu_src1 = tcg_temp_new(TCG_TYPE_TL); // const
1905
    cpu_src2 = tcg_temp_new(TCG_TYPE_TL); // const
1906

    
1907
    switch (opc) {
1908
    case 0:                     /* branches/sethi */
1909
        {
1910
            unsigned int xop = GET_FIELD(insn, 7, 9);
1911
            int32_t target;
1912
            switch (xop) {
1913
#ifdef TARGET_SPARC64
1914
            case 0x1:           /* V9 BPcc */
1915
                {
1916
                    int cc;
1917

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

    
1980
                    r_const = tcg_const_tl(value << 10);
1981
                    gen_movl_TN_reg(rd, r_const);
1982
                    tcg_temp_free(r_const);
1983
                }
1984
                break;
1985
            case 0x0:           /* UNIMPL */
1986
            default:
1987
                goto illegal_insn;
1988
            }
1989
            break;
1990
        }
1991
        break;
1992
    case 1:
1993
        /*CALL*/ {
1994
            target_long target = GET_FIELDs(insn, 2, 31) << 2;
1995
            TCGv r_const;
1996

    
1997
            r_const = tcg_const_tl(dc->pc);
1998
            gen_movl_TN_reg(15, r_const);
1999
            tcg_temp_free(r_const);
2000
            target += dc->pc;
2001
            gen_mov_pc_npc(dc, cpu_cond);
2002
            dc->npc = target;
2003
        }
2004
        goto jmp_insn;
2005
    case 2:                     /* FPU & Logical Operations */
2006
        {
2007
            unsigned int xop = GET_FIELD(insn, 7, 12);
2008
            if (xop == 0x3a) {  /* generate trap */
2009
                int cond;
2010

    
2011
                cpu_src1 = get_src1(insn, cpu_src1);
2012
                if (IS_IMM) {
2013
                    rs2 = GET_FIELD(insn, 25, 31);
2014
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, rs2);
2015
                } else {
2016
                    rs2 = GET_FIELD(insn, 27, 31);
2017
                    if (rs2 != 0) {
2018
                        gen_movl_reg_TN(rs2, cpu_src2);
2019
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
2020
                    } else
2021
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
2022
                }
2023
                cond = GET_FIELD(insn, 3, 6);
2024
                if (cond == 0x8) {
2025
                    save_state(dc, cpu_cond);
2026
                    tcg_gen_helper_0_1(helper_trap, cpu_dst);
2027
                } else if (cond != 0) {
2028
                    TCGv r_cond = tcg_temp_new(TCG_TYPE_TL);
2029
#ifdef TARGET_SPARC64
2030
                    /* V9 icc/xcc */
2031
                    int cc = GET_FIELD_SP(insn, 11, 12);
2032

    
2033
                    save_state(dc, cpu_cond);
2034
                    if (cc == 0)
2035
                        gen_cond(r_cond, 0, cond);
2036
                    else if (cc == 2)
2037
                        gen_cond(r_cond, 1, cond);
2038
                    else
2039
                        goto illegal_insn;
2040
#else
2041
                    save_state(dc, cpu_cond);
2042
                    gen_cond(r_cond, 0, cond);
2043
#endif
2044
                    tcg_gen_helper_0_2(helper_trapcc, cpu_dst, r_cond);
2045
                    tcg_temp_free(r_cond);
2046
                }
2047
                gen_op_next_insn();
2048
                tcg_gen_exit_tb(0);
2049
                dc->is_br = 1;
2050
                goto jmp_insn;
2051
            } else if (xop == 0x28) {
2052
                rs1 = GET_FIELD(insn, 13, 17);
2053
                switch(rs1) {
2054
                case 0: /* rdy */
2055
#ifndef TARGET_SPARC64
2056
                case 0x01 ... 0x0e: /* undefined in the SPARCv8
2057
                                       manual, rdy on the microSPARC
2058
                                       II */
2059
                case 0x0f:          /* stbar in the SPARCv8 manual,
2060
                                       rdy on the microSPARC II */
2061
                case 0x10 ... 0x1f: /* implementation-dependent in the
2062
                                       SPARCv8 manual, rdy on the
2063
                                       microSPARC II */
2064
#endif
2065
                    gen_movl_TN_reg(rd, cpu_y);
2066
                    break;
2067
#ifdef TARGET_SPARC64
2068
                case 0x2: /* V9 rdccr */
2069
                    tcg_gen_helper_1_0(helper_rdccr, cpu_dst);
2070
                    gen_movl_TN_reg(rd, cpu_dst);
2071
                    break;
2072
                case 0x3: /* V9 rdasi */
2073
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_asi);
2074
                    gen_movl_TN_reg(rd, cpu_dst);
2075
                    break;
2076
                case 0x4: /* V9 rdtick */
2077
                    {
2078
                        TCGv r_tickptr;
2079

    
2080
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2081
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2082
                                       offsetof(CPUState, tick));
2083
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst,
2084
                                           r_tickptr);
2085
                        tcg_temp_free(r_tickptr);
2086
                        gen_movl_TN_reg(rd, cpu_dst);
2087
                    }
2088
                    break;
2089
                case 0x5: /* V9 rdpc */
2090
                    {
2091
                        TCGv r_const;
2092

    
2093
                        r_const = tcg_const_tl(dc->pc);
2094
                        gen_movl_TN_reg(rd, r_const);
2095
                        tcg_temp_free(r_const);
2096
                    }
2097
                    break;
2098
                case 0x6: /* V9 rdfprs */
2099
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_fprs);
2100
                    gen_movl_TN_reg(rd, cpu_dst);
2101
                    break;
2102
                case 0xf: /* V9 membar */
2103
                    break; /* no effect */
2104
                case 0x13: /* Graphics Status */
2105
                    if (gen_trap_ifnofpu(dc, cpu_cond))
2106
                        goto jmp_insn;
2107
                    gen_movl_TN_reg(rd, cpu_gsr);
2108
                    break;
2109
                case 0x17: /* Tick compare */
2110
                    gen_movl_TN_reg(rd, cpu_tick_cmpr);
2111
                    break;
2112
                case 0x18: /* System tick */
2113
                    {
2114
                        TCGv r_tickptr;
2115

    
2116
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2117
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2118
                                       offsetof(CPUState, stick));
2119
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst,
2120
                                           r_tickptr);
2121
                        tcg_temp_free(r_tickptr);
2122
                        gen_movl_TN_reg(rd, cpu_dst);
2123
                    }
2124
                    break;
2125
                case 0x19: /* System tick compare */
2126
                    gen_movl_TN_reg(rd, cpu_stick_cmpr);
2127
                    break;
2128
                case 0x10: /* Performance Control */
2129
                case 0x11: /* Performance Instrumentation Counter */
2130
                case 0x12: /* Dispatch Control */
2131
                case 0x14: /* Softint set, WO */
2132
                case 0x15: /* Softint clear, WO */
2133
                case 0x16: /* Softint write */
2134
#endif
2135
                default:
2136
                    goto illegal_insn;
2137
                }
2138
#if !defined(CONFIG_USER_ONLY)
2139
            } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
2140
#ifndef TARGET_SPARC64
2141
                if (!supervisor(dc))
2142
                    goto priv_insn;
2143
                tcg_gen_helper_1_0(helper_rdpsr, cpu_dst);
2144
#else
2145
                CHECK_IU_FEATURE(dc, HYPV);
2146
                if (!hypervisor(dc))
2147
                    goto priv_insn;
2148
                rs1 = GET_FIELD(insn, 13, 17);
2149
                switch (rs1) {
2150
                case 0: // hpstate
2151
                    // gen_op_rdhpstate();
2152
                    break;
2153
                case 1: // htstate
2154
                    // gen_op_rdhtstate();
2155
                    break;
2156
                case 3: // hintp
2157
                    tcg_gen_mov_tl(cpu_dst, cpu_hintp);
2158
                    break;
2159
                case 5: // htba
2160
                    tcg_gen_mov_tl(cpu_dst, cpu_htba);
2161
                    break;
2162
                case 6: // hver
2163
                    tcg_gen_mov_tl(cpu_dst, cpu_hver);
2164
                    break;
2165
                case 31: // hstick_cmpr
2166
                    tcg_gen_mov_tl(cpu_dst, cpu_hstick_cmpr);
2167
                    break;
2168
                default:
2169
                    goto illegal_insn;
2170
                }
2171
#endif
2172
                gen_movl_TN_reg(rd, cpu_dst);
2173
                break;
2174
            } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
2175
                if (!supervisor(dc))
2176
                    goto priv_insn;
2177
#ifdef TARGET_SPARC64
2178
                rs1 = GET_FIELD(insn, 13, 17);
2179
                switch (rs1) {
2180
                case 0: // tpc
2181
                    {
2182
                        TCGv r_tsptr;
2183

    
2184
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2185
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2186
                                       offsetof(CPUState, tsptr));
2187
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2188
                                      offsetof(trap_state, tpc));
2189
                        tcg_temp_free(r_tsptr);
2190
                    }
2191
                    break;
2192
                case 1: // tnpc
2193
                    {
2194
                        TCGv r_tsptr;
2195

    
2196
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2197
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2198
                                       offsetof(CPUState, tsptr));
2199
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2200
                                      offsetof(trap_state, tnpc));
2201
                        tcg_temp_free(r_tsptr);
2202
                    }
2203
                    break;
2204
                case 2: // tstate
2205
                    {
2206
                        TCGv r_tsptr;
2207

    
2208
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2209
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2210
                                       offsetof(CPUState, tsptr));
2211
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2212
                                      offsetof(trap_state, tstate));
2213
                        tcg_temp_free(r_tsptr);
2214
                    }
2215
                    break;
2216
                case 3: // tt
2217
                    {
2218
                        TCGv r_tsptr;
2219

    
2220
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2221
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2222
                                       offsetof(CPUState, tsptr));
2223
                        tcg_gen_ld_i32(cpu_tmp0, r_tsptr,
2224
                                       offsetof(trap_state, tt));
2225
                        tcg_temp_free(r_tsptr);
2226
                    }
2227
                    break;
2228
                case 4: // tick
2229
                    {
2230
                        TCGv r_tickptr;
2231

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

    
2658
                    l1 = gen_new_label();
2659
                    cond = GET_FIELD_SP(insn, 14, 17);
2660
                    cpu_src1 = get_src1(insn, cpu_src1);
2661
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2662
                                       0, l1);
2663
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);
2664
                    gen_set_label(l1);
2665
                    break;
2666
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
2667
                    int l1;
2668

    
2669
                    l1 = gen_new_label();
2670
                    cond = GET_FIELD_SP(insn, 14, 17);
2671
                    cpu_src1 = get_src1(insn, cpu_src1);
2672
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2673
                                       0, l1);
2674
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)]);
2675
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], cpu_fpr[DFPREG(rs2) + 1]);
2676
                    gen_set_label(l1);
2677
                    break;
2678
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
2679
                    int l1;
2680

    
2681
                    CHECK_FPU_FEATURE(dc, FLOAT128);
2682
                    l1 = gen_new_label();
2683
                    cond = GET_FIELD_SP(insn, 14, 17);
2684
                    cpu_src1 = get_src1(insn, cpu_src1);
2685
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2686
                                       0, l1);
2687
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], cpu_fpr[QFPREG(rs2)]);
2688
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], cpu_fpr[QFPREG(rs2) + 1]);
2689
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], cpu_fpr[QFPREG(rs2) + 2]);
2690
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], cpu_fpr[QFPREG(rs2) + 3]);
2691
                    gen_set_label(l1);
2692
                    break;
2693
                }
2694
#endif
2695
                switch (xop) {
2696
#ifdef TARGET_SPARC64
2697
#define FMOVSCC(fcc)                                                    \
2698
                    {                                                   \
2699
                        TCGv r_cond;                                    \
2700
                        int l1;                                         \
2701
                                                                        \
2702
                        l1 = gen_new_label();                           \
2703
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2704
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2705
                        gen_fcond(r_cond, fcc, cond);                   \
2706
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2707
                                           0, l1);                      \
2708
                        tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);     \
2709
                        gen_set_label(l1);                              \
2710
                        tcg_temp_free(r_cond);                          \
2711
                    }
2712
#define FMOVDCC(fcc)                                                    \
2713
                    {                                                   \
2714
                        TCGv r_cond;                                    \
2715
                        int l1;                                         \
2716
                                                                        \
2717
                        l1 = gen_new_label();                           \
2718
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2719
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2720
                        gen_fcond(r_cond, fcc, cond);                   \
2721
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2722
                                           0, l1);                      \
2723
                        tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)],            \
2724
                                        cpu_fpr[DFPREG(rs2)]);          \
2725
                        tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1],        \
2726
                                        cpu_fpr[DFPREG(rs2) + 1]);      \
2727
                        gen_set_label(l1);                              \
2728
                        tcg_temp_free(r_cond);                          \
2729
                    }
2730
#define FMOVQCC(fcc)                                                    \
2731
                    {                                                   \
2732
                        TCGv r_cond;                                    \
2733
                        int l1;                                         \
2734
                                                                        \
2735
                        l1 = gen_new_label();                           \
2736
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2737
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2738
                        gen_fcond(r_cond, fcc, cond);                   \
2739
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2740
                                           0, l1);                      \
2741
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)],            \
2742
                                        cpu_fpr[QFPREG(rs2)]);          \
2743
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1],        \
2744
                                        cpu_fpr[QFPREG(rs2) + 1]);      \
2745
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2],        \
2746
                                        cpu_fpr[QFPREG(rs2) + 2]);      \
2747
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3],        \
2748
                                        cpu_fpr[QFPREG(rs2) + 3]);      \
2749
                        gen_set_label(l1);                              \
2750
                        tcg_temp_free(r_cond);                          \
2751
                    }
2752
                    case 0x001: /* V9 fmovscc %fcc0 */
2753
                        FMOVSCC(0);
2754
                        break;
2755
                    case 0x002: /* V9 fmovdcc %fcc0 */
2756
                        FMOVDCC(0);
2757
                        break;
2758
                    case 0x003: /* V9 fmovqcc %fcc0 */
2759
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2760
                        FMOVQCC(0);
2761
                        break;
2762
                    case 0x041: /* V9 fmovscc %fcc1 */
2763
                        FMOVSCC(1);
2764
                        break;
2765
                    case 0x042: /* V9 fmovdcc %fcc1 */
2766
                        FMOVDCC(1);
2767
                        break;
2768
                    case 0x043: /* V9 fmovqcc %fcc1 */
2769
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2770
                        FMOVQCC(1);
2771
                        break;
2772
                    case 0x081: /* V9 fmovscc %fcc2 */
2773
                        FMOVSCC(2);
2774
                        break;
2775
                    case 0x082: /* V9 fmovdcc %fcc2 */
2776
                        FMOVDCC(2);
2777
                        break;
2778
                    case 0x083: /* V9 fmovqcc %fcc2 */
2779
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2780
                        FMOVQCC(2);
2781
                        break;
2782
                    case 0x0c1: /* V9 fmovscc %fcc3 */
2783
                        FMOVSCC(3);
2784
                        break;
2785
                    case 0x0c2: /* V9 fmovdcc %fcc3 */
2786
                        FMOVDCC(3);
2787
                        break;
2788
                    case 0x0c3: /* V9 fmovqcc %fcc3 */
2789
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2790
                        FMOVQCC(3);
2791
                        break;
2792
#undef FMOVSCC
2793
#undef FMOVDCC
2794
#undef FMOVQCC
2795
#define FMOVCC(size_FDQ, icc)                                           \
2796
                    {                                                   \
2797
                        TCGv r_cond;                                    \
2798
                        int l1;                                         \
2799
                                                                        \
2800
                        l1 = gen_new_label();                           \
2801
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2802
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2803
                        gen_cond(r_cond, icc, cond);                    \
2804
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2805
                                           0, l1);                      \
2806
                        glue(glue(gen_op_load_fpr_, size_FDQ), T0)      \
2807
                            (glue(size_FDQ, FPREG(rs2)));               \
2808
                        glue(glue(gen_op_store_, size_FDQ), T0_fpr)     \
2809
                            (glue(size_FDQ, FPREG(rd)));                \
2810
                        gen_set_label(l1);                              \
2811
                        tcg_temp_free(r_cond);                          \
2812
                    }
2813
#define FMOVSCC(icc)                                                    \
2814
                    {                                                   \
2815
                        TCGv r_cond;                                    \
2816
                        int l1;                                         \
2817
                                                                        \
2818
                        l1 = gen_new_label();                           \
2819
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2820
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2821
                        gen_cond(r_cond, icc, cond);                    \
2822
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2823
                                           0, l1);                      \
2824
                        tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);     \
2825
                        gen_set_label(l1);                              \
2826
                        tcg_temp_free(r_cond);                          \
2827
                    }
2828
#define FMOVDCC(icc)                                                    \
2829
                    {                                                   \
2830
                        TCGv r_cond;                                    \
2831
                        int l1;                                         \
2832
                                                                        \
2833
                        l1 = gen_new_label();                           \
2834
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2835
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2836
                        gen_cond(r_cond, icc, cond);                    \
2837
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2838
                                           0, l1);                      \
2839
                        tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)],            \
2840
                                        cpu_fpr[DFPREG(rs2)]);          \
2841
                        tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1],        \
2842
                                        cpu_fpr[DFPREG(rs2) + 1]);      \
2843
                        gen_set_label(l1);                              \
2844
                        tcg_temp_free(r_cond);                          \
2845
                    }
2846
#define FMOVQCC(icc)                                                    \
2847
                    {                                                   \
2848
                        TCGv r_cond;                                    \
2849
                        int l1;                                         \
2850
                                                                        \
2851
                        l1 = gen_new_label();                           \
2852
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2853
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2854
                        gen_cond(r_cond, icc, cond);                    \
2855
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
2856
                                           0, l1);                      \
2857
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)],            \
2858
                                        cpu_fpr[QFPREG(rs2)]);          \
2859
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1],        \
2860
                                        cpu_fpr[QFPREG(rs2) + 1]);      \
2861
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2],        \
2862
                                        cpu_fpr[QFPREG(rs2) + 2]);      \
2863
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3],        \
2864
                                        cpu_fpr[QFPREG(rs2) + 3]);      \
2865
                        gen_set_label(l1);                              \
2866
                        tcg_temp_free(r_cond);                          \
2867
                    }
2868

    
2869
                    case 0x101: /* V9 fmovscc %icc */
2870
                        FMOVSCC(0);
2871
                        break;
2872
                    case 0x102: /* V9 fmovdcc %icc */
2873
                        FMOVDCC(0);
2874
                    case 0x103: /* V9 fmovqcc %icc */
2875
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2876
                        FMOVQCC(0);
2877
                        break;
2878
                    case 0x181: /* V9 fmovscc %xcc */
2879
                        FMOVSCC(1);
2880
                        break;
2881
                    case 0x182: /* V9 fmovdcc %xcc */
2882
                        FMOVDCC(1);
2883
                        break;
2884
                    case 0x183: /* V9 fmovqcc %xcc */
2885
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2886
                        FMOVQCC(1);
2887
                        break;
2888
#undef FMOVSCC
2889
#undef FMOVDCC
2890
#undef FMOVQCC
2891
#endif
2892
                    case 0x51: /* fcmps, V9 %fcc */
2893
                        gen_op_fcmps(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]);
2894
                        break;
2895
                    case 0x52: /* fcmpd, V9 %fcc */
2896
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2897
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2898
                        gen_op_fcmpd(rd & 3);
2899
                        break;
2900
                    case 0x53: /* fcmpq, V9 %fcc */
2901
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2902
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2903
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2904
                        gen_op_fcmpq(rd & 3);
2905
                        break;
2906
                    case 0x55: /* fcmpes, V9 %fcc */
2907
                        gen_op_fcmpes(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]);
2908
                        break;
2909
                    case 0x56: /* fcmped, V9 %fcc */
2910
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2911
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2912
                        gen_op_fcmped(rd & 3);
2913
                        break;
2914
                    case 0x57: /* fcmpeq, V9 %fcc */
2915
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2916
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2917
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2918
                        gen_op_fcmpeq(rd & 3);
2919
                        break;
2920
                    default:
2921
                        goto illegal_insn;
2922
                }
2923
            } else if (xop == 0x2) {
2924
                // clr/mov shortcut
2925

    
2926
                rs1 = GET_FIELD(insn, 13, 17);
2927
                if (rs1 == 0) {
2928
                    // or %g0, x, y -> mov T0, x; mov y, T0
2929
                    if (IS_IMM) {       /* immediate */
2930
                        TCGv r_const;
2931

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

    
3248
                                    tcg_gen_xor_tl(cpu_tick_cmpr, cpu_src1,
3249
                                                   cpu_src2);
3250
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3251
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3252
                                                   offsetof(CPUState, tick));
3253
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3254
                                                       r_tickptr, cpu_tick_cmpr);
3255
                                    tcg_temp_free(r_tickptr);
3256
                                }
3257
                                break;
3258
                            case 0x18: /* System tick */
3259
#if !defined(CONFIG_USER_ONLY)
3260
                                if (!supervisor(dc))
3261
                                    goto illegal_insn;
3262
#endif
3263
                                {
3264
                                    TCGv r_tickptr;
3265

    
3266
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
3267
                                                   cpu_src2);
3268
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3269
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3270
                                                   offsetof(CPUState, stick));
3271
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3272
                                                       r_tickptr, cpu_dst);
3273
                                    tcg_temp_free(r_tickptr);
3274
                                }
3275
                                break;
3276
                            case 0x19: /* System tick compare */
3277
#if !defined(CONFIG_USER_ONLY)
3278
                                if (!supervisor(dc))
3279
                                    goto illegal_insn;
3280
#endif
3281
                                {
3282
                                    TCGv r_tickptr;
3283

    
3284
                                    tcg_gen_xor_tl(cpu_stick_cmpr, cpu_src1,
3285
                                                   cpu_src2);
3286
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3287
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3288
                                                   offsetof(CPUState, stick));
3289
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3290
                                                       r_tickptr, cpu_stick_cmpr);
3291
                                    tcg_temp_free(r_tickptr);
3292
                                }
3293
                                break;
3294

    
3295
                            case 0x10: /* Performance Control */
3296
                            case 0x11: /* Performance Instrumentation
3297
                                          Counter */
3298
                            case 0x12: /* Dispatch Control */
3299
                            case 0x14: /* Softint set */
3300
                            case 0x15: /* Softint clear */
3301
                            case 0x16: /* Softint write */
3302
#endif
3303
                            default:
3304
                                goto illegal_insn;
3305
                            }
3306
                        }
3307
                        break;
3308
#if !defined(CONFIG_USER_ONLY)
3309
                    case 0x31: /* wrpsr, V9 saved, restored */
3310
                        {
3311
                            if (!supervisor(dc))
3312
                                goto priv_insn;
3313
#ifdef TARGET_SPARC64
3314
                            switch (rd) {
3315
                            case 0:
3316
                                tcg_gen_helper_0_0(helper_saved);
3317
                                break;
3318
                            case 1:
3319
                                tcg_gen_helper_0_0(helper_restored);
3320
                                break;
3321
                            case 2: /* UA2005 allclean */
3322
                            case 3: /* UA2005 otherw */
3323
                            case 4: /* UA2005 normalw */
3324
                            case 5: /* UA2005 invalw */
3325
                                // XXX
3326
                            default:
3327
                                goto illegal_insn;
3328
                            }
3329
#else
3330
                            tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3331
                            tcg_gen_helper_0_1(helper_wrpsr, cpu_dst);
3332
                            save_state(dc, cpu_cond);
3333
                            gen_op_next_insn();
3334
                            tcg_gen_exit_tb(0);
3335
                            dc->is_br = 1;
3336
#endif
3337
                        }
3338
                        break;
3339
                    case 0x32: /* wrwim, V9 wrpr */
3340
                        {
3341
                            if (!supervisor(dc))
3342
                                goto priv_insn;
3343
                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
3344
#ifdef TARGET_SPARC64
3345
                            switch (rd) {
3346
                            case 0: // tpc
3347
                                {
3348
                                    TCGv r_tsptr;
3349

    
3350
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3351
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3352
                                                   offsetof(CPUState, tsptr));
3353
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3354
                                                  offsetof(trap_state, tpc));
3355
                                    tcg_temp_free(r_tsptr);
3356
                                }
3357
                                break;
3358
                            case 1: // tnpc
3359
                                {
3360
                                    TCGv r_tsptr;
3361

    
3362
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3363
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3364
                                                   offsetof(CPUState, tsptr));
3365
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3366
                                                  offsetof(trap_state, tnpc));
3367
                                    tcg_temp_free(r_tsptr);
3368
                                }
3369
                                break;
3370
                            case 2: // tstate
3371
                                {
3372
                                    TCGv r_tsptr;
3373

    
3374
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3375
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3376
                                                   offsetof(CPUState, tsptr));
3377
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3378
                                                  offsetof(trap_state,
3379
                                                           tstate));
3380
                                    tcg_temp_free(r_tsptr);
3381
                                }
3382
                                break;
3383
                            case 3: // tt
3384
                                {
3385
                                    TCGv r_tsptr;
3386

    
3387
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3388
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3389
                                                   offsetof(CPUState, tsptr));
3390
                                    tcg_gen_st_i32(cpu_tmp0, r_tsptr,
3391
                                                   offsetof(trap_state, tt));
3392
                                    tcg_temp_free(r_tsptr);
3393
                                }
3394
                                break;
3395
                            case 4: // tick
3396
                                {
3397
                                    TCGv r_tickptr;
3398

    
3399
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3400
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3401
                                                   offsetof(CPUState, tick));
3402
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3403
                                                       r_tickptr, cpu_tmp0);
3404
                                    tcg_temp_free(r_tickptr);
3405
                                }
3406
                                break;
3407
                            case 5: // tba
3408
                                tcg_gen_mov_tl(cpu_tbr, cpu_tmp0);
3409
                                break;
3410
                            case 6: // pstate
3411
                                save_state(dc, cpu_cond);
3412
                                tcg_gen_helper_0_1(helper_wrpstate, cpu_tmp0);
3413
                                gen_op_next_insn();
3414
                                tcg_gen_exit_tb(0);
3415
                                dc->is_br = 1;
3416
                                break;
3417
                            case 7: // tl
3418
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3419
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3420
                                               offsetof(CPUSPARCState, tl));
3421
                                break;
3422
                            case 8: // pil
3423
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3424
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3425
                                               offsetof(CPUSPARCState,
3426
                                                        psrpil));
3427
                                break;
3428
                            case 9: // cwp
3429
                                tcg_gen_helper_0_1(helper_wrcwp, cpu_tmp0);
3430
                                break;
3431
                            case 10: // cansave
3432
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3433
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3434
                                               offsetof(CPUSPARCState,
3435
                                                        cansave));
3436
                                break;
3437
                            case 11: // canrestore
3438
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3439
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3440
                                               offsetof(CPUSPARCState,
3441
                                                        canrestore));
3442
                                break;
3443
                            case 12: // cleanwin
3444
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3445
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3446
                                               offsetof(CPUSPARCState,
3447
                                                        cleanwin));
3448
                                break;
3449
                            case 13: // otherwin
3450
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3451
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3452
                                               offsetof(CPUSPARCState,
3453
                                                        otherwin));
3454
                                break;
3455
                            case 14: // wstate
3456
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3457
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3458
                                               offsetof(CPUSPARCState,
3459
                                                        wstate));
3460
                                break;
3461
                            case 16: // UA2005 gl
3462
                                CHECK_IU_FEATURE(dc, GL);
3463
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3464
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
3465
                                               offsetof(CPUSPARCState, gl));
3466
                                break;
3467
                            case 26: // UA2005 strand status
3468
                                CHECK_IU_FEATURE(dc, HYPV);
3469
                                if (!hypervisor(dc))
3470
                                    goto priv_insn;
3471
                                tcg_gen_trunc_tl_i32(cpu_ssr, cpu_tmp0);
3472
                                break;
3473
                            default:
3474
                                goto illegal_insn;
3475
                            }
3476
#else
3477
                            tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3478
                            if (dc->def->nwindows != 32)
3479
                                tcg_gen_andi_tl(cpu_tmp32, cpu_tmp32,
3480
                                                (1 << dc->def->nwindows) - 1);
3481
                            tcg_gen_mov_i32(cpu_wim, cpu_tmp32);
3482
#endif
3483
                        }
3484
                        break;
3485
                    case 0x33: /* wrtbr, UA2005 wrhpr */
3486
                        {
3487
#ifndef TARGET_SPARC64
3488
                            if (!supervisor(dc))
3489
                                goto priv_insn;
3490
                            tcg_gen_xor_tl(cpu_tbr, cpu_src1, cpu_src2);
3491
#else
3492
                            CHECK_IU_FEATURE(dc, HYPV);
3493
                            if (!hypervisor(dc))
3494
                                goto priv_insn;
3495
                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
3496
                            switch (rd) {
3497
                            case 0: // hpstate
3498
                                // XXX gen_op_wrhpstate();
3499
                                save_state(dc, cpu_cond);
3500
                                gen_op_next_insn();
3501
                                tcg_gen_exit_tb(0);
3502
                                dc->is_br = 1;
3503
                                break;
3504
                            case 1: // htstate
3505
                                // XXX gen_op_wrhtstate();
3506
                                break;
3507
                            case 3: // hintp
3508
                                tcg_gen_mov_tl(cpu_hintp, cpu_tmp0);
3509
                                break;
3510
                            case 5: // htba
3511
                                tcg_gen_mov_tl(cpu_htba, cpu_tmp0);
3512
                                break;
3513
                            case 31: // hstick_cmpr
3514
                                {
3515
                                    TCGv r_tickptr;
3516

    
3517
                                    tcg_gen_mov_tl(cpu_hstick_cmpr, cpu_tmp0);
3518
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3519
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3520
                                                   offsetof(CPUState, hstick));
3521
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3522
                                                       r_tickptr, cpu_hstick_cmpr);
3523
                                    tcg_temp_free(r_tickptr);
3524
                                }
3525
                                break;
3526
                            case 6: // hver readonly
3527
                            default:
3528
                                goto illegal_insn;
3529
                            }
3530
#endif
3531
                        }
3532
                        break;
3533
#endif
3534
#ifdef TARGET_SPARC64
3535
                    case 0x2c: /* V9 movcc */
3536
                        {
3537
                            int cc = GET_FIELD_SP(insn, 11, 12);
3538
                            int cond = GET_FIELD_SP(insn, 14, 17);
3539
                            TCGv r_cond;
3540
                            int l1;
3541

    
3542
                            r_cond = tcg_temp_new(TCG_TYPE_TL);
3543
                            if (insn & (1 << 18)) {
3544
                                if (cc == 0)
3545
                                    gen_cond(r_cond, 0, cond);
3546
                                else if (cc == 2)
3547
                                    gen_cond(r_cond, 1, cond);
3548
                                else
3549
                                    goto illegal_insn;
3550
                            } else {
3551
                                gen_fcond(r_cond, cc, cond);
3552
                            }
3553

    
3554
                            l1 = gen_new_label();
3555

    
3556
                            tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
3557
                            if (IS_IMM) {       /* immediate */
3558
                                TCGv r_const;
3559

    
3560
                                rs2 = GET_FIELD_SPs(insn, 0, 10);
3561
                                r_const = tcg_const_tl((int)rs2);
3562
                                gen_movl_TN_reg(rd, r_const);
3563
                                tcg_temp_free(r_const);
3564
                            } else {
3565
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3566
                                gen_movl_reg_TN(rs2, cpu_tmp0);
3567
                                gen_movl_TN_reg(rd, cpu_tmp0);
3568
                            }
3569
                            gen_set_label(l1);
3570
                            tcg_temp_free(r_cond);
3571
                            break;
3572
                        }
3573
                    case 0x2d: /* V9 sdivx */
3574
                        gen_op_sdivx(cpu_dst, cpu_src1, cpu_src2);
3575
                        gen_movl_TN_reg(rd, cpu_dst);
3576
                        break;
3577
                    case 0x2e: /* V9 popc */
3578
                        {
3579
                            cpu_src2 = get_src2(insn, cpu_src2);
3580
                            tcg_gen_helper_1_1(helper_popc, cpu_dst,
3581
                                               cpu_src2);
3582
                            gen_movl_TN_reg(rd, cpu_dst);
3583
                        }
3584
                    case 0x2f: /* V9 movr */
3585
                        {
3586
                            int cond = GET_FIELD_SP(insn, 10, 12);
3587
                            int l1;
3588

    
3589
                            cpu_src1 = get_src1(insn, cpu_src1);
3590

    
3591
                            l1 = gen_new_label();
3592

    
3593
                            tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond],
3594
                                              cpu_src1, 0, l1);
3595
                            if (IS_IMM) {       /* immediate */
3596
                                TCGv r_const;
3597

    
3598
                                rs2 = GET_FIELD_SPs(insn, 0, 9);
3599
                                r_const = tcg_const_tl((int)rs2);
3600
                                gen_movl_TN_reg(rd, r_const);
3601
                                tcg_temp_free(r_const);
3602
                            } else {
3603
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3604
                                gen_movl_reg_TN(rs2, cpu_tmp0);
3605
                                gen_movl_TN_reg(rd, cpu_tmp0);
3606
                            }
3607
                            gen_set_label(l1);
3608
                            break;
3609
                        }
3610
#endif
3611
                    default:
3612
                        goto illegal_insn;
3613
                    }
3614
                }
3615
            } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
3616
#ifdef TARGET_SPARC64
3617
                int opf = GET_FIELD_SP(insn, 5, 13);
3618
                rs1 = GET_FIELD(insn, 13, 17);
3619
                rs2 = GET_FIELD(insn, 27, 31);
3620
                if (gen_trap_ifnofpu(dc, cpu_cond))
3621
                    goto jmp_insn;
3622

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

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

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

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

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

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

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

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

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

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

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

    
4581
                        CHECK_FPU_FEATURE(dc, FLOAT128);
4582
                        gen_op_load_fpr_QT0(QFPREG(rd));
4583
                        r_const = tcg_const_i32(dc->mem_idx);
4584
                        tcg_gen_helper_0_2(helper_stqf, cpu_addr, r_const);
4585
                        tcg_temp_free(r_const);
4586
                    }
4587
                    break;
4588
#else /* !TARGET_SPARC64 */
4589
                    /* stdfq, store floating point queue */
4590
#if defined(CONFIG_USER_ONLY)
4591
                    goto illegal_insn;
4592
#else
4593
                    if (!supervisor(dc))
4594
                        goto priv_insn;
4595
                    if (gen_trap_ifnofpu(dc, cpu_cond))
4596
                        goto jmp_insn;
4597
                    goto nfq_insn;
4598
#endif
4599
#endif
4600
                case 0x27: /* store double fpreg */
4601
                    {
4602
                        TCGv r_const;
4603

    
4604
                        gen_op_load_fpr_DT0(DFPREG(rd));
4605
                        r_const = tcg_const_i32(dc->mem_idx);
4606
                        tcg_gen_helper_0_2(helper_stdf, cpu_addr, r_const);
4607
                        tcg_temp_free(r_const);
4608
                    }
4609
                    break;
4610
                default:
4611
                    goto illegal_insn;
4612
                }
4613
            } else if (xop > 0x33 && xop < 0x3f) {
4614
                save_state(dc, cpu_cond);
4615
                switch (xop) {
4616
#ifdef TARGET_SPARC64
4617
                case 0x34: /* V9 stfa */
4618
                    gen_stf_asi(cpu_addr, insn, 4, rd);
4619
                    break;
4620
                case 0x36: /* V9 stqfa */
4621
                    {
4622
                        TCGv r_const;
4623

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

    
4679
        save_state(dc, cpu_cond);
4680
        r_const = tcg_const_i32(TT_ILL_INSN);
4681
        tcg_gen_helper_0_1(raise_exception, r_const);
4682
        tcg_temp_free(r_const);
4683
        dc->is_br = 1;
4684
    }
4685
    return;
4686
 unimp_flush:
4687
    {
4688
        TCGv r_const;
4689

    
4690
        save_state(dc, cpu_cond);
4691
        r_const = tcg_const_i32(TT_UNIMP_FLUSH);
4692
        tcg_gen_helper_0_1(raise_exception, r_const);
4693
        tcg_temp_free(r_const);
4694
        dc->is_br = 1;
4695
    }
4696
    return;
4697
#if !defined(CONFIG_USER_ONLY)
4698
 priv_insn:
4699
    {
4700
        TCGv r_const;
4701

    
4702
        save_state(dc, cpu_cond);
4703
        r_const = tcg_const_i32(TT_PRIV_INSN);
4704
        tcg_gen_helper_0_1(raise_exception, r_const);
4705
        tcg_temp_free(r_const);
4706
        dc->is_br = 1;
4707
    }
4708
    return;
4709
#endif
4710
 nfpu_insn:
4711
    save_state(dc, cpu_cond);
4712
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
4713
    dc->is_br = 1;
4714
    return;
4715
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
4716
 nfq_insn:
4717
    save_state(dc, cpu_cond);
4718
    gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
4719
    dc->is_br = 1;
4720
    return;
4721
#endif
4722
#ifndef TARGET_SPARC64
4723
 ncp_insn:
4724
    {
4725
        TCGv r_const;
4726

    
4727
        save_state(dc, cpu_cond);
4728
        r_const = tcg_const_i32(TT_NCP_INSN);
4729
        tcg_gen_helper_0_1(raise_exception, r_const);
4730
        tcg_temp_free(r_const);
4731
        dc->is_br = 1;
4732
    }
4733
    return;
4734
#endif
4735
}
4736

    
4737
static inline void gen_intermediate_code_internal(TranslationBlock * tb,
4738
                                                  int spc, CPUSPARCState *env)
4739
{
4740
    target_ulong pc_start, last_pc;
4741
    uint16_t *gen_opc_end;
4742
    DisasContext dc1, *dc = &dc1;
4743
    int j, lj = -1;
4744
    int num_insns;
4745
    int max_insns;
4746

    
4747
    memset(dc, 0, sizeof(DisasContext));
4748
    dc->tb = tb;
4749
    pc_start = tb->pc;
4750
    dc->pc = pc_start;
4751
    last_pc = dc->pc;
4752
    dc->npc = (target_ulong) tb->cs_base;
4753
    dc->mem_idx = cpu_mmu_index(env);
4754
    dc->def = env->def;
4755
    if ((dc->def->features & CPU_FEATURE_FLOAT))
4756
        dc->fpu_enabled = cpu_fpu_enabled(env);
4757
    else
4758
        dc->fpu_enabled = 0;
4759
#ifdef TARGET_SPARC64
4760
    dc->address_mask_32bit = env->pstate & PS_AM;
4761
#endif
4762
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4763

    
4764
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
4765
    cpu_tmp32 = tcg_temp_new(TCG_TYPE_I32);
4766
    cpu_tmp64 = tcg_temp_new(TCG_TYPE_I64);
4767

    
4768
    cpu_dst = tcg_temp_local_new(TCG_TYPE_TL);
4769

    
4770
    // loads and stores
4771
    cpu_val = tcg_temp_local_new(TCG_TYPE_TL);
4772
    cpu_addr = tcg_temp_local_new(TCG_TYPE_TL);
4773

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

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

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

    
4881
void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
4882
{
4883
    gen_intermediate_code_internal(tb, 0, env);
4884
}
4885

    
4886
void gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
4887
{
4888
    gen_intermediate_code_internal(tb, 1, env);
4889
}
4890

    
4891
void gen_intermediate_code_init(CPUSPARCState *env)
4892
{
4893
    unsigned int i;
4894
    static int inited;
4895
    static const char * const gregnames[8] = {
4896
        NULL, // g0 not used
4897
        "g1",
4898
        "g2",
4899
        "g3",
4900
        "g4",
4901
        "g5",
4902
        "g6",
4903
        "g7",
4904
    };
4905
    static const char * const fregnames[64] = {
4906
        "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
4907
        "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
4908
        "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
4909
        "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
4910
        "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
4911
        "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
4912
        "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
4913
        "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
4914
    };
4915

    
4916
    /* init various static tables */
4917
    if (!inited) {
4918
        inited = 1;
4919

    
4920
        cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
4921
        cpu_regwptr = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
4922
                                         offsetof(CPUState, regwptr),
4923
                                         "regwptr");
4924
#ifdef TARGET_SPARC64
4925
        cpu_xcc = tcg_global_mem_new(TCG_TYPE_I32,
4926
                                     TCG_AREG0, offsetof(CPUState, xcc),
4927
                                     "xcc");
4928
        cpu_asi = tcg_global_mem_new(TCG_TYPE_I32,
4929
                                     TCG_AREG0, offsetof(CPUState, asi),
4930
                                     "asi");
4931
        cpu_fprs = tcg_global_mem_new(TCG_TYPE_I32,
4932
                                      TCG_AREG0, offsetof(CPUState, fprs),
4933
                                      "fprs");
4934
        cpu_gsr = tcg_global_mem_new(TCG_TYPE_TL,
4935
                                     TCG_AREG0, offsetof(CPUState, gsr),
4936
                                     "gsr");
4937
        cpu_tick_cmpr = tcg_global_mem_new(TCG_TYPE_TL,
4938
                                           TCG_AREG0,
4939
                                           offsetof(CPUState, tick_cmpr),
4940
                                           "tick_cmpr");
4941
        cpu_stick_cmpr = tcg_global_mem_new(TCG_TYPE_TL,
4942
                                            TCG_AREG0,
4943
                                            offsetof(CPUState, stick_cmpr),
4944
                                            "stick_cmpr");
4945
        cpu_hstick_cmpr = tcg_global_mem_new(TCG_TYPE_TL,
4946
                                             TCG_AREG0,
4947
                                             offsetof(CPUState, hstick_cmpr),
4948
                                             "hstick_cmpr");
4949
        cpu_hintp = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4950
                                       offsetof(CPUState, hintp),
4951
                                       "hintp");
4952
        cpu_htba = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4953
                                      offsetof(CPUState, htba),
4954
                                       "htba");
4955
        cpu_hver = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4956
                                      offsetof(CPUState, hver),
4957
                                       "hver");
4958
        cpu_ssr = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4959
                                     offsetof(CPUState, ssr), "ssr");
4960
        cpu_ver = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4961
                                     offsetof(CPUState, version), "ver");
4962
#else
4963
        cpu_wim = tcg_global_mem_new(TCG_TYPE_I32,
4964
                                     TCG_AREG0, offsetof(CPUState, wim),
4965
                                     "wim");
4966
#endif
4967
        cpu_cond = tcg_global_mem_new(TCG_TYPE_TL,
4968
                                      TCG_AREG0, offsetof(CPUState, cond),
4969
                                      "cond");
4970
        cpu_cc_src = tcg_global_mem_new(TCG_TYPE_TL,
4971
                                        TCG_AREG0, offsetof(CPUState, cc_src),
4972
                                        "cc_src");
4973
        cpu_cc_src2 = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4974
                                         offsetof(CPUState, cc_src2),
4975
                                         "cc_src2");
4976
        cpu_cc_dst = tcg_global_mem_new(TCG_TYPE_TL,
4977
                                        TCG_AREG0, offsetof(CPUState, cc_dst),
4978
                                        "cc_dst");
4979
        cpu_psr = tcg_global_mem_new(TCG_TYPE_I32,
4980
                                     TCG_AREG0, offsetof(CPUState, psr),
4981
                                     "psr");
4982
        cpu_fsr = tcg_global_mem_new(TCG_TYPE_TL,
4983
                                     TCG_AREG0, offsetof(CPUState, fsr),
4984
                                     "fsr");
4985
        cpu_pc = tcg_global_mem_new(TCG_TYPE_TL,
4986
                                    TCG_AREG0, offsetof(CPUState, pc),
4987
                                    "pc");
4988
        cpu_npc = tcg_global_mem_new(TCG_TYPE_TL,
4989
                                    TCG_AREG0, offsetof(CPUState, npc),
4990
                                    "npc");
4991
        cpu_y = tcg_global_mem_new(TCG_TYPE_TL,
4992
                                   TCG_AREG0, offsetof(CPUState, y), "y");
4993
#ifndef CONFIG_USER_ONLY
4994
        cpu_tbr = tcg_global_mem_new(TCG_TYPE_TL,
4995
                                     TCG_AREG0, offsetof(CPUState, tbr),
4996
                                     "tbr");
4997
#endif
4998
        for (i = 1; i < 8; i++)
4999
            cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
5000
                                              offsetof(CPUState, gregs[i]),
5001
                                              gregnames[i]);
5002
        for (i = 0; i < TARGET_FPREGS; i++)
5003
            cpu_fpr[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
5004
                                            offsetof(CPUState, fpr[i]),
5005
                                            fregnames[i]);
5006

    
5007
        /* register helpers */
5008

    
5009
#undef DEF_HELPER
5010
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
5011
#include "helper.h"
5012
    }
5013
}
5014

    
5015
void gen_pc_load(CPUState *env, TranslationBlock *tb,
5016
                unsigned long searched_pc, int pc_pos, void *puc)
5017
{
5018
    target_ulong npc;
5019
    env->pc = gen_opc_pc[pc_pos];
5020
    npc = gen_opc_npc[pc_pos];
5021
    if (npc == 1) {
5022
        /* dynamic NPC: already stored */
5023
    } else if (npc == 2) {
5024
        target_ulong t2 = (target_ulong)(unsigned long)puc;
5025
        /* jump PC: use T2 and the jump targets of the translation */
5026
        if (t2)
5027
            env->npc = gen_opc_jump_pc[0];
5028
        else
5029
            env->npc = gen_opc_jump_pc[1];
5030
    } else {
5031
        env->npc = npc;
5032
    }
5033
}