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