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