Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ 9c6c6662

History | View | Annotate | Download (173 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
/*
23
   TODO-list:
24

25
   Rest of V9 instructions, VIS instructions
26
   NPC/PC static optimisations (use JUMP_TB when possible)
27
   Optimize synthetic instructions
28
*/
29

    
30
#include <stdarg.h>
31
#include <stdlib.h>
32
#include <stdio.h>
33
#include <string.h>
34
#include <inttypes.h>
35

    
36
#include "cpu.h"
37
#include "exec-all.h"
38
#include "disas.h"
39
#include "helper.h"
40
#include "tcg-op.h"
41

    
42
#define DEBUG_DISAS
43

    
44
#define DYNAMIC_PC  1 /* dynamic pc value */
45
#define JUMP_PC     2 /* dynamic pc value which takes only two values
46
                         according to jump_pc[T2] */
47

    
48
/* global register indexes */
49
static TCGv cpu_env, cpu_T[3], cpu_regwptr, cpu_cc_src, cpu_cc_src2, cpu_cc_dst;
50
static TCGv cpu_psr, cpu_fsr, cpu_pc, cpu_npc, cpu_gregs[8];
51
static TCGv cpu_cond, cpu_src1, cpu_src2, cpu_dst, cpu_addr, cpu_val;
52
#ifdef TARGET_SPARC64
53
static TCGv cpu_xcc;
54
#endif
55
/* local register indexes (only used inside old micro ops) */
56
static TCGv cpu_tmp0, cpu_tmp32, cpu_tmp64;
57

    
58
typedef struct DisasContext {
59
    target_ulong pc;    /* current Program Counter: integer or DYNAMIC_PC */
60
    target_ulong npc;   /* next PC: integer or DYNAMIC_PC or JUMP_PC */
61
    target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
62
    int is_br;
63
    int mem_idx;
64
    int fpu_enabled;
65
    struct TranslationBlock *tb;
66
} DisasContext;
67

    
68
extern FILE *logfile;
69
extern int loglevel;
70

    
71
// This function uses non-native bit order
72
#define GET_FIELD(X, FROM, TO) \
73
  ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
74

    
75
// This function uses the order in the manuals, i.e. bit 0 is 2^0
76
#define GET_FIELD_SP(X, FROM, TO) \
77
    GET_FIELD(X, 31 - (TO), 31 - (FROM))
78

    
79
#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
80
#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
81

    
82
#ifdef TARGET_SPARC64
83
#define FFPREG(r) (r)
84
#define DFPREG(r) (((r & 1) << 5) | (r & 0x1e))
85
#define QFPREG(r) (((r & 1) << 5) | (r & 0x1c))
86
#else
87
#define FFPREG(r) (r)
88
#define DFPREG(r) (r & 0x1e)
89
#define QFPREG(r) (r & 0x1c)
90
#endif
91

    
92
static int sign_extend(int x, int len)
93
{
94
    len = 32 - len;
95
    return (x << len) >> len;
96
}
97

    
98
#define IS_IMM (insn & (1<<13))
99

    
100
/* floating point registers moves */
101
static void gen_op_load_fpr_FT0(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, ft0));
105
}
106

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

    
113
static void gen_op_store_FT0_fpr(unsigned int dst)
114
{
115
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft0));
116
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst]));
117
}
118

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

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

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

    
143
#ifdef CONFIG_USER_ONLY
144
static void gen_op_load_fpr_QT0(unsigned int src)
145
{
146
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
147
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + 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) + offsetof(CPU_QuadU, l.upper));
150
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 2]));
151
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lower));
152
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 3]));
153
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lowest));
154
}
155

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

    
168
static void gen_op_store_QT0_fpr(unsigned int dst)
169
{
170
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upmost));
171
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst]));
172
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.upper));
173
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 1]));
174
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lower));
175
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 2]));
176
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lowest));
177
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 3]));
178
}
179
#endif
180

    
181
/* moves */
182
#ifdef CONFIG_USER_ONLY
183
#define supervisor(dc) 0
184
#ifdef TARGET_SPARC64
185
#define hypervisor(dc) 0
186
#endif
187
#else
188
#define supervisor(dc) (dc->mem_idx >= 1)
189
#ifdef TARGET_SPARC64
190
#define hypervisor(dc) (dc->mem_idx == 2)
191
#else
192
#endif
193
#endif
194

    
195
#ifdef TARGET_ABI32
196
#define ABI32_MASK(addr) tcg_gen_andi_tl(addr, addr, 0xffffffffULL);
197
#else
198
#define ABI32_MASK(addr)
199
#endif
200

    
201
static inline void gen_movl_reg_TN(int reg, TCGv tn)
202
{
203
    if (reg == 0)
204
        tcg_gen_movi_tl(tn, 0);
205
    else if (reg < 8)
206
        tcg_gen_mov_tl(tn, cpu_gregs[reg]);
207
    else {
208
        tcg_gen_ld_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
209
    }
210
}
211

    
212
static inline void gen_movl_TN_reg(int reg, TCGv tn)
213
{
214
    if (reg == 0)
215
        return;
216
    else if (reg < 8)
217
        tcg_gen_mov_tl(cpu_gregs[reg], tn);
218
    else {
219
        tcg_gen_st_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
220
    }
221
}
222

    
223
static inline void gen_goto_tb(DisasContext *s, int tb_num,
224
                               target_ulong pc, target_ulong npc)
225
{
226
    TranslationBlock *tb;
227

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

    
244
// XXX suboptimal
245
static inline void gen_mov_reg_N(TCGv reg, TCGv src)
246
{
247
    tcg_gen_extu_i32_tl(reg, src);
248
    tcg_gen_shri_tl(reg, reg, PSR_NEG_SHIFT);
249
    tcg_gen_andi_tl(reg, reg, 0x1);
250
}
251

    
252
static inline void gen_mov_reg_Z(TCGv reg, TCGv src)
253
{
254
    tcg_gen_extu_i32_tl(reg, src);
255
    tcg_gen_shri_tl(reg, reg, PSR_ZERO_SHIFT);
256
    tcg_gen_andi_tl(reg, reg, 0x1);
257
}
258

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

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

    
273
static inline void gen_cc_clear_icc(void)
274
{
275
    tcg_gen_movi_i32(cpu_psr, 0);
276
}
277

    
278
#ifdef TARGET_SPARC64
279
static inline void gen_cc_clear_xcc(void)
280
{
281
    tcg_gen_movi_i32(cpu_xcc, 0);
282
}
283
#endif
284

    
285
/* old op:
286
    if (!T0)
287
        env->psr |= PSR_ZERO;
288
    if ((int32_t) T0 < 0)
289
        env->psr |= PSR_NEG;
290
*/
291
static inline void gen_cc_NZ_icc(TCGv dst)
292
{
293
    TCGv r_temp;
294
    int l1, l2;
295

    
296
    l1 = gen_new_label();
297
    l2 = gen_new_label();
298
    r_temp = tcg_temp_new(TCG_TYPE_TL);
299
    tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
300
    tcg_gen_brcond_tl(TCG_COND_NE, r_temp, tcg_const_tl(0), l1);
301
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_ZERO);
302
    gen_set_label(l1);
303
    tcg_gen_ext_i32_tl(r_temp, dst);
304
    tcg_gen_brcond_tl(TCG_COND_GE, r_temp, tcg_const_tl(0), l2);
305
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_NEG);
306
    gen_set_label(l2);
307
}
308

    
309
#ifdef TARGET_SPARC64
310
static inline void gen_cc_NZ_xcc(TCGv dst)
311
{
312
    int l1, l2;
313

    
314
    l1 = gen_new_label();
315
    l2 = gen_new_label();
316
    tcg_gen_brcond_tl(TCG_COND_NE, dst, tcg_const_tl(0), l1);
317
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_ZERO);
318
    gen_set_label(l1);
319
    tcg_gen_brcond_tl(TCG_COND_GE, dst, tcg_const_tl(0), l2);
320
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_NEG);
321
    gen_set_label(l2);
322
}
323
#endif
324

    
325
/* old op:
326
    if (T0 < src1)
327
        env->psr |= PSR_CARRY;
328
*/
329
static inline void gen_cc_C_add_icc(TCGv dst, TCGv src1)
330
{
331
    TCGv r_temp;
332
    int l1;
333

    
334
    l1 = gen_new_label();
335
    r_temp = tcg_temp_new(TCG_TYPE_TL);
336
    tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
337
    tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l1);
338
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
339
    gen_set_label(l1);
340
}
341

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

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

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

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

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

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

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

    
395
    l1 = gen_new_label();
396

    
397
    r_temp = tcg_temp_new(TCG_TYPE_TL);
398
    tcg_gen_xor_tl(r_temp, src1, src2);
399
    tcg_gen_xori_tl(r_temp, r_temp, -1);
400
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
401
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
402
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
403
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
404
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
405
    gen_set_label(l1);
406
}
407

    
408
static inline void gen_cc_V_tag(TCGv src1, TCGv src2)
409
{
410
    int l1;
411

    
412
    l1 = gen_new_label();
413
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
414
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
415
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
416
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
417
    gen_set_label(l1);
418
}
419

    
420
static inline void gen_tag_tv(TCGv src1, TCGv src2)
421
{
422
    int l1;
423

    
424
    l1 = gen_new_label();
425
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
426
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
427
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
428
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
429
    gen_set_label(l1);
430
}
431

    
432
static inline void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2)
433
{
434
    tcg_gen_mov_tl(cpu_cc_src, src1);
435
    tcg_gen_mov_tl(cpu_cc_src2, src2);
436
    tcg_gen_add_tl(dst, src1, src2);
437
    tcg_gen_mov_tl(cpu_cc_dst, dst);
438
    gen_cc_clear_icc();
439
    gen_cc_NZ_icc(cpu_cc_dst);
440
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
441
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
442
#ifdef TARGET_SPARC64
443
    gen_cc_clear_xcc();
444
    gen_cc_NZ_xcc(cpu_cc_dst);
445
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
446
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
447
#endif
448
}
449

    
450
static inline void gen_op_addx_cc(TCGv dst, TCGv src1, TCGv src2)
451
{
452
    tcg_gen_mov_tl(cpu_cc_src, src1);
453
    tcg_gen_mov_tl(cpu_cc_src2, src2);
454
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
455
    tcg_gen_add_tl(dst, src1, cpu_tmp0);
456
    gen_cc_clear_icc();
457
    gen_cc_C_add_icc(dst, cpu_cc_src);
458
#ifdef TARGET_SPARC64
459
    gen_cc_clear_xcc();
460
    gen_cc_C_add_xcc(dst, cpu_cc_src);
461
#endif
462
    tcg_gen_add_tl(dst, dst, cpu_cc_src2);
463
    tcg_gen_mov_tl(cpu_cc_dst, dst);
464
    gen_cc_NZ_icc(cpu_cc_dst);
465
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
466
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
467
#ifdef TARGET_SPARC64
468
    gen_cc_NZ_xcc(cpu_cc_dst);
469
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
470
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
471
#endif
472
}
473

    
474
static inline void gen_op_tadd_cc(TCGv dst, TCGv src1, TCGv src2)
475
{
476
    tcg_gen_mov_tl(cpu_cc_src, src1);
477
    tcg_gen_mov_tl(cpu_cc_src2, src2);
478
    tcg_gen_add_tl(dst, src1, src2);
479
    tcg_gen_mov_tl(cpu_cc_dst, dst);
480
    gen_cc_clear_icc();
481
    gen_cc_NZ_icc(cpu_cc_dst);
482
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
483
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
484
    gen_cc_V_tag(cpu_cc_src, cpu_cc_src2);
485
#ifdef TARGET_SPARC64
486
    gen_cc_clear_xcc();
487
    gen_cc_NZ_xcc(cpu_cc_dst);
488
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
489
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
490
#endif
491
}
492

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

    
512
/* old op:
513
    if (src1 < T1)
514
        env->psr |= PSR_CARRY;
515
*/
516
static inline void gen_cc_C_sub_icc(TCGv src1, TCGv src2)
517
{
518
    TCGv r_temp1, r_temp2;
519
    int l1;
520

    
521
    l1 = gen_new_label();
522
    r_temp1 = tcg_temp_new(TCG_TYPE_TL);
523
    r_temp2 = tcg_temp_new(TCG_TYPE_TL);
524
    tcg_gen_andi_tl(r_temp1, src1, 0xffffffffULL);
525
    tcg_gen_andi_tl(r_temp2, src2, 0xffffffffULL);
526
    tcg_gen_brcond_tl(TCG_COND_GEU, r_temp1, r_temp2, l1);
527
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
528
    gen_set_label(l1);
529
}
530

    
531
#ifdef TARGET_SPARC64
532
static inline void gen_cc_C_sub_xcc(TCGv src1, TCGv src2)
533
{
534
    int l1;
535

    
536
    l1 = gen_new_label();
537
    tcg_gen_brcond_tl(TCG_COND_GEU, src1, src2, l1);
538
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
539
    gen_set_label(l1);
540
}
541
#endif
542

    
543
/* old op:
544
    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
545
        env->psr |= PSR_OVF;
546
*/
547
static inline void gen_cc_V_sub_icc(TCGv dst, TCGv src1, TCGv src2)
548
{
549
    TCGv r_temp;
550

    
551
    r_temp = tcg_temp_new(TCG_TYPE_TL);
552
    tcg_gen_xor_tl(r_temp, src1, src2);
553
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
554
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
555
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
556
    tcg_gen_shri_tl(r_temp, r_temp, 31 - PSR_OVF_SHIFT);
557
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
558
    tcg_gen_or_i32(cpu_psr, cpu_psr, cpu_tmp32);
559
}
560

    
561
#ifdef TARGET_SPARC64
562
static inline void gen_cc_V_sub_xcc(TCGv dst, TCGv src1, TCGv src2)
563
{
564
    TCGv r_temp;
565

    
566
    r_temp = tcg_temp_new(TCG_TYPE_TL);
567
    tcg_gen_xor_tl(r_temp, src1, src2);
568
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
569
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
570
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
571
    tcg_gen_shri_tl(r_temp, r_temp, 63 - PSR_OVF_SHIFT);
572
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
573
    tcg_gen_or_i32(cpu_xcc, cpu_xcc, cpu_tmp32);
574
}
575
#endif
576

    
577
static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
578
{
579
    TCGv r_temp;
580
    int l1;
581

    
582
    l1 = gen_new_label();
583

    
584
    r_temp = tcg_temp_new(TCG_TYPE_TL);
585
    tcg_gen_xor_tl(r_temp, src1, src2);
586
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
587
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
588
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
589
    tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
590
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
591
    gen_set_label(l1);
592
}
593

    
594
static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2)
595
{
596
    tcg_gen_mov_tl(cpu_cc_src, src1);
597
    tcg_gen_mov_tl(cpu_cc_src2, src2);
598
    tcg_gen_sub_tl(dst, src1, src2);
599
    tcg_gen_mov_tl(cpu_cc_dst, dst);
600
    gen_cc_clear_icc();
601
    gen_cc_NZ_icc(cpu_cc_dst);
602
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
603
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
604
#ifdef TARGET_SPARC64
605
    gen_cc_clear_xcc();
606
    gen_cc_NZ_xcc(cpu_cc_dst);
607
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
608
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
609
#endif
610
}
611

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

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

    
655
static inline void gen_op_tsub_ccTV(TCGv dst, TCGv src1, TCGv src2)
656
{
657
    tcg_gen_mov_tl(cpu_cc_src, src1);
658
    tcg_gen_mov_tl(cpu_cc_src2, src2);
659
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
660
    tcg_gen_sub_tl(dst, src1, src2);
661
    tcg_gen_mov_tl(cpu_cc_dst, dst);
662
    gen_sub_tv(dst, cpu_cc_src, cpu_cc_src2);
663
    gen_cc_clear_icc();
664
    gen_cc_NZ_icc(cpu_cc_dst);
665
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
666
#ifdef TARGET_SPARC64
667
    gen_cc_clear_xcc();
668
    gen_cc_NZ_xcc(cpu_cc_dst);
669
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
670
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
671
#endif
672
}
673

    
674
static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
675
{
676
    TCGv r_temp, r_temp2;
677
    int l1;
678

    
679
    l1 = gen_new_label();
680
    r_temp = tcg_temp_new(TCG_TYPE_TL);
681
    r_temp2 = tcg_temp_new(TCG_TYPE_I32);
682

    
683
    /* old op:
684
    if (!(env->y & 1))
685
        T1 = 0;
686
    */
687
    tcg_gen_mov_tl(cpu_cc_src, src1);
688
    tcg_gen_ld32u_tl(r_temp, cpu_env, offsetof(CPUSPARCState, y));
689
    tcg_gen_trunc_tl_i32(r_temp2, r_temp);
690
    tcg_gen_andi_i32(r_temp2, r_temp2, 0x1);
691
    tcg_gen_mov_tl(cpu_cc_src2, src2);
692
    tcg_gen_brcond_i32(TCG_COND_NE, r_temp2, tcg_const_i32(0), l1);
693
    tcg_gen_movi_tl(cpu_cc_src2, 0);
694
    gen_set_label(l1);
695

    
696
    // b2 = T0 & 1;
697
    // env->y = (b2 << 31) | (env->y >> 1);
698
    tcg_gen_trunc_tl_i32(r_temp2, cpu_cc_src);
699
    tcg_gen_andi_i32(r_temp2, r_temp2, 0x1);
700
    tcg_gen_shli_i32(r_temp2, r_temp2, 31);
701
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, y));
702
    tcg_gen_shri_i32(cpu_tmp32, cpu_tmp32, 1);
703
    tcg_gen_or_i32(cpu_tmp32, cpu_tmp32, r_temp2);
704
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, y));
705

    
706
    // b1 = N ^ V;
707
    gen_mov_reg_N(cpu_tmp0, cpu_psr);
708
    gen_mov_reg_V(r_temp, cpu_psr);
709
    tcg_gen_xor_tl(cpu_tmp0, cpu_tmp0, r_temp);
710

    
711
    // T0 = (b1 << 31) | (T0 >> 1);
712
    // src1 = T0;
713
    tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
714
    tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
715
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
716

    
717
    /* do addition and update flags */
718
    tcg_gen_add_tl(dst, cpu_cc_src, cpu_cc_src2);
719
    tcg_gen_mov_tl(cpu_cc_dst, dst);
720

    
721
    gen_cc_clear_icc();
722
    gen_cc_NZ_icc(cpu_cc_dst);
723
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
724
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
725
}
726

    
727
static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
728
{
729
    TCGv r_temp, r_temp2;
730

    
731
    r_temp = tcg_temp_new(TCG_TYPE_I64);
732
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);
733

    
734
    tcg_gen_extu_tl_i64(r_temp, src2);
735
    tcg_gen_extu_tl_i64(r_temp2, src1);
736
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
737

    
738
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
739
    tcg_gen_trunc_i64_i32(r_temp, r_temp);
740
    tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
741
#ifdef TARGET_SPARC64
742
    tcg_gen_mov_i64(dst, r_temp2);
743
#else
744
    tcg_gen_trunc_i64_tl(dst, r_temp2);
745
#endif
746
}
747

    
748
static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
749
{
750
    TCGv r_temp, r_temp2;
751

    
752
    r_temp = tcg_temp_new(TCG_TYPE_I64);
753
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);
754

    
755
    tcg_gen_ext_tl_i64(r_temp, src2);
756
    tcg_gen_ext_tl_i64(r_temp2, src1);
757
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
758

    
759
    tcg_gen_shri_i64(r_temp, r_temp2, 32);
760
    tcg_gen_trunc_i64_i32(r_temp, r_temp);
761
    tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
762
#ifdef TARGET_SPARC64
763
    tcg_gen_mov_i64(dst, r_temp2);
764
#else
765
    tcg_gen_trunc_i64_tl(dst, r_temp2);
766
#endif
767
}
768

    
769
#ifdef TARGET_SPARC64
770
static inline void gen_trap_ifdivzero_tl(TCGv divisor)
771
{
772
    int l1;
773

    
774
    l1 = gen_new_label();
775
    tcg_gen_brcond_tl(TCG_COND_NE, divisor, tcg_const_tl(0), l1);
776
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_DIV_ZERO));
777
    gen_set_label(l1);
