Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ 105a1f04

History | View | Annotate | Download (184.7 kB)

1
/*
2
   SPARC translation
3

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

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

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

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

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

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

    
34
#define DEBUG_DISAS
35

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

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

    
51
#include "gen-icount.h"
52

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
422
    l1 = gen_new_label();
423

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
619
    l1 = gen_new_label();
620

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

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

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

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

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

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

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

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

    
734
    // b2 = T0 & 1;
735
    // env->y = (b2 << 31) | (env->y >> 1);
736
    tcg_gen_andi_tl(r_temp, cpu_cc_src, 0x1);
737
    tcg_gen_shli_tl(r_temp, r_temp, 31);
738
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, y));
739
    tcg_gen_shri_tl(cpu_tmp0, cpu_tmp0, 1);
740
    tcg_gen_or_tl(cpu_tmp0, cpu_tmp0, r_temp);
741
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, y));
742

    
743
    // b1 = N ^ V;
744
    gen_mov_reg_N(cpu_tmp0, cpu_psr);
745
    gen_mov_reg_V(r_temp, cpu_psr);
746
    tcg_gen_xor_tl(cpu_tmp0, cpu_tmp0, r_temp);
747
    tcg_temp_free(r_temp);
748

    
749
    // T0 = (b1 << 31) | (T0 >> 1);
750
    // src1 = T0;
751
    tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
752
    tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
753
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
754

    
755
    /* do addition and update flags */
756
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
757

    
758
    gen_cc_clear_icc();
759
    gen_cc_NZ_icc(cpu_cc_dst);
760
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
761
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
762
    tcg_gen_mov_tl(dst, cpu_cc_dst);
763
}
764

    
765
static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
766
{
767
    TCGv r_temp, r_temp2;
768

    
769
    r_temp = tcg_temp_new(TCG_TYPE_I64);
770
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);
771

    
772
    tcg_gen_extu_tl_i64(r_temp, src2);
773
    tcg_gen_extu_tl_i64(r_temp2, src1);
774
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
775

    
776
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
777
    tcg_gen_trunc_i64_tl(cpu_tmp0, r_temp);
778
    tcg_temp_free(r_temp);
779
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffff);
780
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, y));
781
#ifdef TARGET_SPARC64
782
    tcg_gen_mov_i64(dst, r_temp2);
783
#else
784
    tcg_gen_trunc_i64_tl(dst, r_temp2);
785
#endif
786
    tcg_temp_free(r_temp2);
787
}
788

    
789
static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
790
{
791
    TCGv r_temp, r_temp2;
792

    
793
    r_temp = tcg_temp_new(TCG_TYPE_I64);
794
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);
795

    
796
    tcg_gen_ext_tl_i64(r_temp, src2);
797
    tcg_gen_ext_tl_i64(r_temp2, src1);
798
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
799

    
800
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
801
    tcg_gen_trunc_i64_tl(cpu_tmp0, r_temp);
802
    tcg_temp_free(r_temp);
803
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffff);
804
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, y));
805
#ifdef TARGET_SPARC64
806
    tcg_gen_mov_i64(dst, r_temp2);
807
#else
808
    tcg_gen_trunc_i64_tl(dst, r_temp2);
809
#endif
810
    tcg_temp_free(r_temp2);
811
}
812

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

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

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

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

    
846
static inline void gen_op_div_cc(TCGv dst)
847
{
848
    int l1;
849

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

    
859
static inline void gen_op_logic_cc(TCGv dst)
860
{
861
    tcg_gen_mov_tl(cpu_cc_dst, dst);
862

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1145
    l1 = gen_new_label();
1146

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

    
1149
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
1150

    
1151
    gen_set_label(l1);
1152
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
1153
}
1154

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

    
1160
    l1 = gen_new_label();
1161

    
1162
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
1163

    
1164
    gen_goto_tb(dc, 0, pc2, pc1);
1165

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

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

    
1175
    l1 = gen_new_label();
1176
    l2 = gen_new_label();
1177

    
1178
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
1179

    
1180
    tcg_gen_movi_tl(cpu_npc, npc1);
1181
    tcg_gen_br(l2);
1182

    
1183
    gen_set_label(l1);
1184
    tcg_gen_movi_tl(cpu_npc, npc2);
1185
    gen_set_label(l2);
1186
}
1187

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1568
#else
1569

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

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

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

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

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

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

    
1601
static inline void gen_op_fpexception_im(int fsr_flags)
1602
{
1603
    TCGv r_const;
1604

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

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

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

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

    
1634
static inline void gen_clear_float_exceptions(void)
1635
{
1636
    tcg_gen_helper_0_0(helper_clear_float_exceptions);
1637
}
1638

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1773
#elif !defined(CONFIG_USER_ONLY)
1774

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

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

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

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

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

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

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

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

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

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

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

    
1856
    gen_ld_asi(dst, addr, insn, 1, 0);
1857

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

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

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

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

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

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

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

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

    
1920
    rd = GET_FIELD(insn, 2, 6);
1921

    
1922
    cpu_src1 = tcg_temp_new(TCG_TYPE_TL); // const
1923
    cpu_src2 = tcg_temp_new(TCG_TYPE_TL); // const
1924

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
3535
                            l1 = gen_new_label();
3536

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

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

    
3570
                            cpu_src1 = get_src1(insn, cpu_src1);
3571

    
3572
                            l1 = gen_new_label();
3573

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
4680
        save_state(dc, cpu_cond);
4681
        r_const = tcg_const_i32(TT_UNIMP_FLUSH);
4682
        tcg_gen_helper_0_1(raise_exception, r_const);
4683
        tcg_temp_free(r_const);
4684
        dc->is_br = 1;
4685
    }
4686
    return;
4687
#if !defined(CONFIG_USER_ONLY)
4688
 priv_insn:
4689
    {
4690
        TCGv r_const;
4691

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

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

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

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

    
4754
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
4755
    cpu_tmp32 = tcg_temp_new(TCG_TYPE_I32);
4756
    cpu_tmp64 = tcg_temp_new(TCG_TYPE_I64);
4757

    
4758
    cpu_dst = tcg_temp_local_new(TCG_TYPE_TL);
4759

    
4760
    // loads and stores
4761
    cpu_val = tcg_temp_local_new(TCG_TYPE_TL);
4762
    cpu_addr = tcg_temp_local_new(TCG_TYPE_TL);
4763

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

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

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

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

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

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

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

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

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

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