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