778
}
779

    
780
static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
781
{
782
    int l1, l2;
783

    
784
    l1 = gen_new_label();
785
    l2 = gen_new_label();
786
    tcg_gen_mov_tl(cpu_cc_src, src1);
787
    tcg_gen_mov_tl(cpu_cc_src2, src2);
788
    gen_trap_ifdivzero_tl(src2);
789
    tcg_gen_brcond_tl(TCG_COND_NE, cpu_cc_src, tcg_const_tl(INT64_MIN), l1);
790
    tcg_gen_brcond_tl(TCG_COND_NE, cpu_cc_src2, tcg_const_tl(-1), l1);
791
    tcg_gen_movi_i64(dst, INT64_MIN);
792
    tcg_gen_br(l2);
793
    gen_set_label(l1);
794
    tcg_gen_div_i64(dst, cpu_cc_src, cpu_cc_src2);
795
    gen_set_label(l2);
796
}
797
#endif
798

    
799
static inline void gen_op_div_cc(TCGv dst)
800
{
801
    int l1;
802

    
803
    tcg_gen_mov_tl(cpu_cc_dst, dst);
804
    gen_cc_clear_icc();
805
    gen_cc_NZ_icc(cpu_cc_dst);
806
    l1 = gen_new_label();
807
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, cc_src2));
808
    tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
809
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
810
    gen_set_label(l1);
811
}
812

    
813
static inline void gen_op_logic_cc(TCGv dst)
814
{
815
    tcg_gen_mov_tl(cpu_cc_dst, dst);
816

    
817
    gen_cc_clear_icc();
818
    gen_cc_NZ_icc(cpu_cc_dst);
819
#ifdef TARGET_SPARC64
820
    gen_cc_clear_xcc();
821
    gen_cc_NZ_xcc(cpu_cc_dst);
822
#endif
823
}
824

    
825
// 1
826
static inline void gen_op_eval_ba(TCGv dst)
827
{
828
    tcg_gen_movi_tl(dst, 1);
829
}
830

    
831
// Z
832
static inline void gen_op_eval_be(TCGv dst, TCGv src)
833
{
834
    gen_mov_reg_Z(dst, src);
835
}
836

    
837
// Z | (N ^ V)
838
static inline void gen_op_eval_ble(TCGv dst, TCGv src)
839
{
840
    gen_mov_reg_N(cpu_tmp0, src);
841
    gen_mov_reg_V(dst, src);
842
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
843
    gen_mov_reg_Z(cpu_tmp0, src);
844
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
845
}
846

    
847
// N ^ V
848
static inline void gen_op_eval_bl(TCGv dst, TCGv src)
849
{
850
    gen_mov_reg_V(cpu_tmp0, src);
851
    gen_mov_reg_N(dst, src);
852
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
853
}
854

    
855
// C | Z
856
static inline void gen_op_eval_bleu(TCGv dst, TCGv src)
857
{
858
    gen_mov_reg_Z(cpu_tmp0, src);
859
    gen_mov_reg_C(dst, src);
860
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
861
}
862

    
863
// C
864
static inline void gen_op_eval_bcs(TCGv dst, TCGv src)
865
{
866
    gen_mov_reg_C(dst, src);
867
}
868

    
869
// V
870
static inline void gen_op_eval_bvs(TCGv dst, TCGv src)
871
{
872
    gen_mov_reg_V(dst, src);
873
}
874

    
875
// 0
876
static inline void gen_op_eval_bn(TCGv dst)
877
{
878
    tcg_gen_movi_tl(dst, 0);
879
}
880

    
881
// N
882
static inline void gen_op_eval_bneg(TCGv dst, TCGv src)
883
{
884
    gen_mov_reg_N(dst, src);
885
}
886

    
887
// !Z
888
static inline void gen_op_eval_bne(TCGv dst, TCGv src)
889
{
890
    gen_mov_reg_Z(dst, src);
891
    tcg_gen_xori_tl(dst, dst, 0x1);
892
}
893

    
894
// !(Z | (N ^ V))
895
static inline void gen_op_eval_bg(TCGv dst, TCGv src)
896
{
897
    gen_mov_reg_N(cpu_tmp0, src);
898
    gen_mov_reg_V(dst, src);
899
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
900
    gen_mov_reg_Z(cpu_tmp0, src);
901
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
902
    tcg_gen_xori_tl(dst, dst, 0x1);
903
}
904

    
905
// !(N ^ V)
906
static inline void gen_op_eval_bge(TCGv dst, TCGv src)
907
{
908
    gen_mov_reg_V(cpu_tmp0, src);
909
    gen_mov_reg_N(dst, src);
910
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
911
    tcg_gen_xori_tl(dst, dst, 0x1);
912
}
913

    
914
// !(C | Z)
915
static inline void gen_op_eval_bgu(TCGv dst, TCGv src)
916
{
917
    gen_mov_reg_Z(cpu_tmp0, src);
918
    gen_mov_reg_C(dst, src);
919
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
920
    tcg_gen_xori_tl(dst, dst, 0x1);
921
}
922

    
923
// !C
924
static inline void gen_op_eval_bcc(TCGv dst, TCGv src)
925
{
926
    gen_mov_reg_C(dst, src);
927
    tcg_gen_xori_tl(dst, dst, 0x1);
928
}
929

    
930
// !N
931
static inline void gen_op_eval_bpos(TCGv dst, TCGv src)
932
{
933
    gen_mov_reg_N(dst, src);
934
    tcg_gen_xori_tl(dst, dst, 0x1);
935
}
936

    
937
// !V
938
static inline void gen_op_eval_bvc(TCGv dst, TCGv src)
939
{
940
    gen_mov_reg_V(dst, src);
941
    tcg_gen_xori_tl(dst, dst, 0x1);
942
}
943

    
944
/*
945
  FPSR bit field FCC1 | FCC0:
946
   0 =
947
   1 <
948
   2 >
949
   3 unordered
950
*/
951
static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src,
952
                                    unsigned int fcc_offset)
953
{
954
    tcg_gen_extu_i32_tl(reg, src);
955
    tcg_gen_shri_tl(reg, reg, FSR_FCC0_SHIFT + fcc_offset);
956
    tcg_gen_andi_tl(reg, reg, 0x1);
957
}
958

    
959
static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
960
                                    unsigned int fcc_offset)
961
{
962
    tcg_gen_extu_i32_tl(reg, src);
963
    tcg_gen_shri_tl(reg, reg, FSR_FCC1_SHIFT + fcc_offset);
964
    tcg_gen_andi_tl(reg, reg, 0x1);
965
}
966

    
967
// !0: FCC0 | FCC1
968
static inline void gen_op_eval_fbne(TCGv dst, TCGv src,
969
                                    unsigned int fcc_offset)
970
{
971
    gen_mov_reg_FCC0(dst, src, fcc_offset);
972
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
973
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
974
}
975

    
976
// 1 or 2: FCC0 ^ FCC1
977
static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
978
                                    unsigned int fcc_offset)
979
{
980
    gen_mov_reg_FCC0(dst, src, fcc_offset);
981
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
982
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
983
}
984

    
985
// 1 or 3: FCC0
986
static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
987
                                    unsigned int fcc_offset)
988
{
989
    gen_mov_reg_FCC0(dst, src, fcc_offset);
990
}
991

    
992
// 1: FCC0 & !FCC1
993
static inline void gen_op_eval_fbl(TCGv dst, TCGv src,
994
                                    unsigned int fcc_offset)
995
{
996
    gen_mov_reg_FCC0(dst, src, fcc_offset);
997
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
998
    tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
999
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1000
}
1001

    
1002
// 2 or 3: FCC1
1003
static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
1004
                                    unsigned int fcc_offset)
1005
{
1006
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1007
}
1008

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

    
1019
// 3: FCC0 & FCC1
1020
static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
1021
                                    unsigned int fcc_offset)
1022
{
1023
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1024
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1025
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1026
}
1027

    
1028
// 0: !(FCC0 | FCC1)
1029
static inline void gen_op_eval_fbe(TCGv dst, TCGv src,
1030
                                    unsigned int fcc_offset)
1031
{
1032
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1033
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1034
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
1035
    tcg_gen_xori_tl(dst, dst, 0x1);
1036
}
1037

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

    
1048
// 0 or 2: !FCC0
1049
static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
1050
                                    unsigned int fcc_offset)
1051
{
1052
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1053
    tcg_gen_xori_tl(dst, dst, 0x1);
1054
}
1055

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

    
1067
// 0 or 1: !FCC1
1068
static inline void gen_op_eval_fble(TCGv dst, TCGv src,
1069
                                    unsigned int fcc_offset)
1070
{
1071
    gen_mov_reg_FCC1(dst, src, fcc_offset);
1072
    tcg_gen_xori_tl(dst, dst, 0x1);
1073
}
1074

    
1075
// !2: !(!FCC0 & FCC1)
1076
static inline void gen_op_eval_fbule(TCGv dst, TCGv src,
1077
                                    unsigned int fcc_offset)
1078
{
1079
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1080
    tcg_gen_xori_tl(dst, dst, 0x1);
1081
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1082
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1083
    tcg_gen_xori_tl(dst, dst, 0x1);
1084
}
1085

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

    
1096
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
1097
                               target_ulong pc2, TCGv r_cond)
1098
{
1099
    int l1;
1100

    
1101
    l1 = gen_new_label();
1102

    
1103
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1104

    
1105
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
1106

    
1107
    gen_set_label(l1);
1108
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
1109
}
1110

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

    
1116
    l1 = gen_new_label();
1117

    
1118
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1119

    
1120
    gen_goto_tb(dc, 0, pc2, pc1);
1121

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

    
1126
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
1127
                                      TCGv r_cond)
1128
{
1129
    int l1, l2;
1130

    
1131
    l1 = gen_new_label();
1132
    l2 = gen_new_label();
1133

    
1134
    tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
1135

    
1136
    tcg_gen_movi_tl(cpu_npc, npc1);
1137
    tcg_gen_br(l2);
1138

    
1139
    gen_set_label(l1);
1140
    tcg_gen_movi_tl(cpu_npc, npc2);
1141
    gen_set_label(l2);
1142
}
1143

    
1144
/* call this function before using the condition register as it may
1145
   have been set for a jump */
1146
static inline void flush_cond(DisasContext *dc, TCGv cond)
1147
{
1148
    if (dc->npc == JUMP_PC) {
1149
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1150
        dc->npc = DYNAMIC_PC;
1151
    }
1152
}
1153

    
1154
static inline void save_npc(DisasContext *dc, TCGv cond)
1155
{
1156
    if (dc->npc == JUMP_PC) {
1157
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1158
        dc->npc = DYNAMIC_PC;
1159
    } else if (dc->npc != DYNAMIC_PC) {
1160
        tcg_gen_movi_tl(cpu_npc, dc->npc);
1161
    }
1162
}
1163

    
1164
static inline void save_state(DisasContext *dc, TCGv cond)
1165
{
1166
    tcg_gen_movi_tl(cpu_pc, dc->pc);
1167
    save_npc(dc, cond);
1168
}
1169

    
1170
static inline void gen_mov_pc_npc(DisasContext *dc, TCGv cond)
1171
{
1172
    if (dc->npc == JUMP_PC) {
1173
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1174
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1175
        dc->pc = DYNAMIC_PC;
1176
    } else if (dc->npc == DYNAMIC_PC) {
1177
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
1178
        dc->pc = DYNAMIC_PC;
1179
    } else {
1180
        dc->pc = dc->npc;
1181
    }
1182
}
1183

    
1184
static inline void gen_op_next_insn(void)
1185
{
1186
    tcg_gen_mov_tl(cpu_pc, cpu_npc);
1187
    tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
1188
}
1189

    
1190
static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond)
1191
{
1192
    TCGv r_src;
1193

    
1194
#ifdef TARGET_SPARC64
1195
    if (cc)
1196
        r_src = cpu_xcc;
1197
    else
1198
        r_src = cpu_psr;
1199
#else
1200
    r_src = cpu_psr;
1201
#endif
1202
    switch (cond) {
1203
    case 0x0:
1204
        gen_op_eval_bn(r_dst);
1205
        break;
1206
    case 0x1:
1207
        gen_op_eval_be(r_dst, r_src);
1208
        break;
1209
    case 0x2:
1210
        gen_op_eval_ble(r_dst, r_src);
1211
        break;
1212
    case 0x3:
1213
        gen_op_eval_bl(r_dst, r_src);
1214
        break;
1215
    case 0x4:
1216
        gen_op_eval_bleu(r_dst, r_src);
1217
        break;
1218
    case 0x5:
1219
        gen_op_eval_bcs(r_dst, r_src);
1220
        break;
1221
    case 0x6:
1222
        gen_op_eval_bneg(r_dst, r_src);
1223
        break;
1224
    case 0x7:
1225
        gen_op_eval_bvs(r_dst, r_src);
1226
        break;
1227
    case 0x8:
1228
        gen_op_eval_ba(r_dst);
1229
        break;
1230
    case 0x9:
1231
        gen_op_eval_bne(r_dst, r_src);
1232
        break;
1233
    case 0xa:
1234
        gen_op_eval_bg(r_dst, r_src);
1235
        break;
1236
    case 0xb:
1237
        gen_op_eval_bge(r_dst, r_src);
1238
        break;
1239
    case 0xc:
1240
        gen_op_eval_bgu(r_dst, r_src);
1241
        break;
1242
    case 0xd:
1243
        gen_op_eval_bcc(r_dst, r_src);
1244
        break;
1245
    case 0xe:
1246
        gen_op_eval_bpos(r_dst, r_src);
1247
        break;
1248
    case 0xf:
1249
        gen_op_eval_bvc(r_dst, r_src);
1250
        break;
1251
    }
1252
}
1253

    
1254
static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
1255
{
1256
    unsigned int offset;
1257

    
1258
    switch (cc) {
1259
    default:
1260
    case 0x0:
1261
        offset = 0;
1262
        break;
1263
    case 0x1:
1264
        offset = 32 - 10;
1265
        break;
1266
    case 0x2:
1267
        offset = 34 - 10;
1268
        break;
1269
    case 0x3:
1270
        offset = 36 - 10;
1271
        break;
1272
    }
1273

    
1274
    switch (cond) {
1275
    case 0x0:
1276
        gen_op_eval_bn(r_dst);
1277
        break;
1278
    case 0x1:
1279
        gen_op_eval_fbne(r_dst, cpu_fsr, offset);
1280
        break;
1281
    case 0x2:
1282
        gen_op_eval_fblg(r_dst, cpu_fsr, offset);
1283
        break;
1284
    case 0x3:
1285
        gen_op_eval_fbul(r_dst, cpu_fsr, offset);
1286
        break;
1287
    case 0x4:
1288
        gen_op_eval_fbl(r_dst, cpu_fsr, offset);
1289
        break;
1290
    case 0x5:
1291
        gen_op_eval_fbug(r_dst, cpu_fsr, offset);
1292
        break;
1293
    case 0x6:
1294
        gen_op_eval_fbg(r_dst, cpu_fsr, offset);
1295
        break;
1296
    case 0x7:
1297
        gen_op_eval_fbu(r_dst, cpu_fsr, offset);
1298
        break;
1299
    case 0x8:
1300
        gen_op_eval_ba(r_dst);
1301
        break;
1302
    case 0x9:
1303
        gen_op_eval_fbe(r_dst, cpu_fsr, offset);
1304
        break;
1305
    case 0xa:
1306
        gen_op_eval_fbue(r_dst, cpu_fsr, offset);
1307
        break;
1308
    case 0xb:
1309
        gen_op_eval_fbge(r_dst, cpu_fsr, offset);
1310
        break;
1311
    case 0xc:
1312
        gen_op_eval_fbuge(r_dst, cpu_fsr, offset);
1313
        break;
1314
    case 0xd:
1315
        gen_op_eval_fble(r_dst, cpu_fsr, offset);
1316
        break;
1317
    case 0xe:
1318
        gen_op_eval_fbule(r_dst, cpu_fsr, offset);
1319
        break;
1320
    case 0xf:
1321
        gen_op_eval_fbo(r_dst, cpu_fsr, offset);
1322
        break;
1323
    }
1324
}
1325

    
1326
#ifdef TARGET_SPARC64
1327
// Inverted logic
1328
static const int gen_tcg_cond_reg[8] = {
1329
    -1,
1330
    TCG_COND_NE,
1331
    TCG_COND_GT,
1332
    TCG_COND_GE,
1333
    -1,
1334
    TCG_COND_EQ,
1335
    TCG_COND_LE,
1336
    TCG_COND_LT,
1337
};
1338

    
1339
static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
1340
{
1341
    int l1;
1342

    
1343
    l1 = gen_new_label();
1344
    tcg_gen_movi_tl(r_dst, 0);
1345
    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], r_src, tcg_const_tl(0), l1);
1346
    tcg_gen_movi_tl(r_dst, 1);
1347
    gen_set_label(l1);
1348
}
1349
#endif
1350

    
1351
/* XXX: potentially incorrect if dynamic npc */
1352
static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
1353
                      TCGv r_cond)
1354
{
1355
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1356
    target_ulong target = dc->pc + offset;
1357

    
1358
    if (cond == 0x0) {
1359
        /* unconditional not taken */
1360
        if (a) {
1361
            dc->pc = dc->npc + 4;
1362
            dc->npc = dc->pc + 4;
1363
        } else {
1364
            dc->pc = dc->npc;
1365
            dc->npc = dc->pc + 4;
1366
        }
1367
    } else if (cond == 0x8) {
1368
        /* unconditional taken */
1369
        if (a) {
1370
            dc->pc = target;
1371
            dc->npc = dc->pc + 4;
1372
        } else {
1373
            dc->pc = dc->npc;
1374
            dc->npc = target;
1375
        }
1376
    } else {
1377
        flush_cond(dc, r_cond);
1378
        gen_cond(r_cond, cc, cond);
1379
        if (a) {
1380
            gen_branch_a(dc, target, dc->npc, r_cond);
1381
            dc->is_br = 1;
1382
        } else {
1383
            dc->pc = dc->npc;
1384
            dc->jump_pc[0] = target;
1385
            dc->jump_pc[1] = dc->npc + 4;
1386
            dc->npc = JUMP_PC;
1387
        }
1388
    }
1389
}
1390

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

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

    
1431
#ifdef TARGET_SPARC64
1432
/* XXX: potentially incorrect if dynamic npc */
1433
static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
1434
                          TCGv r_cond, TCGv r_reg)
1435
{
1436
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1437
    target_ulong target = dc->pc + offset;
1438

    
1439
    flush_cond(dc, r_cond);
1440
    gen_cond_reg(r_cond, cond, r_reg);
1441
    if (a) {
1442
        gen_branch_a(dc, target, dc->npc, r_cond);
1443
        dc->is_br = 1;
1444
    } else {
1445
        dc->pc = dc->npc;
1446
        dc->jump_pc[0] = target;
1447
        dc->jump_pc[1] = dc->npc + 4;
1448
        dc->npc = JUMP_PC;
1449
    }
1450
}
1451

    
1452
static GenOpFunc * const gen_fcmps[4] = {
1453
    helper_fcmps,
1454
    helper_fcmps_fcc1,
1455
    helper_fcmps_fcc2,
1456
    helper_fcmps_fcc3,
1457
};
1458

    
1459
static GenOpFunc * const gen_fcmpd[4] = {
1460
    helper_fcmpd,
1461
    helper_fcmpd_fcc1,
1462
    helper_fcmpd_fcc2,
1463
    helper_fcmpd_fcc3,
1464
};
1465

    
1466
#if defined(CONFIG_USER_ONLY)
1467
static GenOpFunc * const gen_fcmpq[4] = {
1468
    helper_fcmpq,
1469
    helper_fcmpq_fcc1,
1470
    helper_fcmpq_fcc2,
1471
    helper_fcmpq_fcc3,
1472
};
1473
#endif
1474

    
1475
static GenOpFunc * const gen_fcmpes[4] = {
1476
    helper_fcmpes,
1477
    helper_fcmpes_fcc1,
1478
    helper_fcmpes_fcc2,
1479
    helper_fcmpes_fcc3,
1480
};
1481

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

    
1489
#if defined(CONFIG_USER_ONLY)
1490
static GenOpFunc * const gen_fcmpeq[4] = {
1491
    helper_fcmpeq,
1492
    helper_fcmpeq_fcc1,
1493
    helper_fcmpeq_fcc2,
1494
    helper_fcmpeq_fcc3,
1495
};
1496
#endif
1497

    
1498
static inline void gen_op_fcmps(int fccno)
1499
{
1500
    tcg_gen_helper_0_0(gen_fcmps[fccno]);
1501
}
1502

    
1503
static inline void gen_op_fcmpd(int fccno)
1504
{
1505
    tcg_gen_helper_0_0(gen_fcmpd[fccno]);
1506
}
1507

    
1508
#if defined(CONFIG_USER_ONLY)
1509
static inline void gen_op_fcmpq(int fccno)
1510
{
1511
    tcg_gen_helper_0_0(gen_fcmpq[fccno]);
1512
}
1513
#endif
1514

    
1515
static inline void gen_op_fcmpes(int fccno)
1516
{
1517
    tcg_gen_helper_0_0(gen_fcmpes[fccno]);
1518
}
1519

    
1520
static inline void gen_op_fcmped(int fccno)
1521
{
1522
    tcg_gen_helper_0_0(gen_fcmped[fccno]);
1523
}
1524

    
1525
#if defined(CONFIG_USER_ONLY)
1526
static inline void gen_op_fcmpeq(int fccno)
1527
{
1528
    tcg_gen_helper_0_0(gen_fcmpeq[fccno]);
1529
}
1530
#endif
1531

    
1532
#else
1533

    
1534
static inline void gen_op_fcmps(int fccno)
1535
{
1536
    tcg_gen_helper_0_0(helper_fcmps);
1537
}
1538

    
1539
static inline void gen_op_fcmpd(int fccno)
1540
{
1541
    tcg_gen_helper_0_0(helper_fcmpd);
1542
}
1543

    
1544
#if defined(CONFIG_USER_ONLY)
1545
static inline void gen_op_fcmpq(int fccno)
1546
{
1547
    tcg_gen_helper_0_0(helper_fcmpq);
1548
}
1549
#endif
1550

    
1551
static inline void gen_op_fcmpes(int fccno)
1552
{
1553
    tcg_gen_helper_0_0(helper_fcmpes);
1554
}
1555

    
1556
static inline void gen_op_fcmped(int fccno)
1557
{
1558
    tcg_gen_helper_0_0(helper_fcmped);
1559
}
1560

    
1561
#if defined(CONFIG_USER_ONLY)
1562
static inline void gen_op_fcmpeq(int fccno)
1563
{
1564
    tcg_gen_helper_0_0(helper_fcmpeq);
1565
}
1566
#endif
1567

    
1568
#endif
1569

    
1570
static inline void gen_op_fpexception_im(int fsr_flags)
1571
{
1572
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~FSR_FTT_MASK);
1573
    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
