]> Git Repo - qemu.git/blame - target-sparc/translate.c
Use ext_i32_i64 instead of ext32s_i64
[qemu.git] / target-sparc / translate.c
CommitLineData
7a3f1944
FB
1/*
2 SPARC translation
3
4 Copyright (C) 2003 Thomas M. Ogrisegg <[email protected]>
3475187d 5 Copyright (C) 2003-2005 Fabrice Bellard
7a3f1944
FB
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/*
7a3f1944
FB
23 TODO-list:
24
3475187d 25 Rest of V9 instructions, VIS instructions
bd497938 26 NPC/PC static optimisations (use JUMP_TB when possible)
7a3f1944 27 Optimize synthetic instructions
bd497938 28*/
7a3f1944
FB
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"
1a2fb1c0 39#include "helper.h"
57fec1fe 40#include "tcg-op.h"
7a3f1944
FB
41
42#define DEBUG_DISAS
43
72cbca10
FB
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
1a2fb1c0 48/* global register indexes */
d9bdab86 49static TCGv cpu_env, cpu_T[3], cpu_regwptr, cpu_cc_src, cpu_cc_src2, cpu_cc_dst;
48d5c82b 50static TCGv cpu_psr, cpu_fsr, cpu_pc, cpu_npc, cpu_gregs[8];
dc99a3f2
BS
51#ifdef TARGET_SPARC64
52static TCGv cpu_xcc;
53#endif
1a2fb1c0
BS
54/* local register indexes (only used inside old micro ops) */
55static TCGv cpu_tmp0;
56
7a3f1944 57typedef struct DisasContext {
0f8a249a
BS
58 target_ulong pc; /* current Program Counter: integer or DYNAMIC_PC */
59 target_ulong npc; /* next PC: integer or DYNAMIC_PC or JUMP_PC */
72cbca10 60 target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
cf495bcf 61 int is_br;
e8af50a3 62 int mem_idx;
a80dde08 63 int fpu_enabled;
cf495bcf 64 struct TranslationBlock *tb;
7a3f1944
FB
65} DisasContext;
66
aaed909a
FB
67typedef struct sparc_def_t sparc_def_t;
68
62724a37
BS
69struct sparc_def_t {
70 const unsigned char *name;
71 target_ulong iu_version;
72 uint32_t fpu_version;
73 uint32_t mmu_version;
6d5f237a 74 uint32_t mmu_bm;
3deaeab7
BS
75 uint32_t mmu_ctpr_mask;
76 uint32_t mmu_cxr_mask;
77 uint32_t mmu_sfsr_mask;
78 uint32_t mmu_trcr_mask;
62724a37
BS
79};
80
aaed909a
FB
81static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name);
82
7a3f1944
FB
83extern FILE *logfile;
84extern int loglevel;
85
3475187d 86// This function uses non-native bit order
7a3f1944
FB
87#define GET_FIELD(X, FROM, TO) \
88 ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
89
3475187d
FB
90// This function uses the order in the manuals, i.e. bit 0 is 2^0
91#define GET_FIELD_SP(X, FROM, TO) \
92 GET_FIELD(X, 31 - (TO), 31 - (FROM))
93
94#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
46d38ba8 95#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
3475187d
FB
96
97#ifdef TARGET_SPARC64
19f329ad 98#define FFPREG(r) (r)
0387d928 99#define DFPREG(r) (((r & 1) << 5) | (r & 0x1e))
1f587329 100#define QFPREG(r) (((r & 1) << 5) | (r & 0x1c))
3475187d 101#else
19f329ad 102#define FFPREG(r) (r)
c185970a 103#define DFPREG(r) (r & 0x1e)
1f587329 104#define QFPREG(r) (r & 0x1c)
3475187d
FB
105#endif
106
107static int sign_extend(int x, int len)
108{
109 len = 32 - len;
110 return (x << len) >> len;
111}
112
7a3f1944
FB
113#define IS_IMM (insn & (1<<13))
114
cf495bcf 115static void disas_sparc_insn(DisasContext * dc);
7a3f1944 116
3475187d
FB
117#ifdef TARGET_SPARC64
118#define GEN32(func, NAME) \
a68156d0 119static GenOpFunc * const NAME ## _table [64] = { \
3475187d
FB
120NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \
121NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \
122NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11, \
123NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15, \
124NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19, \
125NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23, \
126NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27, \
127NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31, \
128NAME ## 32, 0, NAME ## 34, 0, NAME ## 36, 0, NAME ## 38, 0, \
129NAME ## 40, 0, NAME ## 42, 0, NAME ## 44, 0, NAME ## 46, 0, \
130NAME ## 48, 0, NAME ## 50, 0, NAME ## 52, 0, NAME ## 54, 0, \
131NAME ## 56, 0, NAME ## 58, 0, NAME ## 60, 0, NAME ## 62, 0, \
132}; \
133static inline void func(int n) \
134{ \
135 NAME ## _table[n](); \
136}
137#else
e8af50a3 138#define GEN32(func, NAME) \
a68156d0 139static GenOpFunc *const NAME ## _table [32] = { \
e8af50a3
FB
140NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3, \
141NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \
142NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11, \
143NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15, \
144NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19, \
145NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23, \
146NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27, \
147NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31, \
148}; \
149static inline void func(int n) \
150{ \
151 NAME ## _table[n](); \
152}
3475187d 153#endif
e8af50a3
FB
154
155/* floating point registers moves */
156GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fprf);
157GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fprf);
e8af50a3
FB
158GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fprf);
159GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fprf);
e8af50a3
FB
160
161GEN32(gen_op_load_fpr_DT0, gen_op_load_fpr_DT0_fprf);
162GEN32(gen_op_load_fpr_DT1, gen_op_load_fpr_DT1_fprf);
e8af50a3
FB
163GEN32(gen_op_store_DT0_fpr, gen_op_store_DT0_fpr_fprf);
164GEN32(gen_op_store_DT1_fpr, gen_op_store_DT1_fpr_fprf);
e8af50a3 165
1f587329
BS
166#if defined(CONFIG_USER_ONLY)
167GEN32(gen_op_load_fpr_QT0, gen_op_load_fpr_QT0_fprf);
168GEN32(gen_op_load_fpr_QT1, gen_op_load_fpr_QT1_fprf);
169GEN32(gen_op_store_QT0_fpr, gen_op_store_QT0_fpr_fprf);
170GEN32(gen_op_store_QT1_fpr, gen_op_store_QT1_fpr_fprf);
171#endif
172
81ad8ba2
BS
173/* moves */
174#ifdef CONFIG_USER_ONLY
3475187d 175#define supervisor(dc) 0
81ad8ba2 176#ifdef TARGET_SPARC64
e9ebed4d 177#define hypervisor(dc) 0
81ad8ba2 178#endif
3475187d 179#define gen_op_ldst(name) gen_op_##name##_raw()
3475187d 180#else
6f27aba6 181#define supervisor(dc) (dc->mem_idx >= 1)
81ad8ba2
BS
182#ifdef TARGET_SPARC64
183#define hypervisor(dc) (dc->mem_idx == 2)
6f27aba6
BS
184#define OP_LD_TABLE(width) \
185 static GenOpFunc * const gen_op_##width[] = { \
186 &gen_op_##width##_user, \
187 &gen_op_##width##_kernel, \
188 &gen_op_##width##_hypv, \
189 };
190#else
0f8a249a 191#define OP_LD_TABLE(width) \
a68156d0 192 static GenOpFunc * const gen_op_##width[] = { \
0f8a249a
BS
193 &gen_op_##width##_user, \
194 &gen_op_##width##_kernel, \
81ad8ba2 195 };
3475187d 196#endif
6f27aba6
BS
197#define gen_op_ldst(name) (*gen_op_##name[dc->mem_idx])()
198#endif
e8af50a3 199
81ad8ba2 200#ifndef CONFIG_USER_ONLY
b25deda7
BS
201#ifdef __i386__
202OP_LD_TABLE(std);
203#endif /* __i386__ */
e8af50a3
FB
204OP_LD_TABLE(stf);
205OP_LD_TABLE(stdf);
206OP_LD_TABLE(ldf);
207OP_LD_TABLE(lddf);
81ad8ba2
BS
208#endif
209
1a2fb1c0
BS
210#ifdef TARGET_ABI32
211#define ABI32_MASK(addr) tcg_gen_andi_i64(addr, addr, 0xffffffffULL);
212#else
213#define ABI32_MASK(addr)
214#endif
3391c818 215
1a2fb1c0 216static inline void gen_movl_simm_T1(int32_t val)
81ad8ba2 217{
1a2fb1c0 218 tcg_gen_movi_tl(cpu_T[1], val);
81ad8ba2
BS
219}
220
1a2fb1c0 221static inline void gen_movl_reg_TN(int reg, TCGv tn)
81ad8ba2 222{
1a2fb1c0
BS
223 if (reg == 0)
224 tcg_gen_movi_tl(tn, 0);
225 else if (reg < 8)
f5069b26 226 tcg_gen_mov_tl(tn, cpu_gregs[reg]);
1a2fb1c0 227 else {
1a2fb1c0 228 tcg_gen_ld_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
81ad8ba2
BS
229 }
230}
231
1a2fb1c0 232static inline void gen_movl_reg_T0(int reg)
81ad8ba2 233{
1a2fb1c0 234 gen_movl_reg_TN(reg, cpu_T[0]);
81ad8ba2
BS
235}
236
1a2fb1c0 237static inline void gen_movl_reg_T1(int reg)
81ad8ba2 238{
1a2fb1c0 239 gen_movl_reg_TN(reg, cpu_T[1]);
81ad8ba2
BS
240}
241
b25deda7
BS
242#ifdef __i386__
243static inline void gen_movl_reg_T2(int reg)
244{
245 gen_movl_reg_TN(reg, cpu_T[2]);
246}
247
248#endif /* __i386__ */
1a2fb1c0 249static inline void gen_movl_TN_reg(int reg, TCGv tn)
81ad8ba2 250{
1a2fb1c0
BS
251 if (reg == 0)
252 return;
253 else if (reg < 8)
f5069b26 254 tcg_gen_mov_tl(cpu_gregs[reg], tn);
1a2fb1c0 255 else {
1a2fb1c0 256 tcg_gen_st_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
81ad8ba2
BS
257 }
258}
259
1a2fb1c0 260static inline void gen_movl_T0_reg(int reg)
3475187d 261{
1a2fb1c0 262 gen_movl_TN_reg(reg, cpu_T[0]);
3475187d
FB
263}
264
1a2fb1c0 265static inline void gen_movl_T1_reg(int reg)
3475187d 266{
1a2fb1c0 267 gen_movl_TN_reg(reg, cpu_T[1]);
3475187d
FB
268}
269
1a2fb1c0 270static inline void gen_op_movl_T0_env(size_t offset)
7a3f1944 271{
1a2fb1c0 272 tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
7a3f1944
FB
273}
274
1a2fb1c0 275static inline void gen_op_movl_env_T0(size_t offset)
7a3f1944 276{
1a2fb1c0 277 tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
7a3f1944
FB
278}
279
1a2fb1c0 280static inline void gen_op_movtl_T0_env(size_t offset)
7a3f1944 281{
1a2fb1c0 282 tcg_gen_ld_tl(cpu_T[0], cpu_env, offset);
7a3f1944
FB
283}
284
1a2fb1c0 285static inline void gen_op_movtl_env_T0(size_t offset)
7a3f1944 286{
1a2fb1c0 287 tcg_gen_st_tl(cpu_T[0], cpu_env, offset);
7a3f1944
FB
288}
289
1a2fb1c0 290static inline void gen_op_add_T1_T0(void)
7a3f1944 291{
1a2fb1c0 292 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
7a3f1944
FB
293}
294
1a2fb1c0 295static inline void gen_op_or_T1_T0(void)
7a3f1944 296{
1a2fb1c0 297 tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
7a3f1944
FB
298}
299
1a2fb1c0 300static inline void gen_op_xor_T1_T0(void)
7a3f1944 301{
1a2fb1c0 302 tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
7a3f1944
FB
303}
304
3475187d
FB
305static inline void gen_jmp_im(target_ulong pc)
306{
48d5c82b 307 tcg_gen_movi_tl(cpu_pc, pc);
3475187d
FB
308}
309
310static inline void gen_movl_npc_im(target_ulong npc)
311{
48d5c82b 312 tcg_gen_movi_tl(cpu_npc, npc);
3475187d
FB
313}
314
5fafdf24 315static inline void gen_goto_tb(DisasContext *s, int tb_num,
6e256c93
FB
316 target_ulong pc, target_ulong npc)
317{
318 TranslationBlock *tb;
319
320 tb = s->tb;
321 if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
322 (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK)) {
323 /* jump to same page: we can use a direct jump */
57fec1fe 324 tcg_gen_goto_tb(tb_num);
6e256c93
FB
325 gen_jmp_im(pc);
326 gen_movl_npc_im(npc);
57fec1fe 327 tcg_gen_exit_tb((long)tb + tb_num);
6e256c93
FB
328 } else {
329 /* jump to another page: currently not optimized */
330 gen_jmp_im(pc);
331 gen_movl_npc_im(npc);
57fec1fe 332 tcg_gen_exit_tb(0);
6e256c93
FB
333 }
334}
335
19f329ad
BS
336// XXX suboptimal
337static inline void gen_mov_reg_N(TCGv reg, TCGv src)
338{
339 tcg_gen_shri_i32(reg, src, 23);
340 tcg_gen_andi_tl(reg, reg, 0x1);
341}
342
343static inline void gen_mov_reg_Z(TCGv reg, TCGv src)
344{
345 tcg_gen_shri_i32(reg, src, 22);
346 tcg_gen_andi_tl(reg, reg, 0x1);
347}
348
349static inline void gen_mov_reg_V(TCGv reg, TCGv src)
350{
351 tcg_gen_shri_i32(reg, src, 21);
352 tcg_gen_andi_tl(reg, reg, 0x1);
353}
354
355static inline void gen_mov_reg_C(TCGv reg, TCGv src)
356{
357 tcg_gen_shri_i32(reg, src, 20);
358 tcg_gen_andi_tl(reg, reg, 0x1);
359}
360
dc99a3f2
BS
361static inline void gen_op_exception(int exception)
362{
0425bee5
BS
363 tcg_gen_movi_i32(cpu_tmp0, exception);
364 tcg_gen_helper_0_1(raise_exception, cpu_tmp0);
dc99a3f2
BS
365}
366
367static inline void gen_cc_clear(void)
368{
369 tcg_gen_movi_i32(cpu_psr, 0);
370#ifdef TARGET_SPARC64
371 tcg_gen_movi_i32(cpu_xcc, 0);
372#endif
373}
374
375/* old op:
376 if (!T0)
377 env->psr |= PSR_ZERO;
378 if ((int32_t) T0 < 0)
379 env->psr |= PSR_NEG;
380*/
381static inline void gen_cc_NZ(TCGv dst)
382{
383 int l1, l2;
dc99a3f2
BS
384
385 l1 = gen_new_label();
386 l2 = gen_new_label();
0425bee5 387 tcg_gen_brcond_i32(TCG_COND_NE, dst, tcg_const_i32(0), l1);
dc99a3f2
BS
388 tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_ZERO);
389 gen_set_label(l1);
0425bee5 390 tcg_gen_brcond_i32(TCG_COND_GE, dst, tcg_const_i32(0), l2);
dc99a3f2
BS
391 tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_NEG);
392 gen_set_label(l2);
393#ifdef TARGET_SPARC64
394 {
395 int l3, l4;
396
397 l3 = gen_new_label();
398 l4 = gen_new_label();
0425bee5 399 tcg_gen_brcond_tl(TCG_COND_NE, dst, tcg_const_tl(0), l3);
dc99a3f2
BS
400 tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_ZERO);
401 gen_set_label(l3);
0425bee5 402 tcg_gen_brcond_tl(TCG_COND_GE, dst, tcg_const_tl(0), l4);
dc99a3f2
BS
403 tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_NEG);
404 gen_set_label(l4);
405 }
406#endif
407}
408
409/* old op:
410 if (T0 < src1)
411 env->psr |= PSR_CARRY;
412*/
413static inline void gen_cc_C_add(TCGv dst, TCGv src1)
414{
415 int l1;
416
417 l1 = gen_new_label();
418 tcg_gen_brcond_i32(TCG_COND_GEU, dst, src1, l1);
419 tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
420 gen_set_label(l1);
421#ifdef TARGET_SPARC64
422 {
423 int l2;
424
425 l2 = gen_new_label();
426 tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l2);
427 tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
428 gen_set_label(l2);
429 }
430#endif
431}
432
433/* old op:
434 if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
435 env->psr |= PSR_OVF;
436*/
437static inline void gen_cc_V_add(TCGv dst, TCGv src1, TCGv src2)
438{
0425bee5 439 TCGv r_temp;
dc99a3f2
BS
440 int l1;
441
442 l1 = gen_new_label();
443
444 r_temp = tcg_temp_new(TCG_TYPE_TL);
dc99a3f2
BS
445 tcg_gen_xor_tl(r_temp, src1, src2);
446 tcg_gen_xori_tl(r_temp, r_temp, -1);
0425bee5
BS
447 tcg_gen_xor_tl(cpu_tmp0, src1, dst);
448 tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
449 tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
450 tcg_gen_brcond_i32(TCG_COND_EQ, r_temp, tcg_const_i32(0), l1);
dc99a3f2
BS
451 tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
452 gen_set_label(l1);
453#ifdef TARGET_SPARC64
454 {
455 int l2;
456
457 l2 = gen_new_label();
dc99a3f2
BS
458 tcg_gen_xor_tl(r_temp, src1, src2);
459 tcg_gen_xori_tl(r_temp, r_temp, -1);
0425bee5
BS
460 tcg_gen_xor_tl(cpu_tmp0, src1, dst);
461 tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
462 tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
463 tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l2);
dc99a3f2
BS
464 tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_OVF);
465 gen_set_label(l2);
466 }
467#endif
0425bee5 468 tcg_gen_discard_tl(r_temp);
dc99a3f2
BS
469}
470
471static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
472{
0425bee5 473 TCGv r_temp;
dc99a3f2
BS
474 int l1;
475
476 l1 = gen_new_label();
477
478 r_temp = tcg_temp_new(TCG_TYPE_TL);
dc99a3f2
BS
479 tcg_gen_xor_tl(r_temp, src1, src2);
480 tcg_gen_xori_tl(r_temp, r_temp, -1);
0425bee5
BS
481 tcg_gen_xor_tl(cpu_tmp0, src1, dst);
482 tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
483 tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
484 tcg_gen_brcond_i32(TCG_COND_EQ, r_temp, tcg_const_i32(0), l1);
dc99a3f2
BS
485 gen_op_exception(TT_TOVF);
486 gen_set_label(l1);
487#ifdef TARGET_SPARC64
488 {
489 int l2;
490
491 l2 = gen_new_label();
dc99a3f2
BS
492 tcg_gen_xor_tl(r_temp, src1, src2);
493 tcg_gen_xori_tl(r_temp, r_temp, -1);
0425bee5
BS
494 tcg_gen_xor_tl(cpu_tmp0, src1, dst);
495 tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
496 tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
497 tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l2);
dc99a3f2
BS
498 gen_op_exception(TT_TOVF);
499 gen_set_label(l2);
500 }
501#endif
0425bee5 502 tcg_gen_discard_tl(r_temp);
dc99a3f2
BS
503}
504
505static inline void gen_cc_V_tag(TCGv src1, TCGv src2)
506{
507 int l1;
dc99a3f2
BS
508
509 l1 = gen_new_label();
0425bee5
BS
510 tcg_gen_or_tl(cpu_tmp0, src1, src2);
511 tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
512 tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
dc99a3f2
BS
513 tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
514 gen_set_label(l1);
515}
516
517static inline void gen_tag_tv(TCGv src1, TCGv src2)
518{
519 int l1;
dc99a3f2
BS
520
521 l1 = gen_new_label();
0425bee5
BS
522 tcg_gen_or_tl(cpu_tmp0, src1, src2);
523 tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
524 tcg_gen_brcond_tl(TCG_COND_EQ, cpu_tmp0, tcg_const_tl(0), l1);
dc99a3f2
BS
525 gen_op_exception(TT_TOVF);
526 gen_set_label(l1);
527}
528
529static inline void gen_op_add_T1_T0_cc(void)
530{
531 tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
532 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
533 gen_cc_clear();
534 gen_cc_NZ(cpu_T[0]);
535 gen_cc_C_add(cpu_T[0], cpu_cc_src);
536 gen_cc_V_add(cpu_T[0], cpu_cc_src, cpu_T[1]);
537}
538
539static inline void gen_op_addx_T1_T0_cc(void)
540{
541 tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
542 gen_mov_reg_C(cpu_tmp0, cpu_psr);
543 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
544 gen_cc_clear();
545 gen_cc_C_add(cpu_T[0], cpu_cc_src);
546 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
547 gen_cc_C_add(cpu_T[0], cpu_cc_src);
548 gen_cc_NZ(cpu_T[0]);
549 gen_cc_V_add(cpu_T[0], cpu_cc_src, cpu_T[1]);
550}
551
552static inline void gen_op_tadd_T1_T0_cc(void)
553{
554 tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
555 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
556 gen_cc_clear();
557 gen_cc_NZ(cpu_T[0]);
558 gen_cc_C_add(cpu_T[0], cpu_cc_src);
559 gen_cc_V_add(cpu_T[0], cpu_cc_src, cpu_T[1]);
560 gen_cc_V_tag(cpu_cc_src, cpu_T[1]);
561}
562
563static inline void gen_op_tadd_T1_T0_ccTV(void)
564{
565 gen_tag_tv(cpu_T[0], cpu_T[1]);
566 tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
567 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
568 gen_add_tv(cpu_T[0], cpu_cc_src, cpu_T[1]);
569 gen_cc_clear();
570 gen_cc_NZ(cpu_T[0]);
571 gen_cc_C_add(cpu_T[0], cpu_cc_src);
572}
573
574/* old op:
575 if (src1 < T1)
576 env->psr |= PSR_CARRY;
577*/
578static inline void gen_cc_C_sub(TCGv src1, TCGv src2)
579{
580 int l1;
581
582 l1 = gen_new_label();
583 tcg_gen_brcond_i32(TCG_COND_GEU, src1, src2, l1);
584 tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
585 gen_set_label(l1);
586#ifdef TARGET_SPARC64
587 {
588 int l2;
589
590 l2 = gen_new_label();
591 tcg_gen_brcond_tl(TCG_COND_GEU, src1, src2, l2);
592 tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
593 gen_set_label(l2);
594 }
595#endif
596}
597
598/* old op:
599 if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
600 env->psr |= PSR_OVF;
601*/
602static inline void gen_cc_V_sub(TCGv dst, TCGv src1, TCGv src2)
603{
0425bee5 604 TCGv r_temp;
dc99a3f2
BS
605 int l1;
606
607 l1 = gen_new_label();
608
609 r_temp = tcg_temp_new(TCG_TYPE_TL);
dc99a3f2 610 tcg_gen_xor_tl(r_temp, src1, src2);
0425bee5
BS
611 tcg_gen_xor_tl(cpu_tmp0, src1, dst);
612 tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
613 tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
614 tcg_gen_brcond_i32(TCG_COND_EQ, r_temp, tcg_const_i32(0), l1);
dc99a3f2
BS
615 tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
616 gen_set_label(l1);
617#ifdef TARGET_SPARC64
618 {
619 int l2;
620
621 l2 = gen_new_label();
dc99a3f2 622 tcg_gen_xor_tl(r_temp, src1, src2);
0425bee5
BS
623 tcg_gen_xor_tl(cpu_tmp0, src1, dst);
624 tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
625 tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
626 tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l2);
dc99a3f2
BS
627 tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_OVF);
628 gen_set_label(l2);
629 }
630#endif
0425bee5 631 tcg_gen_discard_tl(r_temp);
dc99a3f2
BS
632}
633
634static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
635{
0425bee5 636 TCGv r_temp;
dc99a3f2
BS
637 int l1;
638
639 l1 = gen_new_label();
640
641 r_temp = tcg_temp_new(TCG_TYPE_TL);
dc99a3f2 642 tcg_gen_xor_tl(r_temp, src1, src2);
0425bee5
BS
643 tcg_gen_xor_tl(cpu_tmp0, src1, dst);
644 tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
645 tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
646 tcg_gen_brcond_i32(TCG_COND_EQ, r_temp, tcg_const_i32(0), l1);
dc99a3f2
BS
647 gen_op_exception(TT_TOVF);
648 gen_set_label(l1);
649#ifdef TARGET_SPARC64
650 {
651 int l2;
652
653 l2 = gen_new_label();
dc99a3f2 654 tcg_gen_xor_tl(r_temp, src1, src2);
0425bee5
BS
655 tcg_gen_xor_tl(cpu_tmp0, src1, dst);
656 tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
657 tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
658 tcg_gen_brcond_tl(TCG_COND_EQ, r_temp, tcg_const_tl(0), l2);
dc99a3f2
BS
659 gen_op_exception(TT_TOVF);
660 gen_set_label(l2);
661 }
662#endif
0425bee5 663 tcg_gen_discard_tl(r_temp);
dc99a3f2
BS
664}
665
666static inline void gen_op_sub_T1_T0_cc(void)
667{
668 tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
669 tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
670 gen_cc_clear();
671 gen_cc_NZ(cpu_T[0]);
672 gen_cc_C_sub(cpu_cc_src, cpu_T[1]);
673 gen_cc_V_sub(cpu_T[0], cpu_cc_src, cpu_T[1]);
674}
675
676static inline void gen_op_subx_T1_T0_cc(void)
677{
678 tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
679 gen_mov_reg_C(cpu_tmp0, cpu_psr);
680 tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
681 gen_cc_clear();
682 gen_cc_C_sub(cpu_T[0], cpu_cc_src);
683 tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
684 gen_cc_C_sub(cpu_T[0], cpu_cc_src);
685 gen_cc_NZ(cpu_T[0]);
686 gen_cc_V_sub(cpu_T[0], cpu_cc_src, cpu_T[1]);
687}
688
689static inline void gen_op_tsub_T1_T0_cc(void)
690{
691 tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
692 tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
693 gen_cc_clear();
694 gen_cc_NZ(cpu_T[0]);
695 gen_cc_C_sub(cpu_cc_src, cpu_T[1]);
696 gen_cc_V_sub(cpu_T[0], cpu_cc_src, cpu_T[1]);
697 gen_cc_V_tag(cpu_cc_src, cpu_T[1]);
698}
699
700static inline void gen_op_tsub_T1_T0_ccTV(void)
701{
702 gen_tag_tv(cpu_T[0], cpu_T[1]);
703 tcg_gen_mov_tl(cpu_cc_src, cpu_T[0]);
704 tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
705 gen_sub_tv(cpu_T[0], cpu_cc_src, cpu_T[1]);
706 gen_cc_clear();
707 gen_cc_NZ(cpu_T[0]);
708 gen_cc_C_sub(cpu_cc_src, cpu_T[1]);
709}
710
d9bdab86
BS
711static inline void gen_op_mulscc_T1_T0(void)
712{
713 TCGv r_temp;
714 int l1, l2;
715
716 l1 = gen_new_label();
717 l2 = gen_new_label();
718 r_temp = tcg_temp_new(TCG_TYPE_TL);
719
720 /* old op:
721 if (!(env->y & 1))
722 T1 = 0;
723 */
724 tcg_gen_ld_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
725 tcg_gen_andi_i32(r_temp, r_temp, 0x1);
726 tcg_gen_brcond_i32(TCG_COND_EQ, r_temp, tcg_const_tl(0), l1);
727 tcg_gen_mov_tl(cpu_cc_src2, cpu_T[1]);
728 gen_op_jmp_label(l2);
729 gen_set_label(l1);
730 tcg_gen_movi_tl(cpu_cc_src2, 0);
731 gen_set_label(l2);
732
733 // b2 = T0 & 1;
734 // env->y = (b2 << 31) | (env->y >> 1);
735 tcg_gen_shli_i32(r_temp, cpu_T[0], 31);
736 tcg_gen_ld_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, y));
737 tcg_gen_shri_i32(cpu_tmp0, cpu_tmp0, 1);
738 tcg_gen_or_i32(cpu_tmp0, cpu_tmp0, r_temp);
739 tcg_gen_st_i32(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, y));
740
741 // b1 = N ^ V;
742 gen_mov_reg_N(cpu_tmp0, cpu_psr);
743 gen_mov_reg_V(r_temp, cpu_psr);
744 tcg_gen_xor_tl(cpu_tmp0, cpu_tmp0, r_temp);
745
746 // T0 = (b1 << 31) | (T0 >> 1);
747 // src1 = T0;
748 tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
749 tcg_gen_shri_tl(cpu_cc_src, cpu_T[0], 1);
750 tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);
751
752 /* do addition and update flags */
753 tcg_gen_add_tl(cpu_T[0], cpu_cc_src, cpu_cc_src2);
754 tcg_gen_discard_tl(r_temp);
755
756 gen_cc_clear();
757 gen_cc_NZ(cpu_T[0]);
758 gen_cc_V_add(cpu_T[0], cpu_cc_src, cpu_cc_src2);
759 gen_cc_C_add(cpu_T[0], cpu_cc_src);
760}
761
8879d139
BS
762static inline void gen_op_umul_T1_T0(void)
763{
764 TCGv r_temp, r_temp2;
765
766 r_temp = tcg_temp_new(TCG_TYPE_I64);
767 r_temp2 = tcg_temp_new(TCG_TYPE_I64);
768
769 tcg_gen_extu_i32_i64(r_temp, cpu_T[1]);
770 tcg_gen_extu_i32_i64(r_temp2, cpu_T[0]);
771 tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
772
773 tcg_gen_shri_i64(r_temp, r_temp2, 32);
774 tcg_gen_trunc_i64_i32(r_temp, r_temp);
775 tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
776#ifdef TARGET_SPARC64
777 tcg_gen_mov_i64(cpu_T[0], r_temp2);
778#else
779 tcg_gen_trunc_i64_i32(cpu_T[0], r_temp2);
780#endif
781
782 tcg_gen_discard_i64(r_temp);
783 tcg_gen_discard_i64(r_temp2);
784}
785
786static inline void gen_op_smul_T1_T0(void)
787{
788 TCGv r_temp, r_temp2;
789
790 r_temp = tcg_temp_new(TCG_TYPE_I64);
791 r_temp2 = tcg_temp_new(TCG_TYPE_I64);
792
2483386a
BS
793 tcg_gen_ext_i32_i64(r_temp, cpu_T[1]);
794 tcg_gen_ext_i32_i64(r_temp2, cpu_T[0]);
8879d139
BS
795 tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);
796
797 tcg_gen_shri_i64(r_temp, r_temp2, 32);
798 tcg_gen_trunc_i64_i32(r_temp, r_temp);
799 tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
800#ifdef TARGET_SPARC64
801 tcg_gen_mov_i64(cpu_T[0], r_temp2);
802#else
803 tcg_gen_trunc_i64_i32(cpu_T[0], r_temp2);
804#endif
805
806 tcg_gen_discard_i64(r_temp);
807 tcg_gen_discard_i64(r_temp2);
808}
809
1a7b60e7
BS
810#ifdef TARGET_SPARC64
811static inline void gen_trap_ifdivzero_i64(TCGv divisor)
812{
813 int l1;
814
815 l1 = gen_new_label();
816 tcg_gen_brcond_i64(TCG_COND_NE, divisor, tcg_const_tl(0), l1);
817 gen_op_exception(TT_DIV_ZERO);
818 gen_set_label(l1);
819}
820
821static inline void gen_op_sdivx_T1_T0(void)
822{
823 int l1, l2;
824
825 l1 = gen_new_label();
826 l2 = gen_new_label();
827 gen_trap_ifdivzero_i64(cpu_T[1]);
828 tcg_gen_brcond_i64(TCG_COND_NE, cpu_T[0], tcg_const_i64(INT64_MIN), l1);
829 tcg_gen_brcond_i64(TCG_COND_NE, cpu_T[1], tcg_const_i64(-1), l1);
830 tcg_gen_movi_i64(cpu_T[0], INT64_MIN);
831 gen_op_jmp_label(l2);
832 gen_set_label(l1);
833 tcg_gen_div_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
834 gen_set_label(l2);
835}
836#endif
837
dc99a3f2
BS
838static inline void gen_op_div_cc(void)
839{
840 int l1;
dc99a3f2
BS
841
842 gen_cc_clear();
843 gen_cc_NZ(cpu_T[0]);
844 l1 = gen_new_label();
0425bee5 845 tcg_gen_brcond_i32(TCG_COND_EQ, cpu_T[1], tcg_const_i32(0), l1);
dc99a3f2
BS
846 tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
847 gen_set_label(l1);
848}
849
850static inline void gen_op_logic_T0_cc(void)
851{
852 gen_cc_clear();
853 gen_cc_NZ(cpu_T[0]);
854}
855
19f329ad
BS
856// 1
857static inline void gen_op_eval_ba(TCGv dst)
858{
859 tcg_gen_movi_tl(dst, 1);
860}
861
862// Z
863static inline void gen_op_eval_be(TCGv dst, TCGv src)
864{
865 gen_mov_reg_Z(dst, src);
866}
867
868// Z | (N ^ V)
869static inline void gen_op_eval_ble(TCGv dst, TCGv src)
870{
0425bee5 871 gen_mov_reg_N(cpu_tmp0, src);
19f329ad 872 gen_mov_reg_V(dst, src);
0425bee5
BS
873 tcg_gen_xor_tl(dst, dst, cpu_tmp0);
874 gen_mov_reg_Z(cpu_tmp0, src);
875 tcg_gen_or_tl(dst, dst, cpu_tmp0);
19f329ad
BS
876}
877
878// N ^ V
879static inline void gen_op_eval_bl(TCGv dst, TCGv src)
880{
0425bee5 881 gen_mov_reg_V(cpu_tmp0, src);
19f329ad 882 gen_mov_reg_N(dst, src);
0425bee5 883 tcg_gen_xor_tl(dst, dst, cpu_tmp0);
19f329ad
BS
884}
885
886// C | Z
887static inline void gen_op_eval_bleu(TCGv dst, TCGv src)
888{
0425bee5 889 gen_mov_reg_Z(cpu_tmp0, src);
19f329ad 890 gen_mov_reg_C(dst, src);
0425bee5 891 tcg_gen_or_tl(dst, dst, cpu_tmp0);
19f329ad
BS
892}
893
894// C
895static inline void gen_op_eval_bcs(TCGv dst, TCGv src)
896{
897 gen_mov_reg_C(dst, src);
898}
899
900// V
901static inline void gen_op_eval_bvs(TCGv dst, TCGv src)
902{
903 gen_mov_reg_V(dst, src);
904}
905
906// 0
907static inline void gen_op_eval_bn(TCGv dst)
908{
909 tcg_gen_movi_tl(dst, 0);
910}
911
912// N
913static inline void gen_op_eval_bneg(TCGv dst, TCGv src)
914{
915 gen_mov_reg_N(dst, src);
916}
917
918// !Z
919static inline void gen_op_eval_bne(TCGv dst, TCGv src)
920{
921 gen_mov_reg_Z(dst, src);
922 tcg_gen_xori_tl(dst, dst, 0x1);
923}
924
925// !(Z | (N ^ V))
926static inline void gen_op_eval_bg(TCGv dst, TCGv src)
927{
0425bee5 928 gen_mov_reg_N(cpu_tmp0, src);
19f329ad 929 gen_mov_reg_V(dst, src);
0425bee5
BS
930 tcg_gen_xor_tl(dst, dst, cpu_tmp0);
931 gen_mov_reg_Z(cpu_tmp0, src);
932 tcg_gen_or_tl(dst, dst, cpu_tmp0);
19f329ad
BS
933 tcg_gen_xori_tl(dst, dst, 0x1);
934}
935
936// !(N ^ V)
937static inline void gen_op_eval_bge(TCGv dst, TCGv src)
938{
0425bee5 939 gen_mov_reg_V(cpu_tmp0, src);
19f329ad 940 gen_mov_reg_N(dst, src);
0425bee5 941 tcg_gen_xor_tl(dst, dst, cpu_tmp0);
19f329ad
BS
942 tcg_gen_xori_tl(dst, dst, 0x1);
943}
944
945// !(C | Z)
946static inline void gen_op_eval_bgu(TCGv dst, TCGv src)
947{
0425bee5 948 gen_mov_reg_Z(cpu_tmp0, src);
19f329ad 949 gen_mov_reg_C(dst, src);
0425bee5 950 tcg_gen_or_tl(dst, dst, cpu_tmp0);
19f329ad
BS
951 tcg_gen_xori_tl(dst, dst, 0x1);
952}
953
954// !C
955static inline void gen_op_eval_bcc(TCGv dst, TCGv src)
956{
957 gen_mov_reg_C(dst, src);
958 tcg_gen_xori_tl(dst, dst, 0x1);
959}
960
961// !N
962static inline void gen_op_eval_bpos(TCGv dst, TCGv src)
963{
964 gen_mov_reg_N(dst, src);
965 tcg_gen_xori_tl(dst, dst, 0x1);
966}
967
968// !V
969static inline void gen_op_eval_bvc(TCGv dst, TCGv src)
970{
971 gen_mov_reg_V(dst, src);
972 tcg_gen_xori_tl(dst, dst, 0x1);
973}
974
975/*
976 FPSR bit field FCC1 | FCC0:
977 0 =
978 1 <
979 2 >
980 3 unordered
981*/
982static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src,
983 unsigned int fcc_offset)
984{
985 tcg_gen_shri_i32(reg, src, 10 + fcc_offset);
986 tcg_gen_andi_tl(reg, reg, 0x1);
987}
988
989static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
990 unsigned int fcc_offset)
991{
992 tcg_gen_shri_i32(reg, src, 11 + fcc_offset);
993 tcg_gen_andi_tl(reg, reg, 0x1);
994}
995
996// !0: FCC0 | FCC1
997static inline void gen_op_eval_fbne(TCGv dst, TCGv src,
998 unsigned int fcc_offset)
999{
19f329ad 1000 gen_mov_reg_FCC0(dst, src, fcc_offset);
0425bee5
BS
1001 gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1002 tcg_gen_or_tl(dst, dst, cpu_tmp0);
19f329ad
BS
1003}
1004
1005// 1 or 2: FCC0 ^ FCC1
1006static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
1007 unsigned int fcc_offset)
1008{
19f329ad 1009 gen_mov_reg_FCC0(dst, src, fcc_offset);
0425bee5
BS
1010 gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1011 tcg_gen_xor_tl(dst, dst, cpu_tmp0);
19f329ad
BS
1012}
1013
1014// 1 or 3: FCC0
1015static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
1016 unsigned int fcc_offset)
1017{
1018 gen_mov_reg_FCC0(dst, src, fcc_offset);
1019}
1020
1021// 1: FCC0 & !FCC1
1022static inline void gen_op_eval_fbl(TCGv dst, TCGv src,
1023 unsigned int fcc_offset)
1024{
19f329ad 1025 gen_mov_reg_FCC0(dst, src, fcc_offset);
0425bee5
BS
1026 gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1027 tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
1028 tcg_gen_and_tl(dst, dst, cpu_tmp0);
19f329ad
BS
1029}
1030
1031// 2 or 3: FCC1
1032static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
1033 unsigned int fcc_offset)
1034{
1035 gen_mov_reg_FCC1(dst, src, fcc_offset);
1036}
1037
1038// 2: !FCC0 & FCC1
1039static inline void gen_op_eval_fbg(TCGv dst, TCGv src,
1040 unsigned int fcc_offset)
1041{
19f329ad
BS
1042 gen_mov_reg_FCC0(dst, src, fcc_offset);
1043 tcg_gen_xori_tl(dst, dst, 0x1);
0425bee5
BS
1044 gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1045 tcg_gen_and_tl(dst, dst, cpu_tmp0);
19f329ad
BS
1046}
1047
1048// 3: FCC0 & FCC1
1049static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
1050 unsigned int fcc_offset)
1051{
19f329ad 1052 gen_mov_reg_FCC0(dst, src, fcc_offset);
0425bee5
BS
1053 gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1054 tcg_gen_and_tl(dst, dst, cpu_tmp0);
19f329ad
BS
1055}
1056
1057// 0: !(FCC0 | FCC1)
1058static inline void gen_op_eval_fbe(TCGv dst, TCGv src,
1059 unsigned int fcc_offset)
1060{
19f329ad 1061 gen_mov_reg_FCC0(dst, src, fcc_offset);
0425bee5
BS
1062 gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1063 tcg_gen_or_tl(dst, dst, cpu_tmp0);
19f329ad
BS
1064 tcg_gen_xori_tl(dst, dst, 0x1);
1065}
1066
1067// 0 or 3: !(FCC0 ^ FCC1)
1068static inline void gen_op_eval_fbue(TCGv dst, TCGv src,
1069 unsigned int fcc_offset)
1070{
19f329ad 1071 gen_mov_reg_FCC0(dst, src, fcc_offset);
0425bee5
BS
1072 gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1073 tcg_gen_xor_tl(dst, dst, cpu_tmp0);
19f329ad
BS
1074 tcg_gen_xori_tl(dst, dst, 0x1);
1075}
1076
1077// 0 or 2: !FCC0
1078static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
1079 unsigned int fcc_offset)
1080{
1081 gen_mov_reg_FCC0(dst, src, fcc_offset);
1082 tcg_gen_xori_tl(dst, dst, 0x1);
1083}
1084
1085// !1: !(FCC0 & !FCC1)
1086static inline void gen_op_eval_fbuge(TCGv dst, TCGv src,
1087 unsigned int fcc_offset)
1088{
19f329ad 1089 gen_mov_reg_FCC0(dst, src, fcc_offset);
0425bee5
BS
1090 gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1091 tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
1092 tcg_gen_and_tl(dst, dst, cpu_tmp0);
19f329ad
BS
1093 tcg_gen_xori_tl(dst, dst, 0x1);
1094}
1095
1096// 0 or 1: !FCC1
1097static inline void gen_op_eval_fble(TCGv dst, TCGv src,
1098 unsigned int fcc_offset)
1099{
1100 gen_mov_reg_FCC1(dst, src, fcc_offset);
1101 tcg_gen_xori_tl(dst, dst, 0x1);
1102}
1103
1104// !2: !(!FCC0 & FCC1)
1105static inline void gen_op_eval_fbule(TCGv dst, TCGv src,
1106 unsigned int fcc_offset)
1107{
19f329ad
BS
1108 gen_mov_reg_FCC0(dst, src, fcc_offset);
1109 tcg_gen_xori_tl(dst, dst, 0x1);
0425bee5
BS
1110 gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1111 tcg_gen_and_tl(dst, dst, cpu_tmp0);
19f329ad
BS
1112 tcg_gen_xori_tl(dst, dst, 0x1);
1113}
1114
1115// !3: !(FCC0 & FCC1)
1116static inline void gen_op_eval_fbo(TCGv dst, TCGv src,
1117 unsigned int fcc_offset)
1118{
19f329ad 1119 gen_mov_reg_FCC0(dst, src, fcc_offset);
0425bee5
BS
1120 gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
1121 tcg_gen_and_tl(dst, dst, cpu_tmp0);
19f329ad
BS
1122 tcg_gen_xori_tl(dst, dst, 0x1);
1123}
1124
46525e1f 1125static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
19f329ad 1126 target_ulong pc2, TCGv r_cond)
83469015
FB
1127{
1128 int l1;
1129
1130 l1 = gen_new_label();
1131
0425bee5 1132 tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
83469015 1133
6e256c93 1134 gen_goto_tb(dc, 0, pc1, pc1 + 4);
83469015
FB
1135
1136 gen_set_label(l1);
6e256c93 1137 gen_goto_tb(dc, 1, pc2, pc2 + 4);
83469015
FB
1138}
1139
46525e1f 1140static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
19f329ad 1141 target_ulong pc2, TCGv r_cond)
83469015
FB
1142{
1143 int l1;
1144
1145 l1 = gen_new_label();
1146
0425bee5 1147 tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
83469015 1148
6e256c93 1149 gen_goto_tb(dc, 0, pc2, pc1);
83469015
FB
1150
1151 gen_set_label(l1);
6e256c93 1152 gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
83469015
FB
1153}
1154
46525e1f
BS
1155static inline void gen_branch(DisasContext *dc, target_ulong pc,
1156 target_ulong npc)
83469015 1157{
6e256c93 1158 gen_goto_tb(dc, 0, pc, npc);
83469015
FB
1159}
1160
19f329ad
BS
1161static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
1162 TCGv r_cond)
83469015
FB
1163{
1164 int l1, l2;
1165
1166 l1 = gen_new_label();
1167 l2 = gen_new_label();
19f329ad 1168
0425bee5 1169 tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, tcg_const_tl(0), l1);
83469015
FB
1170
1171 gen_movl_npc_im(npc1);
1172 gen_op_jmp_label(l2);
1173
1174 gen_set_label(l1);
1175 gen_movl_npc_im(npc2);
1176 gen_set_label(l2);
1177}
1178
1179/* call this function before using T2 as it may have been set for a jump */
1180static inline void flush_T2(DisasContext * dc)
1181{
1182 if (dc->npc == JUMP_PC) {
19f329ad 1183 gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
83469015
FB
1184 dc->npc = DYNAMIC_PC;
1185 }
1186}
1187
72cbca10
FB
1188static inline void save_npc(DisasContext * dc)
1189{
1190 if (dc->npc == JUMP_PC) {
19f329ad 1191 gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
72cbca10
FB
1192 dc->npc = DYNAMIC_PC;
1193 } else if (dc->npc != DYNAMIC_PC) {
3475187d 1194 gen_movl_npc_im(dc->npc);
72cbca10
FB
1195 }
1196}
1197
1198static inline void save_state(DisasContext * dc)
1199{
3475187d 1200 gen_jmp_im(dc->pc);
72cbca10
FB
1201 save_npc(dc);
1202}
1203
0bee699e
FB
1204static inline void gen_mov_pc_npc(DisasContext * dc)
1205{
1206 if (dc->npc == JUMP_PC) {
19f329ad 1207 gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
48d5c82b 1208 tcg_gen_mov_tl(cpu_pc, cpu_npc);
0bee699e
FB
1209 dc->pc = DYNAMIC_PC;
1210 } else if (dc->npc == DYNAMIC_PC) {
48d5c82b 1211 tcg_gen_mov_tl(cpu_pc, cpu_npc);
0bee699e
FB
1212 dc->pc = DYNAMIC_PC;
1213 } else {
1214 dc->pc = dc->npc;
1215 }
1216}
1217
38bc628b
BS
1218static inline void gen_op_next_insn(void)
1219{
48d5c82b
BS
1220 tcg_gen_mov_tl(cpu_pc, cpu_npc);
1221 tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
38bc628b
BS
1222}
1223
19f329ad
BS
1224static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond)
1225{
1226 TCGv r_src;
3475187d 1227
3475187d 1228#ifdef TARGET_SPARC64
19f329ad 1229 if (cc)
dc99a3f2 1230 r_src = cpu_xcc;
19f329ad 1231 else
dc99a3f2 1232 r_src = cpu_psr;
3475187d 1233#else
dc99a3f2 1234 r_src = cpu_psr;
3475187d 1235#endif
19f329ad
BS
1236 switch (cond) {
1237 case 0x0:
1238 gen_op_eval_bn(r_dst);
1239 break;
1240 case 0x1:
1241 gen_op_eval_be(r_dst, r_src);
1242 break;
1243 case 0x2:
1244 gen_op_eval_ble(r_dst, r_src);
1245 break;
1246 case 0x3:
1247 gen_op_eval_bl(r_dst, r_src);
1248 break;
1249 case 0x4:
1250 gen_op_eval_bleu(r_dst, r_src);
1251 break;
1252 case 0x5:
1253 gen_op_eval_bcs(r_dst, r_src);
1254 break;
1255 case 0x6:
1256 gen_op_eval_bneg(r_dst, r_src);
1257 break;
1258 case 0x7:
1259 gen_op_eval_bvs(r_dst, r_src);
1260 break;
1261 case 0x8:
1262 gen_op_eval_ba(r_dst);
1263 break;
1264 case 0x9:
1265 gen_op_eval_bne(r_dst, r_src);
1266 break;
1267 case 0xa:
1268 gen_op_eval_bg(r_dst, r_src);
1269 break;
1270 case 0xb:
1271 gen_op_eval_bge(r_dst, r_src);
1272 break;
1273 case 0xc:
1274 gen_op_eval_bgu(r_dst, r_src);
1275 break;
1276 case 0xd:
1277 gen_op_eval_bcc(r_dst, r_src);
1278 break;
1279 case 0xe:
1280 gen_op_eval_bpos(r_dst, r_src);
1281 break;
1282 case 0xf:
1283 gen_op_eval_bvc(r_dst, r_src);
1284 break;
1285 }
1286}
7a3f1944 1287
19f329ad 1288static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
e8af50a3 1289{
19f329ad
BS
1290 unsigned int offset;
1291
19f329ad
BS
1292 switch (cc) {
1293 default:
1294 case 0x0:
1295 offset = 0;
1296 break;
1297 case 0x1:
1298 offset = 32 - 10;
1299 break;
1300 case 0x2:
1301 offset = 34 - 10;
1302 break;
1303 case 0x3:
1304 offset = 36 - 10;
1305 break;
1306 }
1307
1308 switch (cond) {
1309 case 0x0:
1310 gen_op_eval_bn(r_dst);
1311 break;
1312 case 0x1:
87e92502 1313 gen_op_eval_fbne(r_dst, cpu_fsr, offset);
19f329ad
BS
1314 break;
1315 case 0x2:
87e92502 1316 gen_op_eval_fblg(r_dst, cpu_fsr, offset);
19f329ad
BS
1317 break;
1318 case 0x3:
87e92502 1319 gen_op_eval_fbul(r_dst, cpu_fsr, offset);
19f329ad
BS
1320 break;
1321 case 0x4:
87e92502 1322 gen_op_eval_fbl(r_dst, cpu_fsr, offset);
19f329ad
BS
1323 break;
1324 case 0x5:
87e92502 1325 gen_op_eval_fbug(r_dst, cpu_fsr, offset);
19f329ad
BS
1326 break;
1327 case 0x6:
87e92502 1328 gen_op_eval_fbg(r_dst, cpu_fsr, offset);
19f329ad
BS
1329 break;
1330 case 0x7:
87e92502 1331 gen_op_eval_fbu(r_dst, cpu_fsr, offset);
19f329ad
BS
1332 break;
1333 case 0x8:
1334 gen_op_eval_ba(r_dst);
1335 break;
1336 case 0x9:
87e92502 1337 gen_op_eval_fbe(r_dst, cpu_fsr, offset);
19f329ad
BS
1338 break;
1339 case 0xa:
87e92502 1340 gen_op_eval_fbue(r_dst, cpu_fsr, offset);
19f329ad
BS
1341 break;
1342 case 0xb:
87e92502 1343 gen_op_eval_fbge(r_dst, cpu_fsr, offset);
19f329ad
BS
1344 break;
1345 case 0xc:
87e92502 1346 gen_op_eval_fbuge(r_dst, cpu_fsr, offset);
19f329ad
BS
1347 break;
1348 case 0xd:
87e92502 1349 gen_op_eval_fble(r_dst, cpu_fsr, offset);
19f329ad
BS
1350 break;
1351 case 0xe:
87e92502 1352 gen_op_eval_fbule(r_dst, cpu_fsr, offset);
19f329ad
BS
1353 break;
1354 case 0xf:
87e92502 1355 gen_op_eval_fbo(r_dst, cpu_fsr, offset);
19f329ad
BS
1356 break;
1357 }
e8af50a3 1358}
00f219bf 1359
19f329ad 1360#ifdef TARGET_SPARC64
00f219bf
BS
1361// Inverted logic
1362static const int gen_tcg_cond_reg[8] = {
1363 -1,
1364 TCG_COND_NE,
1365 TCG_COND_GT,
1366 TCG_COND_GE,
1367 -1,
1368 TCG_COND_EQ,
1369 TCG_COND_LE,
1370 TCG_COND_LT,
1371};
19f329ad
BS
1372
1373static inline void gen_cond_reg(TCGv r_dst, int cond)
1374{
19f329ad
BS
1375 int l1;
1376
1377 l1 = gen_new_label();
0425bee5
BS
1378 tcg_gen_movi_tl(r_dst, 0);
1379 tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0], tcg_const_tl(0), l1);
19f329ad
BS
1380 tcg_gen_movi_tl(r_dst, 1);
1381 gen_set_label(l1);
1382}
3475187d 1383#endif
cf495bcf 1384
0bee699e 1385/* XXX: potentially incorrect if dynamic npc */
3475187d 1386static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
7a3f1944 1387{
cf495bcf 1388 unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
af7bf89b 1389 target_ulong target = dc->pc + offset;
5fafdf24 1390
cf495bcf 1391 if (cond == 0x0) {
0f8a249a
BS
1392 /* unconditional not taken */
1393 if (a) {
1394 dc->pc = dc->npc + 4;
1395 dc->npc = dc->pc + 4;
1396 } else {
1397 dc->pc = dc->npc;
1398 dc->npc = dc->pc + 4;
1399 }
cf495bcf 1400 } else if (cond == 0x8) {
0f8a249a
BS
1401 /* unconditional taken */
1402 if (a) {
1403 dc->pc = target;
1404 dc->npc = dc->pc + 4;
1405 } else {
1406 dc->pc = dc->npc;
1407 dc->npc = target;
1408 }
cf495bcf 1409 } else {
72cbca10 1410 flush_T2(dc);
19f329ad 1411 gen_cond(cpu_T[2], cc, cond);
0f8a249a 1412 if (a) {
19f329ad 1413 gen_branch_a(dc, target, dc->npc, cpu_T[2]);
cf495bcf 1414 dc->is_br = 1;
0f8a249a 1415 } else {
cf495bcf 1416 dc->pc = dc->npc;
72cbca10
FB
1417 dc->jump_pc[0] = target;
1418 dc->jump_pc[1] = dc->npc + 4;
1419 dc->npc = JUMP_PC;
0f8a249a 1420 }
cf495bcf 1421 }
7a3f1944
FB
1422}
1423
0bee699e 1424/* XXX: potentially incorrect if dynamic npc */
3475187d 1425static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
e8af50a3
FB
1426{
1427 unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
af7bf89b
FB
1428 target_ulong target = dc->pc + offset;
1429
e8af50a3 1430 if (cond == 0x0) {
0f8a249a
BS
1431 /* unconditional not taken */
1432 if (a) {
1433 dc->pc = dc->npc + 4;
1434 dc->npc = dc->pc + 4;
1435 } else {
1436 dc->pc = dc->npc;
1437 dc->npc = dc->pc + 4;
1438 }
e8af50a3 1439 } else if (cond == 0x8) {
0f8a249a
BS
1440 /* unconditional taken */
1441 if (a) {
1442 dc->pc = target;
1443 dc->npc = dc->pc + 4;
1444 } else {
1445 dc->pc = dc->npc;
1446 dc->npc = target;
1447 }
e8af50a3
FB
1448 } else {
1449 flush_T2(dc);
19f329ad 1450 gen_fcond(cpu_T[2], cc, cond);
0f8a249a 1451 if (a) {
19f329ad 1452 gen_branch_a(dc, target, dc->npc, cpu_T[2]);
e8af50a3 1453 dc->is_br = 1;
0f8a249a 1454 } else {
e8af50a3
FB
1455 dc->pc = dc->npc;
1456 dc->jump_pc[0] = target;
1457 dc->jump_pc[1] = dc->npc + 4;
1458 dc->npc = JUMP_PC;
0f8a249a 1459 }
e8af50a3
FB
1460 }
1461}
1462
3475187d
FB
1463#ifdef TARGET_SPARC64
1464/* XXX: potentially incorrect if dynamic npc */
1465static void do_branch_reg(DisasContext * dc, int32_t offset, uint32_t insn)
7a3f1944 1466{
3475187d
FB
1467 unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1468 target_ulong target = dc->pc + offset;
1469
1470 flush_T2(dc);
19f329ad 1471 gen_cond_reg(cpu_T[2], cond);
3475187d 1472 if (a) {
19f329ad 1473 gen_branch_a(dc, target, dc->npc, cpu_T[2]);
0f8a249a 1474 dc->is_br = 1;
3475187d 1475 } else {
0f8a249a
BS
1476 dc->pc = dc->npc;
1477 dc->jump_pc[0] = target;
1478 dc->jump_pc[1] = dc->npc + 4;
1479 dc->npc = JUMP_PC;
3475187d 1480 }
7a3f1944
FB
1481}
1482
3475187d 1483static GenOpFunc * const gen_fcmps[4] = {
7e8c2b6c
BS
1484 helper_fcmps,
1485 helper_fcmps_fcc1,
1486 helper_fcmps_fcc2,
1487 helper_fcmps_fcc3,
3475187d
FB
1488};
1489
1490static GenOpFunc * const gen_fcmpd[4] = {
7e8c2b6c
BS
1491 helper_fcmpd,
1492 helper_fcmpd_fcc1,
1493 helper_fcmpd_fcc2,
1494 helper_fcmpd_fcc3,
3475187d 1495};
417454b0 1496
1f587329
BS
1497#if defined(CONFIG_USER_ONLY)
1498static GenOpFunc * const gen_fcmpq[4] = {
7e8c2b6c
BS
1499 helper_fcmpq,
1500 helper_fcmpq_fcc1,
1501 helper_fcmpq_fcc2,
1502 helper_fcmpq_fcc3,
1f587329
BS
1503};
1504#endif
1505
417454b0 1506static GenOpFunc * const gen_fcmpes[4] = {
7e8c2b6c
BS
1507 helper_fcmpes,
1508 helper_fcmpes_fcc1,
1509 helper_fcmpes_fcc2,
1510 helper_fcmpes_fcc3,
417454b0
BS
1511};
1512
1513static GenOpFunc * const gen_fcmped[4] = {
7e8c2b6c
BS
1514 helper_fcmped,
1515 helper_fcmped_fcc1,
1516 helper_fcmped_fcc2,
1517 helper_fcmped_fcc3,
417454b0
BS
1518};
1519
1f587329
BS
1520#if defined(CONFIG_USER_ONLY)
1521static GenOpFunc * const gen_fcmpeq[4] = {
7e8c2b6c
BS
1522 helper_fcmpeq,
1523 helper_fcmpeq_fcc1,
1524 helper_fcmpeq_fcc2,
1525 helper_fcmpeq_fcc3,
1f587329
BS
1526};
1527#endif
7e8c2b6c
BS
1528
1529static inline void gen_op_fcmps(int fccno)
1530{
1531 tcg_gen_helper_0_0(gen_fcmps[fccno]);
1532}
1533
1534static inline void gen_op_fcmpd(int fccno)
1535{
1536 tcg_gen_helper_0_0(gen_fcmpd[fccno]);
1537}
1538
1539#if defined(CONFIG_USER_ONLY)
1540static inline void gen_op_fcmpq(int fccno)
1541{
1542 tcg_gen_helper_0_0(gen_fcmpq[fccno]);
1543}
1544#endif
1545
1546static inline void gen_op_fcmpes(int fccno)
1547{
1548 tcg_gen_helper_0_0(gen_fcmpes[fccno]);
1549}
1550
1551static inline void gen_op_fcmped(int fccno)
1552{
1553 tcg_gen_helper_0_0(gen_fcmped[fccno]);
1554}
1555
1556#if defined(CONFIG_USER_ONLY)
1557static inline void gen_op_fcmpeq(int fccno)
1558{
1559 tcg_gen_helper_0_0(gen_fcmpeq[fccno]);
1560}
1561#endif
1562
1563#else
1564
1565static inline void gen_op_fcmps(int fccno)
1566{
1567 tcg_gen_helper_0_0(helper_fcmps);
1568}
1569
1570static inline void gen_op_fcmpd(int fccno)
1571{
1572 tcg_gen_helper_0_0(helper_fcmpd);
1573}
1574
1575#if defined(CONFIG_USER_ONLY)
1576static inline void gen_op_fcmpq(int fccno)
1577{
1578 tcg_gen_helper_0_0(helper_fcmpq);
1579}
1580#endif
1581
1582static inline void gen_op_fcmpes(int fccno)
1583{
1584 tcg_gen_helper_0_0(helper_fcmpes);
1585}
1586
1587static inline void gen_op_fcmped(int fccno)
1588{
1589 tcg_gen_helper_0_0(helper_fcmped);
1590}
1591
1592#if defined(CONFIG_USER_ONLY)
1593static inline void gen_op_fcmpeq(int fccno)
1594{
1595 tcg_gen_helper_0_0(helper_fcmpeq);
1596}
1597#endif
1598
3475187d
FB
1599#endif
1600
134d77a1
BS
1601static inline void gen_op_fpexception_im(int fsr_flags)
1602{
87e92502
BS
1603 tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~FSR_FTT_MASK);
1604 tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
134d77a1
BS
1605 gen_op_exception(TT_FP_EXCP);
1606}
1607
a80dde08
FB
1608static int gen_trap_ifnofpu(DisasContext * dc)
1609{
1610#if !defined(CONFIG_USER_ONLY)
1611 if (!dc->fpu_enabled) {
1612 save_state(dc);
1613 gen_op_exception(TT_NFPU_INSN);
1614 dc->is_br = 1;
1615 return 1;
1616 }
1617#endif
1618 return 0;
1619}
1620
7e8c2b6c
BS
1621static inline void gen_op_clear_ieee_excp_and_FTT(void)
1622{
87e92502 1623 tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~(FSR_FTT_MASK | FSR_CEXC_MASK));
7e8c2b6c
BS
1624}
1625
1626static inline void gen_clear_float_exceptions(void)
1627{
1628 tcg_gen_helper_0_0(helper_clear_float_exceptions);
1629}
1630
1a2fb1c0
BS
1631/* asi moves */
1632#ifdef TARGET_SPARC64
0425bee5 1633static inline TCGv gen_get_asi(int insn, TCGv r_addr)
1a2fb1c0
BS
1634{
1635 int asi, offset;
0425bee5 1636 TCGv r_asi;
1a2fb1c0 1637
1a2fb1c0 1638 if (IS_IMM) {
0425bee5 1639 r_asi = tcg_temp_new(TCG_TYPE_I32);
1a2fb1c0 1640 offset = GET_FIELD(insn, 25, 31);
0425bee5
BS
1641 tcg_gen_addi_tl(r_addr, r_addr, offset);
1642 tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
1a2fb1c0
BS
1643 } else {
1644 asi = GET_FIELD(insn, 19, 26);
0425bee5 1645 r_asi = tcg_const_i32(asi);
1a2fb1c0 1646 }
0425bee5
BS
1647 return r_asi;
1648}
1649
1650static inline void gen_ld_asi(int insn, int size, int sign)
1651{
1652 TCGv r_asi;
1653
1654 r_asi = gen_get_asi(insn, cpu_T[0]);
1655 tcg_gen_helper_1_4(helper_ld_asi, cpu_T[1], cpu_T[0], r_asi,
1656 tcg_const_i32(size), tcg_const_i32(sign));
1657 tcg_gen_discard_i32(r_asi);
1a2fb1c0
BS
1658}
1659
1660static inline void gen_st_asi(int insn, int size)
1661{
0425bee5 1662 TCGv r_asi;
1a2fb1c0 1663
0425bee5
BS
1664 r_asi = gen_get_asi(insn, cpu_T[0]);
1665 tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], r_asi,
1666 tcg_const_i32(size));
1667 tcg_gen_discard_i32(r_asi);
1a2fb1c0
BS
1668}
1669
1670static inline void gen_ldf_asi(int insn, int size, int rd)
1671{
0425bee5 1672 TCGv r_asi;
1a2fb1c0 1673
0425bee5
BS
1674 r_asi = gen_get_asi(insn, cpu_T[0]);
1675 tcg_gen_helper_0_4(helper_ldf_asi, cpu_T[0], r_asi, tcg_const_i32(size),
1676 tcg_const_i32(rd));
1677 tcg_gen_discard_i32(r_asi);
1a2fb1c0
BS
1678}
1679
1680static inline void gen_stf_asi(int insn, int size, int rd)
1681{
0425bee5 1682 TCGv r_asi;
1a2fb1c0 1683
0425bee5
BS
1684 r_asi = gen_get_asi(insn, cpu_T[0]);
1685 tcg_gen_helper_0_4(helper_stf_asi, cpu_T[0], r_asi, tcg_const_i32(size),
1686 tcg_const_i32(rd));
1687 tcg_gen_discard_i32(r_asi);
1a2fb1c0
BS
1688}
1689
1690static inline void gen_swap_asi(int insn)
1691{
0425bee5 1692 TCGv r_temp, r_asi;
1a2fb1c0 1693
1a2fb1c0 1694 r_temp = tcg_temp_new(TCG_TYPE_I32);
0425bee5
BS
1695 r_asi = gen_get_asi(insn, cpu_T[0]);
1696 tcg_gen_helper_1_4(helper_ld_asi, r_temp, cpu_T[0], r_asi,
1697 tcg_const_i32(4), tcg_const_i32(0));
1698 tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_temp, r_asi,
1699 tcg_const_i32(4));
1a2fb1c0 1700 tcg_gen_mov_i32(cpu_T[1], r_temp);
0425bee5
BS
1701 tcg_gen_discard_i32(r_asi);
1702 tcg_gen_discard_i32(r_temp);
1a2fb1c0
BS
1703}
1704
1705static inline void gen_ldda_asi(int insn)
1706{
0425bee5 1707 TCGv r_dword, r_asi;
1a2fb1c0 1708
1a2fb1c0 1709 r_dword = tcg_temp_new(TCG_TYPE_I64);
0425bee5
BS
1710 r_asi = gen_get_asi(insn, cpu_T[0]);
1711 tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], r_asi,
1712 tcg_const_i32(8), tcg_const_i32(0));
1a2fb1c0
BS
1713 tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
1714 tcg_gen_shri_i64(r_dword, r_dword, 32);
1715 tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
0425bee5
BS
1716 tcg_gen_discard_i32(r_asi);
1717 tcg_gen_discard_i64(r_dword);
1718}
1719
1720static inline void gen_stda_asi(int insn, int rd)
1721{
1722 TCGv r_dword, r_temp, r_asi;
1723
1724 r_dword = tcg_temp_new(TCG_TYPE_I64);
1725 r_temp = tcg_temp_new(TCG_TYPE_I32);
1726 gen_movl_reg_TN(rd + 1, r_temp);
1727 tcg_gen_helper_1_2(helper_pack64, r_dword, cpu_T[1],
1728 r_temp);
1729 r_asi = gen_get_asi(insn, cpu_T[0]);
1730 tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, r_asi,
1731 tcg_const_i32(8));
1732 tcg_gen_discard_i32(r_asi);
1733 tcg_gen_discard_i32(r_temp);
1734 tcg_gen_discard_i64(r_dword);
1a2fb1c0
BS
1735}
1736
1737static inline void gen_cas_asi(int insn, int rd)
1738{
1a2fb1c0
BS
1739 TCGv r_val1, r_asi;
1740
1741 r_val1 = tcg_temp_new(TCG_TYPE_I32);
1a2fb1c0 1742 gen_movl_reg_TN(rd, r_val1);
0425bee5 1743 r_asi = gen_get_asi(insn, cpu_T[0]);
1a2fb1c0
BS
1744 tcg_gen_helper_1_4(helper_cas_asi, cpu_T[1], cpu_T[0], r_val1, cpu_T[1],
1745 r_asi);
0425bee5
BS
1746 tcg_gen_discard_i32(r_asi);
1747 tcg_gen_discard_i32(r_val1);
1a2fb1c0
BS
1748}
1749
1750static inline void gen_casx_asi(int insn, int rd)
1751{
1a2fb1c0
BS
1752 TCGv r_val1, r_asi;
1753
1754 r_val1 = tcg_temp_new(TCG_TYPE_I64);
1a2fb1c0 1755 gen_movl_reg_TN(rd, r_val1);
0425bee5 1756 r_asi = gen_get_asi(insn, cpu_T[0]);
1a2fb1c0
BS
1757 tcg_gen_helper_1_4(helper_casx_asi, cpu_T[1], cpu_T[0], r_val1, cpu_T[1],
1758 r_asi);
0425bee5
BS
1759 tcg_gen_discard_i32(r_asi);
1760 tcg_gen_discard_i32(r_val1);
1a2fb1c0
BS
1761}
1762
1763#elif !defined(CONFIG_USER_ONLY)
1764
1765static inline void gen_ld_asi(int insn, int size, int sign)
1766{
1767 int asi;
0425bee5 1768 TCGv r_dword;
1a2fb1c0 1769
1a2fb1c0 1770 r_dword = tcg_temp_new(TCG_TYPE_I64);
1a2fb1c0 1771 asi = GET_FIELD(insn, 19, 26);
0425bee5
BS
1772 tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], tcg_const_i32(asi),
1773 tcg_const_i32(size), tcg_const_i32(sign));
1a2fb1c0 1774 tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
0425bee5 1775 tcg_gen_discard_i64(r_dword);
1a2fb1c0
BS
1776}
1777
1778static inline void gen_st_asi(int insn, int size)
1779{
1780 int asi;
0425bee5 1781 TCGv r_dword;
1a2fb1c0
BS
1782
1783 r_dword = tcg_temp_new(TCG_TYPE_I64);
1784 tcg_gen_extu_i32_i64(r_dword, cpu_T[1]);
1a2fb1c0 1785 asi = GET_FIELD(insn, 19, 26);
0425bee5
BS
1786 tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, tcg_const_i32(asi),
1787 tcg_const_i32(size));
1788 tcg_gen_discard_i64(r_dword);
1a2fb1c0
BS
1789}
1790
1791static inline void gen_swap_asi(int insn)
1792{
1793 int asi;
0425bee5 1794 TCGv r_temp;
1a2fb1c0 1795
1a2fb1c0 1796 r_temp = tcg_temp_new(TCG_TYPE_I32);
1a2fb1c0 1797 asi = GET_FIELD(insn, 19, 26);
0425bee5
BS
1798 tcg_gen_helper_1_4(helper_ld_asi, r_temp, cpu_T[0], tcg_const_i32(asi),
1799 tcg_const_i32(4), tcg_const_i32(0));
1800 tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], tcg_const_i32(asi),
1801 tcg_const_i32(4));
1a2fb1c0 1802 tcg_gen_mov_i32(cpu_T[1], r_temp);
0425bee5 1803 tcg_gen_discard_i32(r_temp);
1a2fb1c0
BS
1804}
1805
1806static inline void gen_ldda_asi(int insn)
1807{
1808 int asi;
0425bee5 1809 TCGv r_dword;
1a2fb1c0 1810
1a2fb1c0 1811 r_dword = tcg_temp_new(TCG_TYPE_I64);
1a2fb1c0 1812 asi = GET_FIELD(insn, 19, 26);
0425bee5
BS
1813 tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], tcg_const_i32(asi),
1814 tcg_const_i32(8), tcg_const_i32(0));
1a2fb1c0
BS
1815 tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
1816 tcg_gen_shri_i64(r_dword, r_dword, 32);
1817 tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
0425bee5
BS
1818 tcg_gen_discard_i64(r_dword);
1819}
1820
1821static inline void gen_stda_asi(int insn, int rd)
1822{
1823 int asi;
1824 TCGv r_dword, r_temp;
1825
1826 r_dword = tcg_temp_new(TCG_TYPE_I64);
1827 r_temp = tcg_temp_new(TCG_TYPE_I32);
1828 gen_movl_reg_TN(rd + 1, r_temp);
1829 tcg_gen_helper_1_2(helper_pack64, r_dword, cpu_T[1], r_temp);
1830 asi = GET_FIELD(insn, 19, 26);
1831 tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, tcg_const_i32(asi),
1832 tcg_const_i32(8));
1833 tcg_gen_discard_i64(r_dword);
1a2fb1c0
BS
1834}
1835#endif
1836
1837#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1838static inline void gen_ldstub_asi(int insn)
1839{
1840 int asi;
1a2fb1c0
BS
1841
1842 gen_ld_asi(insn, 1, 0);
1843
1a2fb1c0 1844 asi = GET_FIELD(insn, 19, 26);
0425bee5
BS
1845 tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], tcg_const_i64(0xff),
1846 tcg_const_i32(asi), tcg_const_i32(1));
1a2fb1c0
BS
1847}
1848#endif
1849
0bee699e 1850/* before an instruction, dc->pc must be static */
cf495bcf
FB
1851static void disas_sparc_insn(DisasContext * dc)
1852{
1853 unsigned int insn, opc, rs1, rs2, rd;
7a3f1944 1854
0fa85d43 1855 insn = ldl_code(dc->pc);
cf495bcf 1856 opc = GET_FIELD(insn, 0, 1);
7a3f1944 1857
cf495bcf
FB
1858 rd = GET_FIELD(insn, 2, 6);
1859 switch (opc) {
0f8a249a
BS
1860 case 0: /* branches/sethi */
1861 {
1862 unsigned int xop = GET_FIELD(insn, 7, 9);
1863 int32_t target;
1864 switch (xop) {
3475187d 1865#ifdef TARGET_SPARC64
0f8a249a
BS
1866 case 0x1: /* V9 BPcc */
1867 {
1868 int cc;
1869
1870 target = GET_FIELD_SP(insn, 0, 18);
1871 target = sign_extend(target, 18);
1872 target <<= 2;
1873 cc = GET_FIELD_SP(insn, 20, 21);
1874 if (cc == 0)
1875 do_branch(dc, target, insn, 0);
1876 else if (cc == 2)
1877 do_branch(dc, target, insn, 1);
1878 else
1879 goto illegal_insn;
1880 goto jmp_insn;
1881 }
1882 case 0x3: /* V9 BPr */
1883 {
1884 target = GET_FIELD_SP(insn, 0, 13) |
13846e70 1885 (GET_FIELD_SP(insn, 20, 21) << 14);
0f8a249a
BS
1886 target = sign_extend(target, 16);
1887 target <<= 2;
1888 rs1 = GET_FIELD(insn, 13, 17);
1889 gen_movl_reg_T0(rs1);
1890 do_branch_reg(dc, target, insn);
1891 goto jmp_insn;
1892 }
1893 case 0x5: /* V9 FBPcc */
1894 {
1895 int cc = GET_FIELD_SP(insn, 20, 21);
a80dde08
FB
1896 if (gen_trap_ifnofpu(dc))
1897 goto jmp_insn;
0f8a249a
BS
1898 target = GET_FIELD_SP(insn, 0, 18);
1899 target = sign_extend(target, 19);
1900 target <<= 2;
1901 do_fbranch(dc, target, insn, cc);
1902 goto jmp_insn;
1903 }
a4d17f19 1904#else
0f8a249a
BS
1905 case 0x7: /* CBN+x */
1906 {
1907 goto ncp_insn;
1908 }
1909#endif
1910 case 0x2: /* BN+x */
1911 {
1912 target = GET_FIELD(insn, 10, 31);
1913 target = sign_extend(target, 22);
1914 target <<= 2;
1915 do_branch(dc, target, insn, 0);
1916 goto jmp_insn;
1917 }
1918 case 0x6: /* FBN+x */
1919 {
a80dde08
FB
1920 if (gen_trap_ifnofpu(dc))
1921 goto jmp_insn;
0f8a249a
BS
1922 target = GET_FIELD(insn, 10, 31);
1923 target = sign_extend(target, 22);
1924 target <<= 2;
1925 do_fbranch(dc, target, insn, 0);
1926 goto jmp_insn;
1927 }
1928 case 0x4: /* SETHI */
e80cfcfc
FB
1929#define OPTIM
1930#if defined(OPTIM)
0f8a249a 1931 if (rd) { // nop
e80cfcfc 1932#endif
0f8a249a 1933 uint32_t value = GET_FIELD(insn, 10, 31);
1a2fb1c0 1934 tcg_gen_movi_tl(cpu_T[0], value << 10);
0f8a249a 1935 gen_movl_T0_reg(rd);
e80cfcfc 1936#if defined(OPTIM)
0f8a249a 1937 }
e80cfcfc 1938#endif
0f8a249a
BS
1939 break;
1940 case 0x0: /* UNIMPL */
1941 default:
3475187d 1942 goto illegal_insn;
0f8a249a
BS
1943 }
1944 break;
1945 }
1946 break;
cf495bcf 1947 case 1:
0f8a249a
BS
1948 /*CALL*/ {
1949 target_long target = GET_FIELDs(insn, 2, 31) << 2;
cf495bcf 1950
48d5c82b 1951 gen_movl_TN_reg(15, tcg_const_tl(dc->pc));
0f8a249a 1952 target += dc->pc;
0bee699e 1953 gen_mov_pc_npc(dc);
0f8a249a
BS
1954 dc->npc = target;
1955 }
1956 goto jmp_insn;
1957 case 2: /* FPU & Logical Operations */
1958 {
1959 unsigned int xop = GET_FIELD(insn, 7, 12);
1960 if (xop == 0x3a) { /* generate trap */
cf495bcf 1961 int cond;
3475187d 1962
cf495bcf
FB
1963 rs1 = GET_FIELD(insn, 13, 17);
1964 gen_movl_reg_T0(rs1);
0f8a249a
BS
1965 if (IS_IMM) {
1966 rs2 = GET_FIELD(insn, 25, 31);
1a2fb1c0 1967 tcg_gen_addi_tl(cpu_T[0], cpu_T[0], rs2);
cf495bcf
FB
1968 } else {
1969 rs2 = GET_FIELD(insn, 27, 31);
e80cfcfc 1970#if defined(OPTIM)
0f8a249a 1971 if (rs2 != 0) {
e80cfcfc 1972#endif
0f8a249a
BS
1973 gen_movl_reg_T1(rs2);
1974 gen_op_add_T1_T0();
e80cfcfc 1975#if defined(OPTIM)
0f8a249a 1976 }
e80cfcfc 1977#endif
cf495bcf 1978 }
cf495bcf
FB
1979 cond = GET_FIELD(insn, 3, 6);
1980 if (cond == 0x8) {
a80dde08 1981 save_state(dc);
1a2fb1c0 1982 tcg_gen_helper_0_1(helper_trap, cpu_T[0]);
af7bf89b 1983 } else if (cond != 0) {
748b9d8e 1984 TCGv r_cond = tcg_temp_new(TCG_TYPE_TL);
3475187d 1985#ifdef TARGET_SPARC64
0f8a249a
BS
1986 /* V9 icc/xcc */
1987 int cc = GET_FIELD_SP(insn, 11, 12);
748b9d8e 1988
a80dde08 1989 save_state(dc);
0f8a249a 1990 if (cc == 0)
748b9d8e 1991 gen_cond(r_cond, 0, cond);
0f8a249a 1992 else if (cc == 2)
748b9d8e 1993 gen_cond(r_cond, 1, cond);
0f8a249a
BS
1994 else
1995 goto illegal_insn;
3475187d 1996#else
a80dde08 1997 save_state(dc);
748b9d8e 1998 gen_cond(r_cond, 0, cond);
3475187d 1999#endif
748b9d8e 2000 tcg_gen_helper_0_2(helper_trapcc, cpu_T[0], r_cond);
0425bee5 2001 tcg_gen_discard_tl(r_cond);
cf495bcf 2002 }
a80dde08 2003 gen_op_next_insn();
57fec1fe 2004 tcg_gen_exit_tb(0);
a80dde08
FB
2005 dc->is_br = 1;
2006 goto jmp_insn;
cf495bcf
FB
2007 } else if (xop == 0x28) {
2008 rs1 = GET_FIELD(insn, 13, 17);
2009 switch(rs1) {
2010 case 0: /* rdy */
65fe7b09
BS
2011#ifndef TARGET_SPARC64
2012 case 0x01 ... 0x0e: /* undefined in the SPARCv8
2013 manual, rdy on the microSPARC
2014 II */
2015 case 0x0f: /* stbar in the SPARCv8 manual,
2016 rdy on the microSPARC II */
2017 case 0x10 ... 0x1f: /* implementation-dependent in the
2018 SPARCv8 manual, rdy on the
2019 microSPARC II */
2020#endif
2021 gen_op_movtl_T0_env(offsetof(CPUSPARCState, y));
cf495bcf
FB
2022 gen_movl_T0_reg(rd);
2023 break;
3475187d 2024#ifdef TARGET_SPARC64
0f8a249a 2025 case 0x2: /* V9 rdccr */
d35527d9 2026 tcg_gen_helper_1_0(helper_rdccr, cpu_T[0]);
3475187d
FB
2027 gen_movl_T0_reg(rd);
2028 break;
0f8a249a
BS
2029 case 0x3: /* V9 rdasi */
2030 gen_op_movl_T0_env(offsetof(CPUSPARCState, asi));
3475187d
FB
2031 gen_movl_T0_reg(rd);
2032 break;
0f8a249a 2033 case 0x4: /* V9 rdtick */
ccd4a219
BS
2034 {
2035 TCGv r_tickptr;
2036
2037 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2038 tcg_gen_ld_ptr(r_tickptr, cpu_env,
2039 offsetof(CPUState, tick));
2040 tcg_gen_helper_1_1(helper_tick_get_count, cpu_T[0],
2041 r_tickptr);
2042 gen_movl_T0_reg(rd);
0425bee5 2043 tcg_gen_discard_ptr(r_tickptr);
ccd4a219 2044 }
3475187d 2045 break;
0f8a249a 2046 case 0x5: /* V9 rdpc */
1a2fb1c0 2047 tcg_gen_movi_tl(cpu_T[0], dc->pc);
0f8a249a
BS
2048 gen_movl_T0_reg(rd);
2049 break;
2050 case 0x6: /* V9 rdfprs */
2051 gen_op_movl_T0_env(offsetof(CPUSPARCState, fprs));
3475187d
FB
2052 gen_movl_T0_reg(rd);
2053 break;
65fe7b09
BS
2054 case 0xf: /* V9 membar */
2055 break; /* no effect */
0f8a249a 2056 case 0x13: /* Graphics Status */
725cb90b
FB
2057 if (gen_trap_ifnofpu(dc))
2058 goto jmp_insn;
0f8a249a 2059 gen_op_movtl_T0_env(offsetof(CPUSPARCState, gsr));
725cb90b
FB
2060 gen_movl_T0_reg(rd);
2061 break;
0f8a249a
BS
2062 case 0x17: /* Tick compare */
2063 gen_op_movtl_T0_env(offsetof(CPUSPARCState, tick_cmpr));
83469015
FB
2064 gen_movl_T0_reg(rd);
2065 break;
0f8a249a 2066 case 0x18: /* System tick */
ccd4a219
BS
2067 {
2068 TCGv r_tickptr;
2069
2070 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2071 tcg_gen_ld_ptr(r_tickptr, cpu_env,
2072 offsetof(CPUState, stick));
2073 tcg_gen_helper_1_1(helper_tick_get_count, cpu_T[0],
2074 r_tickptr);
2075 gen_movl_T0_reg(rd);
0425bee5 2076 tcg_gen_discard_ptr(r_tickptr);
ccd4a219 2077 }
83469015 2078 break;
0f8a249a
BS
2079 case 0x19: /* System tick compare */
2080 gen_op_movtl_T0_env(offsetof(CPUSPARCState, stick_cmpr));
83469015
FB
2081 gen_movl_T0_reg(rd);
2082 break;
0f8a249a
BS
2083 case 0x10: /* Performance Control */
2084 case 0x11: /* Performance Instrumentation Counter */
2085 case 0x12: /* Dispatch Control */
2086 case 0x14: /* Softint set, WO */
2087 case 0x15: /* Softint clear, WO */
2088 case 0x16: /* Softint write */
3475187d
FB
2089#endif
2090 default:
cf495bcf
FB
2091 goto illegal_insn;
2092 }
e8af50a3 2093#if !defined(CONFIG_USER_ONLY)
e9ebed4d 2094 } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
3475187d 2095#ifndef TARGET_SPARC64
0f8a249a
BS
2096 if (!supervisor(dc))
2097 goto priv_insn;
1a2fb1c0 2098 tcg_gen_helper_1_0(helper_rdpsr, cpu_T[0]);
e9ebed4d
BS
2099#else
2100 if (!hypervisor(dc))
2101 goto priv_insn;
2102 rs1 = GET_FIELD(insn, 13, 17);
2103 switch (rs1) {
2104 case 0: // hpstate
2105 // gen_op_rdhpstate();
2106 break;
2107 case 1: // htstate
2108 // gen_op_rdhtstate();
2109 break;
2110 case 3: // hintp
2111 gen_op_movl_T0_env(offsetof(CPUSPARCState, hintp));
2112 break;
2113 case 5: // htba
2114 gen_op_movl_T0_env(offsetof(CPUSPARCState, htba));
2115 break;
2116 case 6: // hver
2117 gen_op_movl_T0_env(offsetof(CPUSPARCState, hver));
2118 break;
2119 case 31: // hstick_cmpr
2120 gen_op_movl_env_T0(offsetof(CPUSPARCState, hstick_cmpr));
2121 break;
2122 default:
2123 goto illegal_insn;
2124 }
2125#endif
e8af50a3
FB
2126 gen_movl_T0_reg(rd);
2127 break;
3475187d 2128 } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
0f8a249a
BS
2129 if (!supervisor(dc))
2130 goto priv_insn;
3475187d
FB
2131#ifdef TARGET_SPARC64
2132 rs1 = GET_FIELD(insn, 13, 17);
0f8a249a
BS
2133 switch (rs1) {
2134 case 0: // tpc
375ee38b
BS
2135 {
2136 TCGv r_tsptr;
2137
2138 r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2139 tcg_gen_ld_ptr(r_tsptr, cpu_env,
2140 offsetof(CPUState, tsptr));
2141 tcg_gen_ld_tl(cpu_T[0], r_tsptr,
2142 offsetof(trap_state, tpc));
0425bee5 2143 tcg_gen_discard_ptr(r_tsptr);
375ee38b 2144 }
0f8a249a
BS
2145 break;
2146 case 1: // tnpc
375ee38b
BS
2147 {
2148 TCGv r_tsptr;
2149
2150 r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2151 tcg_gen_ld_ptr(r_tsptr, cpu_env,
2152 offsetof(CPUState, tsptr));
2153 tcg_gen_ld_tl(cpu_T[0], r_tsptr,
2154 offsetof(trap_state, tnpc));
0425bee5 2155 tcg_gen_discard_ptr(r_tsptr);
375ee38b 2156 }
0f8a249a
BS
2157 break;
2158 case 2: // tstate
375ee38b
BS
2159 {
2160 TCGv r_tsptr;
2161
2162 r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2163 tcg_gen_ld_ptr(r_tsptr, cpu_env,
2164 offsetof(CPUState, tsptr));
2165 tcg_gen_ld_tl(cpu_T[0], r_tsptr,
2166 offsetof(trap_state, tstate));
0425bee5 2167 tcg_gen_discard_ptr(r_tsptr);
375ee38b 2168 }
0f8a249a
BS
2169 break;
2170 case 3: // tt
375ee38b
BS
2171 {
2172 TCGv r_tsptr;
2173
2174 r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2175 tcg_gen_ld_ptr(r_tsptr, cpu_env,
2176 offsetof(CPUState, tsptr));
2177 tcg_gen_ld_i32(cpu_T[0], r_tsptr,
2178 offsetof(trap_state, tt));
0425bee5 2179 tcg_gen_discard_ptr(r_tsptr);
375ee38b 2180 }
0f8a249a
BS
2181 break;
2182 case 4: // tick
ccd4a219
BS
2183 {
2184 TCGv r_tickptr;
2185
2186 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2187 tcg_gen_ld_ptr(r_tickptr, cpu_env,
2188 offsetof(CPUState, tick));
2189 tcg_gen_helper_1_1(helper_tick_get_count, cpu_T[0],
2190 r_tickptr);
2191 gen_movl_T0_reg(rd);
0425bee5 2192 tcg_gen_discard_ptr(r_tickptr);
ccd4a219 2193 }
0f8a249a
BS
2194 break;
2195 case 5: // tba
2196 gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
2197 break;
2198 case 6: // pstate
1a2fb1c0 2199 gen_op_movl_T0_env(offsetof(CPUSPARCState, pstate));
0f8a249a
BS
2200 break;
2201 case 7: // tl
2202 gen_op_movl_T0_env(offsetof(CPUSPARCState, tl));
2203 break;
2204 case 8: // pil
2205 gen_op_movl_T0_env(offsetof(CPUSPARCState, psrpil));
2206 break;
2207 case 9: // cwp
d35527d9 2208 tcg_gen_helper_1_0(helper_rdcwp, cpu_T[0]);
0f8a249a
BS
2209 break;
2210 case 10: // cansave
2211 gen_op_movl_T0_env(offsetof(CPUSPARCState, cansave));
2212 break;
2213 case 11: // canrestore
2214 gen_op_movl_T0_env(offsetof(CPUSPARCState, canrestore));
2215 break;
2216 case 12: // cleanwin
2217 gen_op_movl_T0_env(offsetof(CPUSPARCState, cleanwin));
2218 break;
2219 case 13: // otherwin
2220 gen_op_movl_T0_env(offsetof(CPUSPARCState, otherwin));
2221 break;
2222 case 14: // wstate
2223 gen_op_movl_T0_env(offsetof(CPUSPARCState, wstate));
2224 break;
e9ebed4d
BS
2225 case 16: // UA2005 gl
2226 gen_op_movl_T0_env(offsetof(CPUSPARCState, gl));
2227 break;
2228 case 26: // UA2005 strand status
2229 if (!hypervisor(dc))
2230 goto priv_insn;
2231 gen_op_movl_T0_env(offsetof(CPUSPARCState, ssr));
2232 break;
0f8a249a
BS
2233 case 31: // ver
2234 gen_op_movtl_T0_env(offsetof(CPUSPARCState, version));
2235 break;
2236 case 15: // fq
2237 default:
2238 goto illegal_insn;
2239 }
3475187d 2240#else
0f8a249a 2241 gen_op_movl_T0_env(offsetof(CPUSPARCState, wim));
3475187d 2242#endif
e8af50a3
FB
2243 gen_movl_T0_reg(rd);
2244 break;
3475187d
FB
2245 } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
2246#ifdef TARGET_SPARC64
0f8a249a 2247 gen_op_flushw();
3475187d 2248#else
0f8a249a
BS
2249 if (!supervisor(dc))
2250 goto priv_insn;
2251 gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
e8af50a3 2252 gen_movl_T0_reg(rd);
3475187d 2253#endif
e8af50a3
FB
2254 break;
2255#endif
0f8a249a 2256 } else if (xop == 0x34) { /* FPU Operations */
a80dde08
FB
2257 if (gen_trap_ifnofpu(dc))
2258 goto jmp_insn;
0f8a249a 2259 gen_op_clear_ieee_excp_and_FTT();
e8af50a3 2260 rs1 = GET_FIELD(insn, 13, 17);
0f8a249a
BS
2261 rs2 = GET_FIELD(insn, 27, 31);
2262 xop = GET_FIELD(insn, 18, 26);
2263 switch (xop) {
2264 case 0x1: /* fmovs */
2265 gen_op_load_fpr_FT0(rs2);
2266 gen_op_store_FT0_fpr(rd);
2267 break;
2268 case 0x5: /* fnegs */
2269 gen_op_load_fpr_FT1(rs2);
2270 gen_op_fnegs();
2271 gen_op_store_FT0_fpr(rd);
2272 break;
2273 case 0x9: /* fabss */
2274 gen_op_load_fpr_FT1(rs2);
7e8c2b6c 2275 tcg_gen_helper_0_0(helper_fabss);
0f8a249a
BS
2276 gen_op_store_FT0_fpr(rd);
2277 break;
2278 case 0x29: /* fsqrts */
2279 gen_op_load_fpr_FT1(rs2);
7e8c2b6c
BS
2280 gen_clear_float_exceptions();
2281 tcg_gen_helper_0_0(helper_fsqrts);
2282 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2283 gen_op_store_FT0_fpr(rd);
2284 break;
2285 case 0x2a: /* fsqrtd */
2286 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c
BS
2287 gen_clear_float_exceptions();
2288 tcg_gen_helper_0_0(helper_fsqrtd);
2289 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2290 gen_op_store_DT0_fpr(DFPREG(rd));
2291 break;
2292 case 0x2b: /* fsqrtq */
1f587329
BS
2293#if defined(CONFIG_USER_ONLY)
2294 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c
BS
2295 gen_clear_float_exceptions();
2296 tcg_gen_helper_0_0(helper_fsqrtq);
2297 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2298 gen_op_store_QT0_fpr(QFPREG(rd));
2299 break;
2300#else
0f8a249a 2301 goto nfpu_insn;
1f587329 2302#endif
0f8a249a
BS
2303 case 0x41:
2304 gen_op_load_fpr_FT0(rs1);
2305 gen_op_load_fpr_FT1(rs2);
7e8c2b6c 2306 gen_clear_float_exceptions();
0f8a249a 2307 gen_op_fadds();
7e8c2b6c 2308 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2309 gen_op_store_FT0_fpr(rd);
2310 break;
2311 case 0x42:
2312 gen_op_load_fpr_DT0(DFPREG(rs1));
2313 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2314 gen_clear_float_exceptions();
0f8a249a 2315 gen_op_faddd();
7e8c2b6c 2316 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2317 gen_op_store_DT0_fpr(DFPREG(rd));
2318 break;
2319 case 0x43: /* faddq */
1f587329
BS
2320#if defined(CONFIG_USER_ONLY)
2321 gen_op_load_fpr_QT0(QFPREG(rs1));
2322 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2323 gen_clear_float_exceptions();
1f587329 2324 gen_op_faddq();
7e8c2b6c 2325 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2326 gen_op_store_QT0_fpr(QFPREG(rd));
2327 break;
2328#else
0f8a249a 2329 goto nfpu_insn;
1f587329 2330#endif
0f8a249a
BS
2331 case 0x45:
2332 gen_op_load_fpr_FT0(rs1);
2333 gen_op_load_fpr_FT1(rs2);
7e8c2b6c 2334 gen_clear_float_exceptions();
0f8a249a 2335 gen_op_fsubs();
7e8c2b6c 2336 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2337 gen_op_store_FT0_fpr(rd);
2338 break;
2339 case 0x46:
2340 gen_op_load_fpr_DT0(DFPREG(rs1));
2341 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2342 gen_clear_float_exceptions();
0f8a249a 2343 gen_op_fsubd();
7e8c2b6c 2344 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2345 gen_op_store_DT0_fpr(DFPREG(rd));
2346 break;
2347 case 0x47: /* fsubq */
1f587329
BS
2348#if defined(CONFIG_USER_ONLY)
2349 gen_op_load_fpr_QT0(QFPREG(rs1));
2350 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2351 gen_clear_float_exceptions();
1f587329 2352 gen_op_fsubq();
7e8c2b6c 2353 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2354 gen_op_store_QT0_fpr(QFPREG(rd));
2355 break;
2356#else
0f8a249a 2357 goto nfpu_insn;
1f587329 2358#endif
0f8a249a
BS
2359 case 0x49:
2360 gen_op_load_fpr_FT0(rs1);
2361 gen_op_load_fpr_FT1(rs2);
7e8c2b6c 2362 gen_clear_float_exceptions();
0f8a249a 2363 gen_op_fmuls();
7e8c2b6c 2364 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2365 gen_op_store_FT0_fpr(rd);
2366 break;
2367 case 0x4a:
2368 gen_op_load_fpr_DT0(DFPREG(rs1));
2369 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2370 gen_clear_float_exceptions();
0f8a249a 2371 gen_op_fmuld();
7e8c2b6c 2372 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2382dc6b 2373 gen_op_store_DT0_fpr(DFPREG(rd));
0f8a249a
BS
2374 break;
2375 case 0x4b: /* fmulq */
1f587329
BS
2376#if defined(CONFIG_USER_ONLY)
2377 gen_op_load_fpr_QT0(QFPREG(rs1));
2378 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2379 gen_clear_float_exceptions();
1f587329 2380 gen_op_fmulq();
7e8c2b6c 2381 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2382 gen_op_store_QT0_fpr(QFPREG(rd));
2383 break;
2384#else
0f8a249a 2385 goto nfpu_insn;
1f587329 2386#endif
0f8a249a
BS
2387 case 0x4d:
2388 gen_op_load_fpr_FT0(rs1);
2389 gen_op_load_fpr_FT1(rs2);
7e8c2b6c 2390 gen_clear_float_exceptions();
0f8a249a 2391 gen_op_fdivs();
7e8c2b6c 2392 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2393 gen_op_store_FT0_fpr(rd);
2394 break;
2395 case 0x4e:
2396 gen_op_load_fpr_DT0(DFPREG(rs1));
2397 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2398 gen_clear_float_exceptions();
0f8a249a 2399 gen_op_fdivd();
7e8c2b6c 2400 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2401 gen_op_store_DT0_fpr(DFPREG(rd));
2402 break;
2403 case 0x4f: /* fdivq */
1f587329
BS
2404#if defined(CONFIG_USER_ONLY)
2405 gen_op_load_fpr_QT0(QFPREG(rs1));
2406 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2407 gen_clear_float_exceptions();
1f587329 2408 gen_op_fdivq();
7e8c2b6c 2409 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2410 gen_op_store_QT0_fpr(QFPREG(rd));
2411 break;
2412#else
0f8a249a 2413 goto nfpu_insn;
1f587329 2414#endif
0f8a249a
BS
2415 case 0x69:
2416 gen_op_load_fpr_FT0(rs1);
2417 gen_op_load_fpr_FT1(rs2);
7e8c2b6c 2418 gen_clear_float_exceptions();
0f8a249a 2419 gen_op_fsmuld();
7e8c2b6c 2420 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2421 gen_op_store_DT0_fpr(DFPREG(rd));
2422 break;
2423 case 0x6e: /* fdmulq */
1f587329
BS
2424#if defined(CONFIG_USER_ONLY)
2425 gen_op_load_fpr_DT0(DFPREG(rs1));
2426 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2427 gen_clear_float_exceptions();
1f587329 2428 gen_op_fdmulq();
7e8c2b6c 2429 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2430 gen_op_store_QT0_fpr(QFPREG(rd));
2431 break;
2432#else
0f8a249a 2433 goto nfpu_insn;
1f587329 2434#endif
0f8a249a
BS
2435 case 0xc4:
2436 gen_op_load_fpr_FT1(rs2);
7e8c2b6c 2437 gen_clear_float_exceptions();
0f8a249a 2438 gen_op_fitos();
7e8c2b6c 2439 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2440 gen_op_store_FT0_fpr(rd);
2441 break;
2442 case 0xc6:
2443 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2444 gen_clear_float_exceptions();
0f8a249a 2445 gen_op_fdtos();
7e8c2b6c 2446 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2447 gen_op_store_FT0_fpr(rd);
2448 break;
2449 case 0xc7: /* fqtos */
1f587329
BS
2450#if defined(CONFIG_USER_ONLY)
2451 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2452 gen_clear_float_exceptions();
1f587329 2453 gen_op_fqtos();
7e8c2b6c 2454 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2455 gen_op_store_FT0_fpr(rd);
2456 break;
2457#else
0f8a249a 2458 goto nfpu_insn;
1f587329 2459#endif
0f8a249a
BS
2460 case 0xc8:
2461 gen_op_load_fpr_FT1(rs2);
2462 gen_op_fitod();
2463 gen_op_store_DT0_fpr(DFPREG(rd));
2464 break;
2465 case 0xc9:
2466 gen_op_load_fpr_FT1(rs2);
2467 gen_op_fstod();
2468 gen_op_store_DT0_fpr(DFPREG(rd));
2469 break;
2470 case 0xcb: /* fqtod */
1f587329
BS
2471#if defined(CONFIG_USER_ONLY)
2472 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2473 gen_clear_float_exceptions();
1f587329 2474 gen_op_fqtod();
7e8c2b6c 2475 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2476 gen_op_store_DT0_fpr(DFPREG(rd));
2477 break;
2478#else
0f8a249a 2479 goto nfpu_insn;
1f587329 2480#endif
0f8a249a 2481 case 0xcc: /* fitoq */
1f587329
BS
2482#if defined(CONFIG_USER_ONLY)
2483 gen_op_load_fpr_FT1(rs2);
2484 gen_op_fitoq();
2485 gen_op_store_QT0_fpr(QFPREG(rd));
2486 break;
2487#else
0f8a249a 2488 goto nfpu_insn;
1f587329 2489#endif
0f8a249a 2490 case 0xcd: /* fstoq */
1f587329
BS
2491#if defined(CONFIG_USER_ONLY)
2492 gen_op_load_fpr_FT1(rs2);
2493 gen_op_fstoq();
2494 gen_op_store_QT0_fpr(QFPREG(rd));
2495 break;
2496#else
0f8a249a 2497 goto nfpu_insn;
1f587329 2498#endif
0f8a249a 2499 case 0xce: /* fdtoq */
1f587329
BS
2500#if defined(CONFIG_USER_ONLY)
2501 gen_op_load_fpr_DT1(DFPREG(rs2));
2502 gen_op_fdtoq();
2503 gen_op_store_QT0_fpr(QFPREG(rd));
2504 break;
2505#else
0f8a249a 2506 goto nfpu_insn;
1f587329 2507#endif
0f8a249a
BS
2508 case 0xd1:
2509 gen_op_load_fpr_FT1(rs2);
7e8c2b6c 2510 gen_clear_float_exceptions();
0f8a249a 2511 gen_op_fstoi();
7e8c2b6c 2512 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2513 gen_op_store_FT0_fpr(rd);
2514 break;
2515 case 0xd2:
2382dc6b 2516 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2517 gen_clear_float_exceptions();
0f8a249a 2518 gen_op_fdtoi();
7e8c2b6c 2519 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2520 gen_op_store_FT0_fpr(rd);
2521 break;
2522 case 0xd3: /* fqtoi */
1f587329
BS
2523#if defined(CONFIG_USER_ONLY)
2524 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2525 gen_clear_float_exceptions();
1f587329 2526 gen_op_fqtoi();
7e8c2b6c 2527 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2528 gen_op_store_FT0_fpr(rd);
2529 break;
2530#else
0f8a249a 2531 goto nfpu_insn;
1f587329 2532#endif
3475187d 2533#ifdef TARGET_SPARC64
0f8a249a
BS
2534 case 0x2: /* V9 fmovd */
2535 gen_op_load_fpr_DT0(DFPREG(rs2));
2536 gen_op_store_DT0_fpr(DFPREG(rd));
2537 break;
1f587329
BS
2538 case 0x3: /* V9 fmovq */
2539#if defined(CONFIG_USER_ONLY)
2540 gen_op_load_fpr_QT0(QFPREG(rs2));
2541 gen_op_store_QT0_fpr(QFPREG(rd));
2542 break;
2543#else
2544 goto nfpu_insn;
2545#endif
0f8a249a
BS
2546 case 0x6: /* V9 fnegd */
2547 gen_op_load_fpr_DT1(DFPREG(rs2));
2548 gen_op_fnegd();
2549 gen_op_store_DT0_fpr(DFPREG(rd));
2550 break;
1f587329
BS
2551 case 0x7: /* V9 fnegq */
2552#if defined(CONFIG_USER_ONLY)
2553 gen_op_load_fpr_QT1(QFPREG(rs2));
2554 gen_op_fnegq();
2555 gen_op_store_QT0_fpr(QFPREG(rd));
2556 break;
2557#else
2558 goto nfpu_insn;
2559#endif
0f8a249a
BS
2560 case 0xa: /* V9 fabsd */
2561 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2562 tcg_gen_helper_0_0(helper_fabsd);
0f8a249a
BS
2563 gen_op_store_DT0_fpr(DFPREG(rd));
2564 break;
1f587329
BS
2565 case 0xb: /* V9 fabsq */
2566#if defined(CONFIG_USER_ONLY)
2567 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2568 tcg_gen_helper_0_0(helper_fabsq);
1f587329
BS
2569 gen_op_store_QT0_fpr(QFPREG(rd));
2570 break;
2571#else
2572 goto nfpu_insn;
2573#endif
0f8a249a
BS
2574 case 0x81: /* V9 fstox */
2575 gen_op_load_fpr_FT1(rs2);
7e8c2b6c 2576 gen_clear_float_exceptions();
0f8a249a 2577 gen_op_fstox();
7e8c2b6c 2578 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2579 gen_op_store_DT0_fpr(DFPREG(rd));
2580 break;
2581 case 0x82: /* V9 fdtox */
2582 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2583 gen_clear_float_exceptions();
0f8a249a 2584 gen_op_fdtox();
7e8c2b6c 2585 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2586 gen_op_store_DT0_fpr(DFPREG(rd));
2587 break;
1f587329
BS
2588 case 0x83: /* V9 fqtox */
2589#if defined(CONFIG_USER_ONLY)
2590 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2591 gen_clear_float_exceptions();
1f587329 2592 gen_op_fqtox();
7e8c2b6c 2593 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2594 gen_op_store_DT0_fpr(DFPREG(rd));
2595 break;
2596#else
2597 goto nfpu_insn;
2598#endif
0f8a249a
BS
2599 case 0x84: /* V9 fxtos */
2600 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2601 gen_clear_float_exceptions();
0f8a249a 2602 gen_op_fxtos();
7e8c2b6c 2603 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2604 gen_op_store_FT0_fpr(rd);
2605 break;
2606 case 0x88: /* V9 fxtod */
2607 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2608 gen_clear_float_exceptions();
0f8a249a 2609 gen_op_fxtod();
7e8c2b6c 2610 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2611 gen_op_store_DT0_fpr(DFPREG(rd));
2612 break;
0f8a249a 2613 case 0x8c: /* V9 fxtoq */
1f587329
BS
2614#if defined(CONFIG_USER_ONLY)
2615 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2616 gen_clear_float_exceptions();
1f587329 2617 gen_op_fxtoq();
7e8c2b6c 2618 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2619 gen_op_store_QT0_fpr(QFPREG(rd));
2620 break;
2621#else
0f8a249a 2622 goto nfpu_insn;
1f587329 2623#endif
0f8a249a
BS
2624#endif
2625 default:
2626 goto illegal_insn;
2627 }
2628 } else if (xop == 0x35) { /* FPU Operations */
3475187d 2629#ifdef TARGET_SPARC64
0f8a249a 2630 int cond;
3475187d 2631#endif
a80dde08
FB
2632 if (gen_trap_ifnofpu(dc))
2633 goto jmp_insn;
0f8a249a 2634 gen_op_clear_ieee_excp_and_FTT();
cf495bcf 2635 rs1 = GET_FIELD(insn, 13, 17);
0f8a249a
BS
2636 rs2 = GET_FIELD(insn, 27, 31);
2637 xop = GET_FIELD(insn, 18, 26);
3475187d 2638#ifdef TARGET_SPARC64
0f8a249a 2639 if ((xop & 0x11f) == 0x005) { // V9 fmovsr
dcf24905
BS
2640 int l1;
2641
2642 l1 = gen_new_label();
0f8a249a 2643 cond = GET_FIELD_SP(insn, 14, 17);
0f8a249a
BS
2644 rs1 = GET_FIELD(insn, 13, 17);
2645 gen_movl_reg_T0(rs1);
0425bee5
BS
2646 tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0],
2647 tcg_const_tl(0), l1);
19f329ad 2648 gen_op_load_fpr_FT0(rs2);
0f8a249a 2649 gen_op_store_FT0_fpr(rd);
dcf24905 2650 gen_set_label(l1);
0f8a249a
BS
2651 break;
2652 } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
dcf24905
BS
2653 int l1;
2654
2655 l1 = gen_new_label();
0f8a249a 2656 cond = GET_FIELD_SP(insn, 14, 17);
0f8a249a
BS
2657 rs1 = GET_FIELD(insn, 13, 17);
2658 gen_movl_reg_T0(rs1);
0425bee5
BS
2659 tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0],
2660 tcg_const_tl(0), l1);
19f329ad 2661 gen_op_load_fpr_DT0(DFPREG(rs2));
2382dc6b 2662 gen_op_store_DT0_fpr(DFPREG(rd));
dcf24905 2663 gen_set_label(l1);
0f8a249a
BS
2664 break;
2665 } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
1f587329 2666#if defined(CONFIG_USER_ONLY)
dcf24905
BS
2667 int l1;
2668
2669 l1 = gen_new_label();
1f587329 2670 cond = GET_FIELD_SP(insn, 14, 17);
1f587329
BS
2671 rs1 = GET_FIELD(insn, 13, 17);
2672 gen_movl_reg_T0(rs1);
0425bee5
BS
2673 tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0],
2674 tcg_const_tl(0), l1);
19f329ad 2675 gen_op_load_fpr_QT0(QFPREG(rs2));
1f587329 2676 gen_op_store_QT0_fpr(QFPREG(rd));
dcf24905 2677 gen_set_label(l1);
1f587329
BS
2678 break;
2679#else
0f8a249a 2680 goto nfpu_insn;
1f587329 2681#endif
0f8a249a
BS
2682 }
2683#endif
2684 switch (xop) {
3475187d 2685#ifdef TARGET_SPARC64
19f329ad
BS
2686#define FMOVCC(size_FDQ, fcc) \
2687 { \
0425bee5 2688 TCGv r_cond; \
19f329ad
BS
2689 int l1; \
2690 \
2691 l1 = gen_new_label(); \
19f329ad 2692 r_cond = tcg_temp_new(TCG_TYPE_TL); \
19f329ad
BS
2693 cond = GET_FIELD_SP(insn, 14, 17); \
2694 gen_fcond(r_cond, fcc, cond); \
0425bee5
BS
2695 tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, \
2696 tcg_const_tl(0), l1); \
19f329ad
BS
2697 glue(glue(gen_op_load_fpr_, size_FDQ), T0)(glue(size_FDQ, FPREG(rs2))); \
2698 glue(glue(gen_op_store_, size_FDQ), T0_fpr)(glue(size_FDQ, FPREG(rd))); \
2699 gen_set_label(l1); \
0425bee5 2700 tcg_gen_discard_tl(r_cond); \
19f329ad 2701 }
0f8a249a 2702 case 0x001: /* V9 fmovscc %fcc0 */
19f329ad 2703 FMOVCC(F, 0);
0f8a249a
BS
2704 break;
2705 case 0x002: /* V9 fmovdcc %fcc0 */
19f329ad 2706 FMOVCC(D, 0);
0f8a249a
BS
2707 break;
2708 case 0x003: /* V9 fmovqcc %fcc0 */
1f587329 2709#if defined(CONFIG_USER_ONLY)
19f329ad 2710 FMOVCC(Q, 0);
1f587329
BS
2711 break;
2712#else
0f8a249a 2713 goto nfpu_insn;
1f587329 2714#endif
0f8a249a 2715 case 0x041: /* V9 fmovscc %fcc1 */
19f329ad 2716 FMOVCC(F, 1);
0f8a249a
BS
2717 break;
2718 case 0x042: /* V9 fmovdcc %fcc1 */
19f329ad 2719 FMOVCC(D, 1);
0f8a249a
BS
2720 break;
2721 case 0x043: /* V9 fmovqcc %fcc1 */
1f587329 2722#if defined(CONFIG_USER_ONLY)
19f329ad 2723 FMOVCC(Q, 1);
1f587329
BS
2724 break;
2725#else
0f8a249a 2726 goto nfpu_insn;
1f587329 2727#endif
0f8a249a 2728 case 0x081: /* V9 fmovscc %fcc2 */
19f329ad 2729 FMOVCC(F, 2);
0f8a249a
BS
2730 break;
2731 case 0x082: /* V9 fmovdcc %fcc2 */
19f329ad 2732 FMOVCC(D, 2);
0f8a249a
BS
2733 break;
2734 case 0x083: /* V9 fmovqcc %fcc2 */
1f587329 2735#if defined(CONFIG_USER_ONLY)
19f329ad 2736 FMOVCC(Q, 2);
1f587329
BS
2737 break;
2738#else
0f8a249a 2739 goto nfpu_insn;
1f587329 2740#endif
0f8a249a 2741 case 0x0c1: /* V9 fmovscc %fcc3 */
19f329ad 2742 FMOVCC(F, 3);
0f8a249a
BS
2743 break;
2744 case 0x0c2: /* V9 fmovdcc %fcc3 */
19f329ad 2745 FMOVCC(D, 3);
0f8a249a
BS
2746 break;
2747 case 0x0c3: /* V9 fmovqcc %fcc3 */
1f587329 2748#if defined(CONFIG_USER_ONLY)
19f329ad 2749 FMOVCC(Q, 3);
1f587329
BS
2750 break;
2751#else
0f8a249a 2752 goto nfpu_insn;
1f587329 2753#endif
19f329ad
BS
2754#undef FMOVCC
2755#define FMOVCC(size_FDQ, icc) \
2756 { \
0425bee5 2757 TCGv r_cond; \
19f329ad
BS
2758 int l1; \
2759 \
2760 l1 = gen_new_label(); \
19f329ad 2761 r_cond = tcg_temp_new(TCG_TYPE_TL); \
19f329ad
BS
2762 cond = GET_FIELD_SP(insn, 14, 17); \
2763 gen_cond(r_cond, icc, cond); \
0425bee5
BS
2764 tcg_gen_brcond_tl(TCG_COND_EQ, r_cond, \
2765 tcg_const_tl(0), l1); \
19f329ad
BS
2766 glue(glue(gen_op_load_fpr_, size_FDQ), T0)(glue(size_FDQ, FPREG(rs2))); \
2767 glue(glue(gen_op_store_, size_FDQ), T0_fpr)(glue(size_FDQ, FPREG(rd))); \
2768 gen_set_label(l1); \
0425bee5 2769 tcg_gen_discard_tl(r_cond); \
19f329ad
BS
2770 }
2771
0f8a249a 2772 case 0x101: /* V9 fmovscc %icc */
19f329ad 2773 FMOVCC(F, 0);
0f8a249a
BS
2774 break;
2775 case 0x102: /* V9 fmovdcc %icc */
19f329ad 2776 FMOVCC(D, 0);
0f8a249a 2777 case 0x103: /* V9 fmovqcc %icc */
1f587329 2778#if defined(CONFIG_USER_ONLY)
19f329ad 2779 FMOVCC(D, 0);
1f587329
BS
2780 break;
2781#else
0f8a249a 2782 goto nfpu_insn;
1f587329 2783#endif
0f8a249a 2784 case 0x181: /* V9 fmovscc %xcc */
19f329ad 2785 FMOVCC(F, 1);
0f8a249a
BS
2786 break;
2787 case 0x182: /* V9 fmovdcc %xcc */
19f329ad 2788 FMOVCC(D, 1);
0f8a249a
BS
2789 break;
2790 case 0x183: /* V9 fmovqcc %xcc */
1f587329 2791#if defined(CONFIG_USER_ONLY)
19f329ad 2792 FMOVCC(Q, 1);
1f587329
BS
2793 break;
2794#else
0f8a249a
BS
2795 goto nfpu_insn;
2796#endif
19f329ad 2797#undef FMOVCC
1f587329
BS
2798#endif
2799 case 0x51: /* fcmps, V9 %fcc */
0f8a249a
BS
2800 gen_op_load_fpr_FT0(rs1);
2801 gen_op_load_fpr_FT1(rs2);
7e8c2b6c 2802 gen_op_fcmps(rd & 3);
0f8a249a 2803 break;
1f587329 2804 case 0x52: /* fcmpd, V9 %fcc */
0f8a249a
BS
2805 gen_op_load_fpr_DT0(DFPREG(rs1));
2806 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2807 gen_op_fcmpd(rd & 3);
0f8a249a 2808 break;
1f587329
BS
2809 case 0x53: /* fcmpq, V9 %fcc */
2810#if defined(CONFIG_USER_ONLY)
2811 gen_op_load_fpr_QT0(QFPREG(rs1));
2812 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2813 gen_op_fcmpq(rd & 3);
1f587329
BS
2814 break;
2815#else /* !defined(CONFIG_USER_ONLY) */
0f8a249a 2816 goto nfpu_insn;
1f587329 2817#endif
0f8a249a
BS
2818 case 0x55: /* fcmpes, V9 %fcc */
2819 gen_op_load_fpr_FT0(rs1);
2820 gen_op_load_fpr_FT1(rs2);
7e8c2b6c 2821 gen_op_fcmpes(rd & 3);
0f8a249a
BS
2822 break;
2823 case 0x56: /* fcmped, V9 %fcc */
2824 gen_op_load_fpr_DT0(DFPREG(rs1));
2825 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2826 gen_op_fcmped(rd & 3);
0f8a249a 2827 break;
1f587329
BS
2828 case 0x57: /* fcmpeq, V9 %fcc */
2829#if defined(CONFIG_USER_ONLY)
2830 gen_op_load_fpr_QT0(QFPREG(rs1));
2831 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2832 gen_op_fcmpeq(rd & 3);
1f587329
BS
2833 break;
2834#else/* !defined(CONFIG_USER_ONLY) */
0f8a249a 2835 goto nfpu_insn;
1f587329 2836#endif
0f8a249a
BS
2837 default:
2838 goto illegal_insn;
2839 }
e80cfcfc 2840#if defined(OPTIM)
0f8a249a
BS
2841 } else if (xop == 0x2) {
2842 // clr/mov shortcut
e80cfcfc
FB
2843
2844 rs1 = GET_FIELD(insn, 13, 17);
0f8a249a 2845 if (rs1 == 0) {
1a2fb1c0 2846 // or %g0, x, y -> mov T0, x; mov y, T0
0f8a249a
BS
2847 if (IS_IMM) { /* immediate */
2848 rs2 = GET_FIELDs(insn, 19, 31);
1a2fb1c0 2849 tcg_gen_movi_tl(cpu_T[0], (int)rs2);
0f8a249a
BS
2850 } else { /* register */
2851 rs2 = GET_FIELD(insn, 27, 31);
1a2fb1c0 2852 gen_movl_reg_T0(rs2);
0f8a249a 2853 }
0f8a249a
BS
2854 } else {
2855 gen_movl_reg_T0(rs1);
2856 if (IS_IMM) { /* immediate */
0f8a249a 2857 rs2 = GET_FIELDs(insn, 19, 31);
1a2fb1c0 2858 tcg_gen_ori_tl(cpu_T[0], cpu_T[0], (int)rs2);
0f8a249a
BS
2859 } else { /* register */
2860 // or x, %g0, y -> mov T1, x; mov y, T1
2861 rs2 = GET_FIELD(insn, 27, 31);
2862 if (rs2 != 0) {
2863 gen_movl_reg_T1(rs2);
2864 gen_op_or_T1_T0();
2865 }
2866 }
0f8a249a 2867 }
1a2fb1c0 2868 gen_movl_T0_reg(rd);
83469015
FB
2869#endif
2870#ifdef TARGET_SPARC64
0f8a249a 2871 } else if (xop == 0x25) { /* sll, V9 sllx */
83469015 2872 rs1 = GET_FIELD(insn, 13, 17);
0f8a249a
BS
2873 gen_movl_reg_T0(rs1);
2874 if (IS_IMM) { /* immediate */
83469015 2875 rs2 = GET_FIELDs(insn, 20, 31);
1a2fb1c0
BS
2876 if (insn & (1 << 12)) {
2877 tcg_gen_shli_i64(cpu_T[0], cpu_T[0], rs2 & 0x3f);
2878 } else {
2879 tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
2880 tcg_gen_shli_i64(cpu_T[0], cpu_T[0], rs2 & 0x1f);
2881 }
0f8a249a 2882 } else { /* register */
83469015
FB
2883 rs2 = GET_FIELD(insn, 27, 31);
2884 gen_movl_reg_T1(rs2);
1a2fb1c0
BS
2885 if (insn & (1 << 12)) {
2886 tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x3f);
2887 tcg_gen_shl_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2888 } else {
2889 tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x1f);
2890 tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
2891 tcg_gen_shl_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2892 }
83469015 2893 }
0f8a249a
BS
2894 gen_movl_T0_reg(rd);
2895 } else if (xop == 0x26) { /* srl, V9 srlx */
83469015 2896 rs1 = GET_FIELD(insn, 13, 17);
0f8a249a
BS
2897 gen_movl_reg_T0(rs1);
2898 if (IS_IMM) { /* immediate */
83469015 2899 rs2 = GET_FIELDs(insn, 20, 31);
1a2fb1c0
BS
2900 if (insn & (1 << 12)) {
2901 tcg_gen_shri_i64(cpu_T[0], cpu_T[0], rs2 & 0x3f);
2902 } else {
2903 tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
2904 tcg_gen_shri_i64(cpu_T[0], cpu_T[0], rs2 & 0x1f);
2905 }
0f8a249a 2906 } else { /* register */
83469015
FB
2907 rs2 = GET_FIELD(insn, 27, 31);
2908 gen_movl_reg_T1(rs2);
1a2fb1c0
BS
2909 if (insn & (1 << 12)) {
2910 tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x3f);
2911 tcg_gen_shr_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2912 } else {
2913 tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x1f);
2914 tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
2915 tcg_gen_shr_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2916 }
83469015 2917 }
0f8a249a
BS
2918 gen_movl_T0_reg(rd);
2919 } else if (xop == 0x27) { /* sra, V9 srax */
83469015 2920 rs1 = GET_FIELD(insn, 13, 17);
0f8a249a
BS
2921 gen_movl_reg_T0(rs1);
2922 if (IS_IMM) { /* immediate */
83469015 2923 rs2 = GET_FIELDs(insn, 20, 31);
1a2fb1c0
BS
2924 if (insn & (1 << 12)) {
2925 tcg_gen_sari_i64(cpu_T[0], cpu_T[0], rs2 & 0x3f);
2926 } else {
2927 tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
2928 tcg_gen_ext_i32_i64(cpu_T[0], cpu_T[0]);
2929 tcg_gen_sari_i64(cpu_T[0], cpu_T[0], rs2 & 0x1f);
2930 }
0f8a249a 2931 } else { /* register */
83469015
FB
2932 rs2 = GET_FIELD(insn, 27, 31);
2933 gen_movl_reg_T1(rs2);
1a2fb1c0
BS
2934 if (insn & (1 << 12)) {
2935 tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x3f);
2936 tcg_gen_sar_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2937 } else {
2938 tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x1f);
2939 tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
2940 tcg_gen_sar_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
2941 }
83469015 2942 }
0f8a249a 2943 gen_movl_T0_reg(rd);
e80cfcfc 2944#endif
fcc72045 2945 } else if (xop < 0x36) {
e80cfcfc 2946 rs1 = GET_FIELD(insn, 13, 17);
0f8a249a
BS
2947 gen_movl_reg_T0(rs1);
2948 if (IS_IMM) { /* immediate */
cf495bcf 2949 rs2 = GET_FIELDs(insn, 19, 31);
3475187d 2950 gen_movl_simm_T1(rs2);
0f8a249a 2951 } else { /* register */
cf495bcf
FB
2952 rs2 = GET_FIELD(insn, 27, 31);
2953 gen_movl_reg_T1(rs2);
2954 }
2955 if (xop < 0x20) {
2956 switch (xop & ~0x10) {
2957 case 0x0:
2958 if (xop & 0x10)
2959 gen_op_add_T1_T0_cc();
2960 else
2961 gen_op_add_T1_T0();
2962 break;
2963 case 0x1:
1a2fb1c0 2964 tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
cf495bcf
FB
2965 if (xop & 0x10)
2966 gen_op_logic_T0_cc();
2967 break;
2968 case 0x2:
1a2fb1c0 2969 tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
0f8a249a
BS
2970 if (xop & 0x10)
2971 gen_op_logic_T0_cc();
2972 break;
cf495bcf 2973 case 0x3:
1a2fb1c0 2974 tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
cf495bcf
FB
2975 if (xop & 0x10)
2976 gen_op_logic_T0_cc();
2977 break;
2978 case 0x4:
2979 if (xop & 0x10)
2980 gen_op_sub_T1_T0_cc();
2981 else
1a2fb1c0 2982 tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
cf495bcf
FB
2983 break;
2984 case 0x5:
56ec06bb
BS
2985 tcg_gen_xori_tl(cpu_T[1], cpu_T[1], -1);
2986 tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
cf495bcf
FB
2987 if (xop & 0x10)
2988 gen_op_logic_T0_cc();
2989 break;
2990 case 0x6:
56ec06bb
BS
2991 tcg_gen_xori_tl(cpu_T[1], cpu_T[1], -1);
2992 tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
cf495bcf
FB
2993 if (xop & 0x10)
2994 gen_op_logic_T0_cc();
2995 break;
2996 case 0x7:
56ec06bb
BS
2997 tcg_gen_xori_tl(cpu_T[1], cpu_T[1], -1);
2998 tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
cf495bcf
FB
2999 if (xop & 0x10)
3000 gen_op_logic_T0_cc();
3001 break;
3002 case 0x8:
cf495bcf 3003 if (xop & 0x10)
af7bf89b 3004 gen_op_addx_T1_T0_cc();
38bc628b 3005 else {
dc99a3f2 3006 gen_mov_reg_C(cpu_tmp0, cpu_psr);
38bc628b
BS
3007 tcg_gen_add_tl(cpu_T[1], cpu_T[1], cpu_tmp0);
3008 tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3009 }
cf495bcf 3010 break;
ded3ab80 3011#ifdef TARGET_SPARC64
0f8a249a 3012 case 0x9: /* V9 mulx */
1a2fb1c0 3013 tcg_gen_mul_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
ded3ab80
PB
3014 break;
3015#endif
cf495bcf
FB
3016 case 0xa:
3017 gen_op_umul_T1_T0();
3018 if (xop & 0x10)
3019 gen_op_logic_T0_cc();
3020 break;
3021 case 0xb:
3022 gen_op_smul_T1_T0();
3023 if (xop & 0x10)
3024 gen_op_logic_T0_cc();
3025 break;
3026 case 0xc:
cf495bcf 3027 if (xop & 0x10)
af7bf89b 3028 gen_op_subx_T1_T0_cc();
38bc628b 3029 else {
dc99a3f2 3030 gen_mov_reg_C(cpu_tmp0, cpu_psr);
38bc628b
BS
3031 tcg_gen_add_tl(cpu_T[1], cpu_T[1], cpu_tmp0);
3032 tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
3033 }
cf495bcf 3034 break;
ded3ab80 3035#ifdef TARGET_SPARC64
0f8a249a 3036 case 0xd: /* V9 udivx */
1a7b60e7
BS
3037 gen_trap_ifdivzero_i64(cpu_T[1]);
3038 tcg_gen_divu_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
ded3ab80
PB
3039 break;
3040#endif
cf495bcf
FB
3041 case 0xe:
3042 gen_op_udiv_T1_T0();
3043 if (xop & 0x10)
3044 gen_op_div_cc();
3045 break;
3046 case 0xf:
3047 gen_op_sdiv_T1_T0();
3048 if (xop & 0x10)
3049 gen_op_div_cc();
3050 break;
3051 default:
3052 goto illegal_insn;
3053 }
0f8a249a 3054 gen_movl_T0_reg(rd);
cf495bcf
FB
3055 } else {
3056 switch (xop) {
0f8a249a
BS
3057 case 0x20: /* taddcc */
3058 gen_op_tadd_T1_T0_cc();
3059 gen_movl_T0_reg(rd);
3060 break;
3061 case 0x21: /* tsubcc */
3062 gen_op_tsub_T1_T0_cc();
3063 gen_movl_T0_reg(rd);
3064 break;
3065 case 0x22: /* taddcctv */
90251fb9 3066 save_state(dc);
0f8a249a
BS
3067 gen_op_tadd_T1_T0_ccTV();
3068 gen_movl_T0_reg(rd);
3069 break;
3070 case 0x23: /* tsubcctv */
90251fb9 3071 save_state(dc);
0f8a249a
BS
3072 gen_op_tsub_T1_T0_ccTV();
3073 gen_movl_T0_reg(rd);
3074 break;
cf495bcf
FB
3075 case 0x24: /* mulscc */
3076 gen_op_mulscc_T1_T0();
3077 gen_movl_T0_reg(rd);
3078 break;
83469015 3079#ifndef TARGET_SPARC64
0f8a249a 3080 case 0x25: /* sll */
1a2fb1c0
BS
3081 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0x1f);
3082 tcg_gen_shl_i32(cpu_T[0], cpu_T[0], cpu_T[1]);
cf495bcf
FB
3083 gen_movl_T0_reg(rd);
3084 break;
83469015 3085 case 0x26: /* srl */
1a2fb1c0
BS
3086 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0x1f);
3087 tcg_gen_shr_i32(cpu_T[0], cpu_T[0], cpu_T[1]);
cf495bcf
FB
3088 gen_movl_T0_reg(rd);
3089 break;
83469015 3090 case 0x27: /* sra */
1a2fb1c0
BS
3091 tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0x1f);
3092 tcg_gen_sar_i32(cpu_T[0], cpu_T[0], cpu_T[1]);
cf495bcf
FB
3093 gen_movl_T0_reg(rd);
3094 break;
83469015 3095#endif
cf495bcf
FB
3096 case 0x30:
3097 {
cf495bcf 3098 switch(rd) {
3475187d 3099 case 0: /* wry */
0f8a249a
BS
3100 gen_op_xor_T1_T0();
3101 gen_op_movtl_env_T0(offsetof(CPUSPARCState, y));
cf495bcf 3102 break;
65fe7b09
BS
3103#ifndef TARGET_SPARC64
3104 case 0x01 ... 0x0f: /* undefined in the
3105 SPARCv8 manual, nop
3106 on the microSPARC
3107 II */
3108 case 0x10 ... 0x1f: /* implementation-dependent
3109 in the SPARCv8
3110 manual, nop on the
3111 microSPARC II */
3112 break;
3113#else
0f8a249a 3114 case 0x2: /* V9 wrccr */
ee0b03fd 3115 gen_op_xor_T1_T0();
d35527d9 3116 tcg_gen_helper_0_1(helper_wrccr, cpu_T[0]);
0f8a249a
BS
3117 break;
3118 case 0x3: /* V9 wrasi */
ee0b03fd 3119 gen_op_xor_T1_T0();
0f8a249a
BS
3120 gen_op_movl_env_T0(offsetof(CPUSPARCState, asi));
3121 break;
3122 case 0x6: /* V9 wrfprs */
3123 gen_op_xor_T1_T0();
3124 gen_op_movl_env_T0(offsetof(CPUSPARCState, fprs));
3299908c
BS
3125 save_state(dc);
3126 gen_op_next_insn();
57fec1fe 3127 tcg_gen_exit_tb(0);
3299908c 3128 dc->is_br = 1;
0f8a249a
BS
3129 break;
3130 case 0xf: /* V9 sir, nop if user */
3475187d 3131#if !defined(CONFIG_USER_ONLY)
0f8a249a 3132 if (supervisor(dc))
1a2fb1c0 3133 ; // XXX
3475187d 3134#endif
0f8a249a
BS
3135 break;
3136 case 0x13: /* Graphics Status */
725cb90b
FB
3137 if (gen_trap_ifnofpu(dc))
3138 goto jmp_insn;
ee0b03fd 3139 gen_op_xor_T1_T0();
0f8a249a
BS
3140 gen_op_movtl_env_T0(offsetof(CPUSPARCState, gsr));
3141 break;
3142 case 0x17: /* Tick compare */
83469015 3143#if !defined(CONFIG_USER_ONLY)
0f8a249a
BS
3144 if (!supervisor(dc))
3145 goto illegal_insn;
83469015 3146#endif
ccd4a219
BS
3147 {
3148 TCGv r_tickptr;
3149
3150 gen_op_xor_T1_T0();
3151 gen_op_movtl_env_T0(offsetof(CPUSPARCState,
3152 tick_cmpr));
3153 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3154 tcg_gen_ld_ptr(r_tickptr, cpu_env,
3155 offsetof(CPUState, tick));
3156 tcg_gen_helper_0_2(helper_tick_set_limit,
3157 r_tickptr, cpu_T[0]);
0425bee5 3158 tcg_gen_discard_ptr(r_tickptr);
ccd4a219 3159 }
0f8a249a
BS
3160 break;
3161 case 0x18: /* System tick */
83469015 3162#if !defined(CONFIG_USER_ONLY)
0f8a249a
BS
3163 if (!supervisor(dc))
3164 goto illegal_insn;
83469015 3165#endif
ccd4a219
BS
3166 {
3167 TCGv r_tickptr;
3168
3169 gen_op_xor_T1_T0();
3170 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3171 tcg_gen_ld_ptr(r_tickptr, cpu_env,
3172 offsetof(CPUState, stick));
3173 tcg_gen_helper_0_2(helper_tick_set_count,
3174 r_tickptr, cpu_T[0]);
0425bee5 3175 tcg_gen_discard_ptr(r_tickptr);
ccd4a219 3176 }
0f8a249a
BS
3177 break;
3178 case 0x19: /* System tick compare */
83469015 3179#if !defined(CONFIG_USER_ONLY)
0f8a249a
BS
3180 if (!supervisor(dc))
3181 goto illegal_insn;
3475187d 3182#endif
ccd4a219
BS
3183 {
3184 TCGv r_tickptr;
3185
3186 gen_op_xor_T1_T0();
3187 gen_op_movtl_env_T0(offsetof(CPUSPARCState,
3188 stick_cmpr));
3189 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3190 tcg_gen_ld_ptr(r_tickptr, cpu_env,
3191 offsetof(CPUState, stick));
3192 tcg_gen_helper_0_2(helper_tick_set_limit,
3193 r_tickptr, cpu_T[0]);
0425bee5 3194 tcg_gen_discard_ptr(r_tickptr);
ccd4a219 3195 }
0f8a249a 3196 break;
83469015 3197
0f8a249a
BS
3198 case 0x10: /* Performance Control */
3199 case 0x11: /* Performance Instrumentation Counter */
3200 case 0x12: /* Dispatch Control */
3201 case 0x14: /* Softint set */
3202 case 0x15: /* Softint clear */
3203 case 0x16: /* Softint write */
83469015 3204#endif
3475187d 3205 default:
cf495bcf
FB
3206 goto illegal_insn;
3207 }
3208 }
3209 break;
e8af50a3 3210#if !defined(CONFIG_USER_ONLY)
af7bf89b 3211 case 0x31: /* wrpsr, V9 saved, restored */
e8af50a3 3212 {
0f8a249a
BS
3213 if (!supervisor(dc))
3214 goto priv_insn;
3475187d 3215#ifdef TARGET_SPARC64
0f8a249a
BS
3216 switch (rd) {
3217 case 0:
3218 gen_op_saved();
3219 break;
3220 case 1:
3221 gen_op_restored();
3222 break;
e9ebed4d
BS
3223 case 2: /* UA2005 allclean */
3224 case 3: /* UA2005 otherw */
3225 case 4: /* UA2005 normalw */
3226 case 5: /* UA2005 invalw */
3227 // XXX
0f8a249a 3228 default:
3475187d
FB
3229 goto illegal_insn;
3230 }
3231#else
e8af50a3 3232 gen_op_xor_T1_T0();
1a2fb1c0 3233 tcg_gen_helper_0_1(helper_wrpsr, cpu_T[0]);
9e61bde5
FB
3234 save_state(dc);
3235 gen_op_next_insn();
57fec1fe 3236 tcg_gen_exit_tb(0);
0f8a249a 3237 dc->is_br = 1;
3475187d 3238#endif
e8af50a3
FB
3239 }
3240 break;
af7bf89b 3241 case 0x32: /* wrwim, V9 wrpr */
e8af50a3 3242 {
0f8a249a
BS
3243 if (!supervisor(dc))
3244 goto priv_insn;
e8af50a3 3245 gen_op_xor_T1_T0();
3475187d 3246#ifdef TARGET_SPARC64
0f8a249a
BS
3247 switch (rd) {
3248 case 0: // tpc
375ee38b
BS
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_tl(cpu_T[0], r_tsptr,
3256 offsetof(trap_state, tpc));
0425bee5 3257 tcg_gen_discard_ptr(r_tsptr);
375ee38b 3258 }
0f8a249a
BS
3259 break;
3260 case 1: // tnpc
375ee38b
BS
3261 {
3262 TCGv r_tsptr;
3263
3264 r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3265 tcg_gen_ld_ptr(r_tsptr, cpu_env,
3266 offsetof(CPUState, tsptr));
3267 tcg_gen_st_tl(cpu_T[0], r_tsptr,
3268 offsetof(trap_state, tnpc));
0425bee5 3269 tcg_gen_discard_ptr(r_tsptr);
375ee38b 3270 }
0f8a249a
BS
3271 break;
3272 case 2: // tstate
375ee38b
BS
3273 {
3274 TCGv r_tsptr;
3275
3276 r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3277 tcg_gen_ld_ptr(r_tsptr, cpu_env,
3278 offsetof(CPUState, tsptr));
3279 tcg_gen_st_tl(cpu_T[0], r_tsptr,
3280 offsetof(trap_state, tstate));
0425bee5 3281 tcg_gen_discard_ptr(r_tsptr);
375ee38b 3282 }
0f8a249a
BS
3283 break;
3284 case 3: // tt
375ee38b
BS
3285 {
3286 TCGv r_tsptr;
3287
3288 r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3289 tcg_gen_ld_ptr(r_tsptr, cpu_env,
3290 offsetof(CPUState, tsptr));
3291 tcg_gen_st_i32(cpu_T[0], r_tsptr,
3292 offsetof(trap_state, tt));
0425bee5 3293 tcg_gen_discard_ptr(r_tsptr);
375ee38b 3294 }
0f8a249a
BS
3295 break;
3296 case 4: // tick
ccd4a219
BS
3297 {
3298 TCGv r_tickptr;
3299
3300 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3301 tcg_gen_ld_ptr(r_tickptr, cpu_env,
3302 offsetof(CPUState, tick));
3303 tcg_gen_helper_0_2(helper_tick_set_count,
3304 r_tickptr, cpu_T[0]);
0425bee5 3305 tcg_gen_discard_ptr(r_tickptr);
ccd4a219 3306 }
0f8a249a
BS
3307 break;
3308 case 5: // tba
3309 gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
3310 break;
3311 case 6: // pstate
ded3ab80 3312 save_state(dc);
1a2fb1c0 3313 tcg_gen_helper_0_1(helper_wrpstate, cpu_T[0]);
ded3ab80 3314 gen_op_next_insn();
57fec1fe 3315 tcg_gen_exit_tb(0);
ded3ab80 3316 dc->is_br = 1;
0f8a249a
BS
3317 break;
3318 case 7: // tl
3319 gen_op_movl_env_T0(offsetof(CPUSPARCState, tl));
3320 break;
3321 case 8: // pil
3322 gen_op_movl_env_T0(offsetof(CPUSPARCState, psrpil));
3323 break;
3324 case 9: // cwp
d35527d9 3325 tcg_gen_helper_0_1(helper_wrcwp, cpu_T[0]);
0f8a249a
BS
3326 break;
3327 case 10: // cansave
3328 gen_op_movl_env_T0(offsetof(CPUSPARCState, cansave));
3329 break;
3330 case 11: // canrestore
3331 gen_op_movl_env_T0(offsetof(CPUSPARCState, canrestore));
3332 break;
3333 case 12: // cleanwin
3334 gen_op_movl_env_T0(offsetof(CPUSPARCState, cleanwin));
3335 break;
3336 case 13: // otherwin
3337 gen_op_movl_env_T0(offsetof(CPUSPARCState, otherwin));
3338 break;
3339 case 14: // wstate
3340 gen_op_movl_env_T0(offsetof(CPUSPARCState, wstate));
3341 break;
e9ebed4d
BS
3342 case 16: // UA2005 gl
3343 gen_op_movl_env_T0(offsetof(CPUSPARCState, gl));
3344 break;
3345 case 26: // UA2005 strand status
3346 if (!hypervisor(dc))
3347 goto priv_insn;
3348 gen_op_movl_env_T0(offsetof(CPUSPARCState, ssr));
3349 break;
0f8a249a
BS
3350 default:
3351 goto illegal_insn;
3352 }
3475187d 3353#else
1a2fb1c0
BS
3354 tcg_gen_andi_i32(cpu_T[0], cpu_T[0], ((1 << NWINDOWS) - 1));
3355 gen_op_movl_env_T0(offsetof(CPUSPARCState, wim));
3475187d 3356#endif
e8af50a3
FB
3357 }
3358 break;
e9ebed4d 3359 case 0x33: /* wrtbr, UA2005 wrhpr */
e8af50a3 3360 {
e9ebed4d 3361#ifndef TARGET_SPARC64
0f8a249a
BS
3362 if (!supervisor(dc))
3363 goto priv_insn;
e8af50a3 3364 gen_op_xor_T1_T0();
e9ebed4d
BS
3365 gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
3366#else
3367 if (!hypervisor(dc))
3368 goto priv_insn;
3369 gen_op_xor_T1_T0();
3370 switch (rd) {
3371 case 0: // hpstate
3372 // XXX gen_op_wrhpstate();
3373 save_state(dc);
3374 gen_op_next_insn();
57fec1fe 3375 tcg_gen_exit_tb(0);
e9ebed4d
BS
3376 dc->is_br = 1;
3377 break;
3378 case 1: // htstate
3379 // XXX gen_op_wrhtstate();
3380 break;
3381 case 3: // hintp
3382 gen_op_movl_env_T0(offsetof(CPUSPARCState, hintp));
3383 break;
3384 case 5: // htba
3385 gen_op_movl_env_T0(offsetof(CPUSPARCState, htba));
3386 break;
3387 case 31: // hstick_cmpr
ccd4a219
BS
3388 {
3389 TCGv r_tickptr;
3390
3391 gen_op_movtl_env_T0(offsetof(CPUSPARCState,
3392 hstick_cmpr));
3393 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3394 tcg_gen_ld_ptr(r_tickptr, cpu_env,
3395 offsetof(CPUState, hstick));
3396 tcg_gen_helper_0_2(helper_tick_set_limit,
3397 r_tickptr, cpu_T[0]);
0425bee5 3398 tcg_gen_discard_ptr(r_tickptr);
ccd4a219 3399 }
e9ebed4d
BS
3400 break;
3401 case 6: // hver readonly
3402 default:
3403 goto illegal_insn;
3404 }
3405#endif
e8af50a3
FB
3406 }
3407 break;
3408#endif
3475187d 3409#ifdef TARGET_SPARC64
0f8a249a
BS
3410 case 0x2c: /* V9 movcc */
3411 {
3412 int cc = GET_FIELD_SP(insn, 11, 12);
3413 int cond = GET_FIELD_SP(insn, 14, 17);
748b9d8e 3414 TCGv r_cond;
00f219bf
BS
3415 int l1;
3416
748b9d8e 3417 r_cond = tcg_temp_new(TCG_TYPE_TL);
0f8a249a
BS
3418 if (insn & (1 << 18)) {
3419 if (cc == 0)
748b9d8e 3420 gen_cond(r_cond, 0, cond);
0f8a249a 3421 else if (cc == 2)
748b9d8e 3422 gen_cond(r_cond, 1, cond);
0f8a249a
BS
3423 else
3424 goto illegal_insn;
3425 } else {
748b9d8e 3426 gen_fcond(r_cond, cc, cond);
0f8a249a 3427 }
00f219bf
BS
3428
3429 l1 = gen_new_label();
3430
748b9d8e
BS
3431 tcg_gen_brcond_tl(TCG_COND_EQ, r_cond,
3432 tcg_const_tl(0), l1);
00f219bf
BS
3433 if (IS_IMM) { /* immediate */
3434 rs2 = GET_FIELD_SPs(insn, 0, 10);
3435 gen_movl_simm_T1(rs2);
3436 } else {
3437 rs2 = GET_FIELD_SP(insn, 0, 4);
3438 gen_movl_reg_T1(rs2);
3439 }
3440 gen_movl_T1_reg(rd);
3441 gen_set_label(l1);
0425bee5 3442 tcg_gen_discard_tl(r_cond);
0f8a249a
BS
3443 break;
3444 }
3445 case 0x2d: /* V9 sdivx */
3475187d 3446 gen_op_sdivx_T1_T0();
0f8a249a
BS
3447 gen_movl_T0_reg(rd);
3448 break;
3449 case 0x2e: /* V9 popc */
3450 {
3451 if (IS_IMM) { /* immediate */
3452 rs2 = GET_FIELD_SPs(insn, 0, 12);
3453 gen_movl_simm_T1(rs2);
3454 // XXX optimize: popc(constant)
3455 }
3456 else {
3457 rs2 = GET_FIELD_SP(insn, 0, 4);
3458 gen_movl_reg_T1(rs2);
3459 }
1a2fb1c0
BS
3460 tcg_gen_helper_1_1(helper_popc, cpu_T[0],
3461 cpu_T[1]);
0f8a249a
BS
3462 gen_movl_T0_reg(rd);
3463 }
3464 case 0x2f: /* V9 movr */
3465 {
3466 int cond = GET_FIELD_SP(insn, 10, 12);
00f219bf
BS
3467 int l1;
3468
0f8a249a 3469 rs1 = GET_FIELD(insn, 13, 17);
0f8a249a 3470 gen_movl_reg_T0(rs1);
00f219bf
BS
3471
3472 l1 = gen_new_label();
3473
0425bee5
BS
3474 tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0],
3475 tcg_const_tl(0), l1);
0f8a249a
BS
3476 if (IS_IMM) { /* immediate */
3477 rs2 = GET_FIELD_SPs(insn, 0, 9);
3478 gen_movl_simm_T1(rs2);
00f219bf 3479 } else {
0f8a249a
BS
3480 rs2 = GET_FIELD_SP(insn, 0, 4);
3481 gen_movl_reg_T1(rs2);
3482 }
00f219bf
BS
3483 gen_movl_T1_reg(rd);
3484 gen_set_label(l1);
0f8a249a
BS
3485 break;
3486 }
3487#endif
3488 default:
3489 goto illegal_insn;
3490 }
3491 }
3299908c
BS
3492 } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
3493#ifdef TARGET_SPARC64
3494 int opf = GET_FIELD_SP(insn, 5, 13);
3495 rs1 = GET_FIELD(insn, 13, 17);
3496 rs2 = GET_FIELD(insn, 27, 31);
e9ebed4d
BS
3497 if (gen_trap_ifnofpu(dc))
3498 goto jmp_insn;
3299908c
BS
3499
3500 switch (opf) {
e9ebed4d
BS
3501 case 0x000: /* VIS I edge8cc */
3502 case 0x001: /* VIS II edge8n */
3503 case 0x002: /* VIS I edge8lcc */
3504 case 0x003: /* VIS II edge8ln */
3505 case 0x004: /* VIS I edge16cc */
3506 case 0x005: /* VIS II edge16n */
3507 case 0x006: /* VIS I edge16lcc */
3508 case 0x007: /* VIS II edge16ln */
3509 case 0x008: /* VIS I edge32cc */
3510 case 0x009: /* VIS II edge32n */
3511 case 0x00a: /* VIS I edge32lcc */
3512 case 0x00b: /* VIS II edge32ln */
3513 // XXX
3514 goto illegal_insn;
3515 case 0x010: /* VIS I array8 */
3516 gen_movl_reg_T0(rs1);
3517 gen_movl_reg_T1(rs2);
1f5063fb
BS
3518 tcg_gen_helper_1_2(helper_array8, cpu_T[0], cpu_T[0],
3519 cpu_T[1]);
e9ebed4d
BS
3520 gen_movl_T0_reg(rd);
3521 break;
3522 case 0x012: /* VIS I array16 */
3523 gen_movl_reg_T0(rs1);
3524 gen_movl_reg_T1(rs2);
1f5063fb
BS
3525 tcg_gen_helper_1_2(helper_array8, cpu_T[0], cpu_T[0],
3526 cpu_T[1]);
3527 tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 1);
e9ebed4d
BS
3528 gen_movl_T0_reg(rd);
3529 break;
3530 case 0x014: /* VIS I array32 */
3531 gen_movl_reg_T0(rs1);
3532 gen_movl_reg_T1(rs2);
1f5063fb
BS
3533 tcg_gen_helper_1_2(helper_array8, cpu_T[0], cpu_T[0],
3534 cpu_T[1]);
3535 tcg_gen_shli_i64(cpu_T[0], cpu_T[0], 2);
e9ebed4d
BS
3536 gen_movl_T0_reg(rd);
3537 break;
3299908c 3538 case 0x018: /* VIS I alignaddr */
3299908c
BS
3539 gen_movl_reg_T0(rs1);
3540 gen_movl_reg_T1(rs2);
1f5063fb
BS
3541 tcg_gen_helper_1_2(helper_alignaddr, cpu_T[0], cpu_T[0],
3542 cpu_T[1]);
3299908c
BS
3543 gen_movl_T0_reg(rd);
3544 break;
e9ebed4d 3545 case 0x019: /* VIS II bmask */
3299908c 3546 case 0x01a: /* VIS I alignaddrl */
3299908c 3547 // XXX
e9ebed4d
BS
3548 goto illegal_insn;
3549 case 0x020: /* VIS I fcmple16 */
2382dc6b
BS
3550 gen_op_load_fpr_DT0(DFPREG(rs1));
3551 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3552 gen_op_fcmple16();
2382dc6b 3553 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3554 break;
3555 case 0x022: /* VIS I fcmpne16 */
2382dc6b
BS
3556 gen_op_load_fpr_DT0(DFPREG(rs1));
3557 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3558 gen_op_fcmpne16();
2382dc6b 3559 gen_op_store_DT0_fpr(DFPREG(rd));
3299908c 3560 break;
e9ebed4d 3561 case 0x024: /* VIS I fcmple32 */
2382dc6b
BS
3562 gen_op_load_fpr_DT0(DFPREG(rs1));
3563 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3564 gen_op_fcmple32();
2382dc6b 3565 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3566 break;
3567 case 0x026: /* VIS I fcmpne32 */
2382dc6b
BS
3568 gen_op_load_fpr_DT0(DFPREG(rs1));
3569 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3570 gen_op_fcmpne32();
2382dc6b 3571 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3572 break;
3573 case 0x028: /* VIS I fcmpgt16 */
2382dc6b
BS
3574 gen_op_load_fpr_DT0(DFPREG(rs1));
3575 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3576 gen_op_fcmpgt16();
2382dc6b 3577 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3578 break;
3579 case 0x02a: /* VIS I fcmpeq16 */
2382dc6b
BS
3580 gen_op_load_fpr_DT0(DFPREG(rs1));
3581 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3582 gen_op_fcmpeq16();
2382dc6b 3583 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3584 break;
3585 case 0x02c: /* VIS I fcmpgt32 */
2382dc6b
BS
3586 gen_op_load_fpr_DT0(DFPREG(rs1));
3587 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3588 gen_op_fcmpgt32();
2382dc6b 3589 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3590 break;
3591 case 0x02e: /* VIS I fcmpeq32 */
2382dc6b
BS
3592 gen_op_load_fpr_DT0(DFPREG(rs1));
3593 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3594 gen_op_fcmpeq32();
2382dc6b 3595 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3596 break;
3597 case 0x031: /* VIS I fmul8x16 */
2382dc6b
BS
3598 gen_op_load_fpr_DT0(DFPREG(rs1));
3599 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3600 gen_op_fmul8x16();
2382dc6b 3601 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3602 break;
3603 case 0x033: /* VIS I fmul8x16au */
2382dc6b
BS
3604 gen_op_load_fpr_DT0(DFPREG(rs1));
3605 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3606 gen_op_fmul8x16au();
2382dc6b 3607 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3608 break;
3609 case 0x035: /* VIS I fmul8x16al */
2382dc6b
BS
3610 gen_op_load_fpr_DT0(DFPREG(rs1));
3611 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3612 gen_op_fmul8x16al();
2382dc6b 3613 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3614 break;
3615 case 0x036: /* VIS I fmul8sux16 */
2382dc6b
BS
3616 gen_op_load_fpr_DT0(DFPREG(rs1));
3617 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3618 gen_op_fmul8sux16();
2382dc6b 3619 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3620 break;
3621 case 0x037: /* VIS I fmul8ulx16 */
2382dc6b
BS
3622 gen_op_load_fpr_DT0(DFPREG(rs1));
3623 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3624 gen_op_fmul8ulx16();
2382dc6b 3625 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3626 break;
3627 case 0x038: /* VIS I fmuld8sux16 */
2382dc6b
BS
3628 gen_op_load_fpr_DT0(DFPREG(rs1));
3629 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3630 gen_op_fmuld8sux16();
2382dc6b 3631 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3632 break;
3633 case 0x039: /* VIS I fmuld8ulx16 */
2382dc6b
BS
3634 gen_op_load_fpr_DT0(DFPREG(rs1));
3635 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3636 gen_op_fmuld8ulx16();
2382dc6b 3637 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3638 break;
3639 case 0x03a: /* VIS I fpack32 */
3640 case 0x03b: /* VIS I fpack16 */
3641 case 0x03d: /* VIS I fpackfix */
3642 case 0x03e: /* VIS I pdist */
3643 // XXX
3644 goto illegal_insn;
3299908c 3645 case 0x048: /* VIS I faligndata */
2382dc6b
BS
3646 gen_op_load_fpr_DT0(DFPREG(rs1));
3647 gen_op_load_fpr_DT1(DFPREG(rs2));
3299908c 3648 gen_op_faligndata();
2382dc6b 3649 gen_op_store_DT0_fpr(DFPREG(rd));
3299908c 3650 break;
e9ebed4d 3651 case 0x04b: /* VIS I fpmerge */
2382dc6b
BS
3652 gen_op_load_fpr_DT0(DFPREG(rs1));
3653 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3654 gen_op_fpmerge();
2382dc6b 3655 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3656 break;
3657 case 0x04c: /* VIS II bshuffle */
3658 // XXX
3659 goto illegal_insn;
3660 case 0x04d: /* VIS I fexpand */
2382dc6b
BS
3661 gen_op_load_fpr_DT0(DFPREG(rs1));
3662 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3663 gen_op_fexpand();
2382dc6b 3664 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3665 break;
3666 case 0x050: /* VIS I fpadd16 */
2382dc6b
BS
3667 gen_op_load_fpr_DT0(DFPREG(rs1));
3668 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3669 gen_op_fpadd16();
2382dc6b 3670 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3671 break;
3672 case 0x051: /* VIS I fpadd16s */
3673 gen_op_load_fpr_FT0(rs1);
3674 gen_op_load_fpr_FT1(rs2);
3675 gen_op_fpadd16s();
3676 gen_op_store_FT0_fpr(rd);
3677 break;
3678 case 0x052: /* VIS I fpadd32 */
2382dc6b
BS
3679 gen_op_load_fpr_DT0(DFPREG(rs1));
3680 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3681 gen_op_fpadd32();
2382dc6b 3682 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3683 break;
3684 case 0x053: /* VIS I fpadd32s */
3685 gen_op_load_fpr_FT0(rs1);
3686 gen_op_load_fpr_FT1(rs2);
3687 gen_op_fpadd32s();
3688 gen_op_store_FT0_fpr(rd);
3689 break;
3690 case 0x054: /* VIS I fpsub16 */
2382dc6b
BS
3691 gen_op_load_fpr_DT0(DFPREG(rs1));
3692 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3693 gen_op_fpsub16();
2382dc6b 3694 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3695 break;
3696 case 0x055: /* VIS I fpsub16s */
3697 gen_op_load_fpr_FT0(rs1);
3698 gen_op_load_fpr_FT1(rs2);
3699 gen_op_fpsub16s();
3700 gen_op_store_FT0_fpr(rd);
3701 break;
3702 case 0x056: /* VIS I fpsub32 */
2382dc6b
BS
3703 gen_op_load_fpr_DT0(DFPREG(rs1));
3704 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3705 gen_op_fpadd32();
2382dc6b 3706 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3707 break;
3708 case 0x057: /* VIS I fpsub32s */
3709 gen_op_load_fpr_FT0(rs1);
3710 gen_op_load_fpr_FT1(rs2);
3711 gen_op_fpsub32s();
3712 gen_op_store_FT0_fpr(rd);
3713 break;
3299908c 3714 case 0x060: /* VIS I fzero */
3299908c 3715 gen_op_movl_DT0_0();
2382dc6b 3716 gen_op_store_DT0_fpr(DFPREG(rd));
3299908c
BS
3717 break;
3718 case 0x061: /* VIS I fzeros */
3299908c
BS
3719 gen_op_movl_FT0_0();
3720 gen_op_store_FT0_fpr(rd);
3721 break;
e9ebed4d 3722 case 0x062: /* VIS I fnor */
2382dc6b
BS
3723 gen_op_load_fpr_DT0(DFPREG(rs1));
3724 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3725 gen_op_fnor();
2382dc6b 3726 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3727 break;
3728 case 0x063: /* VIS I fnors */
3729 gen_op_load_fpr_FT0(rs1);
3730 gen_op_load_fpr_FT1(rs2);
3731 gen_op_fnors();
3732 gen_op_store_FT0_fpr(rd);
3733 break;
3734 case 0x064: /* VIS I fandnot2 */
2382dc6b
BS
3735 gen_op_load_fpr_DT1(DFPREG(rs1));
3736 gen_op_load_fpr_DT0(DFPREG(rs2));
e9ebed4d 3737 gen_op_fandnot();
2382dc6b 3738 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3739 break;
3740 case 0x065: /* VIS I fandnot2s */
3741 gen_op_load_fpr_FT1(rs1);
3742 gen_op_load_fpr_FT0(rs2);
3743 gen_op_fandnots();
3744 gen_op_store_FT0_fpr(rd);
3745 break;
3746 case 0x066: /* VIS I fnot2 */
2382dc6b 3747 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3748 gen_op_fnot();
2382dc6b 3749 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3750 break;
3751 case 0x067: /* VIS I fnot2s */
3752 gen_op_load_fpr_FT1(rs2);
3753 gen_op_fnot();
3754 gen_op_store_FT0_fpr(rd);
3755 break;
3756 case 0x068: /* VIS I fandnot1 */
2382dc6b
BS
3757 gen_op_load_fpr_DT0(DFPREG(rs1));
3758 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3759 gen_op_fandnot();
2382dc6b 3760 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3761 break;
3762 case 0x069: /* VIS I fandnot1s */
3763 gen_op_load_fpr_FT0(rs1);
3764 gen_op_load_fpr_FT1(rs2);
3765 gen_op_fandnots();
3766 gen_op_store_FT0_fpr(rd);
3767 break;
3768 case 0x06a: /* VIS I fnot1 */
2382dc6b 3769 gen_op_load_fpr_DT1(DFPREG(rs1));
e9ebed4d 3770 gen_op_fnot();
2382dc6b 3771 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3772 break;
3773 case 0x06b: /* VIS I fnot1s */
3774 gen_op_load_fpr_FT1(rs1);
3775 gen_op_fnot();
3776 gen_op_store_FT0_fpr(rd);
3777 break;
3778 case 0x06c: /* VIS I fxor */
2382dc6b
BS
3779 gen_op_load_fpr_DT0(DFPREG(rs1));
3780 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3781 gen_op_fxor();
2382dc6b 3782 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3783 break;
3784 case 0x06d: /* VIS I fxors */
3785 gen_op_load_fpr_FT0(rs1);
3786 gen_op_load_fpr_FT1(rs2);
3787 gen_op_fxors();
3788 gen_op_store_FT0_fpr(rd);
3789 break;
3790 case 0x06e: /* VIS I fnand */
2382dc6b
BS
3791 gen_op_load_fpr_DT0(DFPREG(rs1));
3792 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3793 gen_op_fnand();
2382dc6b 3794 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3795 break;
3796 case 0x06f: /* VIS I fnands */
3797 gen_op_load_fpr_FT0(rs1);
3798 gen_op_load_fpr_FT1(rs2);
3799 gen_op_fnands();
3800 gen_op_store_FT0_fpr(rd);
3801 break;
3802 case 0x070: /* VIS I fand */
2382dc6b
BS
3803 gen_op_load_fpr_DT0(DFPREG(rs1));
3804 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3805 gen_op_fand();
2382dc6b 3806 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3807 break;
3808 case 0x071: /* VIS I fands */
3809 gen_op_load_fpr_FT0(rs1);
3810 gen_op_load_fpr_FT1(rs2);
3811 gen_op_fands();
3812 gen_op_store_FT0_fpr(rd);
3813 break;
3814 case 0x072: /* VIS I fxnor */
2382dc6b
BS
3815 gen_op_load_fpr_DT0(DFPREG(rs1));
3816 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3817 gen_op_fxnor();
2382dc6b 3818 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3819 break;
3820 case 0x073: /* VIS I fxnors */
3821 gen_op_load_fpr_FT0(rs1);
3822 gen_op_load_fpr_FT1(rs2);
3823 gen_op_fxnors();
3824 gen_op_store_FT0_fpr(rd);
3825 break;
3299908c 3826 case 0x074: /* VIS I fsrc1 */
2382dc6b
BS
3827 gen_op_load_fpr_DT0(DFPREG(rs1));
3828 gen_op_store_DT0_fpr(DFPREG(rd));
3299908c
BS
3829 break;
3830 case 0x075: /* VIS I fsrc1s */
3299908c
BS
3831 gen_op_load_fpr_FT0(rs1);
3832 gen_op_store_FT0_fpr(rd);
3833 break;
e9ebed4d 3834 case 0x076: /* VIS I fornot2 */
2382dc6b
BS
3835 gen_op_load_fpr_DT1(DFPREG(rs1));
3836 gen_op_load_fpr_DT0(DFPREG(rs2));
e9ebed4d 3837 gen_op_fornot();
2382dc6b 3838 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3839 break;
3840 case 0x077: /* VIS I fornot2s */
3841 gen_op_load_fpr_FT1(rs1);
3842 gen_op_load_fpr_FT0(rs2);
3843 gen_op_fornots();
3844 gen_op_store_FT0_fpr(rd);
3845 break;
3299908c 3846 case 0x078: /* VIS I fsrc2 */
2382dc6b
BS
3847 gen_op_load_fpr_DT0(DFPREG(rs2));
3848 gen_op_store_DT0_fpr(DFPREG(rd));
3299908c
BS
3849 break;
3850 case 0x079: /* VIS I fsrc2s */
3299908c
BS
3851 gen_op_load_fpr_FT0(rs2);
3852 gen_op_store_FT0_fpr(rd);
3853 break;
e9ebed4d 3854 case 0x07a: /* VIS I fornot1 */
2382dc6b
BS
3855 gen_op_load_fpr_DT0(DFPREG(rs1));
3856 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3857 gen_op_fornot();
2382dc6b 3858 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3859 break;
3860 case 0x07b: /* VIS I fornot1s */
3861 gen_op_load_fpr_FT0(rs1);
3862 gen_op_load_fpr_FT1(rs2);
3863 gen_op_fornots();
3864 gen_op_store_FT0_fpr(rd);
3865 break;
3866 case 0x07c: /* VIS I for */
2382dc6b
BS
3867 gen_op_load_fpr_DT0(DFPREG(rs1));
3868 gen_op_load_fpr_DT1(DFPREG(rs2));
e9ebed4d 3869 gen_op_for();
2382dc6b 3870 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3871 break;
3872 case 0x07d: /* VIS I fors */
3873 gen_op_load_fpr_FT0(rs1);
3874 gen_op_load_fpr_FT1(rs2);
3875 gen_op_fors();
3876 gen_op_store_FT0_fpr(rd);
3877 break;
3299908c 3878 case 0x07e: /* VIS I fone */
3299908c 3879 gen_op_movl_DT0_1();
2382dc6b 3880 gen_op_store_DT0_fpr(DFPREG(rd));
3299908c
BS
3881 break;
3882 case 0x07f: /* VIS I fones */
3299908c
BS
3883 gen_op_movl_FT0_1();
3884 gen_op_store_FT0_fpr(rd);
3885 break;
e9ebed4d
BS
3886 case 0x080: /* VIS I shutdown */
3887 case 0x081: /* VIS II siam */
3888 // XXX
3889 goto illegal_insn;
3299908c
BS
3890 default:
3891 goto illegal_insn;
3892 }
3893#else
0f8a249a 3894 goto ncp_insn;
3299908c
BS
3895#endif
3896 } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
fcc72045 3897#ifdef TARGET_SPARC64
0f8a249a 3898 goto illegal_insn;
fcc72045 3899#else
0f8a249a 3900 goto ncp_insn;
fcc72045 3901#endif
3475187d 3902#ifdef TARGET_SPARC64
0f8a249a 3903 } else if (xop == 0x39) { /* V9 return */
3475187d 3904 rs1 = GET_FIELD(insn, 13, 17);
1ad21e69 3905 save_state(dc);
0f8a249a
BS
3906 gen_movl_reg_T0(rs1);
3907 if (IS_IMM) { /* immediate */
3908 rs2 = GET_FIELDs(insn, 19, 31);
1a2fb1c0 3909 tcg_gen_addi_tl(cpu_T[0], cpu_T[0], (int)rs2);
0f8a249a 3910 } else { /* register */
3475187d
FB
3911 rs2 = GET_FIELD(insn, 27, 31);
3912#if defined(OPTIM)
0f8a249a 3913 if (rs2) {
3475187d 3914#endif
0f8a249a
BS
3915 gen_movl_reg_T1(rs2);
3916 gen_op_add_T1_T0();
3475187d 3917#if defined(OPTIM)
0f8a249a 3918 }
3475187d
FB
3919#endif
3920 }
0f8a249a
BS
3921 gen_op_restore();
3922 gen_mov_pc_npc(dc);
6ea4a6c8 3923 gen_op_check_align_T0_3();
48d5c82b 3924 tcg_gen_mov_tl(cpu_npc, cpu_T[0]);
0f8a249a
BS
3925 dc->npc = DYNAMIC_PC;
3926 goto jmp_insn;
3475187d 3927#endif
0f8a249a 3928 } else {
e80cfcfc 3929 rs1 = GET_FIELD(insn, 13, 17);
0f8a249a
BS
3930 gen_movl_reg_T0(rs1);
3931 if (IS_IMM) { /* immediate */
3932 rs2 = GET_FIELDs(insn, 19, 31);
1a2fb1c0 3933 tcg_gen_addi_tl(cpu_T[0], cpu_T[0], (int)rs2);
0f8a249a 3934 } else { /* register */
e80cfcfc
FB
3935 rs2 = GET_FIELD(insn, 27, 31);
3936#if defined(OPTIM)
0f8a249a 3937 if (rs2) {
e80cfcfc 3938#endif
0f8a249a
BS
3939 gen_movl_reg_T1(rs2);
3940 gen_op_add_T1_T0();
e80cfcfc 3941#if defined(OPTIM)
0f8a249a 3942 }
e8af50a3 3943#endif
cf495bcf 3944 }
0f8a249a
BS
3945 switch (xop) {
3946 case 0x38: /* jmpl */
3947 {
3948 if (rd != 0) {
1a2fb1c0 3949 tcg_gen_movi_tl(cpu_T[1], dc->pc);
0f8a249a
BS
3950 gen_movl_T1_reg(rd);
3951 }
0bee699e 3952 gen_mov_pc_npc(dc);
6ea4a6c8 3953 gen_op_check_align_T0_3();
48d5c82b 3954 tcg_gen_mov_tl(cpu_npc, cpu_T[0]);
0f8a249a
BS
3955 dc->npc = DYNAMIC_PC;
3956 }
3957 goto jmp_insn;
3475187d 3958#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
0f8a249a
BS
3959 case 0x39: /* rett, V9 return */
3960 {
3961 if (!supervisor(dc))
3962 goto priv_insn;
0bee699e 3963 gen_mov_pc_npc(dc);
6ea4a6c8 3964 gen_op_check_align_T0_3();
48d5c82b 3965 tcg_gen_mov_tl(cpu_npc, cpu_T[0]);
0f8a249a 3966 dc->npc = DYNAMIC_PC;
1a2fb1c0 3967 tcg_gen_helper_0_0(helper_rett);
0f8a249a
BS
3968 }
3969 goto jmp_insn;
3970#endif
3971 case 0x3b: /* flush */
1a2fb1c0 3972 tcg_gen_helper_0_1(helper_flush, cpu_T[0]);
0f8a249a
BS
3973 break;
3974 case 0x3c: /* save */
3975 save_state(dc);
3976 gen_op_save();
3977 gen_movl_T0_reg(rd);
3978 break;
3979 case 0x3d: /* restore */
3980 save_state(dc);
3981 gen_op_restore();
3982 gen_movl_T0_reg(rd);
3983 break;
3475187d 3984#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
0f8a249a
BS
3985 case 0x3e: /* V9 done/retry */
3986 {
3987 switch (rd) {
3988 case 0:
3989 if (!supervisor(dc))
3990 goto priv_insn;
3991 dc->npc = DYNAMIC_PC;
3992 dc->pc = DYNAMIC_PC;
1a2fb1c0 3993 tcg_gen_helper_0_0(helper_done);
0f8a249a
BS
3994 goto jmp_insn;
3995 case 1:
3996 if (!supervisor(dc))
3997 goto priv_insn;
3998 dc->npc = DYNAMIC_PC;
3999 dc->pc = DYNAMIC_PC;
1a2fb1c0 4000 tcg_gen_helper_0_0(helper_retry);
0f8a249a
BS
4001 goto jmp_insn;
4002 default:
4003 goto illegal_insn;
4004 }
4005 }
4006 break;
4007#endif
4008 default:
4009 goto illegal_insn;
4010 }
cf495bcf 4011 }
0f8a249a
BS
4012 break;
4013 }
4014 break;
4015 case 3: /* load/store instructions */
4016 {
4017 unsigned int xop = GET_FIELD(insn, 7, 12);
4018 rs1 = GET_FIELD(insn, 13, 17);
2371aaa2 4019 save_state(dc);
0f8a249a 4020 gen_movl_reg_T0(rs1);
81ad8ba2
BS
4021 if (xop == 0x3c || xop == 0x3e)
4022 {
4023 rs2 = GET_FIELD(insn, 27, 31);
4024 gen_movl_reg_T1(rs2);
4025 }
4026 else if (IS_IMM) { /* immediate */
0f8a249a 4027 rs2 = GET_FIELDs(insn, 19, 31);
1a2fb1c0 4028 tcg_gen_addi_tl(cpu_T[0], cpu_T[0], (int)rs2);
0f8a249a
BS
4029 } else { /* register */
4030 rs2 = GET_FIELD(insn, 27, 31);
e80cfcfc 4031#if defined(OPTIM)
0f8a249a 4032 if (rs2 != 0) {
e80cfcfc 4033#endif
0f8a249a
BS
4034 gen_movl_reg_T1(rs2);
4035 gen_op_add_T1_T0();
e80cfcfc 4036#if defined(OPTIM)
0f8a249a 4037 }
e80cfcfc 4038#endif
0f8a249a 4039 }
2f2ecb83
BS
4040 if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
4041 (xop > 0x17 && xop <= 0x1d ) ||
4042 (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
0f8a249a 4043 switch (xop) {
1a2fb1c0 4044 case 0x0: /* load unsigned word */
6ea4a6c8 4045 gen_op_check_align_T0_3();
1a2fb1c0
BS
4046 ABI32_MASK(cpu_T[0]);
4047 tcg_gen_qemu_ld32u(cpu_T[1], cpu_T[0], dc->mem_idx);
0f8a249a
BS
4048 break;
4049 case 0x1: /* load unsigned byte */
1a2fb1c0
BS
4050 ABI32_MASK(cpu_T[0]);
4051 tcg_gen_qemu_ld8u(cpu_T[1], cpu_T[0], dc->mem_idx);
0f8a249a
BS
4052 break;
4053 case 0x2: /* load unsigned halfword */
6ea4a6c8 4054 gen_op_check_align_T0_1();
1a2fb1c0
BS
4055 ABI32_MASK(cpu_T[0]);
4056 tcg_gen_qemu_ld16u(cpu_T[1], cpu_T[0], dc->mem_idx);
0f8a249a
BS
4057 break;
4058 case 0x3: /* load double word */
0f8a249a 4059 if (rd & 1)
d4218d99 4060 goto illegal_insn;
1a2fb1c0
BS
4061 else {
4062 TCGv r_dword;
4063
4064 r_dword = tcg_temp_new(TCG_TYPE_I64);
4065 gen_op_check_align_T0_7();
4066 ABI32_MASK(cpu_T[0]);
4067 tcg_gen_qemu_ld64(r_dword, cpu_T[0], dc->mem_idx);
4068 tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
4069 gen_movl_T0_reg(rd + 1);
4070 tcg_gen_shri_i64(r_dword, r_dword, 32);
4071 tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
0425bee5 4072 tcg_gen_discard_i64(r_dword);
1a2fb1c0 4073 }
0f8a249a
BS
4074 break;
4075 case 0x9: /* load signed byte */
1a2fb1c0
BS
4076 ABI32_MASK(cpu_T[0]);
4077 tcg_gen_qemu_ld8s(cpu_T[1], cpu_T[0], dc->mem_idx);
0f8a249a
BS
4078 break;
4079 case 0xa: /* load signed halfword */
6ea4a6c8 4080 gen_op_check_align_T0_1();
1a2fb1c0
BS
4081 ABI32_MASK(cpu_T[0]);
4082 tcg_gen_qemu_ld16s(cpu_T[1], cpu_T[0], dc->mem_idx);
0f8a249a
BS
4083 break;
4084 case 0xd: /* ldstub -- XXX: should be atomically */
1a2fb1c0
BS
4085 tcg_gen_movi_i32(cpu_tmp0, 0xff);
4086 ABI32_MASK(cpu_T[0]);
4087 tcg_gen_qemu_ld8s(cpu_T[1], cpu_T[0], dc->mem_idx);
4088 tcg_gen_qemu_st8(cpu_tmp0, cpu_T[0], dc->mem_idx);
0f8a249a
BS
4089 break;
4090 case 0x0f: /* swap register with memory. Also atomically */
6ea4a6c8 4091 gen_op_check_align_T0_3();
0f8a249a 4092 gen_movl_reg_T1(rd);
1a2fb1c0
BS
4093 ABI32_MASK(cpu_T[0]);
4094 tcg_gen_qemu_ld32u(cpu_tmp0, cpu_T[0], dc->mem_idx);
4095 tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], dc->mem_idx);
4096 tcg_gen_mov_i32(cpu_T[1], cpu_tmp0);
0f8a249a 4097 break;
3475187d 4098#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
0f8a249a 4099 case 0x10: /* load word alternate */
3475187d 4100#ifndef TARGET_SPARC64
0f8a249a
BS
4101 if (IS_IMM)
4102 goto illegal_insn;
4103 if (!supervisor(dc))
4104 goto priv_insn;
6ea4a6c8 4105#endif
8f577d3d 4106 gen_op_check_align_T0_3();
81ad8ba2 4107 gen_ld_asi(insn, 4, 0);
0f8a249a
BS
4108 break;
4109 case 0x11: /* load unsigned byte alternate */
3475187d 4110#ifndef TARGET_SPARC64
0f8a249a
BS
4111 if (IS_IMM)
4112 goto illegal_insn;
4113 if (!supervisor(dc))
4114 goto priv_insn;
4115#endif
81ad8ba2 4116 gen_ld_asi(insn, 1, 0);
0f8a249a
BS
4117 break;
4118 case 0x12: /* load unsigned halfword alternate */
3475187d 4119#ifndef TARGET_SPARC64
0f8a249a
BS
4120 if (IS_IMM)
4121 goto illegal_insn;
4122 if (!supervisor(dc))
4123 goto priv_insn;
3475187d 4124#endif
8f577d3d 4125 gen_op_check_align_T0_1();
81ad8ba2 4126 gen_ld_asi(insn, 2, 0);
0f8a249a
BS
4127 break;
4128 case 0x13: /* load double word alternate */
3475187d 4129#ifndef TARGET_SPARC64
0f8a249a
BS
4130 if (IS_IMM)
4131 goto illegal_insn;
4132 if (!supervisor(dc))
4133 goto priv_insn;
3475187d 4134#endif
0f8a249a 4135 if (rd & 1)
d4218d99 4136 goto illegal_insn;
6ea4a6c8 4137 gen_op_check_align_T0_7();
81ad8ba2 4138 gen_ldda_asi(insn);
0f8a249a
BS
4139 gen_movl_T0_reg(rd + 1);
4140 break;
4141 case 0x19: /* load signed byte alternate */
3475187d 4142#ifndef TARGET_SPARC64
0f8a249a
BS
4143 if (IS_IMM)
4144 goto illegal_insn;
4145 if (!supervisor(dc))
4146 goto priv_insn;
4147#endif
81ad8ba2 4148 gen_ld_asi(insn, 1, 1);
0f8a249a
BS
4149 break;
4150 case 0x1a: /* load signed halfword alternate */
3475187d 4151#ifndef TARGET_SPARC64
0f8a249a
BS
4152 if (IS_IMM)
4153 goto illegal_insn;
4154 if (!supervisor(dc))
4155 goto priv_insn;
3475187d 4156#endif
8f577d3d 4157 gen_op_check_align_T0_1();
81ad8ba2 4158 gen_ld_asi(insn, 2, 1);
0f8a249a
BS
4159 break;
4160 case 0x1d: /* ldstuba -- XXX: should be atomically */
3475187d 4161#ifndef TARGET_SPARC64
0f8a249a
BS
4162 if (IS_IMM)
4163 goto illegal_insn;
4164 if (!supervisor(dc))
4165 goto priv_insn;
4166#endif
81ad8ba2 4167 gen_ldstub_asi(insn);
0f8a249a
BS
4168 break;
4169 case 0x1f: /* swap reg with alt. memory. Also atomically */
3475187d 4170#ifndef TARGET_SPARC64
0f8a249a
BS
4171 if (IS_IMM)
4172 goto illegal_insn;
4173 if (!supervisor(dc))
4174 goto priv_insn;
6ea4a6c8 4175#endif
8f577d3d 4176 gen_op_check_align_T0_3();
81ad8ba2
BS
4177 gen_movl_reg_T1(rd);
4178 gen_swap_asi(insn);
0f8a249a 4179 break;
3475187d
FB
4180
4181#ifndef TARGET_SPARC64
0f8a249a
BS
4182 case 0x30: /* ldc */
4183 case 0x31: /* ldcsr */
4184 case 0x33: /* lddc */
4185 goto ncp_insn;
3475187d
FB
4186#endif
4187#endif
4188#ifdef TARGET_SPARC64
0f8a249a 4189 case 0x08: /* V9 ldsw */
6ea4a6c8 4190 gen_op_check_align_T0_3();
1a2fb1c0
BS
4191 ABI32_MASK(cpu_T[0]);
4192 tcg_gen_qemu_ld32s(cpu_T[1], cpu_T[0], dc->mem_idx);
0f8a249a
BS
4193 break;
4194 case 0x0b: /* V9 ldx */
6ea4a6c8 4195 gen_op_check_align_T0_7();
1a2fb1c0
BS
4196 ABI32_MASK(cpu_T[0]);
4197 tcg_gen_qemu_ld64(cpu_T[1], cpu_T[0], dc->mem_idx);
0f8a249a
BS
4198 break;
4199 case 0x18: /* V9 ldswa */
6ea4a6c8 4200 gen_op_check_align_T0_3();
81ad8ba2 4201 gen_ld_asi(insn, 4, 1);
0f8a249a
BS
4202 break;
4203 case 0x1b: /* V9 ldxa */
6ea4a6c8 4204 gen_op_check_align_T0_7();
81ad8ba2 4205 gen_ld_asi(insn, 8, 0);
0f8a249a
BS
4206 break;
4207 case 0x2d: /* V9 prefetch, no effect */
4208 goto skip_move;
4209 case 0x30: /* V9 ldfa */
6ea4a6c8 4210 gen_op_check_align_T0_3();
2382dc6b 4211 gen_ldf_asi(insn, 4, rd);
81ad8ba2 4212 goto skip_move;
0f8a249a 4213 case 0x33: /* V9 lddfa */
3391c818 4214 gen_op_check_align_T0_3();
2382dc6b 4215 gen_ldf_asi(insn, 8, DFPREG(rd));
81ad8ba2 4216 goto skip_move;
0f8a249a
BS
4217 case 0x3d: /* V9 prefetcha, no effect */
4218 goto skip_move;
4219 case 0x32: /* V9 ldqfa */
1f587329
BS
4220#if defined(CONFIG_USER_ONLY)
4221 gen_op_check_align_T0_3();
2382dc6b 4222 gen_ldf_asi(insn, 16, QFPREG(rd));
1f587329
BS
4223 goto skip_move;
4224#else
0f8a249a 4225 goto nfpu_insn;
1f587329 4226#endif
0f8a249a
BS
4227#endif
4228 default:
4229 goto illegal_insn;
4230 }
4231 gen_movl_T1_reg(rd);
3475187d 4232#ifdef TARGET_SPARC64
0f8a249a 4233 skip_move: ;
3475187d 4234#endif
0f8a249a 4235 } else if (xop >= 0x20 && xop < 0x24) {
a80dde08
FB
4236 if (gen_trap_ifnofpu(dc))
4237 goto jmp_insn;
0f8a249a
BS
4238 switch (xop) {
4239 case 0x20: /* load fpreg */
6ea4a6c8 4240 gen_op_check_align_T0_3();
0f8a249a
BS
4241 gen_op_ldst(ldf);
4242 gen_op_store_FT0_fpr(rd);
4243 break;
4244 case 0x21: /* load fsr */
6ea4a6c8 4245 gen_op_check_align_T0_3();
0f8a249a 4246 gen_op_ldst(ldf);
7e8c2b6c 4247 tcg_gen_helper_0_0(helper_ldfsr);
0f8a249a
BS
4248 break;
4249 case 0x22: /* load quad fpreg */
1f587329
BS
4250#if defined(CONFIG_USER_ONLY)
4251 gen_op_check_align_T0_7();
4252 gen_op_ldst(ldqf);
4253 gen_op_store_QT0_fpr(QFPREG(rd));
4254 break;
4255#else
0f8a249a 4256 goto nfpu_insn;
1f587329 4257#endif
0f8a249a 4258 case 0x23: /* load double fpreg */
6ea4a6c8 4259 gen_op_check_align_T0_7();
0f8a249a
BS
4260 gen_op_ldst(lddf);
4261 gen_op_store_DT0_fpr(DFPREG(rd));
4262 break;
4263 default:
4264 goto illegal_insn;
4265 }
4266 } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) || \
4267 xop == 0xe || xop == 0x1e) {
4268 gen_movl_reg_T1(rd);
4269 switch (xop) {
1a2fb1c0 4270 case 0x4: /* store word */
6ea4a6c8 4271 gen_op_check_align_T0_3();
1a2fb1c0
BS
4272 ABI32_MASK(cpu_T[0]);
4273 tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], dc->mem_idx);
0f8a249a 4274 break;
1a2fb1c0
BS
4275 case 0x5: /* store byte */
4276 ABI32_MASK(cpu_T[0]);
4277 tcg_gen_qemu_st8(cpu_T[1], cpu_T[0], dc->mem_idx);
0f8a249a 4278 break;
1a2fb1c0 4279 case 0x6: /* store halfword */
6ea4a6c8 4280 gen_op_check_align_T0_1();
1a2fb1c0
BS
4281 ABI32_MASK(cpu_T[0]);
4282 tcg_gen_qemu_st16(cpu_T[1], cpu_T[0], dc->mem_idx);
0f8a249a 4283 break;
1a2fb1c0 4284 case 0x7: /* store double word */
0f8a249a 4285 if (rd & 1)
d4218d99 4286 goto illegal_insn;
b25deda7 4287#ifndef __i386__
1a2fb1c0
BS
4288 else {
4289 TCGv r_dword, r_low;
4290
4291 gen_op_check_align_T0_7();
4292 r_dword = tcg_temp_new(TCG_TYPE_I64);
4293 r_low = tcg_temp_new(TCG_TYPE_I32);
4294 gen_movl_reg_TN(rd + 1, r_low);
4295 tcg_gen_helper_1_2(helper_pack64, r_dword, cpu_T[1],
4296 r_low);
4297 tcg_gen_qemu_st64(r_dword, cpu_T[0], dc->mem_idx);
0425bee5 4298 tcg_gen_discard_i64(r_dword);
1a2fb1c0 4299 }
b25deda7
BS
4300#else /* __i386__ */
4301 gen_op_check_align_T0_7();
4302 flush_T2(dc);
4303 gen_movl_reg_T2(rd + 1);
4304 gen_op_ldst(std);
4305#endif /* __i386__ */
0f8a249a 4306 break;
3475187d 4307#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1a2fb1c0 4308 case 0x14: /* store word alternate */
3475187d 4309#ifndef TARGET_SPARC64
0f8a249a
BS
4310 if (IS_IMM)
4311 goto illegal_insn;
4312 if (!supervisor(dc))
4313 goto priv_insn;
6ea4a6c8 4314#endif
6ea4a6c8 4315 gen_op_check_align_T0_3();
81ad8ba2 4316 gen_st_asi(insn, 4);
d39c0b99 4317 break;
1a2fb1c0 4318 case 0x15: /* store byte alternate */
3475187d 4319#ifndef TARGET_SPARC64
0f8a249a
BS
4320 if (IS_IMM)
4321 goto illegal_insn;
4322 if (!supervisor(dc))
4323 goto priv_insn;
3475187d 4324#endif
81ad8ba2 4325 gen_st_asi(insn, 1);
d39c0b99 4326 break;
1a2fb1c0 4327 case 0x16: /* store halfword alternate */
3475187d 4328#ifndef TARGET_SPARC64
0f8a249a
BS
4329 if (IS_IMM)
4330 goto illegal_insn;
4331 if (!supervisor(dc))
4332 goto priv_insn;
6ea4a6c8 4333#endif
6ea4a6c8 4334 gen_op_check_align_T0_1();
81ad8ba2 4335 gen_st_asi(insn, 2);
d39c0b99 4336 break;
1a2fb1c0 4337 case 0x17: /* store double word alternate */
3475187d 4338#ifndef TARGET_SPARC64
0f8a249a
BS
4339 if (IS_IMM)
4340 goto illegal_insn;
4341 if (!supervisor(dc))
4342 goto priv_insn;
3475187d 4343#endif
0f8a249a 4344 if (rd & 1)
d4218d99 4345 goto illegal_insn;
1a2fb1c0 4346 else {
1a2fb1c0 4347 gen_op_check_align_T0_7();
0425bee5 4348 gen_stda_asi(insn, rd);
1a2fb1c0 4349 }
d39c0b99 4350 break;
e80cfcfc 4351#endif
3475187d 4352#ifdef TARGET_SPARC64
0f8a249a 4353 case 0x0e: /* V9 stx */
6ea4a6c8 4354 gen_op_check_align_T0_7();
1a2fb1c0
BS
4355 ABI32_MASK(cpu_T[0]);
4356 tcg_gen_qemu_st64(cpu_T[1], cpu_T[0], dc->mem_idx);
0f8a249a
BS
4357 break;
4358 case 0x1e: /* V9 stxa */
6ea4a6c8 4359 gen_op_check_align_T0_7();
81ad8ba2 4360 gen_st_asi(insn, 8);
0f8a249a 4361 break;
3475187d 4362#endif
0f8a249a
BS
4363 default:
4364 goto illegal_insn;
4365 }
4366 } else if (xop > 0x23 && xop < 0x28) {
a80dde08
FB
4367 if (gen_trap_ifnofpu(dc))
4368 goto jmp_insn;
0f8a249a
BS
4369 switch (xop) {
4370 case 0x24:
6ea4a6c8 4371 gen_op_check_align_T0_3();
e8af50a3 4372 gen_op_load_fpr_FT0(rd);
0f8a249a
BS
4373 gen_op_ldst(stf);
4374 break;
4375 case 0x25: /* stfsr, V9 stxfsr */
6ea4a6c8
BS
4376#ifdef CONFIG_USER_ONLY
4377 gen_op_check_align_T0_3();
4378#endif
bb5529bb 4379 tcg_gen_helper_0_0(helper_stfsr);
0f8a249a
BS
4380 gen_op_ldst(stf);
4381 break;
1f587329
BS
4382 case 0x26:
4383#ifdef TARGET_SPARC64
4384#if defined(CONFIG_USER_ONLY)
4385 /* V9 stqf, store quad fpreg */
4386 gen_op_check_align_T0_7();
4387 gen_op_load_fpr_QT0(QFPREG(rd));
4388 gen_op_ldst(stqf);
4389 break;
4390#else
4391 goto nfpu_insn;
4392#endif
4393#else /* !TARGET_SPARC64 */
4394 /* stdfq, store floating point queue */
4395#if defined(CONFIG_USER_ONLY)
4396 goto illegal_insn;
4397#else
0f8a249a
BS
4398 if (!supervisor(dc))
4399 goto priv_insn;
4400 if (gen_trap_ifnofpu(dc))
4401 goto jmp_insn;
4402 goto nfq_insn;
1f587329 4403#endif
0f8a249a
BS
4404#endif
4405 case 0x27:
6ea4a6c8 4406 gen_op_check_align_T0_7();
3475187d 4407 gen_op_load_fpr_DT0(DFPREG(rd));
0f8a249a
BS
4408 gen_op_ldst(stdf);
4409 break;
4410 default:
4411 goto illegal_insn;
4412 }
4413 } else if (xop > 0x33 && xop < 0x3f) {
4414 switch (xop) {
a4d17f19 4415#ifdef TARGET_SPARC64
0f8a249a 4416 case 0x34: /* V9 stfa */
6ea4a6c8 4417 gen_op_check_align_T0_3();
3391c818 4418 gen_op_load_fpr_FT0(rd);
2382dc6b 4419 gen_stf_asi(insn, 4, rd);
0f8a249a 4420 break;
1f587329
BS
4421 case 0x36: /* V9 stqfa */
4422#if defined(CONFIG_USER_ONLY)
4423 gen_op_check_align_T0_7();
4424 gen_op_load_fpr_QT0(QFPREG(rd));
2382dc6b 4425 gen_stf_asi(insn, 16, QFPREG(rd));
1f587329
BS
4426 break;
4427#else
4428 goto nfpu_insn;
4429#endif
0f8a249a 4430 case 0x37: /* V9 stdfa */
3391c818
BS
4431 gen_op_check_align_T0_3();
4432 gen_op_load_fpr_DT0(DFPREG(rd));
2382dc6b 4433 gen_stf_asi(insn, 8, DFPREG(rd));
0f8a249a
BS
4434 break;
4435 case 0x3c: /* V9 casa */
6ea4a6c8 4436 gen_op_check_align_T0_3();
1a2fb1c0 4437 gen_cas_asi(insn, rd);
81ad8ba2 4438 gen_movl_T1_reg(rd);
0f8a249a
BS
4439 break;
4440 case 0x3e: /* V9 casxa */
6ea4a6c8 4441 gen_op_check_align_T0_7();
1a2fb1c0 4442 gen_casx_asi(insn, rd);
81ad8ba2 4443 gen_movl_T1_reg(rd);
0f8a249a 4444 break;
a4d17f19 4445#else
0f8a249a
BS
4446 case 0x34: /* stc */
4447 case 0x35: /* stcsr */
4448 case 0x36: /* stdcq */
4449 case 0x37: /* stdc */
4450 goto ncp_insn;
4451#endif
4452 default:
4453 goto illegal_insn;
4454 }
e8af50a3 4455 }
0f8a249a
BS
4456 else
4457 goto illegal_insn;
4458 }
4459 break;
cf495bcf
FB
4460 }
4461 /* default case for non jump instructions */
72cbca10 4462 if (dc->npc == DYNAMIC_PC) {
0f8a249a
BS
4463 dc->pc = DYNAMIC_PC;
4464 gen_op_next_insn();
72cbca10
FB
4465 } else if (dc->npc == JUMP_PC) {
4466 /* we can do a static jump */
19f329ad 4467 gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_T[2]);
72cbca10
FB
4468 dc->is_br = 1;
4469 } else {
0f8a249a
BS
4470 dc->pc = dc->npc;
4471 dc->npc = dc->npc + 4;
cf495bcf 4472 }
e80cfcfc 4473 jmp_insn:
cf495bcf
FB
4474 return;
4475 illegal_insn:
72cbca10 4476 save_state(dc);
cf495bcf
FB
4477 gen_op_exception(TT_ILL_INSN);
4478 dc->is_br = 1;
e8af50a3 4479 return;
e80cfcfc 4480#if !defined(CONFIG_USER_ONLY)
e8af50a3
FB
4481 priv_insn:
4482 save_state(dc);
4483 gen_op_exception(TT_PRIV_INSN);
4484 dc->is_br = 1;
e80cfcfc 4485 return;
e80cfcfc
FB
4486 nfpu_insn:
4487 save_state(dc);
4488 gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
4489 dc->is_br = 1;
fcc72045 4490 return;
1f587329 4491#ifndef TARGET_SPARC64
9143e598
BS
4492 nfq_insn:
4493 save_state(dc);
4494 gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
4495 dc->is_br = 1;
4496 return;
4497#endif
1f587329 4498#endif
fcc72045
BS
4499#ifndef TARGET_SPARC64
4500 ncp_insn:
4501 save_state(dc);
4502 gen_op_exception(TT_NCP_INSN);
4503 dc->is_br = 1;
4504 return;
4505#endif
7a3f1944
FB
4506}
4507
1a2fb1c0
BS
4508static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
4509{
4510}
4511
cf495bcf 4512static inline int gen_intermediate_code_internal(TranslationBlock * tb,
0f8a249a 4513 int spc, CPUSPARCState *env)
7a3f1944 4514{
72cbca10 4515 target_ulong pc_start, last_pc;
cf495bcf
FB
4516 uint16_t *gen_opc_end;
4517 DisasContext dc1, *dc = &dc1;
e8af50a3 4518 int j, lj = -1;
cf495bcf
FB
4519
4520 memset(dc, 0, sizeof(DisasContext));
cf495bcf 4521 dc->tb = tb;
72cbca10 4522 pc_start = tb->pc;
cf495bcf 4523 dc->pc = pc_start;
e80cfcfc 4524 last_pc = dc->pc;
72cbca10 4525 dc->npc = (target_ulong) tb->cs_base;
6f27aba6
BS
4526 dc->mem_idx = cpu_mmu_index(env);
4527 dc->fpu_enabled = cpu_fpu_enabled(env);
cf495bcf 4528 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
cf495bcf 4529
1a2fb1c0 4530 cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
1a2fb1c0 4531
cf495bcf 4532 do {
e8af50a3
FB
4533 if (env->nb_breakpoints > 0) {
4534 for(j = 0; j < env->nb_breakpoints; j++) {
4535 if (env->breakpoints[j] == dc->pc) {
0f8a249a
BS
4536 if (dc->pc != pc_start)
4537 save_state(dc);
1a2fb1c0 4538 tcg_gen_helper_0_0(helper_debug);
57fec1fe 4539 tcg_gen_exit_tb(0);
0f8a249a 4540 dc->is_br = 1;
e80cfcfc 4541 goto exit_gen_loop;
e8af50a3
FB
4542 }
4543 }
4544 }
4545 if (spc) {
4546 if (loglevel > 0)
4547 fprintf(logfile, "Search PC...\n");
4548 j = gen_opc_ptr - gen_opc_buf;
4549 if (lj < j) {
4550 lj++;
4551 while (lj < j)
4552 gen_opc_instr_start[lj++] = 0;
4553 gen_opc_pc[lj] = dc->pc;
4554 gen_opc_npc[lj] = dc->npc;
4555 gen_opc_instr_start[lj] = 1;
4556 }
4557 }
0f8a249a
BS
4558 last_pc = dc->pc;
4559 disas_sparc_insn(dc);
4560
4561 if (dc->is_br)
4562 break;
4563 /* if the next PC is different, we abort now */
4564 if (dc->pc != (last_pc + 4))
4565 break;
d39c0b99
FB
4566 /* if we reach a page boundary, we stop generation so that the
4567 PC of a TT_TFAULT exception is always in the right page */
4568 if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
4569 break;
e80cfcfc
FB
4570 /* if single step mode, we generate only one instruction and
4571 generate an exception */
4572 if (env->singlestep_enabled) {
3475187d 4573 gen_jmp_im(dc->pc);
57fec1fe 4574 tcg_gen_exit_tb(0);
e80cfcfc
FB
4575 break;
4576 }
cf495bcf 4577 } while ((gen_opc_ptr < gen_opc_end) &&
0f8a249a 4578 (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
e80cfcfc
FB
4579
4580 exit_gen_loop:
72cbca10 4581 if (!dc->is_br) {
5fafdf24 4582 if (dc->pc != DYNAMIC_PC &&
72cbca10
FB
4583 (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
4584 /* static PC and NPC: we can use direct chaining */
46525e1f 4585 gen_branch(dc, dc->pc, dc->npc);
72cbca10
FB
4586 } else {
4587 if (dc->pc != DYNAMIC_PC)
3475187d 4588 gen_jmp_im(dc->pc);
72cbca10 4589 save_npc(dc);
57fec1fe 4590 tcg_gen_exit_tb(0);
72cbca10
FB
4591 }
4592 }
cf495bcf 4593 *gen_opc_ptr = INDEX_op_end;
e8af50a3
FB
4594 if (spc) {
4595 j = gen_opc_ptr - gen_opc_buf;
4596 lj++;
4597 while (lj <= j)
4598 gen_opc_instr_start[lj++] = 0;
e8af50a3
FB
4599#if 0
4600 if (loglevel > 0) {
4601 page_dump(logfile);
4602 }
4603#endif
c3278b7b
FB
4604 gen_opc_jump_pc[0] = dc->jump_pc[0];
4605 gen_opc_jump_pc[1] = dc->jump_pc[1];
e8af50a3 4606 } else {
e80cfcfc 4607 tb->size = last_pc + 4 - pc_start;
e8af50a3 4608 }
7a3f1944 4609#ifdef DEBUG_DISAS
e19e89a5 4610 if (loglevel & CPU_LOG_TB_IN_ASM) {
0f8a249a
BS
4611 fprintf(logfile, "--------------\n");
4612 fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
4613 target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
4614 fprintf(logfile, "\n");
cf495bcf 4615 }
7a3f1944 4616#endif
cf495bcf 4617 return 0;
7a3f1944
FB
4618}
4619
cf495bcf 4620int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
7a3f1944 4621{
e8af50a3 4622 return gen_intermediate_code_internal(tb, 0, env);
7a3f1944
FB
4623}
4624
cf495bcf 4625int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
7a3f1944 4626{
e8af50a3 4627 return gen_intermediate_code_internal(tb, 1, env);
7a3f1944
FB
4628}
4629
e80cfcfc
FB
4630void cpu_reset(CPUSPARCState *env)
4631{
bb05683b 4632 tlb_flush(env, 1);
cf495bcf
FB
4633 env->cwp = 0;
4634 env->wim = 1;
4635 env->regwptr = env->regbase + (env->cwp * 16);
e8af50a3 4636#if defined(CONFIG_USER_ONLY)
cf495bcf 4637 env->user_mode_only = 1;
5ef54116 4638#ifdef TARGET_SPARC64
6ef905f6
BS
4639 env->cleanwin = NWINDOWS - 2;
4640 env->cansave = NWINDOWS - 2;
4641 env->pstate = PS_RMO | PS_PEF | PS_IE;
4642 env->asi = 0x82; // Primary no-fault
5ef54116 4643#endif
e8af50a3 4644#else
32af58f9 4645 env->psret = 0;
e8af50a3 4646 env->psrs = 1;
0bee699e 4647 env->psrps = 1;
3475187d 4648#ifdef TARGET_SPARC64
83469015 4649 env->pstate = PS_PRIV;
6f27aba6 4650 env->hpstate = HS_PRIV;
83469015 4651 env->pc = 0x1fff0000000ULL;
375ee38b 4652 env->tsptr = &env->ts[env->tl];
3475187d 4653#else
40ce0a9a 4654 env->pc = 0;
32af58f9 4655 env->mmuregs[0] &= ~(MMU_E | MMU_NF);
6d5f237a 4656 env->mmuregs[0] |= env->mmu_bm;
3475187d 4657#endif
83469015 4658 env->npc = env->pc + 4;
e8af50a3 4659#endif
e80cfcfc
FB
4660}
4661
aaed909a 4662CPUSPARCState *cpu_sparc_init(const char *cpu_model)
e80cfcfc
FB
4663{
4664 CPUSPARCState *env;
aaed909a 4665 const sparc_def_t *def;
1a2fb1c0 4666 static int inited;
f5069b26
BS
4667 unsigned int i;
4668 static const char * const gregnames[8] = {
4669 NULL, // g0 not used
4670 "g1",
4671 "g2",
4672 "g3",
4673 "g4",
4674 "g5",
4675 "g6",
4676 "g7",
4677 };
aaed909a
FB
4678
4679 def = cpu_sparc_find_by_name(cpu_model);
4680 if (!def)
4681 return NULL;
e80cfcfc 4682
c68ea704
FB
4683 env = qemu_mallocz(sizeof(CPUSPARCState));
4684 if (!env)
0f8a249a 4685 return NULL;
c68ea704 4686 cpu_exec_init(env);
01ba9816 4687 env->cpu_model_str = cpu_model;
aaed909a
FB
4688 env->version = def->iu_version;
4689 env->fsr = def->fpu_version;
4690#if !defined(TARGET_SPARC64)
4691 env->mmu_bm = def->mmu_bm;
3deaeab7
BS
4692 env->mmu_ctpr_mask = def->mmu_ctpr_mask;
4693 env->mmu_cxr_mask = def->mmu_cxr_mask;
4694 env->mmu_sfsr_mask = def->mmu_sfsr_mask;
4695 env->mmu_trcr_mask = def->mmu_trcr_mask;
aaed909a
FB
4696 env->mmuregs[0] |= def->mmu_version;
4697 cpu_sparc_set_id(env, 0);
4698#endif
1a2fb1c0
BS
4699
4700 /* init various static tables */
4701 if (!inited) {
4702 inited = 1;
4703
4704 tcg_set_macro_func(&tcg_ctx, tcg_macro_func);
4705 cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
db4a4ea4
BS
4706 cpu_regwptr = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
4707 offsetof(CPUState, regwptr),
4708 "regwptr");
1a2fb1c0
BS
4709 //#if TARGET_LONG_BITS > HOST_LONG_BITS
4710#ifdef TARGET_SPARC64
4711 cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
4712 TCG_AREG0, offsetof(CPUState, t0), "T0");
4713 cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
4714 TCG_AREG0, offsetof(CPUState, t1), "T1");
4715 cpu_T[2] = tcg_global_mem_new(TCG_TYPE_TL,
4716 TCG_AREG0, offsetof(CPUState, t2), "T2");
dc99a3f2
BS
4717 cpu_xcc = tcg_global_mem_new(TCG_TYPE_I32,
4718 TCG_AREG0, offsetof(CPUState, xcc),
4719 "xcc");
1a2fb1c0
BS
4720#else
4721 cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
4722 cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
4723 cpu_T[2] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T2");
4724#endif
dc99a3f2
BS
4725 cpu_cc_src = tcg_global_mem_new(TCG_TYPE_TL,
4726 TCG_AREG0, offsetof(CPUState, cc_src),
4727 "cc_src");
d9bdab86
BS
4728 cpu_cc_src2 = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4729 offsetof(CPUState, cc_src2),
4730 "cc_src2");
dc99a3f2
BS
4731 cpu_cc_dst = tcg_global_mem_new(TCG_TYPE_TL,
4732 TCG_AREG0, offsetof(CPUState, cc_dst),
4733 "cc_dst");
4734 cpu_psr = tcg_global_mem_new(TCG_TYPE_I32,
4735 TCG_AREG0, offsetof(CPUState, psr),
4736 "psr");
87e92502
BS
4737 cpu_fsr = tcg_global_mem_new(TCG_TYPE_TL,
4738 TCG_AREG0, offsetof(CPUState, fsr),
4739 "fsr");
48d5c82b
BS
4740 cpu_pc = tcg_global_mem_new(TCG_TYPE_TL,
4741 TCG_AREG0, offsetof(CPUState, pc),
4742 "pc");
4743 cpu_npc = tcg_global_mem_new(TCG_TYPE_TL,
4744 TCG_AREG0, offsetof(CPUState, npc),
4745 "npc");
f5069b26
BS
4746 for (i = 1; i < 8; i++)
4747 cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4748 offsetof(CPUState, gregs[i]),
4749 gregnames[i]);
1a2fb1c0
BS
4750 }
4751
aaed909a
FB
4752 cpu_reset(env);
4753
4754 return env;
4755}
4756
4757void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
4758{
4759#if !defined(TARGET_SPARC64)
4760 env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
4761#endif
7a3f1944
FB
4762}
4763
62724a37
BS
4764static const sparc_def_t sparc_defs[] = {
4765#ifdef TARGET_SPARC64
7d77bf20
BS
4766 {
4767 .name = "Fujitsu Sparc64",
4768 .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)
4769 | (MAXTL << 8) | (NWINDOWS - 1)),
4770 .fpu_version = 0x00000000,
4771 .mmu_version = 0,
4772 },
4773 {
4774 .name = "Fujitsu Sparc64 III",
4775 .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)
4776 | (MAXTL << 8) | (NWINDOWS - 1)),
4777 .fpu_version = 0x00000000,
4778 .mmu_version = 0,
4779 },
4780 {
4781 .name = "Fujitsu Sparc64 IV",
4782 .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)
4783 | (MAXTL << 8) | (NWINDOWS - 1)),
4784 .fpu_version = 0x00000000,
4785 .mmu_version = 0,
4786 },
4787 {
4788 .name = "Fujitsu Sparc64 V",
4789 .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)
4790 | (MAXTL << 8) | (NWINDOWS - 1)),
4791 .fpu_version = 0x00000000,
4792 .mmu_version = 0,
4793 },
4794 {
4795 .name = "TI UltraSparc I",
4796 .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)
4797 | (MAXTL << 8) | (NWINDOWS - 1)),
4798 .fpu_version = 0x00000000,
4799 .mmu_version = 0,
4800 },
62724a37
BS
4801 {
4802 .name = "TI UltraSparc II",
7d77bf20
BS
4803 .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)
4804 | (MAXTL << 8) | (NWINDOWS - 1)),
4805 .fpu_version = 0x00000000,
4806 .mmu_version = 0,
4807 },
4808 {
4809 .name = "TI UltraSparc IIi",
4810 .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)
4811 | (MAXTL << 8) | (NWINDOWS - 1)),
4812 .fpu_version = 0x00000000,
4813 .mmu_version = 0,
4814 },
4815 {
4816 .name = "TI UltraSparc IIe",
4817 .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)
4818 | (MAXTL << 8) | (NWINDOWS - 1)),
4819 .fpu_version = 0x00000000,
4820 .mmu_version = 0,
4821 },
4822 {
4823 .name = "Sun UltraSparc III",
4824 .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)
4825 | (MAXTL << 8) | (NWINDOWS - 1)),
4826 .fpu_version = 0x00000000,
4827 .mmu_version = 0,
4828 },
4829 {
4830 .name = "Sun UltraSparc III Cu",
4831 .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)
4832 | (MAXTL << 8) | (NWINDOWS - 1)),
4833 .fpu_version = 0x00000000,
4834 .mmu_version = 0,
4835 },
4836 {
4837 .name = "Sun UltraSparc IIIi",
4838 .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)
4839 | (MAXTL << 8) | (NWINDOWS - 1)),
4840 .fpu_version = 0x00000000,
4841 .mmu_version = 0,
4842 },
4843 {
4844 .name = "Sun UltraSparc IV",
4845 .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)
4846 | (MAXTL << 8) | (NWINDOWS - 1)),
4847 .fpu_version = 0x00000000,
4848 .mmu_version = 0,
4849 },
4850 {
4851 .name = "Sun UltraSparc IV+",
4852 .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)
4853 | (MAXTL << 8) | (NWINDOWS - 1)),
4854 .fpu_version = 0x00000000,
4855 .mmu_version = 0,
4856 },
4857 {
4858 .name = "Sun UltraSparc IIIi+",
4859 .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)
4860 | (MAXTL << 8) | (NWINDOWS - 1)),
4861 .fpu_version = 0x00000000,
4862 .mmu_version = 0,
4863 },
4864 {
4865 .name = "NEC UltraSparc I",
4866 .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)
62724a37
BS
4867 | (MAXTL << 8) | (NWINDOWS - 1)),
4868 .fpu_version = 0x00000000,
4869 .mmu_version = 0,
4870 },
4871#else
406f82e8
BS
4872 {
4873 .name = "Fujitsu MB86900",
4874 .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
4875 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
4876 .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
4877 .mmu_bm = 0x00004000,
3deaeab7
BS
4878 .mmu_ctpr_mask = 0x007ffff0,
4879 .mmu_cxr_mask = 0x0000003f,
4880 .mmu_sfsr_mask = 0xffffffff,
4881 .mmu_trcr_mask = 0xffffffff,
406f82e8 4882 },
62724a37
BS
4883 {
4884 .name = "Fujitsu MB86904",
4885 .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
4886 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
4887 .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
6d5f237a 4888 .mmu_bm = 0x00004000,
3deaeab7
BS
4889 .mmu_ctpr_mask = 0x00ffffc0,
4890 .mmu_cxr_mask = 0x000000ff,
4891 .mmu_sfsr_mask = 0x00016fff,
4892 .mmu_trcr_mask = 0x00ffffff,
62724a37 4893 },
e0353fe2 4894 {
5ef62c5c
BS
4895 .name = "Fujitsu MB86907",
4896 .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
4897 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
4898 .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
6d5f237a 4899 .mmu_bm = 0x00004000,
3deaeab7
BS
4900 .mmu_ctpr_mask = 0xffffffc0,
4901 .mmu_cxr_mask = 0x000000ff,
4902 .mmu_sfsr_mask = 0x00016fff,
4903 .mmu_trcr_mask = 0xffffffff,
5ef62c5c 4904 },
406f82e8
BS
4905 {
4906 .name = "LSI L64811",
4907 .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
4908 .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
4909 .mmu_version = 0x10 << 24,
4910 .mmu_bm = 0x00004000,
3deaeab7
BS
4911 .mmu_ctpr_mask = 0x007ffff0,
4912 .mmu_cxr_mask = 0x0000003f,
4913 .mmu_sfsr_mask = 0xffffffff,
4914 .mmu_trcr_mask = 0xffffffff,
406f82e8
BS
4915 },
4916 {
4917 .name = "Cypress CY7C601",
4918 .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
4919 .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
4920 .mmu_version = 0x10 << 24,
4921 .mmu_bm = 0x00004000,
3deaeab7
BS
4922 .mmu_ctpr_mask = 0x007ffff0,
4923 .mmu_cxr_mask = 0x0000003f,
4924 .mmu_sfsr_mask = 0xffffffff,
4925 .mmu_trcr_mask = 0xffffffff,
406f82e8
BS
4926 },
4927 {
4928 .name = "Cypress CY7C611",
4929 .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
4930 .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
4931 .mmu_version = 0x10 << 24,
4932 .mmu_bm = 0x00004000,
3deaeab7
BS
4933 .mmu_ctpr_mask = 0x007ffff0,
4934 .mmu_cxr_mask = 0x0000003f,
4935 .mmu_sfsr_mask = 0xffffffff,
4936 .mmu_trcr_mask = 0xffffffff,
406f82e8
BS
4937 },
4938 {
4939 .name = "TI SuperSparc II",
4940 .iu_version = 0x40000000,
4941 .fpu_version = 0 << 17,
4942 .mmu_version = 0x04000000,
4943 .mmu_bm = 0x00002000,
3deaeab7
BS
4944 .mmu_ctpr_mask = 0xffffffc0,
4945 .mmu_cxr_mask = 0x0000ffff,
4946 .mmu_sfsr_mask = 0xffffffff,
4947 .mmu_trcr_mask = 0xffffffff,
406f82e8 4948 },
5ef62c5c
BS
4949 {
4950 .name = "TI MicroSparc I",
4951 .iu_version = 0x41000000,
4952 .fpu_version = 4 << 17,
4953 .mmu_version = 0x41000000,
6d5f237a 4954 .mmu_bm = 0x00004000,
3deaeab7
BS
4955 .mmu_ctpr_mask = 0x007ffff0,
4956 .mmu_cxr_mask = 0x0000003f,
4957 .mmu_sfsr_mask = 0x00016fff,
4958 .mmu_trcr_mask = 0x0000003f,
5ef62c5c
BS
4959 },
4960 {
406f82e8
BS
4961 .name = "TI MicroSparc II",
4962 .iu_version = 0x42000000,
4963 .fpu_version = 4 << 17,
4964 .mmu_version = 0x02000000,
4965 .mmu_bm = 0x00004000,
3deaeab7
BS
4966 .mmu_ctpr_mask = 0x00ffffc0,
4967 .mmu_cxr_mask = 0x000000ff,
a3ffaf30 4968 .mmu_sfsr_mask = 0x00016fff,
3deaeab7 4969 .mmu_trcr_mask = 0x00ffffff,
406f82e8
BS
4970 },
4971 {
4972 .name = "TI MicroSparc IIep",
4973 .iu_version = 0x42000000,
4974 .fpu_version = 4 << 17,
4975 .mmu_version = 0x04000000,
4976 .mmu_bm = 0x00004000,
3deaeab7
BS
4977 .mmu_ctpr_mask = 0x00ffffc0,
4978 .mmu_cxr_mask = 0x000000ff,
4979 .mmu_sfsr_mask = 0x00016bff,
4980 .mmu_trcr_mask = 0x00ffffff,
406f82e8
BS
4981 },
4982 {
4983 .name = "TI SuperSparc 51",
4984 .iu_version = 0x43000000,
5ef62c5c
BS
4985 .fpu_version = 0 << 17,
4986 .mmu_version = 0x04000000,
6d5f237a 4987 .mmu_bm = 0x00002000,
3deaeab7
BS
4988 .mmu_ctpr_mask = 0xffffffc0,
4989 .mmu_cxr_mask = 0x0000ffff,
4990 .mmu_sfsr_mask = 0xffffffff,
4991 .mmu_trcr_mask = 0xffffffff,
5ef62c5c
BS
4992 },
4993 {
406f82e8
BS
4994 .name = "TI SuperSparc 61",
4995 .iu_version = 0x44000000,
4996 .fpu_version = 0 << 17,
4997 .mmu_version = 0x04000000,
4998 .mmu_bm = 0x00002000,
3deaeab7
BS
4999 .mmu_ctpr_mask = 0xffffffc0,
5000 .mmu_cxr_mask = 0x0000ffff,
5001 .mmu_sfsr_mask = 0xffffffff,
5002 .mmu_trcr_mask = 0xffffffff,
406f82e8
BS
5003 },
5004 {
5005 .name = "Ross RT625",
5ef62c5c
BS
5006 .iu_version = 0x1e000000,
5007 .fpu_version = 1 << 17,
406f82e8
BS
5008 .mmu_version = 0x1e000000,
5009 .mmu_bm = 0x00004000,
3deaeab7
BS
5010 .mmu_ctpr_mask = 0x007ffff0,
5011 .mmu_cxr_mask = 0x0000003f,
5012 .mmu_sfsr_mask = 0xffffffff,
5013 .mmu_trcr_mask = 0xffffffff,
406f82e8
BS
5014 },
5015 {
5016 .name = "Ross RT620",
5017 .iu_version = 0x1f000000,
5018 .fpu_version = 1 << 17,
5019 .mmu_version = 0x1f000000,
5020 .mmu_bm = 0x00004000,
3deaeab7
BS
5021 .mmu_ctpr_mask = 0x007ffff0,
5022 .mmu_cxr_mask = 0x0000003f,
5023 .mmu_sfsr_mask = 0xffffffff,
5024 .mmu_trcr_mask = 0xffffffff,
406f82e8
BS
5025 },
5026 {
5027 .name = "BIT B5010",
5028 .iu_version = 0x20000000,
5029 .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
5030 .mmu_version = 0x20000000,
5031 .mmu_bm = 0x00004000,
3deaeab7
BS
5032 .mmu_ctpr_mask = 0x007ffff0,
5033 .mmu_cxr_mask = 0x0000003f,
5034 .mmu_sfsr_mask = 0xffffffff,
5035 .mmu_trcr_mask = 0xffffffff,
406f82e8
BS
5036 },
5037 {
5038 .name = "Matsushita MN10501",
5039 .iu_version = 0x50000000,
5040 .fpu_version = 0 << 17,
5041 .mmu_version = 0x50000000,
5042 .mmu_bm = 0x00004000,
3deaeab7
BS
5043 .mmu_ctpr_mask = 0x007ffff0,
5044 .mmu_cxr_mask = 0x0000003f,
5045 .mmu_sfsr_mask = 0xffffffff,
5046 .mmu_trcr_mask = 0xffffffff,
406f82e8
BS
5047 },
5048 {
5049 .name = "Weitek W8601",
5050 .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
5051 .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
5052 .mmu_version = 0x10 << 24,
5053 .mmu_bm = 0x00004000,
3deaeab7
BS
5054 .mmu_ctpr_mask = 0x007ffff0,
5055 .mmu_cxr_mask = 0x0000003f,
5056 .mmu_sfsr_mask = 0xffffffff,
5057 .mmu_trcr_mask = 0xffffffff,
406f82e8
BS
5058 },
5059 {
5060 .name = "LEON2",
5061 .iu_version = 0xf2000000,
5062 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
5063 .mmu_version = 0xf2000000,
5064 .mmu_bm = 0x00004000,
3deaeab7
BS
5065 .mmu_ctpr_mask = 0x007ffff0,
5066 .mmu_cxr_mask = 0x0000003f,
5067 .mmu_sfsr_mask = 0xffffffff,
5068 .mmu_trcr_mask = 0xffffffff,
406f82e8
BS
5069 },
5070 {
5071 .name = "LEON3",
5072 .iu_version = 0xf3000000,
5073 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
5074 .mmu_version = 0xf3000000,
6d5f237a 5075 .mmu_bm = 0x00004000,
3deaeab7
BS
5076 .mmu_ctpr_mask = 0x007ffff0,
5077 .mmu_cxr_mask = 0x0000003f,
5078 .mmu_sfsr_mask = 0xffffffff,
5079 .mmu_trcr_mask = 0xffffffff,
e0353fe2 5080 },
62724a37
BS
5081#endif
5082};
5083
aaed909a 5084static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name)
62724a37 5085{
62724a37
BS
5086 unsigned int i;
5087
62724a37
BS
5088 for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
5089 if (strcasecmp(name, sparc_defs[i].name) == 0) {
aaed909a 5090 return &sparc_defs[i];
62724a37
BS
5091 }
5092 }
aaed909a 5093 return NULL;
62724a37
BS
5094}
5095
5096void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
5097{
5098 unsigned int i;
5099
5100 for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
5101 (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x\n",
5102 sparc_defs[i].name,
5103 sparc_defs[i].iu_version,
5104 sparc_defs[i].fpu_version,
5105 sparc_defs[i].mmu_version);
5106 }
5107}
5108
7a3f1944
FB
5109#define GET_FLAG(a,b) ((env->psr & a)?b:'-')
5110
5fafdf24 5111void cpu_dump_state(CPUState *env, FILE *f,
7fe48483
FB
5112 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
5113 int flags)
7a3f1944 5114{
cf495bcf
FB
5115 int i, x;
5116
af7bf89b 5117 cpu_fprintf(f, "pc: " TARGET_FMT_lx " npc: " TARGET_FMT_lx "\n", env->pc, env->npc);
7fe48483 5118 cpu_fprintf(f, "General Registers:\n");
cf495bcf 5119 for (i = 0; i < 4; i++)
0f8a249a 5120 cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
7fe48483 5121 cpu_fprintf(f, "\n");
cf495bcf 5122 for (; i < 8; i++)
0f8a249a 5123 cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
7fe48483 5124 cpu_fprintf(f, "\nCurrent Register Window:\n");
cf495bcf 5125 for (x = 0; x < 3; x++) {
0f8a249a
BS
5126 for (i = 0; i < 4; i++)
5127 cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
5128 (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
5129 env->regwptr[i + x * 8]);
5130 cpu_fprintf(f, "\n");
5131 for (; i < 8; i++)
5132 cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
5133 (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
5134 env->regwptr[i + x * 8]);
5135 cpu_fprintf(f, "\n");
cf495bcf 5136 }
7fe48483 5137 cpu_fprintf(f, "\nFloating Point Registers:\n");
e8af50a3
FB
5138 for (i = 0; i < 32; i++) {
5139 if ((i & 3) == 0)
7fe48483
FB
5140 cpu_fprintf(f, "%%f%02d:", i);
5141 cpu_fprintf(f, " %016lf", env->fpr[i]);
e8af50a3 5142 if ((i & 3) == 3)
7fe48483 5143 cpu_fprintf(f, "\n");
e8af50a3 5144 }
ded3ab80 5145#ifdef TARGET_SPARC64
3299908c 5146 cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d fprs: %d\n",
0f8a249a 5147 env->pstate, GET_CCR(env), env->asi, env->tl, env->fprs);
ded3ab80 5148 cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d cleanwin %d cwp %d\n",
0f8a249a
BS
5149 env->cansave, env->canrestore, env->otherwin, env->wstate,
5150 env->cleanwin, NWINDOWS - 1 - env->cwp);
ded3ab80 5151#else
7fe48483 5152 cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n", GET_PSR(env),
0f8a249a
BS
5153 GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
5154 GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
5155 env->psrs?'S':'-', env->psrps?'P':'-',
5156 env->psret?'E':'-', env->wim);
ded3ab80 5157#endif
3475187d 5158 cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env));
7a3f1944 5159}
edfcbd99 5160
e80cfcfc 5161#if defined(CONFIG_USER_ONLY)
9b3c35e0 5162target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
edfcbd99
FB
5163{
5164 return addr;
5165}
658138bc 5166
e80cfcfc 5167#else
af7bf89b
FB
5168extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
5169 int *access_index, target_ulong address, int rw,
6ebbf390 5170 int mmu_idx);
0fa85d43 5171
9b3c35e0 5172target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
e80cfcfc 5173{
af7bf89b 5174 target_phys_addr_t phys_addr;
e80cfcfc
FB
5175 int prot, access_index;
5176
9e31b9e2
BS
5177 if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2,
5178 MMU_KERNEL_IDX) != 0)
5179 if (get_physical_address(env, &phys_addr, &prot, &access_index, addr,
5180 0, MMU_KERNEL_IDX) != 0)
6b1575b7 5181 return -1;
6c36d3fa
BS
5182 if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED)
5183 return -1;
e80cfcfc
FB
5184 return phys_addr;
5185}
5186#endif
5187
658138bc
FB
5188void helper_flush(target_ulong addr)
5189{
5190 addr &= ~7;
5191 tb_invalidate_page_range(addr, addr + 8);
5192}
This page took 0.925328 seconds and 4 git commands to generate.