Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ 72ccba79

History | View | Annotate | Download (191.5 kB)

1
/*
2
   SPARC translation
3

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

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

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

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

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

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

    
34
#define DEBUG_DISAS
35

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

    
40
/* global register indexes */
41
static TCGv cpu_env, cpu_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_andi_tl(cpu_cc_src, src1, 0xffffffff);
701
    tcg_gen_andi_tl(r_temp, cpu_y, 0x1);
702
    tcg_gen_andi_tl(cpu_cc_src2, src2, 0xffffffff);
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_andi_tl(cpu_tmp0, cpu_tmp0, 0x7fffffff);
713
    tcg_gen_or_tl(cpu_tmp0, cpu_tmp0, r_temp);
714
    tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
715

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1116
    l1 = gen_new_label();
1117

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

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

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

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

    
1131
    l1 = gen_new_label();
1132

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1551
#else
1552

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1756
#elif !defined(CONFIG_USER_ONLY)
1757

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3555
                            l1 = gen_new_label();
3556

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

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

    
3590
                            cpu_src1 = get_src1(insn, cpu_src1);
3591

    
3592
                            l1 = gen_new_label();
3593

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4769
    cpu_dst = tcg_temp_local_new(TCG_TYPE_TL);
4770

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

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

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

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

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

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

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

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

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

    
5008
        /* register helpers */
5009

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

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