1574
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_FP_EXCP));
1575
}
1576

    
1577
static int gen_trap_ifnofpu(DisasContext *dc, TCGv r_cond)
1578
{
1579
#if !defined(CONFIG_USER_ONLY)
1580
    if (!dc->fpu_enabled) {
1581
        save_state(dc, r_cond);
1582
        tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_NFPU_INSN));
1583
        dc->is_br = 1;
1584
        return 1;
1585
    }
1586
#endif
1587
    return 0;
1588
}
1589

    
1590
static inline void gen_op_clear_ieee_excp_and_FTT(void)
1591
{
1592
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~(FSR_FTT_MASK | FSR_CEXC_MASK));
1593
}
1594

    
1595
static inline void gen_clear_float_exceptions(void)
1596
{
1597
    tcg_gen_helper_0_0(helper_clear_float_exceptions);
1598
}
1599

    
1600
/* asi moves */
1601
#ifdef TARGET_SPARC64
1602
static inline TCGv gen_get_asi(int insn, TCGv r_addr)
1603
{
1604
    int asi, offset;
1605
    TCGv r_asi;
1606

    
1607
    if (IS_IMM) {
1608
        r_asi = tcg_temp_new(TCG_TYPE_I32);
1609
        offset = GET_FIELD(insn, 25, 31);
1610
        tcg_gen_addi_tl(r_addr, r_addr, offset);
1611
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
1612
    } else {
1613
        asi = GET_FIELD(insn, 19, 26);
1614
        r_asi = tcg_const_i32(asi);
1615
    }
1616
    return r_asi;
1617
}
1618

    
1619
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size, int sign)
1620
{
1621
    TCGv r_asi;
1622

    
1623
    r_asi = gen_get_asi(insn, addr);
1624
    tcg_gen_helper_1_4(helper_ld_asi, dst, addr, r_asi,
1625
                       tcg_const_i32(size), tcg_const_i32(sign));
1626
}
1627

    
1628
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1629
{
1630
    TCGv r_asi;
1631

    
1632
    r_asi = gen_get_asi(insn, addr);
1633
    tcg_gen_helper_0_4(helper_st_asi, addr, src, r_asi, tcg_const_i32(size));
1634
}
1635

    
1636
static inline void gen_ldf_asi(TCGv addr, int insn, int size, int rd)
1637
{
1638
    TCGv r_asi;
1639

    
1640
    r_asi = gen_get_asi(insn, addr);
1641
    tcg_gen_helper_0_4(helper_ldf_asi, addr, r_asi, tcg_const_i32(size),
1642
                       tcg_const_i32(rd));
1643
}
1644

    
1645
static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
1646
{
1647
    TCGv r_asi;
1648

    
1649
    r_asi = gen_get_asi(insn, addr);
1650
    tcg_gen_helper_0_4(helper_stf_asi, addr, r_asi, tcg_const_i32(size),
1651
                       tcg_const_i32(rd));
1652
}
1653

    
1654
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1655
{
1656
    TCGv r_temp, r_asi;
1657

    
1658
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1659
    r_asi = gen_get_asi(insn, addr);
1660
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, addr, r_asi,
1661
                       tcg_const_i32(4), tcg_const_i32(0));
1662
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, r_asi,
1663
                       tcg_const_i32(4));
1664
    tcg_gen_extu_i32_tl(dst, r_temp);
1665
}
1666

    
1667
static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn)
1668
{
1669
    TCGv r_asi;
1670

    
1671
    r_asi = gen_get_asi(insn, addr);
1672
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi,
1673
                       tcg_const_i32(8), tcg_const_i32(0));
1674
    tcg_gen_andi_i64(lo, cpu_tmp64, 0xffffffffULL);
1675
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1676
    tcg_gen_andi_i64(hi, cpu_tmp64, 0xffffffffULL);
1677
}
1678

    
1679
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1680
{
1681
    TCGv r_temp, r_asi;
1682

    
1683
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1684
    gen_movl_reg_TN(rd + 1, r_temp);
1685
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi,
1686
                       r_temp);
1687
    r_asi = gen_get_asi(insn, addr);
1688
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi,
1689
                       tcg_const_i32(8));
1690
}
1691

    
1692
static inline void gen_cas_asi(TCGv dst, TCGv addr, TCGv val2, int insn, int rd)
1693
{
1694
    TCGv r_val1, r_asi;
1695

    
1696
    r_val1 = tcg_temp_new(TCG_TYPE_I32);
1697
    gen_movl_reg_TN(rd, r_val1);
1698
    r_asi = gen_get_asi(insn, addr);
1699
    tcg_gen_helper_1_4(helper_cas_asi, dst, addr, r_val1, val2, r_asi);
1700
}
1701

    
1702
static inline void gen_casx_asi(TCGv dst, TCGv addr, TCGv val2, int insn, int rd)
1703
{
1704
    TCGv r_asi;
1705

    
1706
    gen_movl_reg_TN(rd, cpu_tmp64);
1707
    r_asi = gen_get_asi(insn, addr);
1708
    tcg_gen_helper_1_4(helper_casx_asi, dst, addr, cpu_tmp64, val2, r_asi);
1709
}
1710

    
1711
#elif !defined(CONFIG_USER_ONLY)
1712

    
1713
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size, int sign)
1714
{
1715
    int asi;
1716

    
1717
    asi = GET_FIELD(insn, 19, 26);
1718
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, tcg_const_i32(asi),
1719
                       tcg_const_i32(size), tcg_const_i32(sign));
1720
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1721
}
1722

    
1723
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1724
{
1725
    int asi;
1726

    
1727
    tcg_gen_extu_tl_i64(cpu_tmp64, src);
1728
    asi = GET_FIELD(insn, 19, 26);
1729
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, tcg_const_i32(asi),
1730
                       tcg_const_i32(size));
1731
}
1732

    
1733
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1734
{
1735
    int asi;
1736
    TCGv r_temp;
1737

    
1738
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1739
    asi = GET_FIELD(insn, 19, 26);
1740
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, addr, tcg_const_i32(asi),
1741
                       tcg_const_i32(4), tcg_const_i32(0));
1742
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, tcg_const_i32(asi),
1743
                       tcg_const_i32(4));
1744
    tcg_gen_extu_i32_tl(dst, r_temp);
1745
}
1746

    
1747
static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn)
1748
{
1749
    int asi;
1750

    
1751
    asi = GET_FIELD(insn, 19, 26);
1752
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, tcg_const_i32(asi),
1753
                       tcg_const_i32(8), tcg_const_i32(0));
1754
    tcg_gen_trunc_i64_tl(lo, cpu_tmp64);
1755
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1756
    tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
1757
}
1758

    
1759
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1760
{
1761
    int asi;
1762
    TCGv r_temp;
1763

    
1764
    r_temp = tcg_temp_new(TCG_TYPE_I32);
1765
    gen_movl_reg_TN(rd + 1, r_temp);
1766
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi, r_temp);
1767
    asi = GET_FIELD(insn, 19, 26);
1768
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, tcg_const_i32(asi),
1769
                       tcg_const_i32(8));
1770
}
1771
#endif
1772

    
1773
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1774
static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
1775
{
1776
    int asi;
1777

    
1778
    gen_ld_asi(dst, addr, insn, 1, 0);
1779

    
1780
    asi = GET_FIELD(insn, 19, 26);
1781
    tcg_gen_helper_0_4(helper_st_asi, addr, tcg_const_i64(0xffULL),
1782
                       tcg_const_i32(asi), tcg_const_i32(1));
1783
}
1784
#endif
1785

    
1786
static inline TCGv get_src1(unsigned int insn, TCGv def)
1787
{
1788
    TCGv r_rs1 = def;
1789
    unsigned int rs1;
1790

    
1791
    rs1 = GET_FIELD(insn, 13, 17);
1792
    if (rs1 == 0)
1793
        //r_rs1 = tcg_const_tl(0);
1794
        tcg_gen_movi_tl(def, 0);
1795
    else if (rs1 < 8)
1796
        //r_rs1 = cpu_gregs[rs1];
1797
        tcg_gen_mov_tl(def, cpu_gregs[rs1]);
1798
    else
1799
        tcg_gen_ld_tl(def, cpu_regwptr, (rs1 - 8) * sizeof(target_ulong));
1800
    return r_rs1;
1801
}
1802

    
1803
static inline TCGv get_src2(unsigned int insn, TCGv def)
1804
{
1805
    TCGv r_rs2 = def;
1806
    unsigned int rs2;
1807

    
1808
    if (IS_IMM) { /* immediate */
1809
        rs2 = GET_FIELDs(insn, 19, 31);
1810
        r_rs2 = tcg_const_tl((int)rs2);
1811
    } else { /* register */
1812
        rs2 = GET_FIELD(insn, 27, 31);
1813
        if (rs2 == 0)
1814
            r_rs2 = tcg_const_tl(0);
1815
        else if (rs2 < 8)
1816
            r_rs2 = cpu_gregs[rs2];
1817
        else
1818
            tcg_gen_ld_tl(def, cpu_regwptr, (rs2 - 8) * sizeof(target_ulong));
1819
    }
1820
    return r_rs2;
1821
}
1822

    
1823
/* before an instruction, dc->pc must be static */
1824
static void disas_sparc_insn(DisasContext * dc)
1825
{
1826
    unsigned int insn, opc, rs1, rs2, rd;
1827

    
1828
    insn = ldl_code(dc->pc);
1829
    opc = GET_FIELD(insn, 0, 1);
1830

    
1831
    rd = GET_FIELD(insn, 2, 6);
1832

    
1833
    cpu_dst = cpu_T[0];
1834
    cpu_src1 = cpu_T[0]; // const
1835
    cpu_src2 = cpu_T[1]; // const
1836

    
1837
    // loads and stores
1838
    cpu_addr = cpu_T[0];
1839
    cpu_val = cpu_T[1];
1840

    
1841
    switch (opc) {
1842
    case 0:                     /* branches/sethi */
1843
        {
1844
            unsigned int xop = GET_FIELD(insn, 7, 9);
1845
            int32_t target;
1846
            switch (xop) {
1847
#ifdef TARGET_SPARC64
1848
            case 0x1:           /* V9 BPcc */
1849
                {
1850
                    int cc;
1851

    
1852
                    target = GET_FIELD_SP(insn, 0, 18);
1853
                    target = sign_extend(target, 18);
1854
                    target <<= 2;
1855
                    cc = GET_FIELD_SP(insn, 20, 21);
1856
                    if (cc == 0)
1857
                        do_branch(dc, target, insn, 0, cpu_cond);
1858
                    else if (cc == 2)
1859
                        do_branch(dc, target, insn, 1, cpu_cond);
1860
                    else
1861
                        goto illegal_insn;
1862
                    goto jmp_insn;
1863
                }
1864
            case 0x3:           /* V9 BPr */
1865
                {
1866
                    target = GET_FIELD_SP(insn, 0, 13) |
1867
                        (GET_FIELD_SP(insn, 20, 21) << 14);
1868
                    target = sign_extend(target, 16);
1869
                    target <<= 2;
1870
                    cpu_src1 = get_src1(insn, cpu_src1);
1871
                    do_branch_reg(dc, target, insn, cpu_cond, cpu_src1);
1872
                    goto jmp_insn;
1873
                }
1874
            case 0x5:           /* V9 FBPcc */
1875
                {
1876
                    int cc = GET_FIELD_SP(insn, 20, 21);
1877
                    if (gen_trap_ifnofpu(dc, cpu_cond))
1878
                        goto jmp_insn;
1879
                    target = GET_FIELD_SP(insn, 0, 18);
1880
                    target = sign_extend(target, 19);
1881
                    target <<= 2;
1882
                    do_fbranch(dc, target, insn, cc, cpu_cond);
1883
                    goto jmp_insn;
1884
                }
1885
#else
1886
            case 0x7:           /* CBN+x */
1887
                {
1888
                    goto ncp_insn;
1889
                }
1890
#endif
1891
            case 0x2:           /* BN+x */
1892
                {
1893
                    target = GET_FIELD(insn, 10, 31);
1894
                    target = sign_extend(target, 22);
1895
                    target <<= 2;
1896
                    do_branch(dc, target, insn, 0, cpu_cond);
1897
                    goto jmp_insn;
1898
                }
1899
            case 0x6:           /* FBN+x */
1900
                {
1901
                    if (gen_trap_ifnofpu(dc, cpu_cond))
1902
                        goto jmp_insn;
1903
                    target = GET_FIELD(insn, 10, 31);
1904
                    target = sign_extend(target, 22);
1905
                    target <<= 2;
1906
                    do_fbranch(dc, target, insn, 0, cpu_cond);
1907
                    goto jmp_insn;
1908
                }
1909
            case 0x4:           /* SETHI */
1910
                if (rd) { // nop
1911
                    uint32_t value = GET_FIELD(insn, 10, 31);
1912
                    gen_movl_TN_reg(rd, tcg_const_tl(value << 10));
1913
                }
1914
                break;
1915
            case 0x0:           /* UNIMPL */
1916
            default:
1917
                goto illegal_insn;
1918
            }
1919
            break;
1920
        }
1921
        break;
1922
    case 1:
1923
        /*CALL*/ {
1924
            target_long target = GET_FIELDs(insn, 2, 31) << 2;
1925

    
1926
            gen_movl_TN_reg(15, tcg_const_tl(dc->pc));
1927
            target += dc->pc;
1928
            gen_mov_pc_npc(dc, cpu_cond);
1929
            dc->npc = target;
1930
        }
1931
        goto jmp_insn;
1932
    case 2:                     /* FPU & Logical Operations */
1933
        {
1934
            unsigned int xop = GET_FIELD(insn, 7, 12);
1935
            if (xop == 0x3a) {  /* generate trap */
1936
                int cond;
1937

    
1938
                cpu_src1 = get_src1(insn, cpu_src1);
1939
                if (IS_IMM) {
1940
                    rs2 = GET_FIELD(insn, 25, 31);
1941
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, rs2);
1942
                } else {
1943
                    rs2 = GET_FIELD(insn, 27, 31);
1944
                    if (rs2 != 0) {
1945
                        gen_movl_reg_TN(rs2, cpu_src2);
1946
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
1947
                    } else
1948
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
1949
                }
1950
                cond = GET_FIELD(insn, 3, 6);
1951
                if (cond == 0x8) {
1952
                    save_state(dc, cpu_cond);
1953
                    tcg_gen_helper_0_1(helper_trap, cpu_dst);
1954
                } else if (cond != 0) {
1955
                    TCGv r_cond = tcg_temp_new(TCG_TYPE_TL);
1956
#ifdef TARGET_SPARC64
1957
                    /* V9 icc/xcc */
1958
                    int cc = GET_FIELD_SP(insn, 11, 12);
1959

    
1960
                    save_state(dc, cpu_cond);
1961
                    if (cc == 0)
1962
                        gen_cond(r_cond, 0, cond);
1963
                    else if (cc == 2)
1964
                        gen_cond(r_cond, 1, cond);
1965
                    else
1966
                        goto illegal_insn;
1967
#else
1968
                    save_state(dc, cpu_cond);
1969
                    gen_cond(r_cond, 0, cond);
1970
#endif
1971
                    tcg_gen_helper_0_2(helper_trapcc, cpu_dst, r_cond);
1972
                }
1973
                gen_op_next_insn();
1974
                tcg_gen_exit_tb(0);
1975
                dc->is_br = 1;
1976
                goto jmp_insn;
1977
            } else if (xop == 0x28) {
1978
                rs1 = GET_FIELD(insn, 13, 17);
1979
                switch(rs1) {
1980
                case 0: /* rdy */
1981
#ifndef TARGET_SPARC64
1982
                case 0x01 ... 0x0e: /* undefined in the SPARCv8
1983
                                       manual, rdy on the microSPARC
1984
                                       II */
1985
                case 0x0f:          /* stbar in the SPARCv8 manual,
1986
                                       rdy on the microSPARC II */
1987
                case 0x10 ... 0x1f: /* implementation-dependent in the
1988
                                       SPARCv8 manual, rdy on the
1989
                                       microSPARC II */
1990
#endif
1991
                    tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, y));
1992
                    gen_movl_TN_reg(rd, cpu_dst);
1993
                    break;
1994
#ifdef TARGET_SPARC64
1995
                case 0x2: /* V9 rdccr */
1996
                    tcg_gen_helper_1_0(helper_rdccr, cpu_dst);
1997
                    gen_movl_TN_reg(rd, cpu_dst);
1998
                    break;
1999
                case 0x3: /* V9 rdasi */
2000
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, asi));
2001
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2002
                    gen_movl_TN_reg(rd, cpu_dst);
2003
                    break;
2004
                case 0x4: /* V9 rdtick */
2005
                    {
2006
                        TCGv r_tickptr;
2007

    
2008
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2009
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2010
                                       offsetof(CPUState, tick));
2011
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst,
2012
                                           r_tickptr);
2013
                        gen_movl_TN_reg(rd, cpu_dst);
2014
                    }
2015
                    break;
2016
                case 0x5: /* V9 rdpc */
2017
                    gen_movl_TN_reg(rd, tcg_const_tl(dc->pc));
2018
                    break;
2019
                case 0x6: /* V9 rdfprs */
2020
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fprs));
2021
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2022
                    gen_movl_TN_reg(rd, cpu_dst);
2023
                    break;
2024
                case 0xf: /* V9 membar */
2025
                    break; /* no effect */
2026
                case 0x13: /* Graphics Status */
2027
                    if (gen_trap_ifnofpu(dc, cpu_cond))
2028
                        goto jmp_insn;
2029
                    tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, gsr));
2030
                    gen_movl_TN_reg(rd, cpu_dst);
2031
                    break;
2032
                case 0x17: /* Tick compare */
2033
                    tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, tick_cmpr));
2034
                    gen_movl_TN_reg(rd, cpu_dst);
2035
                    break;
2036
                case 0x18: /* System tick */
2037
                    {
2038
                        TCGv r_tickptr;
2039

    
2040
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2041
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2042
                                       offsetof(CPUState, stick));
2043
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst,
2044
                                           r_tickptr);
2045
                        gen_movl_TN_reg(rd, cpu_dst);
2046
                    }
2047
                    break;
2048
                case 0x19: /* System tick compare */
2049
                    tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, stick_cmpr));
2050
                    gen_movl_TN_reg(rd, cpu_dst);
2051
                    break;
2052
                case 0x10: /* Performance Control */
2053
                case 0x11: /* Performance Instrumentation Counter */
2054
                case 0x12: /* Dispatch Control */
2055
                case 0x14: /* Softint set, WO */
2056
                case 0x15: /* Softint clear, WO */
2057
                case 0x16: /* Softint write */
2058
#endif
2059
                default:
2060
                    goto illegal_insn;
2061
                }
2062
#if !defined(CONFIG_USER_ONLY)
2063
            } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
2064
#ifndef TARGET_SPARC64
2065
                if (!supervisor(dc))
2066
                    goto priv_insn;
2067
                tcg_gen_helper_1_0(helper_rdpsr, cpu_dst);
2068
#else
2069
                if (!hypervisor(dc))
2070
                    goto priv_insn;
2071
                rs1 = GET_FIELD(insn, 13, 17);
