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