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