2072
                switch (rs1) {
2073
                case 0: // hpstate
2074
                    // gen_op_rdhpstate();
2075
                    break;
2076
                case 1: // htstate
2077
                    // gen_op_rdhtstate();
2078
                    break;
2079
                case 3: // hintp
2080
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, hintp));
2081
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2082
                    break;
2083
                case 5: // htba
2084
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, htba));
2085
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2086
                    break;
2087
                case 6: // hver
2088
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, hver));
2089
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2090
                    break;
2091
                case 31: // hstick_cmpr
2092
                    tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2093
                    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, hstick_cmpr));
2094
                    break;
2095
                default:
2096
                    goto illegal_insn;
2097
                }
2098
#endif
2099
                gen_movl_TN_reg(rd, cpu_dst);
2100
                break;
2101
            } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
2102
                if (!supervisor(dc))
2103
                    goto priv_insn;
2104
#ifdef TARGET_SPARC64
2105
                rs1 = GET_FIELD(insn, 13, 17);
2106
                switch (rs1) {
2107
                case 0: // tpc
2108
                    {
2109
                        TCGv r_tsptr;
2110

    
2111
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2112
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2113
                                       offsetof(CPUState, tsptr));
2114
                        tcg_gen_ld_tl(cpu_dst, r_tsptr,
2115
                                      offsetof(trap_state, tpc));
2116
                    }
2117
                    break;
2118
                case 1: // tnpc
2119
                    {
2120
                        TCGv r_tsptr;
2121

    
2122
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2123
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2124
                                       offsetof(CPUState, tsptr));
2125
                        tcg_gen_ld_tl(cpu_dst, r_tsptr,
2126
                                      offsetof(trap_state, tnpc));
2127
                    }
2128
                    break;
2129
                case 2: // tstate
2130
                    {
2131
                        TCGv r_tsptr;
2132

    
2133
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2134
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2135
                                       offsetof(CPUState, tsptr));
2136
                        tcg_gen_ld_tl(cpu_dst, r_tsptr,
2137
                                      offsetof(trap_state, tstate));
2138
                    }
2139
                    break;
2140
                case 3: // tt
2141
                    {
2142
                        TCGv r_tsptr;
2143

    
2144
                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2145
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
2146
                                       offsetof(CPUState, tsptr));
2147
                        tcg_gen_ld_i32(cpu_dst, r_tsptr,
2148
                                       offsetof(trap_state, tt));
2149
                    }
2150
                    break;
2151
                case 4: // tick
2152
                    {
2153
                        TCGv r_tickptr;
2154

    
2155
                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2156
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
2157
                                       offsetof(CPUState, tick));
2158
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst,
2159
                                           r_tickptr);
2160
                        gen_movl_TN_reg(rd, cpu_dst);
2161
                    }
2162
                    break;
2163
                case 5: // tba
2164
                    tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, tbr));
2165
                    break;
2166
                case 6: // pstate
2167
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, pstate));
2168
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2169
                    break;
2170
                case 7: // tl
2171
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, tl));
2172
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2173
                    break;
2174
                case 8: // pil
2175
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, psrpil));
2176
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2177
                    break;
2178
                case 9: // cwp
2179
                    tcg_gen_helper_1_0(helper_rdcwp, cpu_dst);
2180
                    break;
2181
                case 10: // cansave
2182
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, cansave));
2183
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2184
                    break;
2185
                case 11: // canrestore
2186
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, canrestore));
2187
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2188
                    break;
2189
                case 12: // cleanwin
2190
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, cleanwin));
2191
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2192
                    break;
2193
                case 13: // otherwin
2194
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, otherwin));
2195
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2196
                    break;
2197
                case 14: // wstate
2198
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, wstate));
2199
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2200
                    break;
2201
                case 16: // UA2005 gl
2202
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, gl));
2203
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2204
                    break;
2205
                case 26: // UA2005 strand status
2206
                    if (!hypervisor(dc))
2207
                        goto priv_insn;
2208
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ssr));
2209
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2210
                    break;
2211
                case 31: // ver
2212
                    tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, version));
2213
                    break;
2214
                case 15: // fq
2215
                default:
2216
                    goto illegal_insn;
2217
                }
2218
#else
2219
                tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, wim));
2220
                tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
2221
#endif
2222
                gen_movl_TN_reg(rd, cpu_dst);
2223
                break;
2224
            } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
2225
#ifdef TARGET_SPARC64
2226
                tcg_gen_helper_0_0(helper_flushw);
2227
#else
2228
                if (!supervisor(dc))
2229
                    goto priv_insn;
2230
                tcg_gen_ld_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, tbr));
2231
                gen_movl_TN_reg(rd, cpu_dst);
2232
#endif
2233
                break;
2234
#endif
2235
            } else if (xop == 0x34) {   /* FPU Operations */
2236
                if (gen_trap_ifnofpu(dc, cpu_cond))
2237
                    goto jmp_insn;
2238
                gen_op_clear_ieee_excp_and_FTT();
2239
                rs1 = GET_FIELD(insn, 13, 17);
2240
                rs2 = GET_FIELD(insn, 27, 31);
2241
                xop = GET_FIELD(insn, 18, 26);
2242
                switch (xop) {
2243
                    case 0x1: /* fmovs */
2244
                        gen_op_load_fpr_FT0(rs2);
2245
                        gen_op_store_FT0_fpr(rd);
2246
                        break;
2247
                    case 0x5: /* fnegs */
2248
                        gen_op_load_fpr_FT1(rs2);
2249
                        tcg_gen_helper_0_0(helper_fnegs);
2250
                        gen_op_store_FT0_fpr(rd);
2251
                        break;
2252
                    case 0x9: /* fabss */
2253
                        gen_op_load_fpr_FT1(rs2);
2254
                        tcg_gen_helper_0_0(helper_fabss);
2255
                        gen_op_store_FT0_fpr(rd);
2256
                        break;
2257
                    case 0x29: /* fsqrts */
2258
                        gen_op_load_fpr_FT1(rs2);
2259
                        gen_clear_float_exceptions();
2260
                        tcg_gen_helper_0_0(helper_fsqrts);
2261
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2262
                        gen_op_store_FT0_fpr(rd);
2263
                        break;
2264
                    case 0x2a: /* fsqrtd */
2265
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2266
                        gen_clear_float_exceptions();
2267
                        tcg_gen_helper_0_0(helper_fsqrtd);
2268
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2269
                        gen_op_store_DT0_fpr(DFPREG(rd));
2270
                        break;
2271
                    case 0x2b: /* fsqrtq */
2272
#if defined(CONFIG_USER_ONLY)
2273
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2274
                        gen_clear_float_exceptions();
2275
                        tcg_gen_helper_0_0(helper_fsqrtq);
2276
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2277
                        gen_op_store_QT0_fpr(QFPREG(rd));
2278
                        break;
2279
#else
2280
                        goto nfpu_insn;
2281
#endif
2282
                    case 0x41:
2283
                        gen_op_load_fpr_FT0(rs1);
2284
                        gen_op_load_fpr_FT1(rs2);
2285
                        gen_clear_float_exceptions();
2286
                        tcg_gen_helper_0_0(helper_fadds);
2287
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2288
                        gen_op_store_FT0_fpr(rd);
2289
                        break;
2290
                    case 0x42:
2291
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2292
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2293
                        gen_clear_float_exceptions();
2294
                        tcg_gen_helper_0_0(helper_faddd);
2295
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2296
                        gen_op_store_DT0_fpr(DFPREG(rd));
2297
                        break;
2298
                    case 0x43: /* faddq */
2299
#if defined(CONFIG_USER_ONLY)
2300
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2301
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2302
                        gen_clear_float_exceptions();
2303
                        tcg_gen_helper_0_0(helper_faddq);
2304
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2305
                        gen_op_store_QT0_fpr(QFPREG(rd));
2306
                        break;
2307
#else
2308
                        goto nfpu_insn;
2309
#endif
2310
                    case 0x45:
2311
                        gen_op_load_fpr_FT0(rs1);
2312
                        gen_op_load_fpr_FT1(rs2);
2313
                        gen_clear_float_exceptions();
2314
                        tcg_gen_helper_0_0(helper_fsubs);
2315
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2316
                        gen_op_store_FT0_fpr(rd);
2317
                        break;
2318
                    case 0x46:
2319
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2320
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2321
                        gen_clear_float_exceptions();
2322
                        tcg_gen_helper_0_0(helper_fsubd);
2323
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2324
                        gen_op_store_DT0_fpr(DFPREG(rd));
2325
                        break;
2326
                    case 0x47: /* fsubq */
2327
#if defined(CONFIG_USER_ONLY)
2328
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2329
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2330
                        gen_clear_float_exceptions();
2331
                        tcg_gen_helper_0_0(helper_fsubq);
2332
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2333
                        gen_op_store_QT0_fpr(QFPREG(rd));
2334
                        break;
2335
#else
2336
                        goto nfpu_insn;
2337
#endif
2338
                    case 0x49:
2339
                        gen_op_load_fpr_FT0(rs1);
2340
                        gen_op_load_fpr_FT1(rs2);
2341
                        gen_clear_float_exceptions();
2342
                        tcg_gen_helper_0_0(helper_fmuls);
2343
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2344
                        gen_op_store_FT0_fpr(rd);
2345
                        break;
2346
                    case 0x4a:
2347
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2348
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2349
                        gen_clear_float_exceptions();
2350
                        tcg_gen_helper_0_0(helper_fmuld);
2351
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2352
                        gen_op_store_DT0_fpr(DFPREG(rd));
2353
                        break;
2354
                    case 0x4b: /* fmulq */
2355
#if defined(CONFIG_USER_ONLY)
2356
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2357
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2358
                        gen_clear_float_exceptions();
2359
                        tcg_gen_helper_0_0(helper_fmulq);
2360
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2361
                        gen_op_store_QT0_fpr(QFPREG(rd));
2362
                        break;
2363
#else
2364
                        goto nfpu_insn;
2365
#endif
2366
                    case 0x4d:
2367
                        gen_op_load_fpr_FT0(rs1);
2368
                        gen_op_load_fpr_FT1(rs2);
2369
                        gen_clear_float_exceptions();
2370
                        tcg_gen_helper_0_0(helper_fdivs);
2371
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2372
                        gen_op_store_FT0_fpr(rd);
2373
                        break;
2374
                    case 0x4e:
2375
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2376
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2377
                        gen_clear_float_exceptions();
2378
                        tcg_gen_helper_0_0(helper_fdivd);
2379
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2380
                        gen_op_store_DT0_fpr(DFPREG(rd));
2381
                        break;
2382
                    case 0x4f: /* fdivq */
2383
#if defined(CONFIG_USER_ONLY)
2384
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2385
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2386
                        gen_clear_float_exceptions();
2387
                        tcg_gen_helper_0_0(helper_fdivq);
2388
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2389
                        gen_op_store_QT0_fpr(QFPREG(rd));
2390
                        break;
2391
#else
2392
                        goto nfpu_insn;
2393
#endif
2394
                    case 0x69:
2395
                        gen_op_load_fpr_FT0(rs1);
2396
                        gen_op_load_fpr_FT1(rs2);
2397
                        gen_clear_float_exceptions();
2398
                        tcg_gen_helper_0_0(helper_fsmuld);
2399
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2400
                        gen_op_store_DT0_fpr(DFPREG(rd));
2401
                        break;
2402
                    case 0x6e: /* fdmulq */
2403
#if defined(CONFIG_USER_ONLY)
2404
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2405
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2406
                        gen_clear_float_exceptions();
2407
                        tcg_gen_helper_0_0(helper_fdmulq);
2408
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2409
                        gen_op_store_QT0_fpr(QFPREG(rd));
2410
                        break;
2411
#else
2412
                        goto nfpu_insn;
2413
#endif
2414
                    case 0xc4:
2415
                        gen_op_load_fpr_FT1(rs2);
2416
                        gen_clear_float_exceptions();
2417
                        tcg_gen_helper_0_0(helper_fitos);
2418
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2419
                        gen_op_store_FT0_fpr(rd);
2420
                        break;
2421
                    case 0xc6:
2422
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2423
                        gen_clear_float_exceptions();
2424
                        tcg_gen_helper_0_0(helper_fdtos);
2425
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2426
                        gen_op_store_FT0_fpr(rd);
2427
                        break;
2428
                    case 0xc7: /* fqtos */
2429
#if defined(CONFIG_USER_ONLY)
2430
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2431
                        gen_clear_float_exceptions();
2432
                        tcg_gen_helper_0_0(helper_fqtos);
2433
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2434
                        gen_op_store_FT0_fpr(rd);
2435
                        break;
2436
#else
2437
                        goto nfpu_insn;
2438
#endif
2439
                    case 0xc8:
2440
                        gen_op_load_fpr_FT1(rs2);
2441
                        tcg_gen_helper_0_0(helper_fitod);
2442
                        gen_op_store_DT0_fpr(DFPREG(rd));
2443
                        break;
2444
                    case 0xc9:
2445
                        gen_op_load_fpr_FT1(rs2);
2446
                        tcg_gen_helper_0_0(helper_fstod);
2447
                        gen_op_store_DT0_fpr(DFPREG(rd));
2448
                        break;
2449
                    case 0xcb: /* fqtod */
2450
#if defined(CONFIG_USER_ONLY)
2451
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2452
                        gen_clear_float_exceptions();
2453
                        tcg_gen_helper_0_0(helper_fqtod);
2454
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2455
                        gen_op_store_DT0_fpr(DFPREG(rd));
2456
                        break;
2457
#else
2458
                        goto nfpu_insn;
2459
#endif
2460
                    case 0xcc: /* fitoq */
2461
#if defined(CONFIG_USER_ONLY)
2462
                        gen_op_load_fpr_FT1(rs2);
2463
                        tcg_gen_helper_0_0(helper_fitoq);
2464
                        gen_op_store_QT0_fpr(QFPREG(rd));
2465
                        break;
2466
#else
2467
                        goto nfpu_insn;
2468
#endif
2469
                    case 0xcd: /* fstoq */
2470
#if defined(CONFIG_USER_ONLY)
2471
                        gen_op_load_fpr_FT1(rs2);
2472
                        tcg_gen_helper_0_0(helper_fstoq);
2473
                        gen_op_store_QT0_fpr(QFPREG(rd));
2474
                        break;
2475
#else
2476
                        goto nfpu_insn;
2477
#endif
2478
                    case 0xce: /* fdtoq */
2479
#if defined(CONFIG_USER_ONLY)
2480
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2481
                        tcg_gen_helper_0_0(helper_fdtoq);
2482
                        gen_op_store_QT0_fpr(QFPREG(rd));
2483
                        break;
2484
#else
2485
                        goto nfpu_insn;
2486
#endif
2487
                    case 0xd1:
2488
                        gen_op_load_fpr_FT1(rs2);
2489
                        gen_clear_float_exceptions();
2490
                        tcg_gen_helper_0_0(helper_fstoi);
2491
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2492
                        gen_op_store_FT0_fpr(rd);
2493
                        break;
2494
                    case 0xd2:
2495
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2496
                        gen_clear_float_exceptions();
2497
                        tcg_gen_helper_0_0(helper_fdtoi);
2498
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2499
                        gen_op_store_FT0_fpr(rd);
2500
                        break;
2501
                    case 0xd3: /* fqtoi */
2502
#if defined(CONFIG_USER_ONLY)
2503
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2504
                        gen_clear_float_exceptions();
2505
                        tcg_gen_helper_0_0(helper_fqtoi);
2506
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2507
                        gen_op_store_FT0_fpr(rd);
2508
                        break;
2509
#else
2510
                        goto nfpu_insn;
2511
#endif
2512
#ifdef TARGET_SPARC64
2513
                    case 0x2: /* V9 fmovd */
2514
                        gen_op_load_fpr_DT0(DFPREG(rs2));
2515
                        gen_op_store_DT0_fpr(DFPREG(rd));
2516
                        break;
2517
                    case 0x3: /* V9 fmovq */
2518
#if defined(CONFIG_USER_ONLY)
2519
                        gen_op_load_fpr_QT0(QFPREG(rs2));
2520
                        gen_op_store_QT0_fpr(QFPREG(rd));
2521
                        break;
2522
#else
2523
                        goto nfpu_insn;
2524
#endif
2525
                    case 0x6: /* V9 fnegd */
2526
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2527
                        tcg_gen_helper_0_0(helper_fnegd);
2528
                        gen_op_store_DT0_fpr(DFPREG(rd));
2529
                        break;
2530
                    case 0x7: /* V9 fnegq */
2531
#if defined(CONFIG_USER_ONLY)
2532
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2533
                        tcg_gen_helper_0_0(helper_fnegq);
2534
                        gen_op_store_QT0_fpr(QFPREG(rd));
2535
                        break;
2536
#else
2537
                        goto nfpu_insn;
2538
#endif
2539
                    case 0xa: /* V9 fabsd */
2540
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2541
                        tcg_gen_helper_0_0(helper_fabsd);
2542
                        gen_op_store_DT0_fpr(DFPREG(rd));
2543
                        break;
2544
                    case 0xb: /* V9 fabsq */
2545
#if defined(CONFIG_USER_ONLY)
2546
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2547
                        tcg_gen_helper_0_0(helper_fabsq);
2548
                        gen_op_store_QT0_fpr(QFPREG(rd));
2549
                        break;
2550
#else
2551
                        goto nfpu_insn;
2552
#endif
2553
                    case 0x81: /* V9 fstox */
2554
                        gen_op_load_fpr_FT1(rs2);
2555
                        gen_clear_float_exceptions();
2556
                        tcg_gen_helper_0_0(helper_fstox);
2557
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2558
                        gen_op_store_DT0_fpr(DFPREG(rd));
2559
                        break;
2560
                    case 0x82: /* V9 fdtox */
2561
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2562
                        gen_clear_float_exceptions();
2563
                        tcg_gen_helper_0_0(helper_fdtox);
2564
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2565
                        gen_op_store_DT0_fpr(DFPREG(rd));
2566
                        break;
2567
                    case 0x83: /* V9 fqtox */
2568
#if defined(CONFIG_USER_ONLY)
2569
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2570
                        gen_clear_float_exceptions();
2571
                        tcg_gen_helper_0_0(helper_fqtox);
2572
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2573
                        gen_op_store_DT0_fpr(DFPREG(rd));
2574
                        break;
2575
#else
2576
                        goto nfpu_insn;
2577
#endif
2578
                    case 0x84: /* V9 fxtos */
2579
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2580
                        gen_clear_float_exceptions();
2581
                        tcg_gen_helper_0_0(helper_fxtos);
2582
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2583
                        gen_op_store_FT0_fpr(rd);
2584
                        break;
2585
                    case 0x88: /* V9 fxtod */
2586
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2587
                        gen_clear_float_exceptions();
2588
                        tcg_gen_helper_0_0(helper_fxtod);
2589
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2590
                        gen_op_store_DT0_fpr(DFPREG(rd));
2591
                        break;
2592
                    case 0x8c: /* V9 fxtoq */
2593
#if defined(CONFIG_USER_ONLY)
2594
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2595
                        gen_clear_float_exceptions();
2596
                        tcg_gen_helper_0_0(helper_fxtoq);
2597
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2598
                        gen_op_store_QT0_fpr(QFPREG(rd));
2599
                        break;
2600
#else
2601
                        goto nfpu_insn;
2602
#endif
2603
#endif
2604
                    default:
2605
                        goto illegal_insn;
2606
                }
2607
            } else if (xop == 0x35) {   /* FPU Operations */
2608
#ifdef TARGET_SPARC64
2609
                int cond;
2610
#endif
2611
                if (gen_trap_ifnofpu(dc, cpu_cond))
2612
                    goto jmp_insn;
2613
                gen_op_clear_ieee_excp_and_FTT();
2614
                rs1 = GET_FIELD(insn, 13, 17);
2615
                rs2 = GET_FIELD(insn, 27, 31);
2616
                xop = GET_FIELD(insn, 18, 26);
2617
#ifdef TARGET_SPARC64
2618
                if ((xop & 0x11f) == 0x005) { // V9 fmovsr
2619
                    int l1;
2620

    
2621
                    l1 = gen_new_label();
2622
                    cond = GET_FIELD_SP(insn, 14, 17);
2623
                    cpu_src1 = get_src1(insn, cpu_src1);
2624
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_src1,
2625
                                      tcg_const_tl(0), l1);
2626
                    gen_op_load_fpr_FT0(rs2);
2627
                    gen_op_store_FT0_fpr(rd);
2628
                    gen_set_label(l1);
2629
                    break;
2630
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
2631
                    int l1;
2632

    
2633
                    l1 = gen_new_label();
2634
                    cond = GET_FIELD_SP(insn, 14, 17);
2635
                    cpu_src1 = get_src1(insn, cpu_src1);
2636
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_src1,
2637
                                      tcg_const_tl(0), l1);
