Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ ece43b8d

History | View | Annotate | Download (183.9 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_T[2], cpu_regwptr;
42
static TCGv cpu_cc_src, cpu_cc_src2, cpu_cc_dst;
43
static TCGv cpu_psr, cpu_fsr, cpu_pc, cpu_npc, cpu_gregs[8];
44
static TCGv cpu_cond, cpu_src1, cpu_src2, cpu_dst, cpu_addr, cpu_val;
45
#ifdef TARGET_SPARC64
46
static TCGv cpu_xcc;
47
#endif
48
/* local register indexes (only used inside old micro ops) */
49
static TCGv cpu_tmp0, cpu_tmp32, cpu_tmp64;
50

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

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

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

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

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

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

    
89
#define IS_IMM (insn & (1<<13))
90

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
406
    l1 = gen_new_label();
407

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
603
    l1 = gen_new_label();
604

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

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

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

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

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

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

    
703
    l1 = gen_new_label();
704
    r_temp = tcg_temp_new(TCG_TYPE_TL);
705
    r_temp2 = tcg_temp_new(TCG_TYPE_I32);
706

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

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

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

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

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

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

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

    
757
    r_temp = tcg_temp_new(TCG_TYPE_I64);
758
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);
759

    
760
    tcg_gen_extu_tl_i64(r_temp, src2);
761
    tcg_gen_extu_tl_i64(r_temp2, src1);
762
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
763

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

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

    
780
    r_temp = tcg_temp_new(TCG_TYPE_I64);
781
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);
782

    
783
    tcg_gen_ext_tl_i64(r_temp, src2);
784
    tcg_gen_ext_tl_i64(r_temp2, src1);
