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