2638
                    gen_op_load_fpr_DT0(DFPREG(rs2));
2639
                    gen_op_store_DT0_fpr(DFPREG(rd));
2640
                    gen_set_label(l1);
2641
                    break;
2642
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
2643
#if defined(CONFIG_USER_ONLY)
2644
                    int l1;
2645

    
2646
                    l1 = gen_new_label();
2647
                    cond = GET_FIELD_SP(insn, 14, 17);
2648
                    cpu_src1 = get_src1(insn, cpu_src1);
2649
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_src1,
2650
                                      tcg_const_tl(0), l1);
2651
                    gen_op_load_fpr_QT0(QFPREG(rs2));
2652
                    gen_op_store_QT0_fpr(QFPREG(rd));
2653
                    gen_set_label(l1);
2654
                    break;
2655
#else
2656
                    goto nfpu_insn;
2657
#endif
2658
                }
2659
#endif
2660
                switch (xop) {
2661
#ifdef TARGET_SPARC64
2662
#define FMOVCC(size_FDQ, fcc)                                           \
2663
                    {                                                   \
2664
                        TCGv r_cond;                                    \
2665
                        int l1;                                         \
2666
                                                                        \
2667
                        l1 = gen_new_label();                           \
2668
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2669
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2670
                        gen_fcond(r_cond, fcc, cond);                   \
2671
                        tcg_gen_brcond_tl(TCG_COND_EQ, r_cond,          \
2672
                                          tcg_const_tl(0), l1);         \
2673
                        glue(glue(gen_op_load_fpr_, size_FDQ), T0)(glue(size_FDQ, FPREG(rs2))); \
2674
                        glue(glue(gen_op_store_, size_FDQ), T0_fpr)(glue(size_FDQ, FPREG(rd))); \
2675
                        gen_set_label(l1);                              \
2676
                    }
2677
                    case 0x001: /* V9 fmovscc %fcc0 */
2678
                        FMOVCC(F, 0);
2679
                        break;
2680
                    case 0x002: /* V9 fmovdcc %fcc0 */
2681
                        FMOVCC(D, 0);
2682
                        break;
2683
                    case 0x003: /* V9 fmovqcc %fcc0 */
2684
#if defined(CONFIG_USER_ONLY)
2685
                        FMOVCC(Q, 0);
2686
                        break;
2687
#else
2688
                        goto nfpu_insn;
2689
#endif
2690
                    case 0x041: /* V9 fmovscc %fcc1 */
2691
                        FMOVCC(F, 1);
2692
                        break;
2693
                    case 0x042: /* V9 fmovdcc %fcc1 */
2694
                        FMOVCC(D, 1);
2695
                        break;
2696
                    case 0x043: /* V9 fmovqcc %fcc1 */
2697
#if defined(CONFIG_USER_ONLY)
2698
                        FMOVCC(Q, 1);
2699
                        break;
2700
#else
2701
                        goto nfpu_insn;
2702
#endif
2703
                    case 0x081: /* V9 fmovscc %fcc2 */
2704
                        FMOVCC(F, 2);
2705
                        break;
2706
                    case 0x082: /* V9 fmovdcc %fcc2 */
2707
                        FMOVCC(D, 2);
2708
                        break;
2709
                    case 0x083: /* V9 fmovqcc %fcc2 */
2710
#if defined(CONFIG_USER_ONLY)
2711
                        FMOVCC(Q, 2);
2712
                        break;
2713
#else
2714
                        goto nfpu_insn;
2715
#endif
2716
                    case 0x0c1: /* V9 fmovscc %fcc3 */
2717
                        FMOVCC(F, 3);
2718
                        break;
2719
                    case 0x0c2: /* V9 fmovdcc %fcc3 */
2720
                        FMOVCC(D, 3);
2721
                        break;
2722
                    case 0x0c3: /* V9 fmovqcc %fcc3 */
2723
#if defined(CONFIG_USER_ONLY)
2724
                        FMOVCC(Q, 3);
2725
                        break;
2726
#else
2727
                        goto nfpu_insn;
2728
#endif
2729
#undef FMOVCC
2730
#define FMOVCC(size_FDQ, icc)                                           \
2731
                    {                                                   \
2732
                        TCGv r_cond;                                    \
2733
                        int l1;                                         \
2734
                                                                        \
2735
                        l1 = gen_new_label();                           \
2736
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
2737
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2738
                        gen_cond(r_cond, icc, cond);                    \
2739
                        tcg_gen_brcond_tl(TCG_COND_EQ, r_cond,          \
2740
                                          tcg_const_tl(0), l1);         \
2741
                        glue(glue(gen_op_load_fpr_, size_FDQ), T0)(glue(size_FDQ, FPREG(rs2))); \
2742
                        glue(glue(gen_op_store_, size_FDQ), T0_fpr)(glue(size_FDQ, FPREG(rd))); \
2743
                        gen_set_label(l1);                              \
2744
                    }
2745

    
2746
                    case 0x101: /* V9 fmovscc %icc */
2747
                        FMOVCC(F, 0);
2748
                        break;
2749
                    case 0x102: /* V9 fmovdcc %icc */
2750
                        FMOVCC(D, 0);
2751
                    case 0x103: /* V9 fmovqcc %icc */
2752
#if defined(CONFIG_USER_ONLY)
2753
                        FMOVCC(D, 0);
2754
                        break;
2755
#else
2756
                        goto nfpu_insn;
2757
#endif
2758
                    case 0x181: /* V9 fmovscc %xcc */
2759
                        FMOVCC(F, 1);
2760
                        break;
2761
                    case 0x182: /* V9 fmovdcc %xcc */
2762
                        FMOVCC(D, 1);
2763
                        break;
2764
                    case 0x183: /* V9 fmovqcc %xcc */
2765
#if defined(CONFIG_USER_ONLY)
2766
                        FMOVCC(Q, 1);
2767
                        break;
2768
#else
2769
                        goto nfpu_insn;
2770
#endif
2771
#undef FMOVCC
2772
#endif
2773
                    case 0x51: /* fcmps, V9 %fcc */
2774
                        gen_op_load_fpr_FT0(rs1);
2775
                        gen_op_load_fpr_FT1(rs2);
2776
                        gen_op_fcmps(rd & 3);
2777
                        break;
2778
                    case 0x52: /* fcmpd, V9 %fcc */
2779
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2780
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2781
                        gen_op_fcmpd(rd & 3);
2782
                        break;
2783
                    case 0x53: /* fcmpq, V9 %fcc */
2784
#if defined(CONFIG_USER_ONLY)
2785
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2786
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2787
                        gen_op_fcmpq(rd & 3);
2788
                        break;
2789
#else /* !defined(CONFIG_USER_ONLY) */
2790
                        goto nfpu_insn;
2791
#endif
2792
                    case 0x55: /* fcmpes, V9 %fcc */
2793
                        gen_op_load_fpr_FT0(rs1);
2794
                        gen_op_load_fpr_FT1(rs2);
2795
                        gen_op_fcmpes(rd & 3);
2796
                        break;
2797
                    case 0x56: /* fcmped, V9 %fcc */
2798
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2799
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2800
                        gen_op_fcmped(rd & 3);
2801
                        break;
2802
                    case 0x57: /* fcmpeq, V9 %fcc */
2803
#if defined(CONFIG_USER_ONLY)
2804
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2805
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2806
                        gen_op_fcmpeq(rd & 3);
2807
                        break;
2808
#else/* !defined(CONFIG_USER_ONLY) */
2809
                        goto nfpu_insn;
2810
#endif
2811
                    default:
2812
                        goto illegal_insn;
2813
                }
2814
            } else if (xop == 0x2) {
2815
                // clr/mov shortcut
2816

    
2817
                rs1 = GET_FIELD(insn, 13, 17);
2818
                if (rs1 == 0) {
2819
                    // or %g0, x, y -> mov T0, x; mov y, T0
2820
                    if (IS_IMM) {       /* immediate */
2821
                        rs2 = GET_FIELDs(insn, 19, 31);
2822
                        gen_movl_TN_reg(rd, tcg_const_tl((int)rs2));
2823
                    } else {            /* register */
2824
                        rs2 = GET_FIELD(insn, 27, 31);
2825
                        gen_movl_reg_TN(rs2, cpu_dst);
2826
                        gen_movl_TN_reg(rd, cpu_dst);
2827
                    }
2828
                } else {
2829
                    cpu_src1 = get_src1(insn, cpu_src1);
2830
                    if (IS_IMM) {       /* immediate */
2831
                        rs2 = GET_FIELDs(insn, 19, 31);
2832
                        tcg_gen_ori_tl(cpu_dst, cpu_src1, (int)rs2);
2833
                        gen_movl_TN_reg(rd, cpu_dst);
2834
                    } else {            /* register */
2835
                        // or x, %g0, y -> mov T1, x; mov y, T1
2836
                        rs2 = GET_FIELD(insn, 27, 31);
2837
                        if (rs2 != 0) {
2838
                            gen_movl_reg_TN(rs2, cpu_src2);
2839
                            tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
2840
                            gen_movl_TN_reg(rd, cpu_dst);
2841
                        } else
2842
                            gen_movl_TN_reg(rd, cpu_src1);
2843
                    }
2844
                }
2845
#ifdef TARGET_SPARC64
2846
            } else if (xop == 0x25) { /* sll, V9 sllx */
2847
                cpu_src1 = get_src1(insn, cpu_src1);
2848
                if (IS_IMM) {   /* immediate */
2849
                    rs2 = GET_FIELDs(insn, 20, 31);
2850
                    if (insn & (1 << 12)) {
2851
                        tcg_gen_shli_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
2852
                    } else {
2853
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2854
                        tcg_gen_shli_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
2855
                    }
2856
                } else {                /* register */
2857
                    rs2 = GET_FIELD(insn, 27, 31);
2858
                    gen_movl_reg_TN(rs2, cpu_src2);
2859
                    if (insn & (1 << 12)) {
2860
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2861
                        tcg_gen_shl_i64(cpu_dst, cpu_src1, cpu_tmp0);
2862
                    } else {
2863
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2864
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2865
                        tcg_gen_shl_i64(cpu_dst, cpu_dst, cpu_tmp0);
2866
                    }
2867
                }
2868
                gen_movl_TN_reg(rd, cpu_dst);
2869
            } else if (xop == 0x26) { /* srl, V9 srlx */
2870
                cpu_src1 = get_src1(insn, cpu_src1);
2871
                if (IS_IMM) {   /* immediate */
2872
                    rs2 = GET_FIELDs(insn, 20, 31);
2873
                    if (insn & (1 << 12)) {
2874
                        tcg_gen_shri_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
2875
                    } else {
2876
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2877
                        tcg_gen_shri_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
2878
                    }
2879
                } else {                /* register */
2880
                    rs2 = GET_FIELD(insn, 27, 31);
2881
                    gen_movl_reg_TN(rs2, cpu_src2);
2882
                    if (insn & (1 << 12)) {
2883
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2884
                        tcg_gen_shr_i64(cpu_dst, cpu_src1, cpu_tmp0);
2885
                    } else {
2886
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2887
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2888
                        tcg_gen_shr_i64(cpu_dst, cpu_dst, cpu_tmp0);
2889
                    }
2890
                }
2891
                gen_movl_TN_reg(rd, cpu_dst);
2892
            } else if (xop == 0x27) { /* sra, V9 srax */
2893
                cpu_src1 = get_src1(insn, cpu_src1);
2894
                if (IS_IMM) {   /* immediate */
2895
                    rs2 = GET_FIELDs(insn, 20, 31);
2896
                    if (insn & (1 << 12)) {
2897
                        tcg_gen_sari_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
2898
                    } else {
2899
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2900
                        tcg_gen_ext_i32_i64(cpu_dst, cpu_dst);
2901
                        tcg_gen_sari_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
2902
                    }
2903
                } else {                /* register */
2904
                    rs2 = GET_FIELD(insn, 27, 31);
2905
                    gen_movl_reg_TN(rs2, cpu_src2);
2906
                    if (insn & (1 << 12)) {
2907
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2908
                        tcg_gen_sar_i64(cpu_dst, cpu_src1, cpu_tmp0);
2909
                    } else {
2910
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2911
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2912
                        tcg_gen_sar_i64(cpu_dst, cpu_dst, cpu_tmp0);
2913
                    }
2914
                }
2915
                gen_movl_TN_reg(rd, cpu_dst);
2916
#endif
2917
            } else if (xop < 0x36) {
2918
                cpu_src1 = get_src1(insn, cpu_src1);
2919
                cpu_src2 = get_src2(insn, cpu_src2);
2920
                if (xop < 0x20) {
2921
                    switch (xop & ~0x10) {
2922
                    case 0x0:
2923
                        if (xop & 0x10)
2924
                            gen_op_add_cc(cpu_dst, cpu_src1, cpu_src2);
2925
                        else
2926
                            tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
2927
                        break;
2928
                    case 0x1:
2929
                        tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_src2);
2930
                        if (xop & 0x10)
2931
                            gen_op_logic_cc(cpu_dst);
2932
                        break;
2933
                    case 0x2:
2934
                        tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
2935
                        if (xop & 0x10)
2936
                            gen_op_logic_cc(cpu_dst);
2937
                        break;
2938
                    case 0x3:
2939
                        tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
2940
                        if (xop & 0x10)
2941
                            gen_op_logic_cc(cpu_dst);
2942
                        break;
2943
                    case 0x4:
2944
                        if (xop & 0x10)
2945
                            gen_op_sub_cc(cpu_dst, cpu_src1, cpu_src2);
2946
                        else
2947
                            tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_src2);
2948
                        break;
2949
                    case 0x5:
2950
                        tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
2951
                        tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_tmp0);
2952
                        if (xop & 0x10)
2953
                            gen_op_logic_cc(cpu_dst);
2954
                        break;
2955
                    case 0x6:
2956
                        tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
2957
                        tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_tmp0);
2958
                        if (xop & 0x10)
2959
                            gen_op_logic_cc(cpu_dst);
2960
                        break;
2961
                    case 0x7:
2962
                        tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
2963
                        tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_tmp0);
2964
                        if (xop & 0x10)
2965
                            gen_op_logic_cc(cpu_dst);
2966
                        break;
2967
                    case 0x8:
2968
                        if (xop & 0x10)
2969
                            gen_op_addx_cc(cpu_dst, cpu_src1, cpu_src2);
2970
                        else {
2971
                            gen_mov_reg_C(cpu_tmp0, cpu_psr);
2972
                            tcg_gen_add_tl(cpu_tmp0, cpu_src2, cpu_tmp0);
2973
                            tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_tmp0);
2974
                        }
2975
                        break;
2976
#ifdef TARGET_SPARC64
2977
                    case 0x9: /* V9 mulx */
2978
                        tcg_gen_mul_i64(cpu_dst, cpu_src1, cpu_src2);
2979
                        break;
2980
#endif
2981
                    case 0xa:
2982
                        gen_op_umul(cpu_dst, cpu_src1, cpu_src2);
2983
                        if (xop & 0x10)
2984
                            gen_op_logic_cc(cpu_dst);
2985
                        break;
2986
                    case 0xb:
2987
                        gen_op_smul(cpu_dst, cpu_src1, cpu_src2);
2988
                        if (xop & 0x10)
2989
                            gen_op_logic_cc(cpu_dst);
2990
                        break;
2991
                    case 0xc:
2992
                        if (xop & 0x10)
2993
                            gen_op_subx_cc(cpu_dst, cpu_src1, cpu_src2);
2994
                        else {
2995
                            gen_mov_reg_C(cpu_tmp0, cpu_psr);
2996
                            tcg_gen_add_tl(cpu_tmp0, cpu_src2, cpu_tmp0);
2997
                            tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_tmp0);
2998
                        }
2999
                        break;
3000
#ifdef TARGET_SPARC64
3001
                    case 0xd: /* V9 udivx */
3002
                        gen_trap_ifdivzero_tl(cpu_src2);
3003
                        tcg_gen_divu_i64(cpu_dst, cpu_src1, cpu_src2);
3004
                        break;
3005
#endif
3006
                    case 0xe:
3007
                        tcg_gen_helper_1_2(helper_udiv, cpu_dst, cpu_src1, cpu_src2);
3008
                        if (xop & 0x10)
3009
                            gen_op_div_cc(cpu_dst);
3010
                        break;
3011
                    case 0xf:
3012
                        tcg_gen_helper_1_2(helper_sdiv, cpu_dst, cpu_src1, cpu_src2);
3013
                        if (xop & 0x10)
3014
                            gen_op_div_cc(cpu_dst);
3015
                        break;
3016
                    default:
3017
                        goto illegal_insn;
3018
                    }
3019
                    gen_movl_TN_reg(rd, cpu_dst);
3020
                } else {
3021
                    switch (xop) {
3022
                    case 0x20: /* taddcc */
3023
                        gen_op_tadd_cc(cpu_dst, cpu_src1, cpu_src2);
3024
                        gen_movl_TN_reg(rd, cpu_dst);
3025
                        break;
3026
                    case 0x21: /* tsubcc */
3027
                        gen_op_tsub_cc(cpu_dst, cpu_src1, cpu_src2);
3028
                        gen_movl_TN_reg(rd, cpu_dst);
3029
                        break;
3030
                    case 0x22: /* taddcctv */
3031
                        save_state(dc, cpu_cond);
3032
                        gen_op_tadd_ccTV(cpu_dst, cpu_src1, cpu_src2);
3033
                        gen_movl_TN_reg(rd, cpu_dst);
3034
                        break;
3035
                    case 0x23: /* tsubcctv */
3036
                        save_state(dc, cpu_cond);
3037
                        gen_op_tsub_ccTV(cpu_dst, cpu_src1, cpu_src2);
3038
                        gen_movl_TN_reg(rd, cpu_dst);
3039
                        break;
3040
                    case 0x24: /* mulscc */
3041
                        gen_op_mulscc(cpu_dst, cpu_src1, cpu_src2);
3042
                        gen_movl_TN_reg(rd, cpu_dst);
3043
                        break;
3044
#ifndef TARGET_SPARC64
3045
                    case 0x25:  /* sll */
3046
                        tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3047
                        tcg_gen_shl_tl(cpu_dst, cpu_src1, cpu_tmp0);
3048
                        gen_movl_TN_reg(rd, cpu_dst);
3049
                        break;
3050
                    case 0x26:  /* srl */
3051
                        tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3052
                        tcg_gen_shr_tl(cpu_dst, cpu_src1, cpu_tmp0);
3053
                        gen_movl_TN_reg(rd, cpu_dst);
3054
                        break;
3055
                    case 0x27:  /* sra */
3056
                        tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3057
                        tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0);
3058
                        gen_movl_TN_reg(rd, cpu_dst);
3059
                        break;
3060
#endif
3061
                    case 0x30:
3062
                        {
3063
                            switch(rd) {
3064
                            case 0: /* wry */
3065
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3066
                                tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, y));
3067
                                break;
3068
#ifndef TARGET_SPARC64
3069
                            case 0x01 ... 0x0f: /* undefined in the
3070
                                                   SPARCv8 manual, nop
3071
                                                   on the microSPARC
3072
                                                   II */
3073
                            case 0x10 ... 0x1f: /* implementation-dependent
3074
                                                   in the SPARCv8
3075
                                                   manual, nop on the
3076
                                                   microSPARC II */
3077
                                break;
3078
#else
3079
                            case 0x2: /* V9 wrccr */
3080
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3081
                                tcg_gen_helper_0_1(helper_wrccr, cpu_dst);
3082
                                break;
3083
                            case 0x3: /* V9 wrasi */
3084
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3085
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3086
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, asi));
3087
                                break;
3088
                            case 0x6: /* V9 wrfprs */
3089
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3090
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3091
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fprs));
3092
                                save_state(dc, cpu_cond);
3093
                                gen_op_next_insn();
3094
                                tcg_gen_exit_tb(0);
3095
                                dc->is_br = 1;
3096
                                break;
3097
                            case 0xf: /* V9 sir, nop if user */
3098
#if !defined(CONFIG_USER_ONLY)
3099
                                if (supervisor(dc))
3100
                                    ; // XXX
3101
#endif
3102
                                break;
3103
                            case 0x13: /* Graphics Status */
3104
                                if (gen_trap_ifnofpu(dc, cpu_cond))
3105
                                    goto jmp_insn;
3106
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3107
                                tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, gsr));
3108
                                break;
3109
                            case 0x17: /* Tick compare */
3110
#if !defined(CONFIG_USER_ONLY)
3111
                                if (!supervisor(dc))
3112
                                    goto illegal_insn;
3113
#endif
3114
                                {
3115
                                    TCGv r_tickptr;
3116

    
3117
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
3118
                                                   cpu_src2);
3119
                                    tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState,
3120
                                                                 tick_cmpr));
3121
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3122
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3123
                                                   offsetof(CPUState, tick));
