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