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