785
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
786

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

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

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

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

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

    
832
static inline void gen_op_div_cc(TCGv dst)
833
{
834
    int l1;
835

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

    
845
static inline void gen_op_logic_cc(TCGv dst)
846
{
847
    tcg_gen_mov_tl(cpu_cc_dst, dst);
848

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1133
    l1 = gen_new_label();
1134

    
1135
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
1136

    
1137
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
1138

    
1139
    gen_set_label(l1);
1140
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
1141
}
1142

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

    
1148
    l1 = gen_new_label();
1149

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

    
1152
    gen_goto_tb(dc, 0, pc2, pc1);
1153

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

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

    
1163
    l1 = gen_new_label();
1164
    l2 = gen_new_label();
1165

    
1166
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
1167

    
1168
    tcg_gen_movi_tl(cpu_npc, npc1);
1169
    tcg_gen_br(l2);
1170

    
1171
    gen_set_label(l1);
1172
    tcg_gen_movi_tl(cpu_npc, npc2);
1173
    gen_set_label(l2);
1174
}
1175

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1556
#else
1557

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

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

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

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

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

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

    
1589
static inline void gen_op_fpexception_im(int fsr_flags)
1590
{
1591
    TCGv r_const;
1592

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

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

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

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

    
1622
static inline void gen_clear_float_exceptions(void)
1623
{
1624
    tcg_gen_helper_0_0(helper_clear_float_exceptions);
1625
}
1626

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1768
#elif !defined(CONFIG_USER_ONLY)
1769

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

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

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

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

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

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

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

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

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

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

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

    
1849
    gen_ld_asi(dst, addr, insn, 1, 0);
1850

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

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

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

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

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

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

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

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

    
1913
    rd = GET_FIELD(insn, 2, 6);
1914

    
1915
    cpu_dst = cpu_T[0];
1916
    cpu_src1 = tcg_temp_new(TCG_TYPE_TL); // const
1917
    cpu_src2 = tcg_temp_new(TCG_TYPE_TL); // const
1918

    
1919
    // loads and stores
1920
    cpu_addr = cpu_T[0];
1921
    cpu_val = cpu_T[1];
1922

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3526
                            l1 = gen_new_label();
3527

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

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

    
3561
                            cpu_src1 = get_src1(insn, cpu_src1);
3562

    
3563
                            l1 = gen_new_label();
3564

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4749
    do {
4750
        if (env->nb_breakpoints > 0) {
4751
            for(j = 0; j < env->nb_breakpoints; j++) {
4752
                if (env->breakpoints[j] == dc->pc) {
4753
                    if (dc->pc != pc_start)
4754
                        save_state(dc, cpu_cond);
4755
                    tcg_gen_helper_0_0(helper_debug);
4756
                    tcg_gen_exit_tb(0);
4757
                    dc->is_br = 1;
4758
                    goto exit_gen_loop;
4759
                }
4760
            }
4761
        }
4762
        if (spc) {
4763
            if (loglevel > 0)
4764
                fprintf(logfile, "Search PC...\n");
4765
            j = gen_opc_ptr - gen_opc_buf;
4766
            if (lj < j) {
4767
                lj++;
4768
                while (lj < j)
4769
                    gen_opc_instr_start[lj++] = 0;
4770
                gen_opc_pc[lj] = dc->pc;
4771
                gen_opc_npc[lj] = dc->npc;
4772
                gen_opc_instr_start[lj] = 1;
4773
            }
4774
        }
4775
        last_pc = dc->pc;
4776
        disas_sparc_insn(dc);
4777

    
4778
        if (dc->is_br)
4779
            break;
4780
        /* if the next PC is different, we abort now */
4781
        if (dc->pc != (last_pc + 4))
4782
            break;
4783
        /* if we reach a page boundary, we stop generation so that the
4784
           PC of a TT_TFAULT exception is always in the right page */
4785
        if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
4786
            break;
4787
        /* if single step mode, we generate only one instruction and
4788
           generate an exception */
4789
        if (env->singlestep_enabled) {
4790
            tcg_gen_movi_tl(cpu_pc, dc->pc);
4791
            tcg_gen_exit_tb(0);
4792
            break;
4793
        }
4794
    } while ((gen_opc_ptr < gen_opc_end) &&
4795
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
4796

    
4797
 exit_gen_loop:
4798
    tcg_temp_free(cpu_tmp64);
4799
    tcg_temp_free(cpu_tmp32);
4800
    tcg_temp_free(cpu_tmp0);
4801
    if (!dc->is_br) {
4802
        if (dc->pc != DYNAMIC_PC &&
4803
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
4804
            /* static PC and NPC: we can use direct chaining */
4805
            gen_goto_tb(dc, 0, dc->pc, dc->npc);
4806
        } else {
4807
            if (dc->pc != DYNAMIC_PC)
4808
                tcg_gen_movi_tl(cpu_pc, dc->pc);
4809
            save_npc(dc, cpu_cond);
4810
            tcg_gen_exit_tb(0);
4811
        }
4812
    }
4813
    *gen_opc_ptr = INDEX_op_end;
4814
    if (spc) {
4815
        j = gen_opc_ptr - gen_opc_buf;
4816
        lj++;
4817
        while (lj <= j)
4818
            gen_opc_instr_start[lj++] = 0;
4819
#if 0
4820
        if (loglevel > 0) {
4821
            page_dump(logfile);
4822
        }
4823
#endif
4824
        gen_opc_jump_pc[0] = dc->jump_pc[0];
4825
        gen_opc_jump_pc[1] = dc->jump_pc[1];
4826
    } else {
4827
        tb->size = last_pc + 4 - pc_start;
4828
    }
4829
#ifdef DEBUG_DISAS
4830
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4831
        fprintf(logfile, "--------------\n");
4832
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
4833
        target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
4834
        fprintf(logfile, "\n");
4835
    }
4836
#endif
4837
    return 0;
4838
}
4839

    
4840
int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
4841
{
4842
    return gen_intermediate_code_internal(tb, 0, env);
4843
}
4844

    
4845
int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
4846
{
4847
    return gen_intermediate_code_internal(tb, 1, env);
4848
}
4849

    
4850
void gen_intermediate_code_init(CPUSPARCState *env)
4851
{
4852
    unsigned int i;
4853
    static int inited;
4854
    static const char * const gregnames[8] = {
4855
        NULL, // g0 not used
4856
        "g1",
4857
        "g2",
4858
        "g3",
4859
        "g4",
4860
        "g5",
4861
        "g6",
4862
        "g7",
4863
    };
4864

    
4865
    /* init various static tables */
4866
    if (!inited) {
4867
        inited = 1;
4868

    
4869
        cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
4870
        cpu_regwptr = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
4871
                                         offsetof(CPUState, regwptr),
4872
                                         "regwptr");
4873
#ifdef TARGET_SPARC64
4874
        cpu_xcc = tcg_global_mem_new(TCG_TYPE_I32,
4875
                                     TCG_AREG0, offsetof(CPUState, xcc),
4876
                                     "xcc");
4877
#endif
4878
        /* XXX: T0 and T1 should be temporaries */
4879
        cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
4880
                                      TCG_AREG0, offsetof(CPUState, t0), "T0");
