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