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