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