3124
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3125
                                                       r_tickptr, cpu_dst);
3126
                                }
3127
                                break;
3128
                            case 0x18: /* System tick */
3129
#if !defined(CONFIG_USER_ONLY)
3130
                                if (!supervisor(dc))
3131
                                    goto illegal_insn;
3132
#endif
3133
                                {
3134
                                    TCGv r_tickptr;
3135

    
3136
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
3137
                                                   cpu_src2);
3138
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3139
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3140
                                                   offsetof(CPUState, stick));
3141
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3142
                                                       r_tickptr, cpu_dst);
3143
                                }
3144
                                break;
3145
                            case 0x19: /* System tick compare */
3146
#if !defined(CONFIG_USER_ONLY)
3147
                                if (!supervisor(dc))
3148
                                    goto illegal_insn;
3149
#endif
3150
                                {
3151
                                    TCGv r_tickptr;
3152

    
3153
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
3154
                                                   cpu_src2);
3155
                                    tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState,
3156
                                                                 stick_cmpr));
3157
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3158
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3159
                                                   offsetof(CPUState, stick));
3160
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3161
                                                       r_tickptr, cpu_dst);
3162
                                }
3163
                                break;
3164

    
3165
                            case 0x10: /* Performance Control */
3166
                            case 0x11: /* Performance Instrumentation Counter */
3167
                            case 0x12: /* Dispatch Control */
3168
                            case 0x14: /* Softint set */
3169
                            case 0x15: /* Softint clear */
3170
                            case 0x16: /* Softint write */
3171
#endif
3172
                            default:
3173
                                goto illegal_insn;
3174
                            }
3175
                        }
3176
                        break;
3177
#if !defined(CONFIG_USER_ONLY)
3178
                    case 0x31: /* wrpsr, V9 saved, restored */
3179
                        {
3180
                            if (!supervisor(dc))
3181
                                goto priv_insn;
3182
#ifdef TARGET_SPARC64
3183
                            switch (rd) {
3184
                            case 0:
3185
                                tcg_gen_helper_0_0(helper_saved);
3186
                                break;
3187
                            case 1:
3188
                                tcg_gen_helper_0_0(helper_restored);
3189
                                break;
3190
                            case 2: /* UA2005 allclean */
3191
                            case 3: /* UA2005 otherw */
3192
                            case 4: /* UA2005 normalw */
3193
                            case 5: /* UA2005 invalw */
3194
                                // XXX
3195
                            default:
3196
                                goto illegal_insn;
3197
                            }
3198
#else
3199
                            tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3200
                            tcg_gen_helper_0_1(helper_wrpsr, cpu_dst);
3201
                            save_state(dc, cpu_cond);
3202
                            gen_op_next_insn();
3203
                            tcg_gen_exit_tb(0);
3204
                            dc->is_br = 1;
3205
#endif
3206
                        }
3207
                        break;
3208
                    case 0x32: /* wrwim, V9 wrpr */
3209
                        {
3210
                            if (!supervisor(dc))
3211
                                goto priv_insn;
3212
                            tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3213
#ifdef TARGET_SPARC64
3214
                            switch (rd) {
3215
                            case 0: // tpc
3216
                                {
3217
                                    TCGv r_tsptr;
3218

    
3219
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3220
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3221
                                                   offsetof(CPUState, tsptr));
3222
                                    tcg_gen_st_tl(cpu_dst, r_tsptr,
3223
                                                  offsetof(trap_state, tpc));
3224
                                }
3225
                                break;
3226
                            case 1: // tnpc
3227
                                {
3228
                                    TCGv r_tsptr;
3229

    
3230
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3231
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3232
                                                   offsetof(CPUState, tsptr));
3233
                                    tcg_gen_st_tl(cpu_dst, r_tsptr,
3234
                                                  offsetof(trap_state, tnpc));
3235
                                }
3236
                                break;
3237
                            case 2: // tstate
3238
                                {
3239
                                    TCGv r_tsptr;
3240

    
3241
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3242
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3243
                                                   offsetof(CPUState, tsptr));
3244
                                    tcg_gen_st_tl(cpu_dst, r_tsptr,
3245
                                                  offsetof(trap_state, tstate));
3246
                                }
3247
                                break;
3248
                            case 3: // tt
3249
                                {
3250
                                    TCGv r_tsptr;
3251

    
3252
                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3253
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
3254
                                                   offsetof(CPUState, tsptr));
3255
                                    tcg_gen_st_i32(cpu_dst, r_tsptr,
3256
                                                   offsetof(trap_state, tt));
3257
                                }
3258
                                break;
3259
                            case 4: // tick
3260
                                {
3261
                                    TCGv r_tickptr;
3262

    
3263
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3264
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3265
                                                   offsetof(CPUState, tick));
3266
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3267
                                                       r_tickptr, cpu_dst);
3268
                                }
3269
                                break;
3270
                            case 5: // tba
3271
                                tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, tbr));
3272
                                break;
3273
                            case 6: // pstate
3274
                                save_state(dc, cpu_cond);
3275
                                tcg_gen_helper_0_1(helper_wrpstate, cpu_dst);
3276
                                gen_op_next_insn();
3277
                                tcg_gen_exit_tb(0);
3278
                                dc->is_br = 1;
3279
                                break;
3280
                            case 7: // tl
3281
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3282
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, tl));
3283
                                break;
3284
                            case 8: // pil
3285
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3286
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, psrpil));
3287
                                break;
3288
                            case 9: // cwp
3289
                                tcg_gen_helper_0_1(helper_wrcwp, cpu_dst);
3290
                                break;
3291
                            case 10: // cansave
3292
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3293
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, cansave));
3294
                                break;
3295
                            case 11: // canrestore
3296
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3297
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, canrestore));
3298
                                break;
3299
                            case 12: // cleanwin
3300
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3301
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, cleanwin));
3302
                                break;
3303
                            case 13: // otherwin
3304
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3305
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, otherwin));
3306
                                break;
3307
                            case 14: // wstate
3308
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3309
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, wstate));
3310
                                break;
3311
                            case 16: // UA2005 gl
3312
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3313
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, gl));
3314
                                break;
3315
                            case 26: // UA2005 strand status
3316
                                if (!hypervisor(dc))
3317
                                    goto priv_insn;
3318
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3319
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ssr));
3320
                                break;
3321
                            default:
3322
                                goto illegal_insn;
3323
                            }
3324
#else
3325
                            tcg_gen_andi_tl(cpu_dst, cpu_dst, ((1 << NWINDOWS) - 1));
3326
                            tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3327
                            tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, wim));
3328
#endif
3329
                        }
3330
                        break;
3331
                    case 0x33: /* wrtbr, UA2005 wrhpr */
3332
                        {
3333
#ifndef TARGET_SPARC64
3334
                            if (!supervisor(dc))
3335
                                goto priv_insn;
3336
                            tcg_gen_xor_tl(cpu_dst, cpu_dst, cpu_src2);
3337
                            tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState, tbr));
3338
#else
3339
                            if (!hypervisor(dc))
3340
                                goto priv_insn;
3341
                            tcg_gen_xor_tl(cpu_dst, cpu_dst, cpu_src2);
3342
                            switch (rd) {
3343
                            case 0: // hpstate
3344
                                // XXX gen_op_wrhpstate();
3345
                                save_state(dc, cpu_cond);
3346
                                gen_op_next_insn();
3347
                                tcg_gen_exit_tb(0);
3348
                                dc->is_br = 1;
3349
                                break;
3350
                            case 1: // htstate
3351
                                // XXX gen_op_wrhtstate();
3352
                                break;
3353
                            case 3: // hintp
3354
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3355
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, hintp));
3356
                                break;
3357
                            case 5: // htba
3358
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3359
                                tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, htba));
3360
                                break;
3361
                            case 31: // hstick_cmpr
3362
                                {
3363
                                    TCGv r_tickptr;
3364

    
3365
                                    tcg_gen_st_tl(cpu_dst, cpu_env, offsetof(CPUSPARCState,
3366
                                                                 hstick_cmpr));
3367
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3368
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
3369
                                                   offsetof(CPUState, hstick));
3370
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3371
                                                       r_tickptr, cpu_dst);
3372
                                }
3373
                                break;
3374
                            case 6: // hver readonly
3375
                            default:
3376
                                goto illegal_insn;
3377
                            }
3378
#endif
3379
                        }
3380
                        break;
3381
#endif
3382
#ifdef TARGET_SPARC64
3383
                    case 0x2c: /* V9 movcc */
3384
                        {
3385
                            int cc = GET_FIELD_SP(insn, 11, 12);
3386
                            int cond = GET_FIELD_SP(insn, 14, 17);
3387
                            TCGv r_cond;
3388
                            int l1;
3389

    
3390
                            r_cond = tcg_temp_new(TCG_TYPE_TL);
3391
                            if (insn & (1 << 18)) {
3392
                                if (cc == 0)
3393
                                    gen_cond(r_cond, 0, cond);
3394
                                else if (cc == 2)
3395
                                    gen_cond(r_cond, 1, cond);
3396
                                else
3397
                                    goto illegal_insn;
3398
                            } else {
3399
                                gen_fcond(r_cond, cc, cond);
3400
                            }
3401

    
3402
                            l1 = gen_new_label();
3403

    
3404
                            tcg_gen_brcond_tl(TCG_COND_EQ, r_cond,
3405
                                              tcg_const_tl(0), l1);
3406
                            if (IS_IMM) {       /* immediate */
3407
                                rs2 = GET_FIELD_SPs(insn, 0, 10);
3408
                                gen_movl_TN_reg(rd, tcg_const_tl((int)rs2));
3409
                            } else {
3410
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3411
                                gen_movl_reg_TN(rs2, cpu_tmp0);
3412
                                gen_movl_TN_reg(rd, cpu_tmp0);
3413
                            }
3414
                            gen_set_label(l1);
3415
                            break;
3416
                        }
3417
                    case 0x2d: /* V9 sdivx */
3418
                        gen_op_sdivx(cpu_dst, cpu_src1, cpu_src2);
3419
                        gen_movl_TN_reg(rd, cpu_dst);
3420
                        break;
3421
                    case 0x2e: /* V9 popc */
3422
                        {
3423
                            cpu_src2 = get_src2(insn, cpu_src2);
3424
                            tcg_gen_helper_1_1(helper_popc, cpu_dst,
3425
                                               cpu_src2);
3426
                            gen_movl_TN_reg(rd, cpu_dst);
3427
                        }
3428
                    case 0x2f: /* V9 movr */
3429
                        {
3430
                            int cond = GET_FIELD_SP(insn, 10, 12);
3431
                            int l1;
3432

    
3433
                            cpu_src1 = get_src1(insn, cpu_src1);
3434

    
3435
                            l1 = gen_new_label();
3436

    
3437
                            tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_src1,
3438
                                              tcg_const_tl(0), l1);
3439
                            if (IS_IMM) {       /* immediate */
3440
                                rs2 = GET_FIELD_SPs(insn, 0, 9);
3441
                                gen_movl_TN_reg(rd, tcg_const_tl((int)rs2));
3442
                            } else {
3443
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3444
                                gen_movl_reg_TN(rs2, cpu_tmp0);
3445
                                gen_movl_TN_reg(rd, cpu_tmp0);
3446
                            }
3447
                            gen_set_label(l1);
3448
                            break;
3449
                        }
3450
#endif
3451
                    default:
3452
                        goto illegal_insn;
3453
                    }
3454
                }
3455
            } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
3456
#ifdef TARGET_SPARC64
3457
                int opf = GET_FIELD_SP(insn, 5, 13);
3458
                rs1 = GET_FIELD(insn, 13, 17);
3459
                rs2 = GET_FIELD(insn, 27, 31);
3460
                if (gen_trap_ifnofpu(dc, cpu_cond))
3461
                    goto jmp_insn;
3462

    
3463
                switch (opf) {
3464
                case 0x000: /* VIS I edge8cc */
3465
                case 0x001: /* VIS II edge8n */
3466
                case 0x002: /* VIS I edge8lcc */
3467
                case 0x003: /* VIS II edge8ln */
3468
                case 0x004: /* VIS I edge16cc */
3469
                case 0x005: /* VIS II edge16n */
3470
                case 0x006: /* VIS I edge16lcc */
3471
                case 0x007: /* VIS II edge16ln */
3472
                case 0x008: /* VIS I edge32cc */
3473
                case 0x009: /* VIS II edge32n */
3474
                case 0x00a: /* VIS I edge32lcc */
3475
                case 0x00b: /* VIS II edge32ln */
3476
                    // XXX
3477
                    goto illegal_insn;
3478
                case 0x010: /* VIS I array8 */
3479
                    cpu_src1 = get_src1(insn, cpu_src1);
3480
                    gen_movl_reg_TN(rs2, cpu_src2);
3481
                    tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
3482
                                       cpu_src2);
3483
                    gen_movl_TN_reg(rd, cpu_dst);
3484
                    break;
3485
                case 0x012: /* VIS I array16 */
3486
                    cpu_src1 = get_src1(insn, cpu_src1);
3487
                    gen_movl_reg_TN(rs2, cpu_src2);
3488
                    tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
3489
                                       cpu_src2);
3490
                    tcg_gen_shli_i64(cpu_dst, cpu_dst, 1);
3491
                    gen_movl_TN_reg(rd, cpu_dst);
3492
                    break;
3493
                case 0x014: /* VIS I array32 */
3494
                    cpu_src1 = get_src1(insn, cpu_src1);
3495
                    gen_movl_reg_TN(rs2, cpu_src2);
3496
                    tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
3497
                                       cpu_src2);
3498
                    tcg_gen_shli_i64(cpu_dst, cpu_dst, 2);
3499
                    gen_movl_TN_reg(rd, cpu_dst);
3500
                    break;
3501
                case 0x018: /* VIS I alignaddr */
3502
                    cpu_src1 = get_src1(insn, cpu_src1);
3503
                    gen_movl_reg_TN(rs2, cpu_src2);
3504
                    tcg_gen_helper_1_2(helper_alignaddr, cpu_dst, cpu_src1,
3505
                                       cpu_src2);
3506
                    gen_movl_TN_reg(rd, cpu_dst);
3507
                    break;
3508
                case 0x019: /* VIS II bmask */
3509
                case 0x01a: /* VIS I alignaddrl */
3510
                    // XXX
3511
                    goto illegal_insn;
3512
                case 0x020: /* VIS I fcmple16 */
3513
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3514
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3515
                    tcg_gen_helper_0_0(helper_fcmple16);
3516
                    gen_op_store_DT0_fpr(DFPREG(rd));
3517
                    break;
3518
                case 0x022: /* VIS I fcmpne16 */
3519
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3520
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3521
                    tcg_gen_helper_0_0(helper_fcmpne16);
3522
                    gen_op_store_DT0_fpr(DFPREG(rd));
3523
                    break;
3524
                case 0x024: /* VIS I fcmple32 */
3525
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3526
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3527
                    tcg_gen_helper_0_0(helper_fcmple32);
3528
                    gen_op_store_DT0_fpr(DFPREG(rd));
3529
                    break;
3530
                case 0x026: /* VIS I fcmpne32 */
3531
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3532
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3533
                    tcg_gen_helper_0_0(helper_fcmpne32);
3534
                    gen_op_store_DT0_fpr(DFPREG(rd));
3535
                    break;
3536
                case 0x028: /* VIS I fcmpgt16 */
3537
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3538
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3539
                    tcg_gen_helper_0_0(helper_fcmpgt16);
3540
                    gen_op_store_DT0_fpr(DFPREG(rd));
3541
                    break;
3542
                case 0x02a: /* VIS I fcmpeq16 */
3543
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3544
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3545
                    tcg_gen_helper_0_0(helper_fcmpeq16);
3546
                    gen_op_store_DT0_fpr(DFPREG(rd));
3547
                    break;
3548
                case 0x02c: /* VIS I fcmpgt32 */
3549
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3550
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3551
                    tcg_gen_helper_0_0(helper_fcmpgt32);
3552
                    gen_op_store_DT0_fpr(DFPREG(rd));
3553
                    break;
3554
                case 0x02e: /* VIS I fcmpeq32 */
3555
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3556
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3557
                    tcg_gen_helper_0_0(helper_fcmpeq32);
3558
                    gen_op_store_DT0_fpr(DFPREG(rd));
3559
                    break;
3560
                case 0x031: /* VIS I fmul8x16 */
3561
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3562
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3563
                    tcg_gen_helper_0_0(helper_fmul8x16);
3564
                    gen_op_store_DT0_fpr(DFPREG(rd));
3565
                    break;
3566
                case 0x033: /* VIS I fmul8x16au */
3567
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3568
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3569
                    tcg_gen_helper_0_0(helper_fmul8x16au);
3570
                    gen_op_store_DT0_fpr(DFPREG(rd));
3571
                    break;
3572
                case 0x035: /* VIS I fmul8x16al */
3573
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3574
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3575
                    tcg_gen_helper_0_0(helper_fmul8x16al);
3576
                    gen_op_store_DT0_fpr(DFPREG(rd));
3577
                    break;
3578
                case 0x036: /* VIS I fmul8sux16 */
3579
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3580
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3581
                    tcg_gen_helper_0_0(helper_fmul8sux16);
3582
                    gen_op_store_DT0_fpr(DFPREG(rd));
3583
                    break;
3584
                case 0x037: /* VIS I fmul8ulx16 */
3585
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3586
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3587
                    tcg_gen_helper_0_0(helper_fmul8ulx16);
3588
                    gen_op_store_DT0_fpr(DFPREG(rd));
3589
                    break;
3590
                case 0x038: /* VIS I fmuld8sux16 */
3591
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3592
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3593
                    tcg_gen_helper_0_0(helper_fmuld8sux16);
3594
                    gen_op_store_DT0_fpr(DFPREG(rd));
3595
                    break;
3596
                case 0x039: /* VIS I fmuld8ulx16 */
3597
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3598
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3599
                    tcg_gen_helper_0_0(helper_fmuld8ulx16);
3600
                    gen_op_store_DT0_fpr(DFPREG(rd));
3601
                    break;
3602
                case 0x03a: /* VIS I fpack32 */
3603
                case 0x03b: /* VIS I fpack16 */
3604
                case 0x03d: /* VIS I fpackfix */
3605
                case 0x03e: /* VIS I pdist */
3606
                    // XXX
3607
                    goto illegal_insn;
3608
                case 0x048: /* VIS I faligndata */
3609
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3610
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3611
                    tcg_gen_helper_0_0(helper_faligndata);
3612
                    gen_op_store_DT0_fpr(DFPREG(rd));
3613
                    break;
3614
                case 0x04b: /* VIS I fpmerge */
3615
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3616
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3617
                    tcg_gen_helper_0_0(helper_fpmerge);
3618
                    gen_op_store_DT0_fpr(DFPREG(rd));
3619
                    break;
3620
                case 0x04c: /* VIS II bshuffle */
3621
                    // XXX
3622
                    goto illegal_insn;
3623
                case 0x04d: /* VIS I fexpand */
3624
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3625
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3626
                    tcg_gen_helper_0_0(helper_fexpand);
3627
                    gen_op_store_DT0_fpr(DFPREG(rd));
3628
                    break;
3629
                case 0x050: /* VIS I fpadd16 */
3630
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3631
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3632
                    tcg_gen_helper_0_0(helper_fpadd16);
3633
                    gen_op_store_DT0_fpr(DFPREG(rd));
3634
                    break;
3635
                case 0x051: /* VIS I fpadd16s */
3636
                    gen_op_load_fpr_FT0(rs1);
3637
                    gen_op_load_fpr_FT1(rs2);
3638
                    tcg_gen_helper_0_0(helper_fpadd16s);
3639
                    gen_op_store_FT0_fpr(rd);
3640
                    break;
3641
                case 0x052: /* VIS I fpadd32 */
3642
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3643
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3644
                    tcg_gen_helper_0_0(helper_fpadd32);
3645
                    gen_op_store_DT0_fpr(DFPREG(rd));
3646
                    break;
3647
                case 0x053: /* VIS I fpadd32s */
3648
                    gen_op_load_fpr_FT0(rs1);
3649
                    gen_op_load_fpr_FT1(rs2);
3650
                    tcg_gen_helper_0_0(helper_fpadd32s);
3651
                    gen_op_store_FT0_fpr(rd);
3652
                    break;
3653
                case 0x054: /* VIS I fpsub16 */
3654
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3655
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3656
                    tcg_gen_helper_0_0(helper_fpsub16);
3657
                    gen_op_store_DT0_fpr(DFPREG(rd));
3658
                    break;
3659
                case 0x055: /* VIS I fpsub16s */
3660
                    gen_op_load_fpr_FT0(rs1);
3661
                    gen_op_load_fpr_FT1(rs2);
3662
                    tcg_gen_helper_0_0(helper_fpsub16s);