4881
        cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
4882
                                      TCG_AREG0, offsetof(CPUState, t1), "T1");
4883
        cpu_cond = tcg_global_mem_new(TCG_TYPE_TL,
4884
                                      TCG_AREG0, offsetof(CPUState, cond),
4885
                                      "cond");
4886
        cpu_cc_src = tcg_global_mem_new(TCG_TYPE_TL,
4887
                                        TCG_AREG0, offsetof(CPUState, cc_src),
4888
                                        "cc_src");
4889
        cpu_cc_src2 = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4890
                                         offsetof(CPUState, cc_src2),
4891
                                         "cc_src2");
4892
        cpu_cc_dst = tcg_global_mem_new(TCG_TYPE_TL,
4893
                                        TCG_AREG0, offsetof(CPUState, cc_dst),
4894
                                        "cc_dst");
4895
        cpu_psr = tcg_global_mem_new(TCG_TYPE_I32,
4896
                                     TCG_AREG0, offsetof(CPUState, psr),
4897
                                     "psr");
4898
        cpu_fsr = tcg_global_mem_new(TCG_TYPE_TL,
4899
                                     TCG_AREG0, offsetof(CPUState, fsr),
4900
                                     "fsr");
4901
        cpu_pc = tcg_global_mem_new(TCG_TYPE_TL,
4902
                                    TCG_AREG0, offsetof(CPUState, pc),
4903
                                    "pc");
4904
        cpu_npc = tcg_global_mem_new(TCG_TYPE_TL,
4905
                                    TCG_AREG0, offsetof(CPUState, npc),
4906
                                    "npc");
4907
        for (i = 1; i < 8; i++)
4908
            cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4909
                                              offsetof(CPUState, gregs[i]),
4910
                                              gregnames[i]);
4911
        /* register helpers */
4912

    
4913
#undef DEF_HELPER
4914
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
4915
#include "helper.h"
4916
    }
4917
}
4918

    
4919
void gen_pc_load(CPUState *env, TranslationBlock *tb,
4920
                unsigned long searched_pc, int pc_pos, void *puc)
4921
{
4922
    target_ulong npc;
4923
    env->pc = gen_opc_pc[pc_pos];
4924
    npc = gen_opc_npc[pc_pos];
4925
    if (npc == 1) {
4926
        /* dynamic NPC: already stored */
4927
    } else if (npc == 2) {
4928
        target_ulong t2 = (target_ulong)(unsigned long)puc;
4929
        /* jump PC: use T2 and the jump targets of the translation */
4930
        if (t2)
4931
            env->npc = gen_opc_jump_pc[0];
4932
        else
4933
            env->npc = gen_opc_jump_pc[1];
4934
    } else {
4935
        env->npc = npc;
4936
    }
4937
}