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