3663
                    gen_op_store_FT0_fpr(rd);
3664
                    break;
3665
                case 0x056: /* VIS I fpsub32 */
3666
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3667
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3668
                    tcg_gen_helper_0_0(helper_fpadd32);
3669
                    gen_op_store_DT0_fpr(DFPREG(rd));
3670
                    break;
3671
                case 0x057: /* VIS I fpsub32s */
3672
                    gen_op_load_fpr_FT0(rs1);
3673
                    gen_op_load_fpr_FT1(rs2);
3674
                    tcg_gen_helper_0_0(helper_fpsub32s);
3675
                    gen_op_store_FT0_fpr(rd);
3676
                    break;
3677
                case 0x060: /* VIS I fzero */
3678
                    tcg_gen_helper_0_0(helper_movl_DT0_0);
3679
                    gen_op_store_DT0_fpr(DFPREG(rd));
3680
                    break;
3681
                case 0x061: /* VIS I fzeros */
3682
                    tcg_gen_helper_0_0(helper_movl_FT0_0);
3683
                    gen_op_store_FT0_fpr(rd);
3684
                    break;
3685
                case 0x062: /* VIS I fnor */
3686
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3687
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3688
                    tcg_gen_helper_0_0(helper_fnor);
3689
                    gen_op_store_DT0_fpr(DFPREG(rd));
3690
                    break;
3691
                case 0x063: /* VIS I fnors */
3692
                    gen_op_load_fpr_FT0(rs1);
3693
                    gen_op_load_fpr_FT1(rs2);
3694
                    tcg_gen_helper_0_0(helper_fnors);
3695
                    gen_op_store_FT0_fpr(rd);
3696
                    break;
3697
                case 0x064: /* VIS I fandnot2 */
3698
                    gen_op_load_fpr_DT1(DFPREG(rs1));
3699
                    gen_op_load_fpr_DT0(DFPREG(rs2));
3700
                    tcg_gen_helper_0_0(helper_fandnot);
3701
                    gen_op_store_DT0_fpr(DFPREG(rd));
3702
                    break;
3703
                case 0x065: /* VIS I fandnot2s */
3704
                    gen_op_load_fpr_FT1(rs1);
3705
                    gen_op_load_fpr_FT0(rs2);
3706
                    tcg_gen_helper_0_0(helper_fandnots);
3707
                    gen_op_store_FT0_fpr(rd);
3708
                    break;
3709
                case 0x066: /* VIS I fnot2 */
3710
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3711
                    tcg_gen_helper_0_0(helper_fnot);
3712
                    gen_op_store_DT0_fpr(DFPREG(rd));
3713
                    break;
3714
                case 0x067: /* VIS I fnot2s */
3715
                    gen_op_load_fpr_FT1(rs2);
3716
                    tcg_gen_helper_0_0(helper_fnot);
3717
                    gen_op_store_FT0_fpr(rd);
3718
                    break;
3719
                case 0x068: /* VIS I fandnot1 */
3720
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3721
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3722
                    tcg_gen_helper_0_0(helper_fandnot);
3723
                    gen_op_store_DT0_fpr(DFPREG(rd));
3724
                    break;
3725
                case 0x069: /* VIS I fandnot1s */
3726
                    gen_op_load_fpr_FT0(rs1);
3727
                    gen_op_load_fpr_FT1(rs2);
3728
                    tcg_gen_helper_0_0(helper_fandnots);
3729
                    gen_op_store_FT0_fpr(rd);
3730
                    break;
3731
                case 0x06a: /* VIS I fnot1 */
3732
                    gen_op_load_fpr_DT1(DFPREG(rs1));
3733
                    tcg_gen_helper_0_0(helper_fnot);
3734
                    gen_op_store_DT0_fpr(DFPREG(rd));
3735
                    break;
3736
                case 0x06b: /* VIS I fnot1s */
3737
                    gen_op_load_fpr_FT1(rs1);
3738
                    tcg_gen_helper_0_0(helper_fnot);
3739
                    gen_op_store_FT0_fpr(rd);
3740
                    break;
3741
                case 0x06c: /* VIS I fxor */
3742
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3743
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3744
                    tcg_gen_helper_0_0(helper_fxor);
3745
                    gen_op_store_DT0_fpr(DFPREG(rd));
3746
                    break;
3747
                case 0x06d: /* VIS I fxors */
3748
                    gen_op_load_fpr_FT0(rs1);
3749
                    gen_op_load_fpr_FT1(rs2);
3750
                    tcg_gen_helper_0_0(helper_fxors);
3751
                    gen_op_store_FT0_fpr(rd);
3752
                    break;
3753
                case 0x06e: /* VIS I fnand */
3754
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3755
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3756
                    tcg_gen_helper_0_0(helper_fnand);
3757
                    gen_op_store_DT0_fpr(DFPREG(rd));
3758
                    break;
3759
                case 0x06f: /* VIS I fnands */
3760
                    gen_op_load_fpr_FT0(rs1);
3761
                    gen_op_load_fpr_FT1(rs2);
3762
                    tcg_gen_helper_0_0(helper_fnands);
3763
                    gen_op_store_FT0_fpr(rd);
3764
                    break;
3765
                case 0x070: /* VIS I fand */
3766
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3767
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3768
                    tcg_gen_helper_0_0(helper_fand);
3769
                    gen_op_store_DT0_fpr(DFPREG(rd));
3770
                    break;
3771
                case 0x071: /* VIS I fands */
3772
                    gen_op_load_fpr_FT0(rs1);
3773
                    gen_op_load_fpr_FT1(rs2);
3774
                    tcg_gen_helper_0_0(helper_fands);
3775
                    gen_op_store_FT0_fpr(rd);
3776
                    break;
3777
                case 0x072: /* VIS I fxnor */
3778
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3779
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3780
                    tcg_gen_helper_0_0(helper_fxnor);
3781
                    gen_op_store_DT0_fpr(DFPREG(rd));
3782
                    break;
3783
                case 0x073: /* VIS I fxnors */
3784
                    gen_op_load_fpr_FT0(rs1);
3785
                    gen_op_load_fpr_FT1(rs2);
3786
                    tcg_gen_helper_0_0(helper_fxnors);
3787
                    gen_op_store_FT0_fpr(rd);
3788
                    break;
3789
                case 0x074: /* VIS I fsrc1 */
3790
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3791
                    gen_op_store_DT0_fpr(DFPREG(rd));
3792
                    break;
3793
                case 0x075: /* VIS I fsrc1s */
3794
                    gen_op_load_fpr_FT0(rs1);
3795
                    gen_op_store_FT0_fpr(rd);
3796
                    break;
3797
                case 0x076: /* VIS I fornot2 */
3798
                    gen_op_load_fpr_DT1(DFPREG(rs1));
3799
                    gen_op_load_fpr_DT0(DFPREG(rs2));
3800
                    tcg_gen_helper_0_0(helper_fornot);
3801
                    gen_op_store_DT0_fpr(DFPREG(rd));
3802
                    break;
3803
                case 0x077: /* VIS I fornot2s */
3804
                    gen_op_load_fpr_FT1(rs1);
3805
                    gen_op_load_fpr_FT0(rs2);
3806
                    tcg_gen_helper_0_0(helper_fornots);
3807
                    gen_op_store_FT0_fpr(rd);
3808
                    break;
3809
                case 0x078: /* VIS I fsrc2 */
3810
                    gen_op_load_fpr_DT0(DFPREG(rs2));
3811
                    gen_op_store_DT0_fpr(DFPREG(rd));
3812
                    break;
3813
                case 0x079: /* VIS I fsrc2s */
3814
                    gen_op_load_fpr_FT0(rs2);
3815
                    gen_op_store_FT0_fpr(rd);
3816
                    break;
3817
                case 0x07a: /* VIS I fornot1 */
3818
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3819
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3820
                    tcg_gen_helper_0_0(helper_fornot);
3821
                    gen_op_store_DT0_fpr(DFPREG(rd));
3822
                    break;
3823
                case 0x07b: /* VIS I fornot1s */
3824
                    gen_op_load_fpr_FT0(rs1);
3825
                    gen_op_load_fpr_FT1(rs2);
3826
                    tcg_gen_helper_0_0(helper_fornots);
3827
                    gen_op_store_FT0_fpr(rd);
3828
                    break;
3829
                case 0x07c: /* VIS I for */
3830
                    gen_op_load_fpr_DT0(DFPREG(rs1));
3831
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3832
                    tcg_gen_helper_0_0(helper_for);
3833
                    gen_op_store_DT0_fpr(DFPREG(rd));
3834
                    break;
3835
                case 0x07d: /* VIS I fors */
3836
                    gen_op_load_fpr_FT0(rs1);
3837
                    gen_op_load_fpr_FT1(rs2);
3838
                    tcg_gen_helper_0_0(helper_fors);
3839
                    gen_op_store_FT0_fpr(rd);
3840
                    break;
3841
                case 0x07e: /* VIS I fone */
3842
                    tcg_gen_helper_0_0(helper_movl_DT0_1);
3843
                    gen_op_store_DT0_fpr(DFPREG(rd));
3844
                    break;
3845
                case 0x07f: /* VIS I fones */
3846
                    tcg_gen_helper_0_0(helper_movl_FT0_1);
3847
                    gen_op_store_FT0_fpr(rd);
3848
                    break;
3849
                case 0x080: /* VIS I shutdown */
3850
                case 0x081: /* VIS II siam */
3851
                    // XXX
3852
                    goto illegal_insn;
3853
                default:
3854
                    goto illegal_insn;
3855
                }
3856
#else
3857
                goto ncp_insn;
3858
#endif
3859
            } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
3860
#ifdef TARGET_SPARC64
3861
                goto illegal_insn;
3862
#else
3863
                goto ncp_insn;
3864
#endif
3865
#ifdef TARGET_SPARC64
3866
            } else if (xop == 0x39) { /* V9 return */
3867
                save_state(dc, cpu_cond);
3868
                cpu_src1 = get_src1(insn, cpu_src1);
3869
                if (IS_IMM) {   /* immediate */
3870
                    rs2 = GET_FIELDs(insn, 19, 31);
3871
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, (int)rs2);
3872
                } else {                /* register */
3873
                    rs2 = GET_FIELD(insn, 27, 31);
3874
                    if (rs2) {
3875
                        gen_movl_reg_TN(rs2, cpu_src2);
3876
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
3877
                    } else
3878
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
3879
                }
3880
                tcg_gen_helper_0_0(helper_restore);
3881
                gen_mov_pc_npc(dc, cpu_cond);
3882
                tcg_gen_helper_0_2(helper_check_align, cpu_dst, tcg_const_i32(3));
3883
                tcg_gen_mov_tl(cpu_npc, cpu_dst);
3884
                dc->npc = DYNAMIC_PC;
3885
                goto jmp_insn;
3886
#endif
3887
            } else {
3888
                cpu_src1 = get_src1(insn, cpu_src1);
3889
                if (IS_IMM) {   /* immediate */
3890
                    rs2 = GET_FIELDs(insn, 19, 31);
3891
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, (int)rs2);
3892
                } else {                /* register */
3893
                    rs2 = GET_FIELD(insn, 27, 31);
3894
                    if (rs2) {
3895
                        gen_movl_reg_TN(rs2, cpu_src2);
3896
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
3897
                    } else
3898
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
3899
                }
3900
                switch (xop) {
3901
                case 0x38:      /* jmpl */
3902
                    {
3903
                        gen_movl_TN_reg(rd, tcg_const_tl(dc->pc));
3904
                        gen_mov_pc_npc(dc, cpu_cond);
3905
                        tcg_gen_helper_0_2(helper_check_align, cpu_dst, tcg_const_i32(3));
3906
                        tcg_gen_mov_tl(cpu_npc, cpu_dst);
3907
                        dc->npc = DYNAMIC_PC;
3908
                    }
3909
                    goto jmp_insn;
3910
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
3911
                case 0x39:      /* rett, V9 return */
3912
                    {
3913
                        if (!supervisor(dc))
3914
                            goto priv_insn;
3915
                        gen_mov_pc_npc(dc, cpu_cond);
3916
                        tcg_gen_helper_0_2(helper_check_align, cpu_dst, tcg_const_i32(3));
3917
                        tcg_gen_mov_tl(cpu_npc, cpu_dst);
3918
                        dc->npc = DYNAMIC_PC;
3919
                        tcg_gen_helper_0_0(helper_rett);
3920
                    }
3921
                    goto jmp_insn;
3922
#endif
3923
                case 0x3b: /* flush */
3924
                    tcg_gen_helper_0_1(helper_flush, cpu_dst);
3925
                    break;
3926
                case 0x3c:      /* save */
3927
                    save_state(dc, cpu_cond);
3928
                    tcg_gen_helper_0_0(helper_save);
3929
                    gen_movl_TN_reg(rd, cpu_dst);
3930
                    break;
3931
                case 0x3d:      /* restore */
3932
                    save_state(dc, cpu_cond);
3933
                    tcg_gen_helper_0_0(helper_restore);
3934
                    gen_movl_TN_reg(rd, cpu_dst);
3935
                    break;
3936
#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
3937
                case 0x3e:      /* V9 done/retry */
3938
                    {
3939
                        switch (rd) {
3940
                        case 0:
3941
                            if (!supervisor(dc))
3942
                                goto priv_insn;
3943
                            dc->npc = DYNAMIC_PC;
3944
                            dc->pc = DYNAMIC_PC;
3945
                            tcg_gen_helper_0_0(helper_done);
3946
                            goto jmp_insn;
3947
                        case 1:
3948
                            if (!supervisor(dc))
3949
                                goto priv_insn;
3950
                            dc->npc = DYNAMIC_PC;
3951
                            dc->pc = DYNAMIC_PC;
3952
                            tcg_gen_helper_0_0(helper_retry);
3953
                            goto jmp_insn;
3954
                        default:
3955
                            goto illegal_insn;
3956
                        }
3957
                    }
3958
                    break;
3959
#endif
3960
                default:
3961
                    goto illegal_insn;
3962
                }
3963
            }
3964
            break;
3965
        }
3966
        break;
3967
    case 3:                     /* load/store instructions */
3968
        {
3969
            unsigned int xop = GET_FIELD(insn, 7, 12);
3970

    
3971
            save_state(dc, cpu_cond);
3972
            cpu_src1 = get_src1(insn, cpu_src1);
3973
            if (xop == 0x3c || xop == 0x3e)
3974
            {
3975
                rs2 = GET_FIELD(insn, 27, 31);
3976
                gen_movl_reg_TN(rs2, cpu_src2);
3977
            }
3978
            else if (IS_IMM) {       /* immediate */
3979
                rs2 = GET_FIELDs(insn, 19, 31);
3980
                tcg_gen_addi_tl(cpu_addr, cpu_src1, (int)rs2);
3981
            } else {            /* register */
3982
                rs2 = GET_FIELD(insn, 27, 31);
3983
                if (rs2 != 0) {
3984
                    gen_movl_reg_TN(rs2, cpu_src2);
3985
                    tcg_gen_add_tl(cpu_addr, cpu_src1, cpu_src2);
3986
                } else
3987
                    tcg_gen_mov_tl(cpu_addr, cpu_src1);
3988
            }
3989
            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
3990
                (xop > 0x17 && xop <= 0x1d ) ||
3991
                (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
3992
                switch (xop) {
3993
                case 0x0:       /* load unsigned word */
3994
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
3995
                    ABI32_MASK(cpu_addr);
3996
                    tcg_gen_qemu_ld32u(cpu_val, cpu_addr, dc->mem_idx);
3997
                    break;
3998
                case 0x1:       /* load unsigned byte */
3999
                    ABI32_MASK(cpu_addr);
4000
                    tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx);
4001
                    break;
4002
                case 0x2:       /* load unsigned halfword */
4003
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
4004
                    ABI32_MASK(cpu_addr);
4005
                    tcg_gen_qemu_ld16u(cpu_val, cpu_addr, dc->mem_idx);
4006
                    break;
4007
                case 0x3:       /* load double word */
4008
                    if (rd & 1)
4009
                        goto illegal_insn;
4010
                    else {
4011
                        tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4012
                        ABI32_MASK(cpu_addr);
4013
                        tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
4014
                        tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
4015
                        tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffffULL);
4016
                        gen_movl_TN_reg(rd + 1, cpu_tmp0);
4017
                        tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
4018
                        tcg_gen_trunc_i64_tl(cpu_val, cpu_tmp64);
4019
                        tcg_gen_andi_tl(cpu_val, cpu_val, 0xffffffffULL);
4020
                    }
4021
                    break;
4022
                case 0x9:       /* load signed byte */
4023
                    ABI32_MASK(cpu_addr);
4024
                    tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
4025
                    break;
4026
                case 0xa:       /* load signed halfword */
4027
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
4028
                    ABI32_MASK(cpu_addr);
4029
                    tcg_gen_qemu_ld16s(cpu_val, cpu_addr, dc->mem_idx);
4030
                    break;
4031
                case 0xd:       /* ldstub -- XXX: should be atomically */
4032
                    ABI32_MASK(cpu_addr);
4033
                    tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
4034
                    tcg_gen_qemu_st8(tcg_const_tl(0xff), cpu_addr, dc->mem_idx);
4035
                    break;
4036
                case 0x0f:      /* swap register with memory. Also atomically */
4037
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4038
                    gen_movl_reg_TN(rd, cpu_val);
4039
                    ABI32_MASK(cpu_addr);
4040
                    tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
4041
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
4042
                    tcg_gen_extu_i32_tl(cpu_val, cpu_tmp32);
4043
                    break;
4044
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4045
                case 0x10:      /* load word alternate */
4046
#ifndef TARGET_SPARC64
4047
                    if (IS_IMM)
4048
                        goto illegal_insn;
4049
                    if (!supervisor(dc))
4050
                        goto priv_insn;
4051
#endif
4052
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4053
                    gen_ld_asi(cpu_val, cpu_addr, insn, 4, 0);
4054
                    break;
4055
                case 0x11:      /* load unsigned byte alternate */
4056
#ifndef TARGET_SPARC64
4057
                    if (IS_IMM)
4058
                        goto illegal_insn;
4059
                    if (!supervisor(dc))
4060
                        goto priv_insn;
4061
#endif
4062
                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 0);
4063
                    break;
4064
                case 0x12:      /* load unsigned halfword alternate */
4065
#ifndef TARGET_SPARC64
4066
                    if (IS_IMM)
4067
                        goto illegal_insn;
4068
                    if (!supervisor(dc))
4069
                        goto priv_insn;
4070
#endif
4071
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
4072
                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 0);
4073
                    break;
4074
                case 0x13:      /* load double word alternate */
4075
#ifndef TARGET_SPARC64
4076
                    if (IS_IMM)
4077
                        goto illegal_insn;
4078
                    if (!supervisor(dc))
4079
                        goto priv_insn;
4080
#endif
4081
                    if (rd & 1)
4082
                        goto illegal_insn;
4083
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4084
                    gen_ldda_asi(cpu_tmp0, cpu_val, cpu_addr, insn);
4085
                    gen_movl_TN_reg(rd + 1, cpu_tmp0);
4086
                    break;
4087
                case 0x19:      /* load signed byte alternate */
4088
#ifndef TARGET_SPARC64
4089
                    if (IS_IMM)
4090
                        goto illegal_insn;
4091
                    if (!supervisor(dc))
4092
                        goto priv_insn;
4093
#endif
4094
                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 1);
4095
                    break;
4096
                case 0x1a:      /* load signed halfword alternate */
4097
#ifndef TARGET_SPARC64
4098
                    if (IS_IMM)
4099
                        goto illegal_insn;
4100
                    if (!supervisor(dc))
4101
                        goto priv_insn;
4102
#endif
4103
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
4104
                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 1);
4105
                    break;
4106
                case 0x1d:      /* ldstuba -- XXX: should be atomically */
4107
#ifndef TARGET_SPARC64
4108
                    if (IS_IMM)
4109
                        goto illegal_insn;
4110
                    if (!supervisor(dc))
4111
                        goto priv_insn;
4112
#endif
4113
                    gen_ldstub_asi(cpu_val, cpu_addr, insn);
4114
                    break;
4115
                case 0x1f:      /* swap reg with alt. memory. Also atomically */
4116
#ifndef TARGET_SPARC64
4117
                    if (IS_IMM)
4118
                        goto illegal_insn;
4119
                    if (!supervisor(dc))
4120
                        goto priv_insn;
4121
#endif
4122
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4123
                    gen_movl_reg_TN(rd, cpu_val);
4124
                    gen_swap_asi(cpu_val, cpu_addr, insn);
4125
                    break;
4126

    
4127
#ifndef TARGET_SPARC64
4128
                case 0x30: /* ldc */
4129
                case 0x31: /* ldcsr */
4130
                case 0x33: /* lddc */
4131
                    goto ncp_insn;
