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