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