4132
#endif
4133
#endif
4134
#ifdef TARGET_SPARC64
4135
                case 0x08: /* V9 ldsw */
4136
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4137
                    ABI32_MASK(cpu_addr);
4138
                    tcg_gen_qemu_ld32s(cpu_val, cpu_addr, dc->mem_idx);
4139
                    break;
4140
                case 0x0b: /* V9 ldx */
4141
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4142
                    ABI32_MASK(cpu_addr);
4143
                    tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx);
4144
                    break;
4145
                case 0x18: /* V9 ldswa */
4146
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4147
                    gen_ld_asi(cpu_val, cpu_addr, insn, 4, 1);
4148
                    break;
4149
                case 0x1b: /* V9 ldxa */
4150
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4151
                    gen_ld_asi(cpu_val, cpu_addr, insn, 8, 0);
4152
                    break;
4153
                case 0x2d: /* V9 prefetch, no effect */
4154
                    goto skip_move;
4155
                case 0x30: /* V9 ldfa */
4156
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4157
                    gen_ldf_asi(cpu_addr, insn, 4, rd);
4158
                    goto skip_move;
4159
                case 0x33: /* V9 lddfa */
4160
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4161
                    gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd));
4162
                    goto skip_move;
4163
                case 0x3d: /* V9 prefetcha, no effect */
4164
                    goto skip_move;
4165
                case 0x32: /* V9 ldqfa */
4166
#if defined(CONFIG_USER_ONLY)
4167
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4168
                    gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd));
4169
                    goto skip_move;
4170
#else
4171
                    goto nfpu_insn;
4172
#endif
4173
#endif
4174
                default:
4175
                    goto illegal_insn;
4176
                }
4177
                gen_movl_TN_reg(rd, cpu_val);
4178
#ifdef TARGET_SPARC64
4179
            skip_move: ;
4180
#endif
4181
            } else if (xop >= 0x20 && xop < 0x24) {
4182
                if (gen_trap_ifnofpu(dc, cpu_cond))
4183
                    goto jmp_insn;
4184
                switch (xop) {
4185
                case 0x20:      /* load fpreg */
4186
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4187
                    tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
4188
                    tcg_gen_st_i32(cpu_tmp32, cpu_env,
4189
                                   offsetof(CPUState, fpr[rd]));
4190
                    break;
4191
                case 0x21:      /* load fsr */
4192
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4193
                    tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
4194
                    tcg_gen_st_i32(cpu_tmp32, cpu_env,
4195
                                   offsetof(CPUState, ft0));
4196
                    tcg_gen_helper_0_0(helper_ldfsr);
4197
                    break;
4198
                case 0x22:      /* load quad fpreg */
4199
#if defined(CONFIG_USER_ONLY)
4200
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr,
4201
                                       tcg_const_i32(7));
4202
                    tcg_gen_helper_0_1(helper_ldqf, cpu_addr);
4203
                    gen_op_store_QT0_fpr(QFPREG(rd));
4204
                    break;
4205
#else
4206
                    goto nfpu_insn;
4207
#endif
4208
                case 0x23:      /* load double fpreg */
4209
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr,
4210
                                       tcg_const_i32(7));
4211
                    tcg_gen_helper_0_2(helper_lddf, cpu_addr,
4212
                                       tcg_const_i32(dc->mem_idx));
4213
                    gen_op_store_DT0_fpr(DFPREG(rd));
4214
                    break;
4215
                default:
4216
                    goto illegal_insn;
4217
                }
4218
            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) || \
4219
                       xop == 0xe || xop == 0x1e) {
4220
                gen_movl_reg_TN(rd, cpu_val);
4221
                switch (xop) {
4222
                case 0x4: /* store word */
4223
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4224
                    ABI32_MASK(cpu_addr);
4225
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
4226
                    break;
4227
                case 0x5: /* store byte */
4228
                    ABI32_MASK(cpu_addr);
4229
                    tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx);
4230
                    break;
4231
                case 0x6: /* store halfword */
4232
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
4233
                    ABI32_MASK(cpu_addr);
4234
                    tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx);
4235
                    break;
4236
                case 0x7: /* store double word */
4237
                    if (rd & 1)
4238
                        goto illegal_insn;
4239
                    else {
4240
                        TCGv r_low;
4241

    
4242
                        tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4243
                        r_low = tcg_temp_new(TCG_TYPE_I32);
4244
                        gen_movl_reg_TN(rd + 1, r_low);
4245
#ifndef __i386__
4246
                        tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, cpu_val,
4247
                                           r_low);
4248
                        tcg_gen_qemu_st64(cpu_tmp64, cpu_addr, dc->mem_idx);
4249
#else /* __i386__ */
4250
                        tcg_gen_st_tl(cpu_val, cpu_env, offsetof(CPUState, t1));
4251
                        tcg_gen_st_tl(r_low, cpu_env, offsetof(CPUState, t2));
4252
                        tcg_gen_helper_0_2(helper_std_i386, cpu_addr,
4253
                                           tcg_const_i32(dc->mem_idx));
4254
#endif /* __i386__ */
4255
                    }
4256
                    break;
4257
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4258
                case 0x14: /* store word alternate */
4259
#ifndef TARGET_SPARC64
4260
                    if (IS_IMM)
4261
                        goto illegal_insn;
4262
                    if (!supervisor(dc))
4263
                        goto priv_insn;
4264
#endif
4265
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4266
                    gen_st_asi(cpu_val, cpu_addr, insn, 4);
4267
                    break;
4268
                case 0x15: /* store byte alternate */
4269
#ifndef TARGET_SPARC64
4270
                    if (IS_IMM)
4271
                        goto illegal_insn;
4272
                    if (!supervisor(dc))
4273
                        goto priv_insn;
4274
#endif
4275
                    gen_st_asi(cpu_val, cpu_addr, insn, 1);
4276
                    break;
4277
                case 0x16: /* store halfword alternate */
4278
#ifndef TARGET_SPARC64
4279
                    if (IS_IMM)
4280
                        goto illegal_insn;
4281
                    if (!supervisor(dc))
4282
                        goto priv_insn;
4283
#endif
4284
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(1));
4285
                    gen_st_asi(cpu_val, cpu_addr, insn, 2);
4286
                    break;
4287
                case 0x17: /* store double word alternate */
4288
#ifndef TARGET_SPARC64
4289
                    if (IS_IMM)
4290
                        goto illegal_insn;
4291
                    if (!supervisor(dc))
4292
                        goto priv_insn;
4293
#endif
4294
                    if (rd & 1)
4295
                        goto illegal_insn;
4296
                    else {
4297
                        tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4298
                        gen_stda_asi(cpu_val, cpu_addr, insn, rd);
4299
                    }
4300
                    break;
4301
#endif
4302
#ifdef TARGET_SPARC64
4303
                case 0x0e: /* V9 stx */
4304
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4305
                    ABI32_MASK(cpu_addr);
4306
                    tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx);
4307
                    break;
4308
                case 0x1e: /* V9 stxa */
4309
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4310
                    gen_st_asi(cpu_val, cpu_addr, insn, 8);
4311
                    break;
4312
#endif
4313
                default:
4314
                    goto illegal_insn;
4315
                }
4316
            } else if (xop > 0x23 && xop < 0x28) {
4317
                if (gen_trap_ifnofpu(dc, cpu_cond))
4318
                    goto jmp_insn;
4319
                switch (xop) {
4320
                case 0x24: /* store fpreg */
4321
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4322
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
4323
                                   offsetof(CPUState, fpr[rd]));
4324
                    tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx);
4325
                    break;
4326
                case 0x25: /* stfsr, V9 stxfsr */
4327
#ifdef CONFIG_USER_ONLY
4328
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4329
#endif
4330
                    tcg_gen_helper_0_0(helper_stfsr);
4331
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
4332
                                   offsetof(CPUState, ft0));
4333
                    tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx);
4334
                    break;
4335
                case 0x26:
4336
#ifdef TARGET_SPARC64
4337
#if defined(CONFIG_USER_ONLY)
4338
                    /* V9 stqf, store quad fpreg */
4339
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr,
4340
                                       tcg_const_i32(7));
4341
                    gen_op_load_fpr_QT0(QFPREG(rd));
4342
                    tcg_gen_helper_0_1(helper_stqf, cpu_addr);
4343
                    break;
4344
#else
4345
                    goto nfpu_insn;
4346
#endif
4347
#else /* !TARGET_SPARC64 */
4348
                    /* stdfq, store floating point queue */
4349
#if defined(CONFIG_USER_ONLY)
4350
                    goto illegal_insn;
4351
#else
4352
                    if (!supervisor(dc))
4353
                        goto priv_insn;
4354
                    if (gen_trap_ifnofpu(dc, cpu_cond))
4355
                        goto jmp_insn;
4356
                    goto nfq_insn;
4357
#endif
4358
#endif
4359
                case 0x27: /* store double fpreg */
4360
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr,
4361
                                       tcg_const_i32(7));
4362
                    gen_op_load_fpr_DT0(DFPREG(rd));
4363
                    tcg_gen_helper_0_2(helper_stdf, cpu_addr,
4364
                                       tcg_const_i32(dc->mem_idx));
4365
                    break;
4366
                default:
4367
                    goto illegal_insn;
4368
                }
4369
            } else if (xop > 0x33 && xop < 0x3f) {
4370
                switch (xop) {
4371
#ifdef TARGET_SPARC64
4372
                case 0x34: /* V9 stfa */
4373
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4374
                    gen_op_load_fpr_FT0(rd);
4375
                    gen_stf_asi(cpu_addr, insn, 4, rd);
4376
                    break;
4377
                case 0x36: /* V9 stqfa */
4378
#if defined(CONFIG_USER_ONLY)
4379
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4380
                    gen_op_load_fpr_QT0(QFPREG(rd));
4381
                    gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd));
4382
                    break;
4383
#else
4384
                    goto nfpu_insn;
4385
#endif
4386
                case 0x37: /* V9 stdfa */
4387
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4388
                    gen_op_load_fpr_DT0(DFPREG(rd));
4389
                    gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
4390
                    break;
4391
                case 0x3c: /* V9 casa */
4392
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4393
                    gen_cas_asi(cpu_val, cpu_addr, cpu_val, insn, rd);
4394
                    gen_movl_TN_reg(rd, cpu_val);
4395
                    break;
4396
                case 0x3e: /* V9 casxa */
4397
                    tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
4398
                    gen_casx_asi(cpu_val, cpu_addr, cpu_val, insn, rd);
4399
                    gen_movl_TN_reg(rd, cpu_val);
4400
                    break;
4401
#else
4402
                case 0x34: /* stc */
4403
                case 0x35: /* stcsr */
4404
                case 0x36: /* stdcq */
4405
                case 0x37: /* stdc */
4406
                    goto ncp_insn;
4407
#endif
4408
                default:
4409
                    goto illegal_insn;
4410
                }
4411
            }
4412
            else
4413
                goto illegal_insn;
4414
        }
4415
        break;
4416
    }
4417
    /* default case for non jump instructions */
4418
    if (dc->npc == DYNAMIC_PC) {
4419
        dc->pc = DYNAMIC_PC;
4420
        gen_op_next_insn();
4421
    } else if (dc->npc == JUMP_PC) {
4422
        /* we can do a static jump */
4423
        gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
4424
        dc->is_br = 1;
4425
    } else {
4426
        dc->pc = dc->npc;
4427
        dc->npc = dc->npc + 4;
4428
    }
4429
 jmp_insn:
4430
    return;
4431
 illegal_insn:
4432
    save_state(dc, cpu_cond);
4433
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_ILL_INSN));
4434
    dc->is_br = 1;
4435
    return;
4436
#if !defined(CONFIG_USER_ONLY)
4437
 priv_insn:
4438
    save_state(dc, cpu_cond);
4439
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_PRIV_INSN));
4440
    dc->is_br = 1;
4441
    return;
4442
 nfpu_insn:
4443
    save_state(dc, cpu_cond);
4444
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
4445
    dc->is_br = 1;
4446
    return;
4447
#ifndef TARGET_SPARC64
4448
 nfq_insn:
4449
    save_state(dc, cpu_cond);
4450
    gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
4451
    dc->is_br = 1;
4452
    return;
4453
#endif
4454
#endif
4455
#ifndef TARGET_SPARC64
4456
 ncp_insn:
4457
    save_state(dc, cpu_cond);
4458
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_NCP_INSN));
4459
    dc->is_br = 1;
4460
    return;
4461
#endif
4462
}
4463

    
4464
static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
4465
{
4466
}
4467

    
4468
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
4469
                                                 int spc, CPUSPARCState *env)
4470
{
4471
    target_ulong pc_start, last_pc;
4472
    uint16_t *gen_opc_end;
4473
    DisasContext dc1, *dc = &dc1;
4474
    int j, lj = -1;
4475

    
4476
    memset(dc, 0, sizeof(DisasContext));
4477
    dc->tb = tb;
4478
    pc_start = tb->pc;
4479
    dc->pc = pc_start;
4480
    last_pc = dc->pc;
4481
    dc->npc = (target_ulong) tb->cs_base;
4482
    dc->mem_idx = cpu_mmu_index(env);
4483
    dc->fpu_enabled = cpu_fpu_enabled(env);
4484
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4485

    
4486
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
4487
    cpu_tmp32 = tcg_temp_new(TCG_TYPE_I32);
4488
    cpu_tmp64 = tcg_temp_new(TCG_TYPE_I64);
4489

    
4490
    cpu_cond = cpu_T[2];
4491

    
4492
    do {
4493
        if (env->nb_breakpoints > 0) {
4494
            for(j = 0; j < env->nb_breakpoints; j++) {
4495
                if (env->breakpoints[j] == dc->pc) {
4496
                    if (dc->pc != pc_start)
4497
                        save_state(dc, cpu_cond);
4498
                    tcg_gen_helper_0_0(helper_debug);
4499
                    tcg_gen_exit_tb(0);
4500
                    dc->is_br = 1;
4501
                    goto exit_gen_loop;
4502
                }
4503
            }
4504
        }
4505
        if (spc) {
4506
            if (loglevel > 0)
4507
                fprintf(logfile, "Search PC...\n");
4508
            j = gen_opc_ptr - gen_opc_buf;
4509
            if (lj < j) {
4510
                lj++;
4511
                while (lj < j)
4512
                    gen_opc_instr_start[lj++] = 0;
4513
                gen_opc_pc[lj] = dc->pc;
4514
                gen_opc_npc[lj] = dc->npc;
4515
                gen_opc_instr_start[lj] = 1;
4516
            }
4517
        }
4518
        last_pc = dc->pc;
4519
        disas_sparc_insn(dc);
4520

    
4521
        if (dc->is_br)
4522
            break;
4523
        /* if the next PC is different, we abort now */
4524
        if (dc->pc != (last_pc + 4))
4525
            break;
4526
        /* if we reach a page boundary, we stop generation so that the
4527
           PC of a TT_TFAULT exception is always in the right page */
4528
        if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
4529
            break;
4530
        /* if single step mode, we generate only one instruction and
4531
           generate an exception */
4532
        if (env->singlestep_enabled) {
4533
            tcg_gen_movi_tl(cpu_pc, dc->pc);
4534
            tcg_gen_exit_tb(0);
4535
            break;
4536
        }
4537
    } while ((gen_opc_ptr < gen_opc_end) &&
4538
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
4539

    
4540
 exit_gen_loop:
4541
    if (!dc->is_br) {
4542
        if (dc->pc != DYNAMIC_PC &&
4543
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
4544
            /* static PC and NPC: we can use direct chaining */
4545
            gen_goto_tb(dc, 0, dc->pc, dc->npc);
4546
        } else {
4547
            if (dc->pc != DYNAMIC_PC)
4548
                tcg_gen_movi_tl(cpu_pc, dc->pc);
4549
            save_npc(dc, cpu_cond);
4550
            tcg_gen_exit_tb(0);
4551
        }
4552
    }
4553
    *gen_opc_ptr = INDEX_op_end;
4554
    if (spc) {
4555
        j = gen_opc_ptr - gen_opc_buf;
4556
        lj++;
4557
        while (lj <= j)
4558
            gen_opc_instr_start[lj++] = 0;
4559
#if 0
4560
        if (loglevel > 0) {
4561
            page_dump(logfile);
4562
        }
4563
#endif
4564
        gen_opc_jump_pc[0] = dc->jump_pc[0];
4565
        gen_opc_jump_pc[1] = dc->jump_pc[1];
4566
    } else {
4567
        tb->size = last_pc + 4 - pc_start;
4568
    }
4569
#ifdef DEBUG_DISAS
4570
    if (loglevel & CPU_LOG_TB_IN_ASM) {
4571
        fprintf(logfile, "--------------\n");
4572
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
4573
        target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
4574
        fprintf(logfile, "\n");
4575
    }
4576
#endif
4577
    return 0;
4578
}
4579

    
4580
int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
4581
{
4582
    return gen_intermediate_code_internal(tb, 0, env);
4583
}
4584

    
4585
int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
4586
{
4587
    return gen_intermediate_code_internal(tb, 1, env);
4588
}
4589

    
4590
void gen_intermediate_code_init(CPUSPARCState *env)
4591
{
4592
    unsigned int i;
4593
    static int inited;
4594
    static const char * const gregnames[8] = {
4595
        NULL, // g0 not used
4596
        "g1",
4597
        "g2",
4598
        "g3",
4599
        "g4",
4600
        "g5",
4601
        "g6",
4602
        "g7",
4603
    };
4604

    
4605
    /* init various static tables */
4606
    if (!inited) {
4607
        inited = 1;
4608

    
4609
        tcg_set_macro_func(&tcg_ctx, tcg_macro_func);
4610
        cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
4611
        cpu_regwptr = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
4612
                                         offsetof(CPUState, regwptr),
4613
                                         "regwptr");
4614
        //#if TARGET_LONG_BITS > HOST_LONG_BITS
4615
#ifdef TARGET_SPARC64
4616
        cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
4617
                                      TCG_AREG0, offsetof(CPUState, t0), "T0");
4618
        cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
4619
                                      TCG_AREG0, offsetof(CPUState, t1), "T1");
4620
        cpu_T[2] = tcg_global_mem_new(TCG_TYPE_TL,
4621
                                      TCG_AREG0, offsetof(CPUState, t2), "T2");
4622
        cpu_xcc = tcg_global_mem_new(TCG_TYPE_I32,
4623
                                     TCG_AREG0, offsetof(CPUState, xcc),
4624
                                     "xcc");
4625
#else
4626
        cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
4627
        cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
4628
        cpu_T[2] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T2");
4629
#endif
4630
        cpu_cc_src = tcg_global_mem_new(TCG_TYPE_TL,
4631
                                        TCG_AREG0, offsetof(CPUState, cc_src),
4632
                                        "cc_src");
4633
        cpu_cc_src2 = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4634
                                         offsetof(CPUState, cc_src2),
4635
                                         "cc_src2");
4636
        cpu_cc_dst = tcg_global_mem_new(TCG_TYPE_TL,
4637
                                        TCG_AREG0, offsetof(CPUState, cc_dst),
4638
                                        "cc_dst");
4639
        cpu_psr = tcg_global_mem_new(TCG_TYPE_I32,
4640
                                     TCG_AREG0, offsetof(CPUState, psr),
4641
                                     "psr");
4642
        cpu_fsr = tcg_global_mem_new(TCG_TYPE_TL,
4643
                                     TCG_AREG0, offsetof(CPUState, fsr),
4644
                                     "fsr");
4645
        cpu_pc = tcg_global_mem_new(TCG_TYPE_TL,
4646
                                    TCG_AREG0, offsetof(CPUState, pc),
4647
                                    "pc");
4648
        cpu_npc = tcg_global_mem_new(TCG_TYPE_TL,
4649
                                    TCG_AREG0, offsetof(CPUState, npc),
4650
                                    "npc");
4651
        for (i = 1; i < 8; i++)
4652
            cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4653
                                              offsetof(CPUState, gregs[i]),
4654
                                              gregnames[i]);
4655
    }
4656
}
4657

    
4658
void gen_pc_load(CPUState *env, TranslationBlock *tb,
4659
                unsigned long searched_pc, int pc_pos, void *puc)
4660
{
4661
    target_ulong npc;
4662
    env->pc = gen_opc_pc[pc_pos];
4663
    npc = gen_opc_npc[pc_pos];
4664
    if (npc == 1) {
4665
        /* dynamic NPC: already stored */
4666
    } else if (npc == 2) {
4667
        target_ulong t2 = (target_ulong)(unsigned long)puc;
4668
        /* jump PC: use T2 and the jump targets of the translation */
4669
        if (t2)
4670
            env->npc = gen_opc_jump_pc[0];
4671
        else
4672
            env->npc = gen_opc_jump_pc[1];
4673
    } else {
4674
        env->npc = npc;
4675
    }
4676
}