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