]> git.proxmox.com Git - qemu.git/blame - target-sparc/translate.c
SPARC64: fp_disabled checks on ldfa/lddfa/ldqfa
[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
7e8c2b6c
BS
1561static inline void gen_op_clear_ieee_excp_and_FTT(void)
1562{
47ad35f1 1563 tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_CEXC_NMASK);
7e8c2b6c
BS
1564}
1565
1566static inline void gen_clear_float_exceptions(void)
1567{
a7812ae4 1568 gen_helper_clear_float_exceptions();
7e8c2b6c
BS
1569}
1570
1a2fb1c0
BS
1571/* asi moves */
1572#ifdef TARGET_SPARC64
a7812ae4 1573static inline TCGv_i32 gen_get_asi(int insn, TCGv r_addr)
1a2fb1c0 1574{
95f9397c 1575 int asi;
a7812ae4 1576 TCGv_i32 r_asi;
1a2fb1c0 1577
1a2fb1c0 1578 if (IS_IMM) {
a7812ae4 1579 r_asi = tcg_temp_new_i32();
255e1fcb 1580 tcg_gen_mov_i32(r_asi, cpu_asi);
1a2fb1c0
BS
1581 } else {
1582 asi = GET_FIELD(insn, 19, 26);
0425bee5 1583 r_asi = tcg_const_i32(asi);
1a2fb1c0 1584 }
0425bee5
BS
1585 return r_asi;
1586}
1587
77f193da
BS
1588static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
1589 int sign)
0425bee5 1590{
a7812ae4 1591 TCGv_i32 r_asi, r_size, r_sign;
0425bee5 1592
4af984a7 1593 r_asi = gen_get_asi(insn, addr);
2ea815ca
BS
1594 r_size = tcg_const_i32(size);
1595 r_sign = tcg_const_i32(sign);
a7812ae4
PB
1596 gen_helper_ld_asi(dst, addr, r_asi, r_size, r_sign);
1597 tcg_temp_free_i32(r_sign);
1598 tcg_temp_free_i32(r_size);
1599 tcg_temp_free_i32(r_asi);
1a2fb1c0
BS
1600}
1601
4af984a7 1602static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1a2fb1c0 1603{
a7812ae4 1604 TCGv_i32 r_asi, r_size;
1a2fb1c0 1605
4af984a7 1606 r_asi = gen_get_asi(insn, addr);
2ea815ca 1607 r_size = tcg_const_i32(size);
a7812ae4
PB
1608 gen_helper_st_asi(addr, src, r_asi, r_size);
1609 tcg_temp_free_i32(r_size);
1610 tcg_temp_free_i32(r_asi);
1a2fb1c0
BS
1611}
1612
4af984a7 1613static inline void gen_ldf_asi(TCGv addr, int insn, int size, int rd)
1a2fb1c0 1614{
a7812ae4 1615 TCGv_i32 r_asi, r_size, r_rd;
1a2fb1c0 1616
4af984a7 1617 r_asi = gen_get_asi(insn, addr);
2ea815ca
BS
1618 r_size = tcg_const_i32(size);
1619 r_rd = tcg_const_i32(rd);
a7812ae4
PB
1620 gen_helper_ldf_asi(addr, r_asi, r_size, r_rd);
1621 tcg_temp_free_i32(r_rd);
1622 tcg_temp_free_i32(r_size);
1623 tcg_temp_free_i32(r_asi);
1a2fb1c0
BS
1624}
1625
4af984a7 1626static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
1a2fb1c0 1627{
a7812ae4 1628 TCGv_i32 r_asi, r_size, r_rd;
1a2fb1c0 1629
31741a27 1630 r_asi = gen_get_asi(insn, addr);
2ea815ca
BS
1631 r_size = tcg_const_i32(size);
1632 r_rd = tcg_const_i32(rd);
a7812ae4
PB
1633 gen_helper_stf_asi(addr, r_asi, r_size, r_rd);
1634 tcg_temp_free_i32(r_rd);
1635 tcg_temp_free_i32(r_size);
1636 tcg_temp_free_i32(r_asi);
1a2fb1c0
BS
1637}
1638
4af984a7 1639static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1a2fb1c0 1640{
a7812ae4 1641 TCGv_i32 r_asi, r_size, r_sign;
1a2fb1c0 1642
4af984a7 1643 r_asi = gen_get_asi(insn, addr);
2ea815ca
BS
1644 r_size = tcg_const_i32(4);
1645 r_sign = tcg_const_i32(0);
a7812ae4
PB
1646 gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
1647 tcg_temp_free_i32(r_sign);
1648 gen_helper_st_asi(addr, dst, r_asi, r_size);
1649 tcg_temp_free_i32(r_size);
1650 tcg_temp_free_i32(r_asi);
8d96d209 1651 tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1a2fb1c0
BS
1652}
1653
db166940 1654static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
1a2fb1c0 1655{
a7812ae4 1656 TCGv_i32 r_asi, r_rd;
1a2fb1c0 1657
4af984a7 1658 r_asi = gen_get_asi(insn, addr);
db166940 1659 r_rd = tcg_const_i32(rd);
a7812ae4
PB
1660 gen_helper_ldda_asi(addr, r_asi, r_rd);
1661 tcg_temp_free_i32(r_rd);
1662 tcg_temp_free_i32(r_asi);
0425bee5
BS
1663}
1664
4af984a7 1665static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
0425bee5 1666{
a7812ae4 1667 TCGv_i32 r_asi, r_size;
a7ec4229
BS
1668
1669 gen_movl_reg_TN(rd + 1, cpu_tmp0);
ab508019 1670 tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, hi);
4af984a7 1671 r_asi = gen_get_asi(insn, addr);
2ea815ca 1672 r_size = tcg_const_i32(8);
a7812ae4
PB
1673 gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
1674 tcg_temp_free_i32(r_size);
1675 tcg_temp_free_i32(r_asi);
1a2fb1c0
BS
1676}
1677
77f193da
BS
1678static inline void gen_cas_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
1679 int rd)
1a2fb1c0 1680{
a7812ae4
PB
1681 TCGv r_val1;
1682 TCGv_i32 r_asi;
1a2fb1c0 1683
a7812ae4 1684 r_val1 = tcg_temp_new();
1a2fb1c0 1685 gen_movl_reg_TN(rd, r_val1);
4af984a7 1686 r_asi = gen_get_asi(insn, addr);
a7812ae4
PB
1687 gen_helper_cas_asi(dst, addr, r_val1, val2, r_asi);
1688 tcg_temp_free_i32(r_asi);
2ea815ca 1689 tcg_temp_free(r_val1);
1a2fb1c0
BS
1690}
1691
77f193da
BS
1692static inline void gen_casx_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
1693 int rd)
1a2fb1c0 1694{
a7812ae4 1695 TCGv_i32 r_asi;
1a2fb1c0 1696
8911f501 1697 gen_movl_reg_TN(rd, cpu_tmp64);
4af984a7 1698 r_asi = gen_get_asi(insn, addr);
a7812ae4
PB
1699 gen_helper_casx_asi(dst, addr, cpu_tmp64, val2, r_asi);
1700 tcg_temp_free_i32(r_asi);
1a2fb1c0
BS
1701}
1702
1703#elif !defined(CONFIG_USER_ONLY)
1704
77f193da
BS
1705static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
1706 int sign)
1a2fb1c0 1707{
a7812ae4 1708 TCGv_i32 r_asi, r_size, r_sign;
1a2fb1c0 1709
2ea815ca
BS
1710 r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1711 r_size = tcg_const_i32(size);
1712 r_sign = tcg_const_i32(sign);
a7812ae4 1713 gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
2ea815ca
BS
1714 tcg_temp_free(r_sign);
1715 tcg_temp_free(r_size);
1716 tcg_temp_free(r_asi);
4af984a7 1717 tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1a2fb1c0
BS
1718}
1719
4af984a7 1720static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1a2fb1c0 1721{
a7812ae4 1722 TCGv_i32 r_asi, r_size;
1a2fb1c0 1723
4af984a7 1724 tcg_gen_extu_tl_i64(cpu_tmp64, src);
2ea815ca
BS
1725 r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1726 r_size = tcg_const_i32(size);
a7812ae4 1727 gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
2ea815ca
BS
1728 tcg_temp_free(r_size);
1729 tcg_temp_free(r_asi);
1a2fb1c0
BS
1730}
1731
4af984a7 1732static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1a2fb1c0 1733{
a7812ae4
PB
1734 TCGv_i32 r_asi, r_size, r_sign;
1735 TCGv_i64 r_val;
1a2fb1c0 1736
2ea815ca
BS
1737 r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1738 r_size = tcg_const_i32(4);
1739 r_sign = tcg_const_i32(0);
a7812ae4 1740 gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
2ea815ca 1741 tcg_temp_free(r_sign);
a7812ae4
PB
1742 r_val = tcg_temp_new_i64();
1743 tcg_gen_extu_tl_i64(r_val, dst);
1744 gen_helper_st_asi(addr, r_val, r_asi, r_size);
1745 tcg_temp_free_i64(r_val);
2ea815ca
BS
1746 tcg_temp_free(r_size);
1747 tcg_temp_free(r_asi);
8d96d209 1748 tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1a2fb1c0
BS
1749}
1750
db166940 1751static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
1a2fb1c0 1752{
a7812ae4 1753 TCGv_i32 r_asi, r_size, r_sign;
1a2fb1c0 1754
2ea815ca
BS
1755 r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1756 r_size = tcg_const_i32(8);
1757 r_sign = tcg_const_i32(0);
a7812ae4 1758 gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
2ea815ca
BS
1759 tcg_temp_free(r_sign);
1760 tcg_temp_free(r_size);
1761 tcg_temp_free(r_asi);
db166940
BS
1762 tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
1763 gen_movl_TN_reg(rd + 1, cpu_tmp0);
8911f501 1764 tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
4af984a7 1765 tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
db166940 1766 gen_movl_TN_reg(rd, hi);
0425bee5
BS
1767}
1768
4af984a7 1769static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
0425bee5 1770{
a7812ae4 1771 TCGv_i32 r_asi, r_size;
a7ec4229
BS
1772
1773 gen_movl_reg_TN(rd + 1, cpu_tmp0);
ab508019 1774 tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, hi);
2ea815ca
BS
1775 r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1776 r_size = tcg_const_i32(8);
a7812ae4 1777 gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
2ea815ca
BS
1778 tcg_temp_free(r_size);
1779 tcg_temp_free(r_asi);
1a2fb1c0
BS
1780}
1781#endif
1782
1783#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4af984a7 1784static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
1a2fb1c0 1785{
a7812ae4
PB
1786 TCGv_i64 r_val;
1787 TCGv_i32 r_asi, r_size;
1a2fb1c0 1788
4af984a7 1789 gen_ld_asi(dst, addr, insn, 1, 0);
1a2fb1c0 1790
2ea815ca
BS
1791 r_val = tcg_const_i64(0xffULL);
1792 r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1793 r_size = tcg_const_i32(1);
a7812ae4
PB
1794 gen_helper_st_asi(addr, r_val, r_asi, r_size);
1795 tcg_temp_free_i32(r_size);
1796 tcg_temp_free_i32(r_asi);
1797 tcg_temp_free_i64(r_val);
1a2fb1c0
BS
1798}
1799#endif
1800
9322a4bf
BS
1801static inline TCGv get_src1(unsigned int insn, TCGv def)
1802{
1803 TCGv r_rs1 = def;
1804 unsigned int rs1;
1805
1806 rs1 = GET_FIELD(insn, 13, 17);
42a8aa83
RH
1807 if (rs1 == 0) {
1808 tcg_gen_movi_tl(def, 0);
1809 } else if (rs1 < 8) {
5c6a0628 1810 r_rs1 = cpu_gregs[rs1];
42a8aa83 1811 } else {
9322a4bf 1812 tcg_gen_ld_tl(def, cpu_regwptr, (rs1 - 8) * sizeof(target_ulong));
42a8aa83 1813 }
9322a4bf
BS
1814 return r_rs1;
1815}
1816
a49d9390
BS
1817static inline TCGv get_src2(unsigned int insn, TCGv def)
1818{
1819 TCGv r_rs2 = def;
a49d9390
BS
1820
1821 if (IS_IMM) { /* immediate */
42a8aa83
RH
1822 target_long simm = GET_FIELDs(insn, 19, 31);
1823 tcg_gen_movi_tl(def, simm);
a49d9390 1824 } else { /* register */
42a8aa83
RH
1825 unsigned int rs2 = GET_FIELD(insn, 27, 31);
1826 if (rs2 == 0) {
1827 tcg_gen_movi_tl(def, 0);
1828 } else if (rs2 < 8) {
a49d9390 1829 r_rs2 = cpu_gregs[rs2];
42a8aa83 1830 } else {
a49d9390 1831 tcg_gen_ld_tl(def, cpu_regwptr, (rs2 - 8) * sizeof(target_ulong));
42a8aa83 1832 }
a49d9390
BS
1833 }
1834 return r_rs2;
1835}
1836
8194f35a
IK
1837#ifdef TARGET_SPARC64
1838static inline void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_ptr cpu_env)
1839{
b551ec04 1840 TCGv_i32 r_tl = tcg_temp_new_i32();
8194f35a
IK
1841
1842 /* load env->tl into r_tl */
b551ec04 1843 tcg_gen_ld_i32(r_tl, cpu_env, offsetof(CPUSPARCState, tl));
8194f35a
IK
1844
1845 /* tl = [0 ... MAXTL_MASK] where MAXTL_MASK must be power of 2 */
b551ec04 1846 tcg_gen_andi_i32(r_tl, r_tl, MAXTL_MASK);
8194f35a
IK
1847
1848 /* calculate offset to current trap state from env->ts, reuse r_tl */
b551ec04 1849 tcg_gen_muli_i32(r_tl, r_tl, sizeof (trap_state));
8194f35a
IK
1850 tcg_gen_addi_ptr(r_tsptr, cpu_env, offsetof(CPUState, ts));
1851
1852 /* tsptr = env->ts[env->tl & MAXTL_MASK] */
b551ec04
JF
1853 {
1854 TCGv_ptr r_tl_tmp = tcg_temp_new_ptr();
1855 tcg_gen_ext_i32_ptr(r_tl_tmp, r_tl);
1856 tcg_gen_add_ptr(r_tsptr, r_tsptr, r_tl_tmp);
bc57c114 1857 tcg_temp_free_ptr(r_tl_tmp);
b551ec04 1858 }
8194f35a 1859
b551ec04 1860 tcg_temp_free_i32(r_tl);
8194f35a
IK
1861}
1862#endif
1863
64a88d5d 1864#define CHECK_IU_FEATURE(dc, FEATURE) \
5578ceab 1865 if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
64a88d5d
BS
1866 goto illegal_insn;
1867#define CHECK_FPU_FEATURE(dc, FEATURE) \
5578ceab 1868 if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
64a88d5d
BS
1869 goto nfpu_insn;
1870
0bee699e 1871/* before an instruction, dc->pc must be static */
cf495bcf
FB
1872static void disas_sparc_insn(DisasContext * dc)
1873{
1874 unsigned int insn, opc, rs1, rs2, rd;
42a8aa83 1875 TCGv cpu_src1, cpu_src2, cpu_tmp1, cpu_tmp2;
67526b20 1876 target_long simm;
7a3f1944 1877
8fec2b8c 1878 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
a8c768c0 1879 tcg_gen_debug_insn_start(dc->pc);
0fa85d43 1880 insn = ldl_code(dc->pc);
cf495bcf 1881 opc = GET_FIELD(insn, 0, 1);
7a3f1944 1882
cf495bcf 1883 rd = GET_FIELD(insn, 2, 6);
6ae20372 1884
42a8aa83
RH
1885 cpu_tmp1 = cpu_src1 = tcg_temp_new();
1886 cpu_tmp2 = cpu_src2 = tcg_temp_new();
6ae20372 1887
cf495bcf 1888 switch (opc) {
0f8a249a
BS
1889 case 0: /* branches/sethi */
1890 {
1891 unsigned int xop = GET_FIELD(insn, 7, 9);
1892 int32_t target;
1893 switch (xop) {
3475187d 1894#ifdef TARGET_SPARC64
0f8a249a
BS
1895 case 0x1: /* V9 BPcc */
1896 {
1897 int cc;
1898
1899 target = GET_FIELD_SP(insn, 0, 18);
86f1f2ae 1900 target = sign_extend(target, 19);
0f8a249a
BS
1901 target <<= 2;
1902 cc = GET_FIELD_SP(insn, 20, 21);
1903 if (cc == 0)
6ae20372 1904 do_branch(dc, target, insn, 0, cpu_cond);
0f8a249a 1905 else if (cc == 2)
6ae20372 1906 do_branch(dc, target, insn, 1, cpu_cond);
0f8a249a
BS
1907 else
1908 goto illegal_insn;
1909 goto jmp_insn;
1910 }
1911 case 0x3: /* V9 BPr */
1912 {
1913 target = GET_FIELD_SP(insn, 0, 13) |
13846e70 1914 (GET_FIELD_SP(insn, 20, 21) << 14);
0f8a249a
BS
1915 target = sign_extend(target, 16);
1916 target <<= 2;
9322a4bf 1917 cpu_src1 = get_src1(insn, cpu_src1);
6ae20372 1918 do_branch_reg(dc, target, insn, cpu_cond, cpu_src1);
0f8a249a
BS
1919 goto jmp_insn;
1920 }
1921 case 0x5: /* V9 FBPcc */
1922 {
1923 int cc = GET_FIELD_SP(insn, 20, 21);
6ae20372 1924 if (gen_trap_ifnofpu(dc, cpu_cond))
a80dde08 1925 goto jmp_insn;
0f8a249a
BS
1926 target = GET_FIELD_SP(insn, 0, 18);
1927 target = sign_extend(target, 19);
1928 target <<= 2;
6ae20372 1929 do_fbranch(dc, target, insn, cc, cpu_cond);
0f8a249a
BS
1930 goto jmp_insn;
1931 }
a4d17f19 1932#else
0f8a249a
BS
1933 case 0x7: /* CBN+x */
1934 {
1935 goto ncp_insn;
1936 }
1937#endif
1938 case 0x2: /* BN+x */
1939 {
1940 target = GET_FIELD(insn, 10, 31);
1941 target = sign_extend(target, 22);
1942 target <<= 2;
6ae20372 1943 do_branch(dc, target, insn, 0, cpu_cond);
0f8a249a
BS
1944 goto jmp_insn;
1945 }
1946 case 0x6: /* FBN+x */
1947 {
6ae20372 1948 if (gen_trap_ifnofpu(dc, cpu_cond))
a80dde08 1949 goto jmp_insn;
0f8a249a
BS
1950 target = GET_FIELD(insn, 10, 31);
1951 target = sign_extend(target, 22);
1952 target <<= 2;
6ae20372 1953 do_fbranch(dc, target, insn, 0, cpu_cond);
0f8a249a
BS
1954 goto jmp_insn;
1955 }
1956 case 0x4: /* SETHI */
0f8a249a 1957 if (rd) { // nop
0f8a249a 1958 uint32_t value = GET_FIELD(insn, 10, 31);
2ea815ca
BS
1959 TCGv r_const;
1960
1961 r_const = tcg_const_tl(value << 10);
1962 gen_movl_TN_reg(rd, r_const);
1963 tcg_temp_free(r_const);
0f8a249a 1964 }
0f8a249a
BS
1965 break;
1966 case 0x0: /* UNIMPL */
1967 default:
3475187d 1968 goto illegal_insn;
0f8a249a
BS
1969 }
1970 break;
1971 }
1972 break;
dc1a6971
BS
1973 case 1: /*CALL*/
1974 {
0f8a249a 1975 target_long target = GET_FIELDs(insn, 2, 31) << 2;
2ea815ca 1976 TCGv r_const;
cf495bcf 1977
2ea815ca
BS
1978 r_const = tcg_const_tl(dc->pc);
1979 gen_movl_TN_reg(15, r_const);
1980 tcg_temp_free(r_const);
0f8a249a 1981 target += dc->pc;
6ae20372 1982 gen_mov_pc_npc(dc, cpu_cond);
0f8a249a
BS
1983 dc->npc = target;
1984 }
1985 goto jmp_insn;
1986 case 2: /* FPU & Logical Operations */
1987 {
1988 unsigned int xop = GET_FIELD(insn, 7, 12);
1989 if (xop == 0x3a) { /* generate trap */
cf495bcf 1990 int cond;
3475187d 1991
9322a4bf 1992 cpu_src1 = get_src1(insn, cpu_src1);
0f8a249a
BS
1993 if (IS_IMM) {
1994 rs2 = GET_FIELD(insn, 25, 31);
6ae20372 1995 tcg_gen_addi_tl(cpu_dst, cpu_src1, rs2);
cf495bcf
FB
1996 } else {
1997 rs2 = GET_FIELD(insn, 27, 31);
0f8a249a 1998 if (rs2 != 0) {
6ae20372
BS
1999 gen_movl_reg_TN(rs2, cpu_src2);
2000 tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
6f551262
BS
2001 } else
2002 tcg_gen_mov_tl(cpu_dst, cpu_src1);
cf495bcf 2003 }
b04d9890 2004
cf495bcf 2005 cond = GET_FIELD(insn, 3, 6);
b04d9890 2006 if (cond == 0x8) { /* Trap Always */
6ae20372 2007 save_state(dc, cpu_cond);
b158a785
BS
2008 if ((dc->def->features & CPU_FEATURE_HYPV) &&
2009 supervisor(dc))
2010 tcg_gen_andi_tl(cpu_dst, cpu_dst, UA2005_HTRAP_MASK);
2011 else
2012 tcg_gen_andi_tl(cpu_dst, cpu_dst, V8_TRAP_MASK);
2013 tcg_gen_addi_tl(cpu_dst, cpu_dst, TT_TRAP);
a7812ae4 2014 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
b04d9890
FC
2015
2016 if (rs2 == 0 &&
2017 dc->def->features & CPU_FEATURE_TA0_SHUTDOWN) {
2018
2019 gen_helper_shutdown();
2020
2021 } else {
2022 gen_helper_raise_exception(cpu_tmp32);
2023 }
af7bf89b 2024 } else if (cond != 0) {
a7812ae4 2025 TCGv r_cond = tcg_temp_new();
b158a785 2026 int l1;
3475187d 2027#ifdef TARGET_SPARC64
0f8a249a
BS
2028 /* V9 icc/xcc */
2029 int cc = GET_FIELD_SP(insn, 11, 12);
748b9d8e 2030
6ae20372 2031 save_state(dc, cpu_cond);
0f8a249a 2032 if (cc == 0)
8393617c 2033 gen_cond(r_cond, 0, cond, dc);
0f8a249a 2034 else if (cc == 2)
8393617c 2035 gen_cond(r_cond, 1, cond, dc);
0f8a249a
BS
2036 else
2037 goto illegal_insn;
3475187d 2038#else
6ae20372 2039 save_state(dc, cpu_cond);
8393617c 2040 gen_cond(r_cond, 0, cond, dc);
3475187d 2041#endif
b158a785
BS
2042 l1 = gen_new_label();
2043 tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
2044
2045 if ((dc->def->features & CPU_FEATURE_HYPV) &&
2046 supervisor(dc))
2047 tcg_gen_andi_tl(cpu_dst, cpu_dst, UA2005_HTRAP_MASK);
2048 else
2049 tcg_gen_andi_tl(cpu_dst, cpu_dst, V8_TRAP_MASK);
2050 tcg_gen_addi_tl(cpu_dst, cpu_dst, TT_TRAP);
a7812ae4
PB
2051 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
2052 gen_helper_raise_exception(cpu_tmp32);
b158a785
BS
2053
2054 gen_set_label(l1);
2ea815ca 2055 tcg_temp_free(r_cond);
cf495bcf 2056 }
a80dde08 2057 gen_op_next_insn();
57fec1fe 2058 tcg_gen_exit_tb(0);
a80dde08
FB
2059 dc->is_br = 1;
2060 goto jmp_insn;
cf495bcf
FB
2061 } else if (xop == 0x28) {
2062 rs1 = GET_FIELD(insn, 13, 17);
2063 switch(rs1) {
2064 case 0: /* rdy */
65fe7b09
BS
2065#ifndef TARGET_SPARC64
2066 case 0x01 ... 0x0e: /* undefined in the SPARCv8
2067 manual, rdy on the microSPARC
2068 II */
2069 case 0x0f: /* stbar in the SPARCv8 manual,
2070 rdy on the microSPARC II */
2071 case 0x10 ... 0x1f: /* implementation-dependent in the
2072 SPARCv8 manual, rdy on the
2073 microSPARC II */
4a2ba232
FC
2074 /* Read Asr17 */
2075 if (rs1 == 0x11 && dc->def->features & CPU_FEATURE_ASR17) {
2076 TCGv r_const;
2077
2078 /* Read Asr17 for a Leon3 monoprocessor */
2079 r_const = tcg_const_tl((1 << 8)
2080 | (dc->def->nwindows - 1));
2081 gen_movl_TN_reg(rd, r_const);
2082 tcg_temp_free(r_const);
2083 break;
2084 }
65fe7b09 2085#endif
255e1fcb 2086 gen_movl_TN_reg(rd, cpu_y);
cf495bcf 2087 break;
3475187d 2088#ifdef TARGET_SPARC64
0f8a249a 2089 case 0x2: /* V9 rdccr */
8393617c 2090 gen_helper_compute_psr();
a7812ae4 2091 gen_helper_rdccr(cpu_dst);
6ae20372 2092 gen_movl_TN_reg(rd, cpu_dst);
3475187d 2093 break;
0f8a249a 2094 case 0x3: /* V9 rdasi */
255e1fcb 2095 tcg_gen_ext_i32_tl(cpu_dst, cpu_asi);
6ae20372 2096 gen_movl_TN_reg(rd, cpu_dst);
3475187d 2097 break;
0f8a249a 2098 case 0x4: /* V9 rdtick */
ccd4a219 2099 {
a7812ae4 2100 TCGv_ptr r_tickptr;
ccd4a219 2101
a7812ae4 2102 r_tickptr = tcg_temp_new_ptr();
ccd4a219
BS
2103 tcg_gen_ld_ptr(r_tickptr, cpu_env,
2104 offsetof(CPUState, tick));
a7812ae4
PB
2105 gen_helper_tick_get_count(cpu_dst, r_tickptr);
2106 tcg_temp_free_ptr(r_tickptr);
6ae20372 2107 gen_movl_TN_reg(rd, cpu_dst);
ccd4a219 2108 }
3475187d 2109 break;
0f8a249a 2110 case 0x5: /* V9 rdpc */
2ea815ca
BS
2111 {
2112 TCGv r_const;
2113
2114 r_const = tcg_const_tl(dc->pc);
2115 gen_movl_TN_reg(rd, r_const);
2116 tcg_temp_free(r_const);
2117 }
0f8a249a
BS
2118 break;
2119 case 0x6: /* V9 rdfprs */
255e1fcb 2120 tcg_gen_ext_i32_tl(cpu_dst, cpu_fprs);
6ae20372 2121 gen_movl_TN_reg(rd, cpu_dst);
3475187d 2122 break;
65fe7b09
BS
2123 case 0xf: /* V9 membar */
2124 break; /* no effect */
0f8a249a 2125 case 0x13: /* Graphics Status */
6ae20372 2126 if (gen_trap_ifnofpu(dc, cpu_cond))
725cb90b 2127 goto jmp_insn;
255e1fcb 2128 gen_movl_TN_reg(rd, cpu_gsr);
725cb90b 2129 break;
9d926598
BS
2130 case 0x16: /* Softint */
2131 tcg_gen_ext_i32_tl(cpu_dst, cpu_softint);
2132 gen_movl_TN_reg(rd, cpu_dst);
2133 break;
0f8a249a 2134 case 0x17: /* Tick compare */
255e1fcb 2135 gen_movl_TN_reg(rd, cpu_tick_cmpr);
83469015 2136 break;
0f8a249a 2137 case 0x18: /* System tick */
ccd4a219 2138 {
a7812ae4 2139 TCGv_ptr r_tickptr;
ccd4a219 2140
a7812ae4 2141 r_tickptr = tcg_temp_new_ptr();
ccd4a219
BS
2142 tcg_gen_ld_ptr(r_tickptr, cpu_env,
2143 offsetof(CPUState, stick));
a7812ae4
PB
2144 gen_helper_tick_get_count(cpu_dst, r_tickptr);
2145 tcg_temp_free_ptr(r_tickptr);
6ae20372 2146 gen_movl_TN_reg(rd, cpu_dst);
ccd4a219 2147 }
83469015 2148 break;
0f8a249a 2149 case 0x19: /* System tick compare */
255e1fcb 2150 gen_movl_TN_reg(rd, cpu_stick_cmpr);
83469015 2151 break;
0f8a249a
BS
2152 case 0x10: /* Performance Control */
2153 case 0x11: /* Performance Instrumentation Counter */
2154 case 0x12: /* Dispatch Control */
2155 case 0x14: /* Softint set, WO */
2156 case 0x15: /* Softint clear, WO */
3475187d
FB
2157#endif
2158 default:
cf495bcf
FB
2159 goto illegal_insn;
2160 }
e8af50a3 2161#if !defined(CONFIG_USER_ONLY)
e9ebed4d 2162 } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
3475187d 2163#ifndef TARGET_SPARC64
0f8a249a
BS
2164 if (!supervisor(dc))
2165 goto priv_insn;
8393617c
BS
2166 gen_helper_compute_psr();
2167 dc->cc_op = CC_OP_FLAGS;
a7812ae4 2168 gen_helper_rdpsr(cpu_dst);
e9ebed4d 2169#else
fb79ceb9 2170 CHECK_IU_FEATURE(dc, HYPV);
e9ebed4d
BS
2171 if (!hypervisor(dc))
2172 goto priv_insn;
2173 rs1 = GET_FIELD(insn, 13, 17);
2174 switch (rs1) {
2175 case 0: // hpstate
2176 // gen_op_rdhpstate();
2177 break;
2178 case 1: // htstate
2179 // gen_op_rdhtstate();
2180 break;
2181 case 3: // hintp
255e1fcb 2182 tcg_gen_mov_tl(cpu_dst, cpu_hintp);
e9ebed4d
BS
2183 break;
2184 case 5: // htba
255e1fcb 2185 tcg_gen_mov_tl(cpu_dst, cpu_htba);
e9ebed4d
BS
2186 break;
2187 case 6: // hver
255e1fcb 2188 tcg_gen_mov_tl(cpu_dst, cpu_hver);
e9ebed4d
BS
2189 break;
2190 case 31: // hstick_cmpr
255e1fcb 2191 tcg_gen_mov_tl(cpu_dst, cpu_hstick_cmpr);
e9ebed4d
BS
2192 break;
2193 default:
2194 goto illegal_insn;
2195 }
2196#endif
6ae20372 2197 gen_movl_TN_reg(rd, cpu_dst);
e8af50a3 2198 break;
3475187d 2199 } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
0f8a249a
BS
2200 if (!supervisor(dc))
2201 goto priv_insn;
3475187d
FB
2202#ifdef TARGET_SPARC64
2203 rs1 = GET_FIELD(insn, 13, 17);
0f8a249a
BS
2204 switch (rs1) {
2205 case 0: // tpc
375ee38b 2206 {
a7812ae4 2207 TCGv_ptr r_tsptr;
375ee38b 2208
a7812ae4 2209 r_tsptr = tcg_temp_new_ptr();
8194f35a 2210 gen_load_trap_state_at_tl(r_tsptr, cpu_env);
a7812ae4 2211 tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
375ee38b 2212 offsetof(trap_state, tpc));
a7812ae4 2213 tcg_temp_free_ptr(r_tsptr);
375ee38b 2214 }
0f8a249a
BS
2215 break;
2216 case 1: // tnpc
375ee38b 2217 {
a7812ae4 2218 TCGv_ptr r_tsptr;
375ee38b 2219
a7812ae4 2220 r_tsptr = tcg_temp_new_ptr();
8194f35a 2221 gen_load_trap_state_at_tl(r_tsptr, cpu_env);
ece43b8d 2222 tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
375ee38b 2223 offsetof(trap_state, tnpc));
a7812ae4 2224 tcg_temp_free_ptr(r_tsptr);
375ee38b 2225 }
0f8a249a
BS
2226 break;
2227 case 2: // tstate
375ee38b 2228 {
a7812ae4 2229 TCGv_ptr r_tsptr;
375ee38b 2230
a7812ae4 2231 r_tsptr = tcg_temp_new_ptr();
8194f35a 2232 gen_load_trap_state_at_tl(r_tsptr, cpu_env);
ece43b8d 2233 tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
375ee38b 2234 offsetof(trap_state, tstate));
a7812ae4 2235 tcg_temp_free_ptr(r_tsptr);
375ee38b 2236 }
0f8a249a
BS
2237 break;
2238 case 3: // tt
375ee38b 2239 {
a7812ae4 2240 TCGv_ptr r_tsptr;
375ee38b 2241
a7812ae4 2242 r_tsptr = tcg_temp_new_ptr();
8194f35a 2243 gen_load_trap_state_at_tl(r_tsptr, cpu_env);
a7812ae4 2244 tcg_gen_ld_i32(cpu_tmp32, r_tsptr,
375ee38b 2245 offsetof(trap_state, tt));
a7812ae4
PB
2246 tcg_temp_free_ptr(r_tsptr);
2247 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
375ee38b 2248 }
0f8a249a
BS
2249 break;
2250 case 4: // tick
ccd4a219 2251 {
a7812ae4 2252 TCGv_ptr r_tickptr;
ccd4a219 2253
a7812ae4 2254 r_tickptr = tcg_temp_new_ptr();
ccd4a219
BS
2255 tcg_gen_ld_ptr(r_tickptr, cpu_env,
2256 offsetof(CPUState, tick));
a7812ae4 2257 gen_helper_tick_get_count(cpu_tmp0, r_tickptr);
ece43b8d 2258 gen_movl_TN_reg(rd, cpu_tmp0);
a7812ae4 2259 tcg_temp_free_ptr(r_tickptr);
ccd4a219 2260 }
0f8a249a
BS
2261 break;
2262 case 5: // tba
255e1fcb 2263 tcg_gen_mov_tl(cpu_tmp0, cpu_tbr);
0f8a249a
BS
2264 break;
2265 case 6: // pstate
77f193da
BS
2266 tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2267 offsetof(CPUSPARCState, pstate));
ece43b8d 2268 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
0f8a249a
BS
2269 break;
2270 case 7: // tl
77f193da
BS
2271 tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2272 offsetof(CPUSPARCState, tl));
ece43b8d 2273 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
0f8a249a
BS
2274 break;
2275 case 8: // pil
77f193da
BS
2276 tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2277 offsetof(CPUSPARCState, psrpil));
ece43b8d 2278 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
0f8a249a
BS
2279 break;
2280 case 9: // cwp
a7812ae4 2281 gen_helper_rdcwp(cpu_tmp0);
0f8a249a
BS
2282 break;
2283 case 10: // cansave
77f193da
BS
2284 tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2285 offsetof(CPUSPARCState, cansave));
ece43b8d 2286 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
0f8a249a
BS
2287 break;
2288 case 11: // canrestore
77f193da
BS
2289 tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2290 offsetof(CPUSPARCState, canrestore));
ece43b8d 2291 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
0f8a249a
BS
2292 break;
2293 case 12: // cleanwin
77f193da
BS
2294 tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2295 offsetof(CPUSPARCState, cleanwin));
ece43b8d 2296 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
0f8a249a
BS
2297 break;
2298 case 13: // otherwin
77f193da
BS
2299 tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2300 offsetof(CPUSPARCState, otherwin));
ece43b8d 2301 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
0f8a249a
BS
2302 break;
2303 case 14: // wstate
77f193da
BS
2304 tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2305 offsetof(CPUSPARCState, wstate));
ece43b8d 2306 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
0f8a249a 2307 break;
e9ebed4d 2308 case 16: // UA2005 gl
fb79ceb9 2309 CHECK_IU_FEATURE(dc, GL);
77f193da
BS
2310 tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2311 offsetof(CPUSPARCState, gl));
ece43b8d 2312 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
e9ebed4d
BS
2313 break;
2314 case 26: // UA2005 strand status
fb79ceb9 2315 CHECK_IU_FEATURE(dc, HYPV);
e9ebed4d
BS
2316 if (!hypervisor(dc))
2317 goto priv_insn;
527067d8 2318 tcg_gen_mov_tl(cpu_tmp0, cpu_ssr);
e9ebed4d 2319 break;
0f8a249a 2320 case 31: // ver
255e1fcb 2321 tcg_gen_mov_tl(cpu_tmp0, cpu_ver);
0f8a249a
BS
2322 break;
2323 case 15: // fq
2324 default:
2325 goto illegal_insn;
2326 }
3475187d 2327#else
255e1fcb 2328 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_wim);
3475187d 2329#endif
ece43b8d 2330 gen_movl_TN_reg(rd, cpu_tmp0);
e8af50a3 2331 break;
3475187d
FB
2332 } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
2333#ifdef TARGET_SPARC64
c5f2f668 2334 save_state(dc, cpu_cond);
a7812ae4 2335 gen_helper_flushw();
3475187d 2336#else
0f8a249a
BS
2337 if (!supervisor(dc))
2338 goto priv_insn;
255e1fcb 2339 gen_movl_TN_reg(rd, cpu_tbr);
3475187d 2340#endif
e8af50a3
FB
2341 break;
2342#endif
0f8a249a 2343 } else if (xop == 0x34) { /* FPU Operations */
6ae20372 2344 if (gen_trap_ifnofpu(dc, cpu_cond))
a80dde08 2345 goto jmp_insn;
0f8a249a 2346 gen_op_clear_ieee_excp_and_FTT();
e8af50a3 2347 rs1 = GET_FIELD(insn, 13, 17);
0f8a249a
BS
2348 rs2 = GET_FIELD(insn, 27, 31);
2349 xop = GET_FIELD(insn, 18, 26);
cca1d527 2350 save_state(dc, cpu_cond);
0f8a249a 2351 switch (xop) {
dc1a6971
BS
2352 case 0x1: /* fmovs */
2353 tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);
2354 break;
2355 case 0x5: /* fnegs */
2356 gen_helper_fnegs(cpu_fpr[rd], cpu_fpr[rs2]);
2357 break;
2358 case 0x9: /* fabss */
2359 gen_helper_fabss(cpu_fpr[rd], cpu_fpr[rs2]);
2360 break;
2361 case 0x29: /* fsqrts */
2362 CHECK_FPU_FEATURE(dc, FSQRT);
2363 gen_clear_float_exceptions();
2364 gen_helper_fsqrts(cpu_tmp32, cpu_fpr[rs2]);
2365 gen_helper_check_ieee_exceptions();
2366 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2367 break;
2368 case 0x2a: /* fsqrtd */
2369 CHECK_FPU_FEATURE(dc, FSQRT);
2370 gen_op_load_fpr_DT1(DFPREG(rs2));
2371 gen_clear_float_exceptions();
2372 gen_helper_fsqrtd();
2373 gen_helper_check_ieee_exceptions();
2374 gen_op_store_DT0_fpr(DFPREG(rd));
2375 break;
2376 case 0x2b: /* fsqrtq */
2377 CHECK_FPU_FEATURE(dc, FLOAT128);
2378 gen_op_load_fpr_QT1(QFPREG(rs2));
2379 gen_clear_float_exceptions();
2380 gen_helper_fsqrtq();
2381 gen_helper_check_ieee_exceptions();
2382 gen_op_store_QT0_fpr(QFPREG(rd));
2383 break;
2384 case 0x41: /* fadds */
2385 gen_clear_float_exceptions();
2386 gen_helper_fadds(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
2387 gen_helper_check_ieee_exceptions();
2388 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2389 break;
2390 case 0x42: /* faddd */
2391 gen_op_load_fpr_DT0(DFPREG(rs1));
2392 gen_op_load_fpr_DT1(DFPREG(rs2));
2393 gen_clear_float_exceptions();
2394 gen_helper_faddd();
2395 gen_helper_check_ieee_exceptions();
2396 gen_op_store_DT0_fpr(DFPREG(rd));
2397 break;
2398 case 0x43: /* faddq */
2399 CHECK_FPU_FEATURE(dc, FLOAT128);
2400 gen_op_load_fpr_QT0(QFPREG(rs1));
2401 gen_op_load_fpr_QT1(QFPREG(rs2));
2402 gen_clear_float_exceptions();
2403 gen_helper_faddq();
2404 gen_helper_check_ieee_exceptions();
2405 gen_op_store_QT0_fpr(QFPREG(rd));
2406 break;
2407 case 0x45: /* fsubs */
2408 gen_clear_float_exceptions();
2409 gen_helper_fsubs(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
2410 gen_helper_check_ieee_exceptions();
2411 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2412 break;
2413 case 0x46: /* fsubd */
2414 gen_op_load_fpr_DT0(DFPREG(rs1));
2415 gen_op_load_fpr_DT1(DFPREG(rs2));
2416 gen_clear_float_exceptions();
2417 gen_helper_fsubd();
2418 gen_helper_check_ieee_exceptions();
2419 gen_op_store_DT0_fpr(DFPREG(rd));
2420 break;
2421 case 0x47: /* fsubq */
2422 CHECK_FPU_FEATURE(dc, FLOAT128);
2423 gen_op_load_fpr_QT0(QFPREG(rs1));
2424 gen_op_load_fpr_QT1(QFPREG(rs2));
2425 gen_clear_float_exceptions();
2426 gen_helper_fsubq();
2427 gen_helper_check_ieee_exceptions();
2428 gen_op_store_QT0_fpr(QFPREG(rd));
2429 break;
2430 case 0x49: /* fmuls */
2431 CHECK_FPU_FEATURE(dc, FMUL);
2432 gen_clear_float_exceptions();
2433 gen_helper_fmuls(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
2434 gen_helper_check_ieee_exceptions();
2435 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2436 break;
2437 case 0x4a: /* fmuld */
2438 CHECK_FPU_FEATURE(dc, FMUL);
2439 gen_op_load_fpr_DT0(DFPREG(rs1));
2440 gen_op_load_fpr_DT1(DFPREG(rs2));
2441 gen_clear_float_exceptions();
2442 gen_helper_fmuld();
2443 gen_helper_check_ieee_exceptions();
2444 gen_op_store_DT0_fpr(DFPREG(rd));
2445 break;
2446 case 0x4b: /* fmulq */
2447 CHECK_FPU_FEATURE(dc, FLOAT128);
2448 CHECK_FPU_FEATURE(dc, FMUL);
2449 gen_op_load_fpr_QT0(QFPREG(rs1));
2450 gen_op_load_fpr_QT1(QFPREG(rs2));
2451 gen_clear_float_exceptions();
2452 gen_helper_fmulq();
2453 gen_helper_check_ieee_exceptions();
2454 gen_op_store_QT0_fpr(QFPREG(rd));
2455 break;
2456 case 0x4d: /* fdivs */
2457 gen_clear_float_exceptions();
2458 gen_helper_fdivs(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
2459 gen_helper_check_ieee_exceptions();
2460 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2461 break;
2462 case 0x4e: /* fdivd */
2463 gen_op_load_fpr_DT0(DFPREG(rs1));
2464 gen_op_load_fpr_DT1(DFPREG(rs2));
2465 gen_clear_float_exceptions();
2466 gen_helper_fdivd();
2467 gen_helper_check_ieee_exceptions();
2468 gen_op_store_DT0_fpr(DFPREG(rd));
2469 break;
2470 case 0x4f: /* fdivq */
2471 CHECK_FPU_FEATURE(dc, FLOAT128);
2472 gen_op_load_fpr_QT0(QFPREG(rs1));
2473 gen_op_load_fpr_QT1(QFPREG(rs2));
2474 gen_clear_float_exceptions();
2475 gen_helper_fdivq();
2476 gen_helper_check_ieee_exceptions();
2477 gen_op_store_QT0_fpr(QFPREG(rd));
2478 break;
2479 case 0x69: /* fsmuld */
2480 CHECK_FPU_FEATURE(dc, FSMULD);
2481 gen_clear_float_exceptions();
2482 gen_helper_fsmuld(cpu_fpr[rs1], cpu_fpr[rs2]);
2483 gen_helper_check_ieee_exceptions();
2484 gen_op_store_DT0_fpr(DFPREG(rd));
2485 break;
2486 case 0x6e: /* fdmulq */
2487 CHECK_FPU_FEATURE(dc, FLOAT128);
2488 gen_op_load_fpr_DT0(DFPREG(rs1));
2489 gen_op_load_fpr_DT1(DFPREG(rs2));
2490 gen_clear_float_exceptions();
2491 gen_helper_fdmulq();
2492 gen_helper_check_ieee_exceptions();
2493 gen_op_store_QT0_fpr(QFPREG(rd));
2494 break;
2495 case 0xc4: /* fitos */
2496 gen_clear_float_exceptions();
2497 gen_helper_fitos(cpu_tmp32, cpu_fpr[rs2]);
2498 gen_helper_check_ieee_exceptions();
2499 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2500 break;
2501 case 0xc6: /* fdtos */
2502 gen_op_load_fpr_DT1(DFPREG(rs2));
2503 gen_clear_float_exceptions();
2504 gen_helper_fdtos(cpu_tmp32);
2505 gen_helper_check_ieee_exceptions();
2506 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2507 break;
2508 case 0xc7: /* fqtos */
2509 CHECK_FPU_FEATURE(dc, FLOAT128);
2510 gen_op_load_fpr_QT1(QFPREG(rs2));
2511 gen_clear_float_exceptions();
2512 gen_helper_fqtos(cpu_tmp32);
2513 gen_helper_check_ieee_exceptions();
2514 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2515 break;
2516 case 0xc8: /* fitod */
2517 gen_helper_fitod(cpu_fpr[rs2]);
2518 gen_op_store_DT0_fpr(DFPREG(rd));
2519 break;
2520 case 0xc9: /* fstod */
2521 gen_helper_fstod(cpu_fpr[rs2]);
2522 gen_op_store_DT0_fpr(DFPREG(rd));
2523 break;
2524 case 0xcb: /* fqtod */
2525 CHECK_FPU_FEATURE(dc, FLOAT128);
2526 gen_op_load_fpr_QT1(QFPREG(rs2));
2527 gen_clear_float_exceptions();
2528 gen_helper_fqtod();
2529 gen_helper_check_ieee_exceptions();
2530 gen_op_store_DT0_fpr(DFPREG(rd));
2531 break;
2532 case 0xcc: /* fitoq */
2533 CHECK_FPU_FEATURE(dc, FLOAT128);
2534 gen_helper_fitoq(cpu_fpr[rs2]);
2535 gen_op_store_QT0_fpr(QFPREG(rd));
2536 break;
2537 case 0xcd: /* fstoq */
2538 CHECK_FPU_FEATURE(dc, FLOAT128);
2539 gen_helper_fstoq(cpu_fpr[rs2]);
2540 gen_op_store_QT0_fpr(QFPREG(rd));
2541 break;
2542 case 0xce: /* fdtoq */
2543 CHECK_FPU_FEATURE(dc, FLOAT128);
2544 gen_op_load_fpr_DT1(DFPREG(rs2));
2545 gen_helper_fdtoq();
2546 gen_op_store_QT0_fpr(QFPREG(rd));
2547 break;
2548 case 0xd1: /* fstoi */
2549 gen_clear_float_exceptions();
2550 gen_helper_fstoi(cpu_tmp32, cpu_fpr[rs2]);
2551 gen_helper_check_ieee_exceptions();
2552 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2553 break;
2554 case 0xd2: /* fdtoi */
2555 gen_op_load_fpr_DT1(DFPREG(rs2));
2556 gen_clear_float_exceptions();
2557 gen_helper_fdtoi(cpu_tmp32);
2558 gen_helper_check_ieee_exceptions();
2559 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2560 break;
2561 case 0xd3: /* fqtoi */
2562 CHECK_FPU_FEATURE(dc, FLOAT128);
2563 gen_op_load_fpr_QT1(QFPREG(rs2));
2564 gen_clear_float_exceptions();
2565 gen_helper_fqtoi(cpu_tmp32);
2566 gen_helper_check_ieee_exceptions();
2567 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2568 break;
3475187d 2569#ifdef TARGET_SPARC64
dc1a6971
BS
2570 case 0x2: /* V9 fmovd */
2571 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)]);
2572 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1],
2573 cpu_fpr[DFPREG(rs2) + 1]);
2574 break;
2575 case 0x3: /* V9 fmovq */
2576 CHECK_FPU_FEATURE(dc, FLOAT128);
2577 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], cpu_fpr[QFPREG(rs2)]);
2578 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1],
2579 cpu_fpr[QFPREG(rs2) + 1]);
2580 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2],
2581 cpu_fpr[QFPREG(rs2) + 2]);
2582 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3],
2583 cpu_fpr[QFPREG(rs2) + 3]);
2584 break;
2585 case 0x6: /* V9 fnegd */
2586 gen_op_load_fpr_DT1(DFPREG(rs2));
2587 gen_helper_fnegd();
2588 gen_op_store_DT0_fpr(DFPREG(rd));
2589 break;
2590 case 0x7: /* V9 fnegq */
2591 CHECK_FPU_FEATURE(dc, FLOAT128);
2592 gen_op_load_fpr_QT1(QFPREG(rs2));
2593 gen_helper_fnegq();
2594 gen_op_store_QT0_fpr(QFPREG(rd));
2595 break;
2596 case 0xa: /* V9 fabsd */
2597 gen_op_load_fpr_DT1(DFPREG(rs2));
2598 gen_helper_fabsd();
2599 gen_op_store_DT0_fpr(DFPREG(rd));
2600 break;
2601 case 0xb: /* V9 fabsq */
2602 CHECK_FPU_FEATURE(dc, FLOAT128);
2603 gen_op_load_fpr_QT1(QFPREG(rs2));
2604 gen_helper_fabsq();
2605 gen_op_store_QT0_fpr(QFPREG(rd));
2606 break;
2607 case 0x81: /* V9 fstox */
2608 gen_clear_float_exceptions();
2609 gen_helper_fstox(cpu_fpr[rs2]);
2610 gen_helper_check_ieee_exceptions();
2611 gen_op_store_DT0_fpr(DFPREG(rd));
2612 break;
2613 case 0x82: /* V9 fdtox */
2614 gen_op_load_fpr_DT1(DFPREG(rs2));
2615 gen_clear_float_exceptions();
2616 gen_helper_fdtox();
2617 gen_helper_check_ieee_exceptions();
2618 gen_op_store_DT0_fpr(DFPREG(rd));
2619 break;
2620 case 0x83: /* V9 fqtox */
2621 CHECK_FPU_FEATURE(dc, FLOAT128);
2622 gen_op_load_fpr_QT1(QFPREG(rs2));
2623 gen_clear_float_exceptions();
2624 gen_helper_fqtox();
2625 gen_helper_check_ieee_exceptions();
2626 gen_op_store_DT0_fpr(DFPREG(rd));
2627 break;
2628 case 0x84: /* V9 fxtos */
2629 gen_op_load_fpr_DT1(DFPREG(rs2));
2630 gen_clear_float_exceptions();
2631 gen_helper_fxtos(cpu_tmp32);
2632 gen_helper_check_ieee_exceptions();
2633 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2634 break;
2635 case 0x88: /* V9 fxtod */
2636 gen_op_load_fpr_DT1(DFPREG(rs2));
2637 gen_clear_float_exceptions();
2638 gen_helper_fxtod();
2639 gen_helper_check_ieee_exceptions();
2640 gen_op_store_DT0_fpr(DFPREG(rd));
2641 break;
2642 case 0x8c: /* V9 fxtoq */
2643 CHECK_FPU_FEATURE(dc, FLOAT128);
2644 gen_op_load_fpr_DT1(DFPREG(rs2));
2645 gen_clear_float_exceptions();
2646 gen_helper_fxtoq();
2647 gen_helper_check_ieee_exceptions();
2648 gen_op_store_QT0_fpr(QFPREG(rd));
2649 break;
0f8a249a 2650#endif
dc1a6971
BS
2651 default:
2652 goto illegal_insn;
0f8a249a
BS
2653 }
2654 } else if (xop == 0x35) { /* FPU Operations */
3475187d 2655#ifdef TARGET_SPARC64
0f8a249a 2656 int cond;
3475187d 2657#endif
6ae20372 2658 if (gen_trap_ifnofpu(dc, cpu_cond))
a80dde08 2659 goto jmp_insn;
0f8a249a 2660 gen_op_clear_ieee_excp_and_FTT();
cf495bcf 2661 rs1 = GET_FIELD(insn, 13, 17);
0f8a249a
BS
2662 rs2 = GET_FIELD(insn, 27, 31);
2663 xop = GET_FIELD(insn, 18, 26);
cca1d527 2664 save_state(dc, cpu_cond);
3475187d 2665#ifdef TARGET_SPARC64
0f8a249a 2666 if ((xop & 0x11f) == 0x005) { // V9 fmovsr
dcf24905
BS
2667 int l1;
2668
2669 l1 = gen_new_label();
0f8a249a 2670 cond = GET_FIELD_SP(insn, 14, 17);
9322a4bf 2671 cpu_src1 = get_src1(insn, cpu_src1);
cb63669a
PB
2672 tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2673 0, l1);
714547bb 2674 tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);
dcf24905 2675 gen_set_label(l1);
0f8a249a
BS
2676 break;
2677 } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
dcf24905
BS
2678 int l1;
2679
2680 l1 = gen_new_label();
0f8a249a 2681 cond = GET_FIELD_SP(insn, 14, 17);
9322a4bf 2682 cpu_src1 = get_src1(insn, cpu_src1);
cb63669a
PB
2683 tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2684 0, l1);
714547bb
BS
2685 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)]);
2686 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], cpu_fpr[DFPREG(rs2) + 1]);
dcf24905 2687 gen_set_label(l1);
0f8a249a
BS
2688 break;
2689 } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
dcf24905
BS
2690 int l1;
2691
64a88d5d 2692 CHECK_FPU_FEATURE(dc, FLOAT128);
dcf24905 2693 l1 = gen_new_label();
1f587329 2694 cond = GET_FIELD_SP(insn, 14, 17);
9322a4bf 2695 cpu_src1 = get_src1(insn, cpu_src1);
cb63669a
PB
2696 tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2697 0, l1);
714547bb
BS
2698 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], cpu_fpr[QFPREG(rs2)]);
2699 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], cpu_fpr[QFPREG(rs2) + 1]);
2700 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], cpu_fpr[QFPREG(rs2) + 2]);
2701 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], cpu_fpr[QFPREG(rs2) + 3]);
dcf24905 2702 gen_set_label(l1);
1f587329 2703 break;
0f8a249a
BS
2704 }
2705#endif
2706 switch (xop) {
3475187d 2707#ifdef TARGET_SPARC64
714547bb 2708#define FMOVSCC(fcc) \
19f329ad 2709 { \
0425bee5 2710 TCGv r_cond; \
19f329ad
BS
2711 int l1; \
2712 \
2713 l1 = gen_new_label(); \
dc1a6971 2714 r_cond = tcg_temp_new(); \
19f329ad
BS
2715 cond = GET_FIELD_SP(insn, 14, 17); \
2716 gen_fcond(r_cond, fcc, cond); \
cb63669a
PB
2717 tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
2718 0, l1); \
714547bb
BS
2719 tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]); \
2720 gen_set_label(l1); \
2721 tcg_temp_free(r_cond); \
2722 }
2723#define FMOVDCC(fcc) \
2724 { \
2725 TCGv r_cond; \
2726 int l1; \
2727 \
2728 l1 = gen_new_label(); \
dc1a6971 2729 r_cond = tcg_temp_new(); \
714547bb
BS
2730 cond = GET_FIELD_SP(insn, 14, 17); \
2731 gen_fcond(r_cond, fcc, cond); \
2732 tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
2733 0, l1); \
2734 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], \
2735 cpu_fpr[DFPREG(rs2)]); \
2736 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], \
2737 cpu_fpr[DFPREG(rs2) + 1]); \
2738 gen_set_label(l1); \
2739 tcg_temp_free(r_cond); \
2740 }
2741#define FMOVQCC(fcc) \
2742 { \
2743 TCGv r_cond; \
2744 int l1; \
2745 \
2746 l1 = gen_new_label(); \
dc1a6971 2747 r_cond = tcg_temp_new(); \
714547bb
BS
2748 cond = GET_FIELD_SP(insn, 14, 17); \
2749 gen_fcond(r_cond, fcc, cond); \
2750 tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
2751 0, l1); \
2752 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], \
2753 cpu_fpr[QFPREG(rs2)]); \
2754 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], \
2755 cpu_fpr[QFPREG(rs2) + 1]); \
2756 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], \
2757 cpu_fpr[QFPREG(rs2) + 2]); \
2758 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], \
2759 cpu_fpr[QFPREG(rs2) + 3]); \
19f329ad 2760 gen_set_label(l1); \
2ea815ca 2761 tcg_temp_free(r_cond); \
19f329ad 2762 }
0f8a249a 2763 case 0x001: /* V9 fmovscc %fcc0 */
714547bb 2764 FMOVSCC(0);
0f8a249a
BS
2765 break;
2766 case 0x002: /* V9 fmovdcc %fcc0 */
714547bb 2767 FMOVDCC(0);
0f8a249a
BS
2768 break;
2769 case 0x003: /* V9 fmovqcc %fcc0 */
64a88d5d 2770 CHECK_FPU_FEATURE(dc, FLOAT128);
714547bb 2771 FMOVQCC(0);
1f587329 2772 break;
0f8a249a 2773 case 0x041: /* V9 fmovscc %fcc1 */
714547bb 2774 FMOVSCC(1);
0f8a249a
BS
2775 break;
2776 case 0x042: /* V9 fmovdcc %fcc1 */
714547bb 2777 FMOVDCC(1);
0f8a249a
BS
2778 break;
2779 case 0x043: /* V9 fmovqcc %fcc1 */
64a88d5d 2780 CHECK_FPU_FEATURE(dc, FLOAT128);
714547bb 2781 FMOVQCC(1);
1f587329 2782 break;
0f8a249a 2783 case 0x081: /* V9 fmovscc %fcc2 */
714547bb 2784 FMOVSCC(2);
0f8a249a
BS
2785 break;
2786 case 0x082: /* V9 fmovdcc %fcc2 */
714547bb 2787 FMOVDCC(2);
0f8a249a
BS
2788 break;
2789 case 0x083: /* V9 fmovqcc %fcc2 */
64a88d5d 2790 CHECK_FPU_FEATURE(dc, FLOAT128);
714547bb 2791 FMOVQCC(2);
1f587329 2792 break;
0f8a249a 2793 case 0x0c1: /* V9 fmovscc %fcc3 */
714547bb 2794 FMOVSCC(3);
0f8a249a
BS
2795 break;
2796 case 0x0c2: /* V9 fmovdcc %fcc3 */
714547bb 2797 FMOVDCC(3);
0f8a249a
BS
2798 break;
2799 case 0x0c3: /* V9 fmovqcc %fcc3 */
64a88d5d 2800 CHECK_FPU_FEATURE(dc, FLOAT128);
714547bb 2801 FMOVQCC(3);
1f587329 2802 break;
714547bb
BS
2803#undef FMOVSCC
2804#undef FMOVDCC
2805#undef FMOVQCC
714547bb
BS
2806#define FMOVSCC(icc) \
2807 { \
2808 TCGv r_cond; \
2809 int l1; \
2810 \
2811 l1 = gen_new_label(); \
dc1a6971 2812 r_cond = tcg_temp_new(); \
714547bb 2813 cond = GET_FIELD_SP(insn, 14, 17); \
8393617c 2814 gen_cond(r_cond, icc, cond, dc); \
714547bb
BS
2815 tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
2816 0, l1); \
2817 tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]); \
2818 gen_set_label(l1); \
2819 tcg_temp_free(r_cond); \
2820 }
2821#define FMOVDCC(icc) \
2822 { \
2823 TCGv r_cond; \
2824 int l1; \
2825 \
2826 l1 = gen_new_label(); \
dc1a6971 2827 r_cond = tcg_temp_new(); \
714547bb 2828 cond = GET_FIELD_SP(insn, 14, 17); \
8393617c 2829 gen_cond(r_cond, icc, cond, dc); \
714547bb
BS
2830 tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
2831 0, l1); \
2832 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], \
2833 cpu_fpr[DFPREG(rs2)]); \
2834 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], \
2835 cpu_fpr[DFPREG(rs2) + 1]); \
2836 gen_set_label(l1); \
2837 tcg_temp_free(r_cond); \
2838 }
2839#define FMOVQCC(icc) \
2840 { \
2841 TCGv r_cond; \
2842 int l1; \
2843 \
2844 l1 = gen_new_label(); \
dc1a6971 2845 r_cond = tcg_temp_new(); \
714547bb 2846 cond = GET_FIELD_SP(insn, 14, 17); \
8393617c 2847 gen_cond(r_cond, icc, cond, dc); \
714547bb
BS
2848 tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
2849 0, l1); \
2850 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], \
2851 cpu_fpr[QFPREG(rs2)]); \
2852 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], \
2853 cpu_fpr[QFPREG(rs2) + 1]); \
2854 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], \
2855 cpu_fpr[QFPREG(rs2) + 2]); \
2856 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], \
2857 cpu_fpr[QFPREG(rs2) + 3]); \
2858 gen_set_label(l1); \
2859 tcg_temp_free(r_cond); \
2860 }
19f329ad 2861
0f8a249a 2862 case 0x101: /* V9 fmovscc %icc */
714547bb 2863 FMOVSCC(0);
0f8a249a
BS
2864 break;
2865 case 0x102: /* V9 fmovdcc %icc */
714547bb 2866 FMOVDCC(0);
0f8a249a 2867 case 0x103: /* V9 fmovqcc %icc */
64a88d5d 2868 CHECK_FPU_FEATURE(dc, FLOAT128);
714547bb 2869 FMOVQCC(0);
1f587329 2870 break;
0f8a249a 2871 case 0x181: /* V9 fmovscc %xcc */
714547bb 2872 FMOVSCC(1);
0f8a249a
BS
2873 break;
2874 case 0x182: /* V9 fmovdcc %xcc */
714547bb 2875 FMOVDCC(1);
0f8a249a
BS
2876 break;
2877 case 0x183: /* V9 fmovqcc %xcc */
64a88d5d 2878 CHECK_FPU_FEATURE(dc, FLOAT128);
714547bb 2879 FMOVQCC(1);
1f587329 2880 break;
714547bb
BS
2881#undef FMOVSCC
2882#undef FMOVDCC
2883#undef FMOVQCC
1f587329
BS
2884#endif
2885 case 0x51: /* fcmps, V9 %fcc */
714547bb 2886 gen_op_fcmps(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]);
0f8a249a 2887 break;
1f587329 2888 case 0x52: /* fcmpd, V9 %fcc */
0f8a249a
BS
2889 gen_op_load_fpr_DT0(DFPREG(rs1));
2890 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2891 gen_op_fcmpd(rd & 3);
0f8a249a 2892 break;
1f587329 2893 case 0x53: /* fcmpq, V9 %fcc */
64a88d5d 2894 CHECK_FPU_FEATURE(dc, FLOAT128);
1f587329
BS
2895 gen_op_load_fpr_QT0(QFPREG(rs1));
2896 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2897 gen_op_fcmpq(rd & 3);
1f587329 2898 break;
0f8a249a 2899 case 0x55: /* fcmpes, V9 %fcc */
714547bb 2900 gen_op_fcmpes(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]);
0f8a249a
BS
2901 break;
2902 case 0x56: /* fcmped, V9 %fcc */
2903 gen_op_load_fpr_DT0(DFPREG(rs1));
2904 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2905 gen_op_fcmped(rd & 3);
0f8a249a 2906 break;
1f587329 2907 case 0x57: /* fcmpeq, V9 %fcc */
64a88d5d 2908 CHECK_FPU_FEATURE(dc, FLOAT128);
1f587329
BS
2909 gen_op_load_fpr_QT0(QFPREG(rs1));
2910 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2911 gen_op_fcmpeq(rd & 3);
1f587329 2912 break;
0f8a249a
BS
2913 default:
2914 goto illegal_insn;
2915 }
0f8a249a
BS
2916 } else if (xop == 0x2) {
2917 // clr/mov shortcut
e80cfcfc
FB
2918
2919 rs1 = GET_FIELD(insn, 13, 17);
0f8a249a 2920 if (rs1 == 0) {
1a2fb1c0 2921 // or %g0, x, y -> mov T0, x; mov y, T0
0f8a249a 2922 if (IS_IMM) { /* immediate */
2ea815ca
BS
2923 TCGv r_const;
2924
67526b20
BS
2925 simm = GET_FIELDs(insn, 19, 31);
2926 r_const = tcg_const_tl(simm);
2ea815ca
BS
2927 gen_movl_TN_reg(rd, r_const);
2928 tcg_temp_free(r_const);
0f8a249a
BS
2929 } else { /* register */
2930 rs2 = GET_FIELD(insn, 27, 31);
6ae20372 2931 gen_movl_reg_TN(rs2, cpu_dst);
9c6c6662 2932 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a 2933 }
0f8a249a 2934 } else {
9322a4bf 2935 cpu_src1 = get_src1(insn, cpu_src1);
0f8a249a 2936 if (IS_IMM) { /* immediate */
67526b20
BS
2937 simm = GET_FIELDs(insn, 19, 31);
2938 tcg_gen_ori_tl(cpu_dst, cpu_src1, simm);
9c6c6662 2939 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a
BS
2940 } else { /* register */
2941 // or x, %g0, y -> mov T1, x; mov y, T1
2942 rs2 = GET_FIELD(insn, 27, 31);
2943 if (rs2 != 0) {
6ae20372
BS
2944 gen_movl_reg_TN(rs2, cpu_src2);
2945 tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
9c6c6662 2946 gen_movl_TN_reg(rd, cpu_dst);
6f551262 2947 } else
9c6c6662 2948 gen_movl_TN_reg(rd, cpu_src1);
0f8a249a 2949 }
0f8a249a 2950 }
83469015 2951#ifdef TARGET_SPARC64
0f8a249a 2952 } else if (xop == 0x25) { /* sll, V9 sllx */
9322a4bf 2953 cpu_src1 = get_src1(insn, cpu_src1);
0f8a249a 2954 if (IS_IMM) { /* immediate */
67526b20 2955 simm = GET_FIELDs(insn, 20, 31);
1a2fb1c0 2956 if (insn & (1 << 12)) {
67526b20 2957 tcg_gen_shli_i64(cpu_dst, cpu_src1, simm & 0x3f);
1a2fb1c0 2958 } else {
67526b20 2959 tcg_gen_shli_i64(cpu_dst, cpu_src1, simm & 0x1f);
1a2fb1c0 2960 }
0f8a249a 2961 } else { /* register */
83469015 2962 rs2 = GET_FIELD(insn, 27, 31);
6ae20372 2963 gen_movl_reg_TN(rs2, cpu_src2);
1a2fb1c0 2964 if (insn & (1 << 12)) {
6ae20372 2965 tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
1a2fb1c0 2966 } else {
6ae20372 2967 tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
1a2fb1c0 2968 }
01b1fa6d 2969 tcg_gen_shl_i64(cpu_dst, cpu_src1, cpu_tmp0);
83469015 2970 }
6ae20372 2971 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a 2972 } else if (xop == 0x26) { /* srl, V9 srlx */
9322a4bf 2973 cpu_src1 = get_src1(insn, cpu_src1);
0f8a249a 2974 if (IS_IMM) { /* immediate */
67526b20 2975 simm = GET_FIELDs(insn, 20, 31);
1a2fb1c0 2976 if (insn & (1 << 12)) {
67526b20 2977 tcg_gen_shri_i64(cpu_dst, cpu_src1, simm & 0x3f);
1a2fb1c0 2978 } else {
6ae20372 2979 tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
67526b20 2980 tcg_gen_shri_i64(cpu_dst, cpu_dst, simm & 0x1f);
1a2fb1c0 2981 }
0f8a249a 2982 } else { /* register */
83469015 2983 rs2 = GET_FIELD(insn, 27, 31);
6ae20372 2984 gen_movl_reg_TN(rs2, cpu_src2);
1a2fb1c0 2985 if (insn & (1 << 12)) {
6ae20372
BS
2986 tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2987 tcg_gen_shr_i64(cpu_dst, cpu_src1, cpu_tmp0);
1a2fb1c0 2988 } else {
6ae20372
BS
2989 tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2990 tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2991 tcg_gen_shr_i64(cpu_dst, cpu_dst, cpu_tmp0);
1a2fb1c0 2992 }
83469015 2993 }
6ae20372 2994 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a 2995 } else if (xop == 0x27) { /* sra, V9 srax */
9322a4bf 2996 cpu_src1 = get_src1(insn, cpu_src1);
0f8a249a 2997 if (IS_IMM) { /* immediate */
67526b20 2998 simm = GET_FIELDs(insn, 20, 31);
1a2fb1c0 2999 if (insn & (1 << 12)) {
67526b20 3000 tcg_gen_sari_i64(cpu_dst, cpu_src1, simm & 0x3f);
1a2fb1c0 3001 } else {
6ae20372 3002 tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
527067d8 3003 tcg_gen_ext32s_i64(cpu_dst, cpu_dst);
67526b20 3004 tcg_gen_sari_i64(cpu_dst, cpu_dst, simm & 0x1f);
1a2fb1c0 3005 }
0f8a249a 3006 } else { /* register */
83469015 3007 rs2 = GET_FIELD(insn, 27, 31);
6ae20372 3008 gen_movl_reg_TN(rs2, cpu_src2);
1a2fb1c0 3009 if (insn & (1 << 12)) {
6ae20372
BS
3010 tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
3011 tcg_gen_sar_i64(cpu_dst, cpu_src1, cpu_tmp0);
1a2fb1c0 3012 } else {
6ae20372
BS
3013 tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
3014 tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
527067d8 3015 tcg_gen_ext32s_i64(cpu_dst, cpu_dst);
6ae20372 3016 tcg_gen_sar_i64(cpu_dst, cpu_dst, cpu_tmp0);
1a2fb1c0 3017 }
83469015 3018 }
6ae20372 3019 gen_movl_TN_reg(rd, cpu_dst);
e80cfcfc 3020#endif
fcc72045 3021 } else if (xop < 0x36) {
cf495bcf 3022 if (xop < 0x20) {
41d72852
BS
3023 cpu_src1 = get_src1(insn, cpu_src1);
3024 cpu_src2 = get_src2(insn, cpu_src2);
cf495bcf 3025 switch (xop & ~0x10) {
b89e94af 3026 case 0x0: /* add */
41d72852
BS
3027 if (IS_IMM) {
3028 simm = GET_FIELDs(insn, 19, 31);
3029 if (xop & 0x10) {
3030 gen_op_addi_cc(cpu_dst, cpu_src1, simm);
bdf9f35d
BS
3031 tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADD);
3032 dc->cc_op = CC_OP_ADD;
41d72852
BS
3033 } else {
3034 tcg_gen_addi_tl(cpu_dst, cpu_src1, simm);
3035 }
3036 } else {
3037 if (xop & 0x10) {
3038 gen_op_add_cc(cpu_dst, cpu_src1, cpu_src2);
bdf9f35d
BS
3039 tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADD);
3040 dc->cc_op = CC_OP_ADD;
41d72852
BS
3041 } else {
3042 tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
3043 }
3044 }
cf495bcf 3045 break;
b89e94af 3046 case 0x1: /* and */
41d72852
BS
3047 if (IS_IMM) {
3048 simm = GET_FIELDs(insn, 19, 31);
3049 tcg_gen_andi_tl(cpu_dst, cpu_src1, simm);
3050 } else {
3051 tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_src2);
3052 }
3053 if (xop & 0x10) {
38482a77
BS
3054 tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3055 tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
3056 dc->cc_op = CC_OP_LOGIC;
41d72852 3057 }
cf495bcf 3058 break;
b89e94af 3059 case 0x2: /* or */
41d72852
BS
3060 if (IS_IMM) {
3061 simm = GET_FIELDs(insn, 19, 31);
3062 tcg_gen_ori_tl(cpu_dst, cpu_src1, simm);
3063 } else {
3064 tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
3065 }
8393617c 3066 if (xop & 0x10) {
38482a77
BS
3067 tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3068 tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
3069 dc->cc_op = CC_OP_LOGIC;
8393617c 3070 }
0f8a249a 3071 break;
b89e94af 3072 case 0x3: /* xor */
41d72852
BS
3073 if (IS_IMM) {
3074 simm = GET_FIELDs(insn, 19, 31);
3075 tcg_gen_xori_tl(cpu_dst, cpu_src1, simm);
3076 } else {
3077 tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3078 }
8393617c 3079 if (xop & 0x10) {
38482a77
BS
3080 tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3081 tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
3082 dc->cc_op = CC_OP_LOGIC;
8393617c 3083 }
cf495bcf 3084 break;
b89e94af 3085 case 0x4: /* sub */
41d72852
BS
3086 if (IS_IMM) {
3087 simm = GET_FIELDs(insn, 19, 31);
3088 if (xop & 0x10) {
d4b0d468 3089 gen_op_subi_cc(cpu_dst, cpu_src1, simm, dc);
41d72852
BS
3090 } else {
3091 tcg_gen_subi_tl(cpu_dst, cpu_src1, simm);
3092 }
3093 } else {
3094 if (xop & 0x10) {
3095 gen_op_sub_cc(cpu_dst, cpu_src1, cpu_src2);
d4b0d468
BS
3096 tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUB);
3097 dc->cc_op = CC_OP_SUB;
41d72852
BS
3098 } else {
3099 tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_src2);
3100 }
3101 }
cf495bcf 3102 break;
b89e94af 3103 case 0x5: /* andn */
41d72852
BS
3104 if (IS_IMM) {
3105 simm = GET_FIELDs(insn, 19, 31);
3106 tcg_gen_andi_tl(cpu_dst, cpu_src1, ~simm);
3107 } else {
3108 tcg_gen_andc_tl(cpu_dst, cpu_src1, cpu_src2);
3109 }
8393617c 3110 if (xop & 0x10) {
38482a77
BS
3111 tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3112 tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
3113 dc->cc_op = CC_OP_LOGIC;
8393617c 3114 }
cf495bcf 3115 break;
b89e94af 3116 case 0x6: /* orn */
41d72852
BS
3117 if (IS_IMM) {
3118 simm = GET_FIELDs(insn, 19, 31);
3119 tcg_gen_ori_tl(cpu_dst, cpu_src1, ~simm);
3120 } else {
3121 tcg_gen_orc_tl(cpu_dst, cpu_src1, cpu_src2);
3122 }
8393617c 3123 if (xop & 0x10) {
38482a77
BS
3124 tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3125 tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
3126 dc->cc_op = CC_OP_LOGIC;
8393617c 3127 }
cf495bcf 3128 break;
b89e94af 3129 case 0x7: /* xorn */
41d72852
BS
3130 if (IS_IMM) {
3131 simm = GET_FIELDs(insn, 19, 31);
3132 tcg_gen_xori_tl(cpu_dst, cpu_src1, ~simm);
3133 } else {
3134 tcg_gen_not_tl(cpu_tmp0, cpu_src2);
3135 tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_tmp0);
3136 }
8393617c 3137 if (xop & 0x10) {
38482a77
BS
3138 tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3139 tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
3140 dc->cc_op = CC_OP_LOGIC;
8393617c 3141 }
cf495bcf 3142 break;
b89e94af 3143 case 0x8: /* addx, V9 addc */
70c48285
RH
3144 gen_op_addx_int(dc, cpu_dst, cpu_src1, cpu_src2,
3145 (xop & 0x10));
cf495bcf 3146 break;
ded3ab80 3147#ifdef TARGET_SPARC64
0f8a249a 3148 case 0x9: /* V9 mulx */
41d72852
BS
3149 if (IS_IMM) {
3150 simm = GET_FIELDs(insn, 19, 31);
3151 tcg_gen_muli_i64(cpu_dst, cpu_src1, simm);
3152 } else {
3153 tcg_gen_mul_i64(cpu_dst, cpu_src1, cpu_src2);
3154 }
ded3ab80
PB
3155 break;
3156#endif
b89e94af 3157 case 0xa: /* umul */
64a88d5d 3158 CHECK_IU_FEATURE(dc, MUL);
6ae20372 3159 gen_op_umul(cpu_dst, cpu_src1, cpu_src2);
8393617c 3160 if (xop & 0x10) {
38482a77
BS
3161 tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3162 tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
3163 dc->cc_op = CC_OP_LOGIC;
8393617c 3164 }
cf495bcf 3165 break;
b89e94af 3166 case 0xb: /* smul */
64a88d5d 3167 CHECK_IU_FEATURE(dc, MUL);
6ae20372 3168 gen_op_smul(cpu_dst, cpu_src1, cpu_src2);
8393617c 3169 if (xop & 0x10) {
38482a77
BS
3170 tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
3171 tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
3172 dc->cc_op = CC_OP_LOGIC;
8393617c 3173 }
cf495bcf 3174 break;
b89e94af 3175 case 0xc: /* subx, V9 subc */
70c48285
RH
3176 gen_op_subx_int(dc, cpu_dst, cpu_src1, cpu_src2,
3177 (xop & 0x10));
cf495bcf 3178 break;
ded3ab80 3179#ifdef TARGET_SPARC64
0f8a249a 3180 case 0xd: /* V9 udivx */
8e91ed30
AT
3181 {
3182 TCGv r_temp1, r_temp2;
3183 r_temp1 = tcg_temp_local_new();
3184 r_temp2 = tcg_temp_local_new();
3185 tcg_gen_mov_tl(r_temp1, cpu_src1);
3186 tcg_gen_mov_tl(r_temp2, cpu_src2);
3187 gen_trap_ifdivzero_tl(r_temp2);
3188 tcg_gen_divu_i64(cpu_dst, r_temp1, r_temp2);
3189 tcg_temp_free(r_temp1);
3190 tcg_temp_free(r_temp2);
3191 }
ded3ab80
PB
3192 break;
3193#endif
b89e94af 3194 case 0xe: /* udiv */
64a88d5d 3195 CHECK_IU_FEATURE(dc, DIV);
8393617c 3196 if (xop & 0x10) {
0fcec41e 3197 gen_helper_udiv_cc(cpu_dst, cpu_src1, cpu_src2);
6c78ea32 3198 dc->cc_op = CC_OP_DIV;
0fcec41e
AJ
3199 } else {
3200 gen_helper_udiv(cpu_dst, cpu_src1, cpu_src2);
8393617c 3201 }
cf495bcf 3202 break;
b89e94af 3203 case 0xf: /* sdiv */
64a88d5d 3204 CHECK_IU_FEATURE(dc, DIV);
8393617c 3205 if (xop & 0x10) {
0fcec41e 3206 gen_helper_sdiv_cc(cpu_dst, cpu_src1, cpu_src2);
6c78ea32 3207 dc->cc_op = CC_OP_DIV;
0fcec41e
AJ
3208 } else {
3209 gen_helper_sdiv(cpu_dst, cpu_src1, cpu_src2);
8393617c 3210 }
cf495bcf
FB
3211 break;
3212 default:
3213 goto illegal_insn;
3214 }
6ae20372 3215 gen_movl_TN_reg(rd, cpu_dst);
cf495bcf 3216 } else {
41d72852
BS
3217 cpu_src1 = get_src1(insn, cpu_src1);
3218 cpu_src2 = get_src2(insn, cpu_src2);
cf495bcf 3219 switch (xop) {
0f8a249a 3220 case 0x20: /* taddcc */
6ae20372
BS
3221 gen_op_tadd_cc(cpu_dst, cpu_src1, cpu_src2);
3222 gen_movl_TN_reg(rd, cpu_dst);
3b2d1e92
BS
3223 tcg_gen_movi_i32(cpu_cc_op, CC_OP_TADD);
3224 dc->cc_op = CC_OP_TADD;
0f8a249a
BS
3225 break;
3226 case 0x21: /* tsubcc */
6ae20372
BS
3227 gen_op_tsub_cc(cpu_dst, cpu_src1, cpu_src2);
3228 gen_movl_TN_reg(rd, cpu_dst);
3b2d1e92
BS
3229 tcg_gen_movi_i32(cpu_cc_op, CC_OP_TSUB);
3230 dc->cc_op = CC_OP_TSUB;
0f8a249a
BS
3231 break;
3232 case 0x22: /* taddcctv */
6ae20372
BS
3233 save_state(dc, cpu_cond);
3234 gen_op_tadd_ccTV(cpu_dst, cpu_src1, cpu_src2);
3235 gen_movl_TN_reg(rd, cpu_dst);
3b2d1e92
BS
3236 tcg_gen_movi_i32(cpu_cc_op, CC_OP_TADDTV);
3237 dc->cc_op = CC_OP_TADDTV;
0f8a249a
BS
3238 break;
3239 case 0x23: /* tsubcctv */
6ae20372
BS
3240 save_state(dc, cpu_cond);
3241 gen_op_tsub_ccTV(cpu_dst, cpu_src1, cpu_src2);
3242 gen_movl_TN_reg(rd, cpu_dst);
3b2d1e92
BS
3243 tcg_gen_movi_i32(cpu_cc_op, CC_OP_TSUBTV);
3244 dc->cc_op = CC_OP_TSUBTV;
0f8a249a 3245 break;
cf495bcf 3246 case 0x24: /* mulscc */
8393617c 3247 gen_helper_compute_psr();
6ae20372
BS
3248 gen_op_mulscc(cpu_dst, cpu_src1, cpu_src2);
3249 gen_movl_TN_reg(rd, cpu_dst);
d084469c
BS
3250 tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADD);
3251 dc->cc_op = CC_OP_ADD;
cf495bcf 3252 break;
83469015 3253#ifndef TARGET_SPARC64
0f8a249a 3254 case 0x25: /* sll */
e35298cd 3255 if (IS_IMM) { /* immediate */
67526b20
BS
3256 simm = GET_FIELDs(insn, 20, 31);
3257 tcg_gen_shli_tl(cpu_dst, cpu_src1, simm & 0x1f);
e35298cd
BS
3258 } else { /* register */
3259 tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3260 tcg_gen_shl_tl(cpu_dst, cpu_src1, cpu_tmp0);
3261 }
6ae20372 3262 gen_movl_TN_reg(rd, cpu_dst);
cf495bcf 3263 break;
83469015 3264 case 0x26: /* srl */
e35298cd 3265 if (IS_IMM) { /* immediate */
67526b20
BS
3266 simm = GET_FIELDs(insn, 20, 31);
3267 tcg_gen_shri_tl(cpu_dst, cpu_src1, simm & 0x1f);
e35298cd
BS
3268 } else { /* register */
3269 tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3270 tcg_gen_shr_tl(cpu_dst, cpu_src1, cpu_tmp0);
3271 }
6ae20372 3272 gen_movl_TN_reg(rd, cpu_dst);
cf495bcf 3273 break;
83469015 3274 case 0x27: /* sra */
e35298cd 3275 if (IS_IMM) { /* immediate */
67526b20
BS
3276 simm = GET_FIELDs(insn, 20, 31);
3277 tcg_gen_sari_tl(cpu_dst, cpu_src1, simm & 0x1f);
e35298cd
BS
3278 } else { /* register */
3279 tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3280 tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0);
3281 }
6ae20372 3282 gen_movl_TN_reg(rd, cpu_dst);
cf495bcf 3283 break;
83469015 3284#endif
cf495bcf
FB
3285 case 0x30:
3286 {
cf495bcf 3287 switch(rd) {
3475187d 3288 case 0: /* wry */
5068cbd9
BS
3289 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
3290 tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
cf495bcf 3291 break;
65fe7b09
BS
3292#ifndef TARGET_SPARC64
3293 case 0x01 ... 0x0f: /* undefined in the
3294 SPARCv8 manual, nop
3295 on the microSPARC
3296 II */
3297 case 0x10 ... 0x1f: /* implementation-dependent
3298 in the SPARCv8
3299 manual, nop on the
3300 microSPARC II */
3301 break;
3302#else
0f8a249a 3303 case 0x2: /* V9 wrccr */
6ae20372 3304 tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
a7812ae4 3305 gen_helper_wrccr(cpu_dst);
8393617c
BS
3306 tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS);
3307 dc->cc_op = CC_OP_FLAGS;
0f8a249a
BS
3308 break;
3309 case 0x3: /* V9 wrasi */
6ae20372 3310 tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
01b5d4e5 3311 tcg_gen_andi_tl(cpu_dst, cpu_dst, 0xff);
255e1fcb 3312 tcg_gen_trunc_tl_i32(cpu_asi, cpu_dst);
0f8a249a
BS
3313 break;
3314 case 0x6: /* V9 wrfprs */
6ae20372 3315 tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
255e1fcb 3316 tcg_gen_trunc_tl_i32(cpu_fprs, cpu_dst);
6ae20372 3317 save_state(dc, cpu_cond);
3299908c 3318 gen_op_next_insn();
57fec1fe 3319 tcg_gen_exit_tb(0);
3299908c 3320 dc->is_br = 1;
0f8a249a
BS
3321 break;
3322 case 0xf: /* V9 sir, nop if user */
3475187d 3323#if !defined(CONFIG_USER_ONLY)
6ad6135d 3324 if (supervisor(dc)) {
1a2fb1c0 3325 ; // XXX
6ad6135d 3326 }
3475187d 3327#endif
0f8a249a
BS
3328 break;
3329 case 0x13: /* Graphics Status */
6ae20372 3330 if (gen_trap_ifnofpu(dc, cpu_cond))
725cb90b 3331 goto jmp_insn;
255e1fcb 3332 tcg_gen_xor_tl(cpu_gsr, cpu_src1, cpu_src2);
0f8a249a 3333 break;
9d926598
BS
3334 case 0x14: /* Softint set */
3335 if (!supervisor(dc))
3336 goto illegal_insn;
3337 tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2);
a7812ae4 3338 gen_helper_set_softint(cpu_tmp64);
9d926598
BS
3339 break;
3340 case 0x15: /* Softint clear */
3341 if (!supervisor(dc))
3342 goto illegal_insn;
3343 tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2);
a7812ae4 3344 gen_helper_clear_softint(cpu_tmp64);
9d926598
BS
3345 break;
3346 case 0x16: /* Softint write */
3347 if (!supervisor(dc))
3348 goto illegal_insn;
3349 tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2);
a7812ae4 3350 gen_helper_write_softint(cpu_tmp64);
9d926598 3351 break;
0f8a249a 3352 case 0x17: /* Tick compare */
83469015 3353#if !defined(CONFIG_USER_ONLY)
0f8a249a
BS
3354 if (!supervisor(dc))
3355 goto illegal_insn;
83469015 3356#endif
ccd4a219 3357 {
a7812ae4 3358 TCGv_ptr r_tickptr;
ccd4a219 3359
255e1fcb 3360 tcg_gen_xor_tl(cpu_tick_cmpr, cpu_src1,
6ae20372 3361 cpu_src2);
a7812ae4 3362 r_tickptr = tcg_temp_new_ptr();
ccd4a219
BS
3363 tcg_gen_ld_ptr(r_tickptr, cpu_env,
3364 offsetof(CPUState, tick));
a7812ae4
PB
3365 gen_helper_tick_set_limit(r_tickptr,
3366 cpu_tick_cmpr);
3367 tcg_temp_free_ptr(r_tickptr);
ccd4a219 3368 }
0f8a249a
BS
3369 break;
3370 case 0x18: /* System tick */
83469015 3371#if !defined(CONFIG_USER_ONLY)
0f8a249a
BS
3372 if (!supervisor(dc))
3373 goto illegal_insn;
83469015 3374#endif
ccd4a219 3375 {
a7812ae4 3376 TCGv_ptr r_tickptr;
ccd4a219 3377
6ae20372
BS
3378 tcg_gen_xor_tl(cpu_dst, cpu_src1,
3379 cpu_src2);
a7812ae4 3380 r_tickptr = tcg_temp_new_ptr();
ccd4a219
BS
3381 tcg_gen_ld_ptr(r_tickptr, cpu_env,
3382 offsetof(CPUState, stick));
a7812ae4
PB
3383 gen_helper_tick_set_count(r_tickptr,
3384 cpu_dst);
3385 tcg_temp_free_ptr(r_tickptr);
ccd4a219 3386 }
0f8a249a
BS
3387 break;
3388 case 0x19: /* System tick compare */
83469015 3389#if !defined(CONFIG_USER_ONLY)
0f8a249a
BS
3390 if (!supervisor(dc))
3391 goto illegal_insn;
3475187d 3392#endif
ccd4a219 3393 {
a7812ae4 3394 TCGv_ptr r_tickptr;
ccd4a219 3395
255e1fcb 3396 tcg_gen_xor_tl(cpu_stick_cmpr, cpu_src1,
6ae20372 3397 cpu_src2);
a7812ae4 3398 r_tickptr = tcg_temp_new_ptr();
ccd4a219
BS
3399 tcg_gen_ld_ptr(r_tickptr, cpu_env,
3400 offsetof(CPUState, stick));
a7812ae4
PB
3401 gen_helper_tick_set_limit(r_tickptr,
3402 cpu_stick_cmpr);
3403 tcg_temp_free_ptr(r_tickptr);
ccd4a219 3404 }
0f8a249a 3405 break;
83469015 3406
0f8a249a 3407 case 0x10: /* Performance Control */
77f193da
BS
3408 case 0x11: /* Performance Instrumentation
3409 Counter */
0f8a249a 3410 case 0x12: /* Dispatch Control */
83469015 3411#endif
3475187d 3412 default:
cf495bcf
FB
3413 goto illegal_insn;
3414 }
3415 }
3416 break;
e8af50a3 3417#if !defined(CONFIG_USER_ONLY)
af7bf89b 3418 case 0x31: /* wrpsr, V9 saved, restored */
e8af50a3 3419 {
0f8a249a
BS
3420 if (!supervisor(dc))
3421 goto priv_insn;
3475187d 3422#ifdef TARGET_SPARC64
0f8a249a
BS
3423 switch (rd) {
3424 case 0:
a7812ae4 3425 gen_helper_saved();
0f8a249a
BS
3426 break;
3427 case 1:
a7812ae4 3428 gen_helper_restored();
0f8a249a 3429 break;
e9ebed4d
BS
3430 case 2: /* UA2005 allclean */
3431 case 3: /* UA2005 otherw */
3432 case 4: /* UA2005 normalw */
3433 case 5: /* UA2005 invalw */
3434 // XXX
0f8a249a 3435 default:
3475187d
FB
3436 goto illegal_insn;
3437 }
3438#else
6ae20372 3439 tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
a7812ae4 3440 gen_helper_wrpsr(cpu_dst);
8393617c
BS
3441 tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS);
3442 dc->cc_op = CC_OP_FLAGS;
6ae20372 3443 save_state(dc, cpu_cond);
9e61bde5 3444 gen_op_next_insn();
57fec1fe 3445 tcg_gen_exit_tb(0);
0f8a249a 3446 dc->is_br = 1;
3475187d 3447#endif
e8af50a3
FB
3448 }
3449 break;
af7bf89b 3450 case 0x32: /* wrwim, V9 wrpr */
e8af50a3 3451 {
0f8a249a
BS
3452 if (!supervisor(dc))
3453 goto priv_insn;
ece43b8d 3454 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
3475187d 3455#ifdef TARGET_SPARC64
0f8a249a
BS
3456 switch (rd) {
3457 case 0: // tpc
375ee38b 3458 {
a7812ae4 3459 TCGv_ptr r_tsptr;
375ee38b 3460
a7812ae4 3461 r_tsptr = tcg_temp_new_ptr();
8194f35a 3462 gen_load_trap_state_at_tl(r_tsptr, cpu_env);
ece43b8d 3463 tcg_gen_st_tl(cpu_tmp0, r_tsptr,
375ee38b 3464 offsetof(trap_state, tpc));
a7812ae4 3465 tcg_temp_free_ptr(r_tsptr);
375ee38b 3466 }
0f8a249a
BS
3467 break;
3468 case 1: // tnpc
375ee38b 3469 {
a7812ae4 3470 TCGv_ptr r_tsptr;
375ee38b 3471
a7812ae4 3472 r_tsptr = tcg_temp_new_ptr();
8194f35a 3473 gen_load_trap_state_at_tl(r_tsptr, cpu_env);
ece43b8d 3474 tcg_gen_st_tl(cpu_tmp0, r_tsptr,
375ee38b 3475 offsetof(trap_state, tnpc));
a7812ae4 3476 tcg_temp_free_ptr(r_tsptr);
375ee38b 3477 }
0f8a249a
BS
3478 break;
3479 case 2: // tstate
375ee38b 3480 {
a7812ae4 3481 TCGv_ptr r_tsptr;
375ee38b 3482
a7812ae4 3483 r_tsptr = tcg_temp_new_ptr();
8194f35a 3484 gen_load_trap_state_at_tl(r_tsptr, cpu_env);
ece43b8d 3485 tcg_gen_st_tl(cpu_tmp0, r_tsptr,
77f193da
BS
3486 offsetof(trap_state,
3487 tstate));
a7812ae4 3488 tcg_temp_free_ptr(r_tsptr);
375ee38b 3489 }
0f8a249a
BS
3490 break;
3491 case 3: // tt
375ee38b 3492 {
a7812ae4 3493 TCGv_ptr r_tsptr;
375ee38b 3494
a7812ae4 3495 r_tsptr = tcg_temp_new_ptr();
8194f35a 3496 gen_load_trap_state_at_tl(r_tsptr, cpu_env);
527067d8
BS
3497 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3498 tcg_gen_st_i32(cpu_tmp32, r_tsptr,
375ee38b 3499 offsetof(trap_state, tt));
a7812ae4 3500 tcg_temp_free_ptr(r_tsptr);
375ee38b 3501 }
0f8a249a
BS
3502 break;
3503 case 4: // tick
ccd4a219 3504 {
a7812ae4 3505 TCGv_ptr r_tickptr;
ccd4a219 3506
a7812ae4 3507 r_tickptr = tcg_temp_new_ptr();
ccd4a219
BS
3508 tcg_gen_ld_ptr(r_tickptr, cpu_env,
3509 offsetof(CPUState, tick));
a7812ae4
PB
3510 gen_helper_tick_set_count(r_tickptr,
3511 cpu_tmp0);
3512 tcg_temp_free_ptr(r_tickptr);
ccd4a219 3513 }
0f8a249a
BS
3514 break;
3515 case 5: // tba
255e1fcb 3516 tcg_gen_mov_tl(cpu_tbr, cpu_tmp0);
0f8a249a
BS
3517 break;
3518 case 6: // pstate
a2589e5c
BS
3519 {
3520 TCGv r_tmp = tcg_temp_local_new();
3521
3522 tcg_gen_mov_tl(r_tmp, cpu_tmp0);
3523 save_state(dc, cpu_cond);
3524 gen_helper_wrpstate(r_tmp);
3525 tcg_temp_free(r_tmp);
3526 dc->npc = DYNAMIC_PC;
3527 }
0f8a249a
BS
3528 break;
3529 case 7: // tl
a2589e5c
BS
3530 {
3531 TCGv r_tmp = tcg_temp_local_new();
3532
3533 tcg_gen_mov_tl(r_tmp, cpu_tmp0);
3534 save_state(dc, cpu_cond);
3535 tcg_gen_trunc_tl_i32(cpu_tmp32, r_tmp);
3536 tcg_temp_free(r_tmp);
3537 tcg_gen_st_i32(cpu_tmp32, cpu_env,
3538 offsetof(CPUSPARCState, tl));
3539 dc->npc = DYNAMIC_PC;
3540 }
0f8a249a
BS
3541 break;
3542 case 8: // pil
1fae7b70 3543 gen_helper_wrpil(cpu_tmp0);
0f8a249a
BS
3544 break;
3545 case 9: // cwp
a7812ae4 3546 gen_helper_wrcwp(cpu_tmp0);
0f8a249a
BS
3547 break;
3548 case 10: // cansave
ece43b8d 3549 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
77f193da
BS
3550 tcg_gen_st_i32(cpu_tmp32, cpu_env,
3551 offsetof(CPUSPARCState,
3552 cansave));
0f8a249a
BS
3553 break;
3554 case 11: // canrestore
ece43b8d 3555 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
77f193da
BS
3556 tcg_gen_st_i32(cpu_tmp32, cpu_env,
3557 offsetof(CPUSPARCState,
3558 canrestore));
0f8a249a
BS
3559 break;
3560 case 12: // cleanwin
ece43b8d 3561 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
77f193da
BS
3562 tcg_gen_st_i32(cpu_tmp32, cpu_env,
3563 offsetof(CPUSPARCState,
3564 cleanwin));
0f8a249a
BS
3565 break;
3566 case 13: // otherwin
ece43b8d 3567 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
77f193da
BS
3568 tcg_gen_st_i32(cpu_tmp32, cpu_env,
3569 offsetof(CPUSPARCState,
3570 otherwin));
0f8a249a
BS
3571 break;
3572 case 14: // wstate
ece43b8d 3573 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
77f193da
BS
3574 tcg_gen_st_i32(cpu_tmp32, cpu_env,
3575 offsetof(CPUSPARCState,
3576 wstate));
0f8a249a 3577 break;
e9ebed4d 3578 case 16: // UA2005 gl
fb79ceb9 3579 CHECK_IU_FEATURE(dc, GL);
ece43b8d 3580 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
77f193da
BS
3581 tcg_gen_st_i32(cpu_tmp32, cpu_env,
3582 offsetof(CPUSPARCState, gl));
e9ebed4d
BS
3583 break;
3584 case 26: // UA2005 strand status
fb79ceb9 3585 CHECK_IU_FEATURE(dc, HYPV);
e9ebed4d
BS
3586 if (!hypervisor(dc))
3587 goto priv_insn;
527067d8 3588 tcg_gen_mov_tl(cpu_ssr, cpu_tmp0);
e9ebed4d 3589 break;
0f8a249a
BS
3590 default:
3591 goto illegal_insn;
3592 }
3475187d 3593#else
ece43b8d 3594 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
c93e7817
BS
3595 if (dc->def->nwindows != 32)
3596 tcg_gen_andi_tl(cpu_tmp32, cpu_tmp32,
3597 (1 << dc->def->nwindows) - 1);
255e1fcb 3598 tcg_gen_mov_i32(cpu_wim, cpu_tmp32);
3475187d 3599#endif
e8af50a3
FB
3600 }
3601 break;
e9ebed4d 3602 case 0x33: /* wrtbr, UA2005 wrhpr */
e8af50a3 3603 {
e9ebed4d 3604#ifndef TARGET_SPARC64
0f8a249a
BS
3605 if (!supervisor(dc))
3606 goto priv_insn;
255e1fcb 3607 tcg_gen_xor_tl(cpu_tbr, cpu_src1, cpu_src2);
e9ebed4d 3608#else
fb79ceb9 3609 CHECK_IU_FEATURE(dc, HYPV);
e9ebed4d
BS
3610 if (!hypervisor(dc))
3611 goto priv_insn;
ece43b8d 3612 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
e9ebed4d
BS
3613 switch (rd) {
3614 case 0: // hpstate
3615 // XXX gen_op_wrhpstate();
6ae20372 3616 save_state(dc, cpu_cond);
e9ebed4d 3617 gen_op_next_insn();
57fec1fe 3618 tcg_gen_exit_tb(0);
e9ebed4d
BS
3619 dc->is_br = 1;
3620 break;
3621 case 1: // htstate
3622 // XXX gen_op_wrhtstate();
3623 break;
3624 case 3: // hintp
255e1fcb 3625 tcg_gen_mov_tl(cpu_hintp, cpu_tmp0);
e9ebed4d
BS
3626 break;
3627 case 5: // htba
255e1fcb 3628 tcg_gen_mov_tl(cpu_htba, cpu_tmp0);
e9ebed4d
BS
3629 break;
3630 case 31: // hstick_cmpr
ccd4a219 3631 {
a7812ae4 3632 TCGv_ptr r_tickptr;
ccd4a219 3633
255e1fcb 3634 tcg_gen_mov_tl(cpu_hstick_cmpr, cpu_tmp0);
a7812ae4 3635 r_tickptr = tcg_temp_new_ptr();
ccd4a219
BS
3636 tcg_gen_ld_ptr(r_tickptr, cpu_env,
3637 offsetof(CPUState, hstick));
a7812ae4
PB
3638 gen_helper_tick_set_limit(r_tickptr,
3639 cpu_hstick_cmpr);
3640 tcg_temp_free_ptr(r_tickptr);
ccd4a219 3641 }
e9ebed4d
BS
3642 break;
3643 case 6: // hver readonly
3644 default:
3645 goto illegal_insn;
3646 }
3647#endif
e8af50a3
FB
3648 }
3649 break;
3650#endif
3475187d 3651#ifdef TARGET_SPARC64
0f8a249a
BS
3652 case 0x2c: /* V9 movcc */
3653 {
3654 int cc = GET_FIELD_SP(insn, 11, 12);
3655 int cond = GET_FIELD_SP(insn, 14, 17);
748b9d8e 3656 TCGv r_cond;
00f219bf
BS
3657 int l1;
3658
a7812ae4 3659 r_cond = tcg_temp_new();
0f8a249a
BS
3660 if (insn & (1 << 18)) {
3661 if (cc == 0)
8393617c 3662 gen_cond(r_cond, 0, cond, dc);
0f8a249a 3663 else if (cc == 2)
8393617c 3664 gen_cond(r_cond, 1, cond, dc);
0f8a249a
BS
3665 else
3666 goto illegal_insn;
3667 } else {
748b9d8e 3668 gen_fcond(r_cond, cc, cond);
0f8a249a 3669 }
00f219bf
BS
3670
3671 l1 = gen_new_label();
3672
cb63669a 3673 tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
00f219bf 3674 if (IS_IMM) { /* immediate */
2ea815ca
BS
3675 TCGv r_const;
3676
67526b20
BS
3677 simm = GET_FIELD_SPs(insn, 0, 10);
3678 r_const = tcg_const_tl(simm);
2ea815ca
BS
3679 gen_movl_TN_reg(rd, r_const);
3680 tcg_temp_free(r_const);
00f219bf
BS
3681 } else {
3682 rs2 = GET_FIELD_SP(insn, 0, 4);
9c6c6662
BS
3683 gen_movl_reg_TN(rs2, cpu_tmp0);
3684 gen_movl_TN_reg(rd, cpu_tmp0);
00f219bf 3685 }
00f219bf 3686 gen_set_label(l1);
2ea815ca 3687 tcg_temp_free(r_cond);
0f8a249a
BS
3688 break;
3689 }
3690 case 0x2d: /* V9 sdivx */
6ae20372
BS
3691 gen_op_sdivx(cpu_dst, cpu_src1, cpu_src2);
3692 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a
BS
3693 break;
3694 case 0x2e: /* V9 popc */
3695 {
a49d9390 3696 cpu_src2 = get_src2(insn, cpu_src2);
a7812ae4 3697 gen_helper_popc(cpu_dst, cpu_src2);
6ae20372 3698 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a
BS
3699 }
3700 case 0x2f: /* V9 movr */
3701 {
3702 int cond = GET_FIELD_SP(insn, 10, 12);
00f219bf
BS
3703 int l1;
3704
9322a4bf 3705 cpu_src1 = get_src1(insn, cpu_src1);
00f219bf
BS
3706
3707 l1 = gen_new_label();
3708
cb63669a
PB
3709 tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond],
3710 cpu_src1, 0, l1);
0f8a249a 3711 if (IS_IMM) { /* immediate */
2ea815ca
BS
3712 TCGv r_const;
3713
67526b20
BS
3714 simm = GET_FIELD_SPs(insn, 0, 9);
3715 r_const = tcg_const_tl(simm);
2ea815ca
BS
3716 gen_movl_TN_reg(rd, r_const);
3717 tcg_temp_free(r_const);
00f219bf 3718 } else {
0f8a249a 3719 rs2 = GET_FIELD_SP(insn, 0, 4);
9c6c6662
BS
3720 gen_movl_reg_TN(rs2, cpu_tmp0);
3721 gen_movl_TN_reg(rd, cpu_tmp0);
0f8a249a 3722 }
00f219bf 3723 gen_set_label(l1);
0f8a249a
BS
3724 break;
3725 }
3726#endif
3727 default:
3728 goto illegal_insn;
3729 }
3730 }
3299908c
BS
3731 } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
3732#ifdef TARGET_SPARC64
3733 int opf = GET_FIELD_SP(insn, 5, 13);
3734 rs1 = GET_FIELD(insn, 13, 17);
3735 rs2 = GET_FIELD(insn, 27, 31);
6ae20372 3736 if (gen_trap_ifnofpu(dc, cpu_cond))
e9ebed4d 3737 goto jmp_insn;
3299908c
BS
3738
3739 switch (opf) {
e9ebed4d
BS
3740 case 0x000: /* VIS I edge8cc */
3741 case 0x001: /* VIS II edge8n */
3742 case 0x002: /* VIS I edge8lcc */
3743 case 0x003: /* VIS II edge8ln */
3744 case 0x004: /* VIS I edge16cc */
3745 case 0x005: /* VIS II edge16n */
3746 case 0x006: /* VIS I edge16lcc */
3747 case 0x007: /* VIS II edge16ln */
3748 case 0x008: /* VIS I edge32cc */
3749 case 0x009: /* VIS II edge32n */
3750 case 0x00a: /* VIS I edge32lcc */
3751 case 0x00b: /* VIS II edge32ln */
3752 // XXX
3753 goto illegal_insn;
3754 case 0x010: /* VIS I array8 */
64a88d5d 3755 CHECK_FPU_FEATURE(dc, VIS1);
9322a4bf 3756 cpu_src1 = get_src1(insn, cpu_src1);
6ae20372 3757 gen_movl_reg_TN(rs2, cpu_src2);
a7812ae4 3758 gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
6ae20372 3759 gen_movl_TN_reg(rd, cpu_dst);
e9ebed4d
BS
3760 break;
3761 case 0x012: /* VIS I array16 */
64a88d5d 3762 CHECK_FPU_FEATURE(dc, VIS1);
9322a4bf 3763 cpu_src1 = get_src1(insn, cpu_src1);
6ae20372 3764 gen_movl_reg_TN(rs2, cpu_src2);
a7812ae4 3765 gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
6ae20372
BS
3766 tcg_gen_shli_i64(cpu_dst, cpu_dst, 1);
3767 gen_movl_TN_reg(rd, cpu_dst);
e9ebed4d
BS
3768 break;
3769 case 0x014: /* VIS I array32 */
64a88d5d 3770 CHECK_FPU_FEATURE(dc, VIS1);
9322a4bf 3771 cpu_src1 = get_src1(insn, cpu_src1);
6ae20372 3772 gen_movl_reg_TN(rs2, cpu_src2);
a7812ae4 3773 gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
6ae20372
BS
3774 tcg_gen_shli_i64(cpu_dst, cpu_dst, 2);
3775 gen_movl_TN_reg(rd, cpu_dst);
e9ebed4d 3776 break;
3299908c 3777 case 0x018: /* VIS I alignaddr */
64a88d5d 3778 CHECK_FPU_FEATURE(dc, VIS1);
9322a4bf 3779 cpu_src1 = get_src1(insn, cpu_src1);
6ae20372 3780 gen_movl_reg_TN(rs2, cpu_src2);
a7812ae4 3781 gen_helper_alignaddr(cpu_dst, cpu_src1, cpu_src2);
6ae20372 3782 gen_movl_TN_reg(rd, cpu_dst);
3299908c 3783 break;
e9ebed4d 3784 case 0x019: /* VIS II bmask */
3299908c 3785 case 0x01a: /* VIS I alignaddrl */
3299908c 3786 // XXX
e9ebed4d
BS
3787 goto illegal_insn;
3788 case 0x020: /* VIS I fcmple16 */
64a88d5d 3789 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3790 gen_op_load_fpr_DT0(DFPREG(rs1));
3791 gen_op_load_fpr_DT1(DFPREG(rs2));
a7812ae4 3792 gen_helper_fcmple16();
2382dc6b 3793 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3794 break;
3795 case 0x022: /* VIS I fcmpne16 */
64a88d5d 3796 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3797 gen_op_load_fpr_DT0(DFPREG(rs1));
3798 gen_op_load_fpr_DT1(DFPREG(rs2));
a7812ae4 3799 gen_helper_fcmpne16();
2382dc6b 3800 gen_op_store_DT0_fpr(DFPREG(rd));
3299908c 3801 break;
e9ebed4d 3802 case 0x024: /* VIS I fcmple32 */
64a88d5d 3803 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3804 gen_op_load_fpr_DT0(DFPREG(rs1));
3805 gen_op_load_fpr_DT1(DFPREG(rs2));
a7812ae4 3806 gen_helper_fcmple32();
2382dc6b 3807 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3808 break;
3809 case 0x026: /* VIS I fcmpne32 */
64a88d5d 3810 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3811 gen_op_load_fpr_DT0(DFPREG(rs1));
3812 gen_op_load_fpr_DT1(DFPREG(rs2));
a7812ae4 3813 gen_helper_fcmpne32();
2382dc6b 3814 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3815 break;
3816 case 0x028: /* VIS I fcmpgt16 */
64a88d5d 3817 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3818 gen_op_load_fpr_DT0(DFPREG(rs1));
3819 gen_op_load_fpr_DT1(DFPREG(rs2));
a7812ae4 3820 gen_helper_fcmpgt16();
2382dc6b 3821 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3822 break;
3823 case 0x02a: /* VIS I fcmpeq16 */
64a88d5d 3824 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3825 gen_op_load_fpr_DT0(DFPREG(rs1));
3826 gen_op_load_fpr_DT1(DFPREG(rs2));
a7812ae4 3827 gen_helper_fcmpeq16();
2382dc6b 3828 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3829 break;
3830 case 0x02c: /* VIS I fcmpgt32 */
64a88d5d 3831 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3832 gen_op_load_fpr_DT0(DFPREG(rs1));
3833 gen_op_load_fpr_DT1(DFPREG(rs2));
a7812ae4 3834 gen_helper_fcmpgt32();
2382dc6b 3835 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3836 break;
3837 case 0x02e: /* VIS I fcmpeq32 */
64a88d5d 3838 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3839 gen_op_load_fpr_DT0(DFPREG(rs1));
3840 gen_op_load_fpr_DT1(DFPREG(rs2));
a7812ae4 3841 gen_helper_fcmpeq32();
2382dc6b 3842 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3843 break;
3844 case 0x031: /* VIS I fmul8x16 */
64a88d5d 3845 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3846 gen_op_load_fpr_DT0(DFPREG(rs1));
3847 gen_op_load_fpr_DT1(DFPREG(rs2));
a7812ae4 3848 gen_helper_fmul8x16();
2382dc6b 3849 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3850 break;
3851 case 0x033: /* VIS I fmul8x16au */
64a88d5d 3852 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3853 gen_op_load_fpr_DT0(DFPREG(rs1));
3854 gen_op_load_fpr_DT1(DFPREG(rs2));
a7812ae4 3855 gen_helper_fmul8x16au();
2382dc6b 3856 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3857 break;
3858 case 0x035: /* VIS I fmul8x16al */
64a88d5d 3859 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3860 gen_op_load_fpr_DT0(DFPREG(rs1));
3861 gen_op_load_fpr_DT1(DFPREG(rs2));
a7812ae4 3862 gen_helper_fmul8x16al();
2382dc6b 3863 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3864 break;
3865 case 0x036: /* VIS I fmul8sux16 */
64a88d5d 3866 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3867 gen_op_load_fpr_DT0(DFPREG(rs1));
3868 gen_op_load_fpr_DT1(DFPREG(rs2));
a7812ae4 3869 gen_helper_fmul8sux16();
2382dc6b 3870 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3871 break;
3872 case 0x037: /* VIS I fmul8ulx16 */
64a88d5d 3873 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3874 gen_op_load_fpr_DT0(DFPREG(rs1));
3875 gen_op_load_fpr_DT1(DFPREG(rs2));
a7812ae4 3876 gen_helper_fmul8ulx16();
2382dc6b 3877 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3878 break;
3879 case 0x038: /* VIS I fmuld8sux16 */
64a88d5d 3880 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3881 gen_op_load_fpr_DT0(DFPREG(rs1));
3882 gen_op_load_fpr_DT1(DFPREG(rs2));
a7812ae4 3883 gen_helper_fmuld8sux16();
2382dc6b 3884 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3885 break;
3886 case 0x039: /* VIS I fmuld8ulx16 */
64a88d5d 3887 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3888 gen_op_load_fpr_DT0(DFPREG(rs1));
3889 gen_op_load_fpr_DT1(DFPREG(rs2));
a7812ae4 3890 gen_helper_fmuld8ulx16();
2382dc6b 3891 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3892 break;
3893 case 0x03a: /* VIS I fpack32 */
3894 case 0x03b: /* VIS I fpack16 */
3895 case 0x03d: /* VIS I fpackfix */
3896 case 0x03e: /* VIS I pdist */
3897 // XXX
3898 goto illegal_insn;
3299908c 3899 case 0x048: /* VIS I faligndata */
64a88d5d 3900 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3901 gen_op_load_fpr_DT0(DFPREG(rs1));
3902 gen_op_load_fpr_DT1(DFPREG(rs2));
a7812ae4 3903 gen_helper_faligndata();
2382dc6b 3904 gen_op_store_DT0_fpr(DFPREG(rd));
3299908c 3905 break;
e9ebed4d 3906 case 0x04b: /* VIS I fpmerge */
64a88d5d 3907 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3908 gen_op_load_fpr_DT0(DFPREG(rs1));
3909 gen_op_load_fpr_DT1(DFPREG(rs2));
a7812ae4 3910 gen_helper_fpmerge();
2382dc6b 3911 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3912 break;
3913 case 0x04c: /* VIS II bshuffle */
3914 // XXX
3915 goto illegal_insn;
3916 case 0x04d: /* VIS I fexpand */
64a88d5d 3917 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3918 gen_op_load_fpr_DT0(DFPREG(rs1));
3919 gen_op_load_fpr_DT1(DFPREG(rs2));
a7812ae4 3920 gen_helper_fexpand();
2382dc6b 3921 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3922 break;
3923 case 0x050: /* VIS I fpadd16 */
64a88d5d 3924 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3925 gen_op_load_fpr_DT0(DFPREG(rs1));
3926 gen_op_load_fpr_DT1(DFPREG(rs2));
a7812ae4 3927 gen_helper_fpadd16();
2382dc6b 3928 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3929 break;
3930 case 0x051: /* VIS I fpadd16s */
64a88d5d 3931 CHECK_FPU_FEATURE(dc, VIS1);
a7812ae4
PB
3932 gen_helper_fpadd16s(cpu_fpr[rd],
3933 cpu_fpr[rs1], cpu_fpr[rs2]);
e9ebed4d
BS
3934 break;
3935 case 0x052: /* VIS I fpadd32 */
64a88d5d 3936 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3937 gen_op_load_fpr_DT0(DFPREG(rs1));
3938 gen_op_load_fpr_DT1(DFPREG(rs2));
a7812ae4 3939 gen_helper_fpadd32();
2382dc6b 3940 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3941 break;
3942 case 0x053: /* VIS I fpadd32s */
64a88d5d 3943 CHECK_FPU_FEATURE(dc, VIS1);
a7812ae4
PB
3944 gen_helper_fpadd32s(cpu_fpr[rd],
3945 cpu_fpr[rs1], cpu_fpr[rs2]);
e9ebed4d
BS
3946 break;
3947 case 0x054: /* VIS I fpsub16 */
64a88d5d 3948 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3949 gen_op_load_fpr_DT0(DFPREG(rs1));
3950 gen_op_load_fpr_DT1(DFPREG(rs2));
a7812ae4 3951 gen_helper_fpsub16();
2382dc6b 3952 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3953 break;
3954 case 0x055: /* VIS I fpsub16s */
64a88d5d 3955 CHECK_FPU_FEATURE(dc, VIS1);
a7812ae4
PB
3956 gen_helper_fpsub16s(cpu_fpr[rd],
3957 cpu_fpr[rs1], cpu_fpr[rs2]);
e9ebed4d
BS
3958 break;
3959 case 0x056: /* VIS I fpsub32 */
64a88d5d 3960 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3961 gen_op_load_fpr_DT0(DFPREG(rs1));
3962 gen_op_load_fpr_DT1(DFPREG(rs2));
a7812ae4 3963 gen_helper_fpsub32();
2382dc6b 3964 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3965 break;
3966 case 0x057: /* VIS I fpsub32s */
64a88d5d 3967 CHECK_FPU_FEATURE(dc, VIS1);
a7812ae4
PB
3968 gen_helper_fpsub32s(cpu_fpr[rd],
3969 cpu_fpr[rs1], cpu_fpr[rs2]);
e9ebed4d 3970 break;
3299908c 3971 case 0x060: /* VIS I fzero */
64a88d5d 3972 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d
BS
3973 tcg_gen_movi_i32(cpu_fpr[DFPREG(rd)], 0);
3974 tcg_gen_movi_i32(cpu_fpr[DFPREG(rd) + 1], 0);
3299908c
BS
3975 break;
3976 case 0x061: /* VIS I fzeros */
64a88d5d 3977 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d 3978 tcg_gen_movi_i32(cpu_fpr[rd], 0);
3299908c 3979 break;
e9ebed4d 3980 case 0x062: /* VIS I fnor */
64a88d5d 3981 CHECK_FPU_FEATURE(dc, VIS1);
81b5b816
BS
3982 tcg_gen_nor_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1)],
3983 cpu_fpr[DFPREG(rs2)]);
3984 tcg_gen_nor_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1) + 1],
3985 cpu_fpr[DFPREG(rs2) + 1]);
e9ebed4d
BS
3986 break;
3987 case 0x063: /* VIS I fnors */
64a88d5d 3988 CHECK_FPU_FEATURE(dc, VIS1);
81b5b816 3989 tcg_gen_nor_i32(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
e9ebed4d
BS
3990 break;
3991 case 0x064: /* VIS I fandnot2 */
64a88d5d 3992 CHECK_FPU_FEATURE(dc, VIS1);
81b5b816
BS
3993 tcg_gen_andc_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
3994 cpu_fpr[DFPREG(rs2)]);
3995 tcg_gen_andc_i32(cpu_fpr[DFPREG(rd) + 1],
3996 cpu_fpr[DFPREG(rs1) + 1],
3997 cpu_fpr[DFPREG(rs2) + 1]);
e9ebed4d
BS
3998 break;
3999 case 0x065: /* VIS I fandnot2s */
64a88d5d 4000 CHECK_FPU_FEATURE(dc, VIS1);
81b5b816 4001 tcg_gen_andc_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
e9ebed4d
BS
4002 break;
4003 case 0x066: /* VIS I fnot2 */
64a88d5d 4004 CHECK_FPU_FEATURE(dc, VIS1);
2576d836
BS
4005 tcg_gen_not_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)]);
4006 tcg_gen_not_i32(cpu_fpr[DFPREG(rd) + 1],
4007 cpu_fpr[DFPREG(rs2) + 1]);
e9ebed4d
BS
4008 break;
4009 case 0x067: /* VIS I fnot2s */
64a88d5d 4010 CHECK_FPU_FEATURE(dc, VIS1);
2576d836 4011 tcg_gen_not_i32(cpu_fpr[rd], cpu_fpr[rs2]);
e9ebed4d
BS
4012 break;
4013 case 0x068: /* VIS I fandnot1 */
64a88d5d 4014 CHECK_FPU_FEATURE(dc, VIS1);
81b5b816
BS
4015 tcg_gen_andc_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)],
4016 cpu_fpr[DFPREG(rs1)]);
4017 tcg_gen_andc_i32(cpu_fpr[DFPREG(rd) + 1],
4018 cpu_fpr[DFPREG(rs2) + 1],
4019 cpu_fpr[DFPREG(rs1) + 1]);
e9ebed4d
BS
4020 break;
4021 case 0x069: /* VIS I fandnot1s */
64a88d5d 4022 CHECK_FPU_FEATURE(dc, VIS1);
81b5b816 4023 tcg_gen_andc_i32(cpu_fpr[rd], cpu_fpr[rs2], cpu_fpr[rs1]);
e9ebed4d
BS
4024 break;
4025 case 0x06a: /* VIS I fnot1 */
64a88d5d 4026 CHECK_FPU_FEATURE(dc, VIS1);
2576d836
BS
4027 tcg_gen_not_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)]);
4028 tcg_gen_not_i32(cpu_fpr[DFPREG(rd) + 1],
4029 cpu_fpr[DFPREG(rs1) + 1]);
e9ebed4d
BS
4030 break;
4031 case 0x06b: /* VIS I fnot1s */
64a88d5d 4032 CHECK_FPU_FEATURE(dc, VIS1);
2576d836 4033 tcg_gen_not_i32(cpu_fpr[rd], cpu_fpr[rs1]);
e9ebed4d
BS
4034 break;
4035 case 0x06c: /* VIS I fxor */
64a88d5d 4036 CHECK_FPU_FEATURE(dc, VIS1);
e2ea21b3
BS
4037 tcg_gen_xor_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
4038 cpu_fpr[DFPREG(rs2)]);
4039 tcg_gen_xor_i32(cpu_fpr[DFPREG(rd) + 1],
4040 cpu_fpr[DFPREG(rs1) + 1],
4041 cpu_fpr[DFPREG(rs2) + 1]);
e9ebed4d
BS
4042 break;
4043 case 0x06d: /* VIS I fxors */
64a88d5d 4044 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d 4045 tcg_gen_xor_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
e9ebed4d
BS
4046 break;
4047 case 0x06e: /* VIS I fnand */
64a88d5d 4048 CHECK_FPU_FEATURE(dc, VIS1);
81b5b816
BS
4049 tcg_gen_nand_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1)],
4050 cpu_fpr[DFPREG(rs2)]);
4051 tcg_gen_nand_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1) + 1],
4052 cpu_fpr[DFPREG(rs2) + 1]);
e9ebed4d
BS
4053 break;
4054 case 0x06f: /* VIS I fnands */
64a88d5d 4055 CHECK_FPU_FEATURE(dc, VIS1);
81b5b816 4056 tcg_gen_nand_i32(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
e9ebed4d
BS
4057 break;
4058 case 0x070: /* VIS I fand */
64a88d5d 4059 CHECK_FPU_FEATURE(dc, VIS1);
e2ea21b3
BS
4060 tcg_gen_and_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
4061 cpu_fpr[DFPREG(rs2)]);
4062 tcg_gen_and_i32(cpu_fpr[DFPREG(rd) + 1],
4063 cpu_fpr[DFPREG(rs1) + 1],
4064 cpu_fpr[DFPREG(rs2) + 1]);
e9ebed4d
BS
4065 break;
4066 case 0x071: /* VIS I fands */
64a88d5d 4067 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d 4068 tcg_gen_and_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
e9ebed4d
BS
4069 break;
4070 case 0x072: /* VIS I fxnor */
64a88d5d 4071 CHECK_FPU_FEATURE(dc, VIS1);
e2ea21b3
BS
4072 tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs2)], -1);
4073 tcg_gen_xor_i32(cpu_fpr[DFPREG(rd)], cpu_tmp32,
4074 cpu_fpr[DFPREG(rs1)]);
4075 tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs2) + 1], -1);
4076 tcg_gen_xor_i32(cpu_fpr[DFPREG(rd) + 1], cpu_tmp32,
4077 cpu_fpr[DFPREG(rs1) + 1]);
e9ebed4d
BS
4078 break;
4079 case 0x073: /* VIS I fxnors */
64a88d5d 4080 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d
BS
4081 tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[rs2], -1);
4082 tcg_gen_xor_i32(cpu_fpr[rd], cpu_tmp32, cpu_fpr[rs1]);
e9ebed4d 4083 break;
3299908c 4084 case 0x074: /* VIS I fsrc1 */
64a88d5d 4085 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d
BS
4086 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)]);
4087 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1],
4088 cpu_fpr[DFPREG(rs1) + 1]);
3299908c
BS
4089 break;
4090 case 0x075: /* VIS I fsrc1s */
64a88d5d 4091 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d 4092 tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs1]);
3299908c 4093 break;
e9ebed4d 4094 case 0x076: /* VIS I fornot2 */
64a88d5d 4095 CHECK_FPU_FEATURE(dc, VIS1);
81b5b816
BS
4096 tcg_gen_orc_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
4097 cpu_fpr[DFPREG(rs2)]);
4098 tcg_gen_orc_i32(cpu_fpr[DFPREG(rd) + 1],
4099 cpu_fpr[DFPREG(rs1) + 1],
4100 cpu_fpr[DFPREG(rs2) + 1]);
e9ebed4d
BS
4101 break;
4102 case 0x077: /* VIS I fornot2s */
64a88d5d 4103 CHECK_FPU_FEATURE(dc, VIS1);
81b5b816 4104 tcg_gen_orc_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
e9ebed4d 4105 break;
3299908c 4106 case 0x078: /* VIS I fsrc2 */
64a88d5d 4107 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
4108 gen_op_load_fpr_DT0(DFPREG(rs2));
4109 gen_op_store_DT0_fpr(DFPREG(rd));
3299908c
BS
4110 break;
4111 case 0x079: /* VIS I fsrc2s */
64a88d5d 4112 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d 4113 tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);
3299908c 4114 break;
e9ebed4d 4115 case 0x07a: /* VIS I fornot1 */
64a88d5d 4116 CHECK_FPU_FEATURE(dc, VIS1);
81b5b816
BS
4117 tcg_gen_orc_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)],
4118 cpu_fpr[DFPREG(rs1)]);
4119 tcg_gen_orc_i32(cpu_fpr[DFPREG(rd) + 1],
4120 cpu_fpr[DFPREG(rs2) + 1],
4121 cpu_fpr[DFPREG(rs1) + 1]);
e9ebed4d
BS
4122 break;
4123 case 0x07b: /* VIS I fornot1s */
64a88d5d 4124 CHECK_FPU_FEATURE(dc, VIS1);
81b5b816 4125 tcg_gen_orc_i32(cpu_fpr[rd], cpu_fpr[rs2], cpu_fpr[rs1]);
e9ebed4d
BS
4126 break;
4127 case 0x07c: /* VIS I for */
64a88d5d 4128 CHECK_FPU_FEATURE(dc, VIS1);
e2ea21b3
BS
4129 tcg_gen_or_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
4130 cpu_fpr[DFPREG(rs2)]);
4131 tcg_gen_or_i32(cpu_fpr[DFPREG(rd) + 1],
4132 cpu_fpr[DFPREG(rs1) + 1],
4133 cpu_fpr[DFPREG(rs2) + 1]);
e9ebed4d
BS
4134 break;
4135 case 0x07d: /* VIS I fors */
64a88d5d 4136 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d 4137 tcg_gen_or_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
e9ebed4d 4138 break;
3299908c 4139 case 0x07e: /* VIS I fone */
64a88d5d 4140 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d
BS
4141 tcg_gen_movi_i32(cpu_fpr[DFPREG(rd)], -1);
4142 tcg_gen_movi_i32(cpu_fpr[DFPREG(rd) + 1], -1);
3299908c
BS
4143 break;
4144 case 0x07f: /* VIS I fones */
64a88d5d 4145 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d 4146 tcg_gen_movi_i32(cpu_fpr[rd], -1);
3299908c 4147 break;
e9ebed4d
BS
4148 case 0x080: /* VIS I shutdown */
4149 case 0x081: /* VIS II siam */
4150 // XXX
4151 goto illegal_insn;
3299908c
BS
4152 default:
4153 goto illegal_insn;
4154 }
4155#else
0f8a249a 4156 goto ncp_insn;
3299908c
BS
4157#endif
4158 } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
fcc72045 4159#ifdef TARGET_SPARC64
0f8a249a 4160 goto illegal_insn;
fcc72045 4161#else
0f8a249a 4162 goto ncp_insn;
fcc72045 4163#endif
3475187d 4164#ifdef TARGET_SPARC64
0f8a249a 4165 } else if (xop == 0x39) { /* V9 return */
a7812ae4 4166 TCGv_i32 r_const;
2ea815ca 4167
6ae20372 4168 save_state(dc, cpu_cond);
9322a4bf 4169 cpu_src1 = get_src1(insn, cpu_src1);
0f8a249a 4170 if (IS_IMM) { /* immediate */
67526b20
BS
4171 simm = GET_FIELDs(insn, 19, 31);
4172 tcg_gen_addi_tl(cpu_dst, cpu_src1, simm);
0f8a249a 4173 } else { /* register */
3475187d 4174 rs2 = GET_FIELD(insn, 27, 31);
0f8a249a 4175 if (rs2) {
6ae20372
BS
4176 gen_movl_reg_TN(rs2, cpu_src2);
4177 tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
6f551262
BS
4178 } else
4179 tcg_gen_mov_tl(cpu_dst, cpu_src1);
3475187d 4180 }
a7812ae4 4181 gen_helper_restore();
6ae20372 4182 gen_mov_pc_npc(dc, cpu_cond);
2ea815ca 4183 r_const = tcg_const_i32(3);
a7812ae4
PB
4184 gen_helper_check_align(cpu_dst, r_const);
4185 tcg_temp_free_i32(r_const);
6ae20372 4186 tcg_gen_mov_tl(cpu_npc, cpu_dst);
0f8a249a
BS
4187 dc->npc = DYNAMIC_PC;
4188 goto jmp_insn;
3475187d 4189#endif
0f8a249a 4190 } else {
9322a4bf 4191 cpu_src1 = get_src1(insn, cpu_src1);
0f8a249a 4192 if (IS_IMM) { /* immediate */
67526b20
BS
4193 simm = GET_FIELDs(insn, 19, 31);
4194 tcg_gen_addi_tl(cpu_dst, cpu_src1, simm);
0f8a249a 4195 } else { /* register */
e80cfcfc 4196 rs2 = GET_FIELD(insn, 27, 31);
0f8a249a 4197 if (rs2) {
6ae20372
BS
4198 gen_movl_reg_TN(rs2, cpu_src2);
4199 tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
6f551262
BS
4200 } else
4201 tcg_gen_mov_tl(cpu_dst, cpu_src1);
cf495bcf 4202 }
0f8a249a
BS
4203 switch (xop) {
4204 case 0x38: /* jmpl */
4205 {
a7812ae4
PB
4206 TCGv r_pc;
4207 TCGv_i32 r_const;
2ea815ca 4208
a7812ae4
PB
4209 r_pc = tcg_const_tl(dc->pc);
4210 gen_movl_TN_reg(rd, r_pc);
4211 tcg_temp_free(r_pc);
6ae20372 4212 gen_mov_pc_npc(dc, cpu_cond);
2ea815ca 4213 r_const = tcg_const_i32(3);
a7812ae4
PB
4214 gen_helper_check_align(cpu_dst, r_const);
4215 tcg_temp_free_i32(r_const);
6ae20372 4216 tcg_gen_mov_tl(cpu_npc, cpu_dst);
0f8a249a
BS
4217 dc->npc = DYNAMIC_PC;
4218 }
4219 goto jmp_insn;
3475187d 4220#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
0f8a249a
BS
4221 case 0x39: /* rett, V9 return */
4222 {
a7812ae4 4223 TCGv_i32 r_const;
2ea815ca 4224
0f8a249a
BS
4225 if (!supervisor(dc))
4226 goto priv_insn;
6ae20372 4227 gen_mov_pc_npc(dc, cpu_cond);
2ea815ca 4228 r_const = tcg_const_i32(3);
a7812ae4
PB
4229 gen_helper_check_align(cpu_dst, r_const);
4230 tcg_temp_free_i32(r_const);
6ae20372 4231 tcg_gen_mov_tl(cpu_npc, cpu_dst);
0f8a249a 4232 dc->npc = DYNAMIC_PC;
a7812ae4 4233 gen_helper_rett();
0f8a249a
BS
4234 }
4235 goto jmp_insn;
4236#endif
4237 case 0x3b: /* flush */
5578ceab 4238 if (!((dc)->def->features & CPU_FEATURE_FLUSH))
64a88d5d 4239 goto unimp_flush;
dcfd14b3 4240 /* nop */
0f8a249a
BS
4241 break;
4242 case 0x3c: /* save */
6ae20372 4243 save_state(dc, cpu_cond);
a7812ae4 4244 gen_helper_save();
6ae20372 4245 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a
BS
4246 break;
4247 case 0x3d: /* restore */
6ae20372 4248 save_state(dc, cpu_cond);
a7812ae4 4249 gen_helper_restore();
6ae20372 4250 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a 4251 break;
3475187d 4252#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
0f8a249a
BS
4253 case 0x3e: /* V9 done/retry */
4254 {
4255 switch (rd) {
4256 case 0:
4257 if (!supervisor(dc))
4258 goto priv_insn;
4259 dc->npc = DYNAMIC_PC;
4260 dc->pc = DYNAMIC_PC;
a7812ae4 4261 gen_helper_done();
0f8a249a
BS
4262 goto jmp_insn;
4263 case 1:
4264 if (!supervisor(dc))
4265 goto priv_insn;
4266 dc->npc = DYNAMIC_PC;
4267 dc->pc = DYNAMIC_PC;
a7812ae4 4268 gen_helper_retry();
0f8a249a
BS
4269 goto jmp_insn;
4270 default:
4271 goto illegal_insn;
4272 }
4273 }
4274 break;
4275#endif
4276 default:
4277 goto illegal_insn;
4278 }
cf495bcf 4279 }
0f8a249a
BS
4280 break;
4281 }
4282 break;
4283 case 3: /* load/store instructions */
4284 {
4285 unsigned int xop = GET_FIELD(insn, 7, 12);
9322a4bf 4286
cfa90513
BS
4287 /* flush pending conditional evaluations before exposing
4288 cpu state */
4289 if (dc->cc_op != CC_OP_FLAGS) {
4290 dc->cc_op = CC_OP_FLAGS;
4291 gen_helper_compute_psr();
4292 }
9322a4bf 4293 cpu_src1 = get_src1(insn, cpu_src1);
71817e48 4294 if (xop == 0x3c || xop == 0x3e) { // V9 casa/casxa
81ad8ba2 4295 rs2 = GET_FIELD(insn, 27, 31);
6ae20372 4296 gen_movl_reg_TN(rs2, cpu_src2);
71817e48
BS
4297 tcg_gen_mov_tl(cpu_addr, cpu_src1);
4298 } else if (IS_IMM) { /* immediate */
67526b20
BS
4299 simm = GET_FIELDs(insn, 19, 31);
4300 tcg_gen_addi_tl(cpu_addr, cpu_src1, simm);
0f8a249a
BS
4301 } else { /* register */
4302 rs2 = GET_FIELD(insn, 27, 31);
0f8a249a 4303 if (rs2 != 0) {
6ae20372
BS
4304 gen_movl_reg_TN(rs2, cpu_src2);
4305 tcg_gen_add_tl(cpu_addr, cpu_src1, cpu_src2);
6f551262
BS
4306 } else
4307 tcg_gen_mov_tl(cpu_addr, cpu_src1);
0f8a249a 4308 }
2f2ecb83
BS
4309 if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
4310 (xop > 0x17 && xop <= 0x1d ) ||
4311 (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
0f8a249a 4312 switch (xop) {
b89e94af 4313 case 0x0: /* ld, V9 lduw, load unsigned word */
2cade6a3 4314 gen_address_mask(dc, cpu_addr);
6ae20372 4315 tcg_gen_qemu_ld32u(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a 4316 break;
b89e94af 4317 case 0x1: /* ldub, load unsigned byte */
2cade6a3 4318 gen_address_mask(dc, cpu_addr);
6ae20372 4319 tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a 4320 break;
b89e94af 4321 case 0x2: /* lduh, load unsigned halfword */
2cade6a3 4322 gen_address_mask(dc, cpu_addr);
6ae20372 4323 tcg_gen_qemu_ld16u(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a 4324 break;
b89e94af 4325 case 0x3: /* ldd, load double word */
0f8a249a 4326 if (rd & 1)
d4218d99 4327 goto illegal_insn;
1a2fb1c0 4328 else {
a7812ae4 4329 TCGv_i32 r_const;
2ea815ca 4330
c2bc0e38 4331 save_state(dc, cpu_cond);
2ea815ca 4332 r_const = tcg_const_i32(7);
a7812ae4
PB
4333 gen_helper_check_align(cpu_addr, r_const); // XXX remove
4334 tcg_temp_free_i32(r_const);
2cade6a3 4335 gen_address_mask(dc, cpu_addr);
6ae20372 4336 tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
32b6c812
BS
4337 tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
4338 tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffffULL);
4339 gen_movl_TN_reg(rd + 1, cpu_tmp0);
8911f501 4340 tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
6ae20372
BS
4341 tcg_gen_trunc_i64_tl(cpu_val, cpu_tmp64);
4342 tcg_gen_andi_tl(cpu_val, cpu_val, 0xffffffffULL);
1a2fb1c0 4343 }
0f8a249a 4344 break;
b89e94af 4345 case 0x9: /* ldsb, load signed byte */
2cade6a3 4346 gen_address_mask(dc, cpu_addr);
6ae20372 4347 tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a 4348 break;
b89e94af 4349 case 0xa: /* ldsh, load signed halfword */
2cade6a3 4350 gen_address_mask(dc, cpu_addr);
6ae20372 4351 tcg_gen_qemu_ld16s(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a
BS
4352 break;
4353 case 0xd: /* ldstub -- XXX: should be atomically */
2ea815ca
BS
4354 {
4355 TCGv r_const;
4356
2cade6a3 4357 gen_address_mask(dc, cpu_addr);
2ea815ca
BS
4358 tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
4359 r_const = tcg_const_tl(0xff);
4360 tcg_gen_qemu_st8(r_const, cpu_addr, dc->mem_idx);
4361 tcg_temp_free(r_const);
4362 }
0f8a249a 4363 break;
b89e94af 4364 case 0x0f: /* swap, swap register with memory. Also
77f193da 4365 atomically */
64a88d5d 4366 CHECK_IU_FEATURE(dc, SWAP);
6ae20372 4367 gen_movl_reg_TN(rd, cpu_val);
2cade6a3 4368 gen_address_mask(dc, cpu_addr);
527067d8 4369 tcg_gen_qemu_ld32u(cpu_tmp0, cpu_addr, dc->mem_idx);
6ae20372 4370 tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
527067d8 4371 tcg_gen_mov_tl(cpu_val, cpu_tmp0);
0f8a249a 4372 break;
3475187d 4373#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
b89e94af 4374 case 0x10: /* lda, V9 lduwa, load word alternate */
3475187d 4375#ifndef TARGET_SPARC64
0f8a249a
BS
4376 if (IS_IMM)
4377 goto illegal_insn;
4378 if (!supervisor(dc))
4379 goto priv_insn;
6ea4a6c8 4380#endif
c2bc0e38 4381 save_state(dc, cpu_cond);
6ae20372 4382 gen_ld_asi(cpu_val, cpu_addr, insn, 4, 0);
0f8a249a 4383 break;
b89e94af 4384 case 0x11: /* lduba, load unsigned byte alternate */
3475187d 4385#ifndef TARGET_SPARC64
0f8a249a
BS
4386 if (IS_IMM)
4387 goto illegal_insn;
4388 if (!supervisor(dc))
4389 goto priv_insn;
4390#endif
c2bc0e38 4391 save_state(dc, cpu_cond);
6ae20372 4392 gen_ld_asi(cpu_val, cpu_addr, insn, 1, 0);
0f8a249a 4393 break;
b89e94af 4394 case 0x12: /* lduha, load unsigned halfword alternate */
3475187d 4395#ifndef TARGET_SPARC64
0f8a249a
BS
4396 if (IS_IMM)
4397 goto illegal_insn;
4398 if (!supervisor(dc))
4399 goto priv_insn;
3475187d 4400#endif
c2bc0e38 4401 save_state(dc, cpu_cond);
6ae20372 4402 gen_ld_asi(cpu_val, cpu_addr, insn, 2, 0);
0f8a249a 4403 break;
b89e94af 4404 case 0x13: /* ldda, load double word alternate */
3475187d 4405#ifndef TARGET_SPARC64
0f8a249a
BS
4406 if (IS_IMM)
4407 goto illegal_insn;
4408 if (!supervisor(dc))
4409 goto priv_insn;
3475187d 4410#endif
0f8a249a 4411 if (rd & 1)
d4218d99 4412 goto illegal_insn;
c2bc0e38 4413 save_state(dc, cpu_cond);
db166940
BS
4414 gen_ldda_asi(cpu_val, cpu_addr, insn, rd);
4415 goto skip_move;
b89e94af 4416 case 0x19: /* ldsba, load signed byte alternate */
3475187d 4417#ifndef TARGET_SPARC64
0f8a249a
BS
4418 if (IS_IMM)
4419 goto illegal_insn;
4420 if (!supervisor(dc))
4421 goto priv_insn;
4422#endif
c2bc0e38 4423 save_state(dc, cpu_cond);
6ae20372 4424 gen_ld_asi(cpu_val, cpu_addr, insn, 1, 1);
0f8a249a 4425 break;
b89e94af 4426 case 0x1a: /* ldsha, load signed halfword alternate */
3475187d 4427#ifndef TARGET_SPARC64
0f8a249a
BS
4428 if (IS_IMM)
4429 goto illegal_insn;
4430 if (!supervisor(dc))
4431 goto priv_insn;
3475187d 4432#endif
c2bc0e38 4433 save_state(dc, cpu_cond);
6ae20372 4434 gen_ld_asi(cpu_val, cpu_addr, insn, 2, 1);
0f8a249a
BS
4435 break;
4436 case 0x1d: /* ldstuba -- XXX: should be atomically */
3475187d 4437#ifndef TARGET_SPARC64
0f8a249a
BS
4438 if (IS_IMM)
4439 goto illegal_insn;
4440 if (!supervisor(dc))
4441 goto priv_insn;
4442#endif
c2bc0e38 4443 save_state(dc, cpu_cond);
6ae20372 4444 gen_ldstub_asi(cpu_val, cpu_addr, insn);
0f8a249a 4445 break;
b89e94af 4446 case 0x1f: /* swapa, swap reg with alt. memory. Also
77f193da 4447 atomically */
64a88d5d 4448 CHECK_IU_FEATURE(dc, SWAP);
3475187d 4449#ifndef TARGET_SPARC64
0f8a249a
BS
4450 if (IS_IMM)
4451 goto illegal_insn;
4452 if (!supervisor(dc))
4453 goto priv_insn;
6ea4a6c8 4454#endif
c2bc0e38 4455 save_state(dc, cpu_cond);
6ae20372
BS
4456 gen_movl_reg_TN(rd, cpu_val);
4457 gen_swap_asi(cpu_val, cpu_addr, insn);
0f8a249a 4458 break;
3475187d
FB
4459
4460#ifndef TARGET_SPARC64
0f8a249a
BS
4461 case 0x30: /* ldc */
4462 case 0x31: /* ldcsr */
4463 case 0x33: /* lddc */
4464 goto ncp_insn;
3475187d
FB
4465#endif
4466#endif
4467#ifdef TARGET_SPARC64
0f8a249a 4468 case 0x08: /* V9 ldsw */
2cade6a3 4469 gen_address_mask(dc, cpu_addr);
6ae20372 4470 tcg_gen_qemu_ld32s(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a
BS
4471 break;
4472 case 0x0b: /* V9 ldx */
2cade6a3 4473 gen_address_mask(dc, cpu_addr);
6ae20372 4474 tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a
BS
4475 break;
4476 case 0x18: /* V9 ldswa */
c2bc0e38 4477 save_state(dc, cpu_cond);
6ae20372 4478 gen_ld_asi(cpu_val, cpu_addr, insn, 4, 1);
0f8a249a
BS
4479 break;
4480 case 0x1b: /* V9 ldxa */
c2bc0e38 4481 save_state(dc, cpu_cond);
6ae20372 4482 gen_ld_asi(cpu_val, cpu_addr, insn, 8, 0);
0f8a249a
BS
4483 break;
4484 case 0x2d: /* V9 prefetch, no effect */
4485 goto skip_move;
4486 case 0x30: /* V9 ldfa */
8872eb4f
TS
4487 if (gen_trap_ifnofpu(dc, cpu_cond)) {
4488 goto jmp_insn;
4489 }
c2bc0e38 4490 save_state(dc, cpu_cond);
6ae20372 4491 gen_ldf_asi(cpu_addr, insn, 4, rd);
81ad8ba2 4492 goto skip_move;
0f8a249a 4493 case 0x33: /* V9 lddfa */
8872eb4f
TS
4494 if (gen_trap_ifnofpu(dc, cpu_cond)) {
4495 goto jmp_insn;
4496 }
c2bc0e38 4497 save_state(dc, cpu_cond);
6ae20372 4498 gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd));
81ad8ba2 4499 goto skip_move;
0f8a249a
BS
4500 case 0x3d: /* V9 prefetcha, no effect */
4501 goto skip_move;
4502 case 0x32: /* V9 ldqfa */
64a88d5d 4503 CHECK_FPU_FEATURE(dc, FLOAT128);
8872eb4f
TS
4504 if (gen_trap_ifnofpu(dc, cpu_cond)) {
4505 goto jmp_insn;
4506 }
c2bc0e38 4507 save_state(dc, cpu_cond);
6ae20372 4508 gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd));
1f587329 4509 goto skip_move;
0f8a249a
BS
4510#endif
4511 default:
4512 goto illegal_insn;
4513 }
6ae20372 4514 gen_movl_TN_reg(rd, cpu_val);
db166940 4515#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
0f8a249a 4516 skip_move: ;
3475187d 4517#endif
0f8a249a 4518 } else if (xop >= 0x20 && xop < 0x24) {
6ae20372 4519 if (gen_trap_ifnofpu(dc, cpu_cond))
a80dde08 4520 goto jmp_insn;
c2bc0e38 4521 save_state(dc, cpu_cond);
0f8a249a 4522 switch (xop) {
b89e94af 4523 case 0x20: /* ldf, load fpreg */
2cade6a3 4524 gen_address_mask(dc, cpu_addr);
527067d8
BS
4525 tcg_gen_qemu_ld32u(cpu_tmp0, cpu_addr, dc->mem_idx);
4526 tcg_gen_trunc_tl_i32(cpu_fpr[rd], cpu_tmp0);
0f8a249a 4527 break;
3a3b925d
BS
4528 case 0x21: /* ldfsr, V9 ldxfsr */
4529#ifdef TARGET_SPARC64
2cade6a3 4530 gen_address_mask(dc, cpu_addr);
3a3b925d
BS
4531 if (rd == 1) {
4532 tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
a7812ae4 4533 gen_helper_ldxfsr(cpu_tmp64);
fe987e23
IK
4534 } else {
4535 tcg_gen_qemu_ld32u(cpu_tmp0, cpu_addr, dc->mem_idx);
4536 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
4537 gen_helper_ldfsr(cpu_tmp32);
4538 }
3a3b925d
BS
4539#else
4540 {
4541 tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
a7812ae4 4542 gen_helper_ldfsr(cpu_tmp32);
3a3b925d
BS
4543 }
4544#endif
0f8a249a 4545 break;
b89e94af 4546 case 0x22: /* ldqf, load quad fpreg */
2ea815ca 4547 {
a7812ae4 4548 TCGv_i32 r_const;
2ea815ca
BS
4549
4550 CHECK_FPU_FEATURE(dc, FLOAT128);
4551 r_const = tcg_const_i32(dc->mem_idx);
1295001c 4552 gen_address_mask(dc, cpu_addr);
a7812ae4
PB
4553 gen_helper_ldqf(cpu_addr, r_const);
4554 tcg_temp_free_i32(r_const);
2ea815ca
BS
4555 gen_op_store_QT0_fpr(QFPREG(rd));
4556 }
1f587329 4557 break;
b89e94af 4558 case 0x23: /* lddf, load double fpreg */
2ea815ca 4559 {
a7812ae4 4560 TCGv_i32 r_const;
2ea815ca
BS
4561
4562 r_const = tcg_const_i32(dc->mem_idx);
1295001c 4563 gen_address_mask(dc, cpu_addr);
a7812ae4
PB
4564 gen_helper_lddf(cpu_addr, r_const);
4565 tcg_temp_free_i32(r_const);
2ea815ca
BS
4566 gen_op_store_DT0_fpr(DFPREG(rd));
4567 }
0f8a249a
BS
4568 break;
4569 default:
4570 goto illegal_insn;
4571 }
dc1a6971 4572 } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) ||
0f8a249a 4573 xop == 0xe || xop == 0x1e) {
6ae20372 4574 gen_movl_reg_TN(rd, cpu_val);
0f8a249a 4575 switch (xop) {
b89e94af 4576 case 0x4: /* st, store word */
2cade6a3 4577 gen_address_mask(dc, cpu_addr);
6ae20372 4578 tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a 4579 break;
b89e94af 4580 case 0x5: /* stb, store byte */
2cade6a3 4581 gen_address_mask(dc, cpu_addr);
6ae20372 4582 tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a 4583 break;
b89e94af 4584 case 0x6: /* sth, store halfword */
2cade6a3 4585 gen_address_mask(dc, cpu_addr);
6ae20372 4586 tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a 4587 break;
b89e94af 4588 case 0x7: /* std, store double word */
0f8a249a 4589 if (rd & 1)
d4218d99 4590 goto illegal_insn;
1a2fb1c0 4591 else {
a7812ae4 4592 TCGv_i32 r_const;
1a2fb1c0 4593
c2bc0e38 4594 save_state(dc, cpu_cond);
2cade6a3 4595 gen_address_mask(dc, cpu_addr);
2ea815ca 4596 r_const = tcg_const_i32(7);
a7812ae4
PB
4597 gen_helper_check_align(cpu_addr, r_const); // XXX remove
4598 tcg_temp_free_i32(r_const);
a7ec4229 4599 gen_movl_reg_TN(rd + 1, cpu_tmp0);
ab508019 4600 tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, cpu_val);
6ae20372 4601 tcg_gen_qemu_st64(cpu_tmp64, cpu_addr, dc->mem_idx);
7fa76c0b 4602 }
0f8a249a 4603 break;
3475187d 4604#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
b89e94af 4605 case 0x14: /* sta, V9 stwa, store word alternate */
3475187d 4606#ifndef TARGET_SPARC64
0f8a249a
BS
4607 if (IS_IMM)
4608 goto illegal_insn;
4609 if (!supervisor(dc))
4610 goto priv_insn;
6ea4a6c8 4611#endif
c2bc0e38 4612 save_state(dc, cpu_cond);
6ae20372 4613 gen_st_asi(cpu_val, cpu_addr, insn, 4);
9fd1ae3a 4614 dc->npc = DYNAMIC_PC;
d39c0b99 4615 break;
b89e94af 4616 case 0x15: /* stba, store byte alternate */
3475187d 4617#ifndef TARGET_SPARC64
0f8a249a
BS
4618 if (IS_IMM)
4619 goto illegal_insn;
4620 if (!supervisor(dc))
4621 goto priv_insn;
3475187d 4622#endif
c2bc0e38 4623 save_state(dc, cpu_cond);
6ae20372 4624 gen_st_asi(cpu_val, cpu_addr, insn, 1);
9fd1ae3a 4625 dc->npc = DYNAMIC_PC;
d39c0b99 4626 break;
b89e94af 4627 case 0x16: /* stha, store halfword alternate */
3475187d 4628#ifndef TARGET_SPARC64
0f8a249a
BS
4629 if (IS_IMM)
4630 goto illegal_insn;
4631 if (!supervisor(dc))
4632 goto priv_insn;
6ea4a6c8 4633#endif
c2bc0e38 4634 save_state(dc, cpu_cond);
6ae20372 4635 gen_st_asi(cpu_val, cpu_addr, insn, 2);
9fd1ae3a 4636 dc->npc = DYNAMIC_PC;
d39c0b99 4637 break;
b89e94af 4638 case 0x17: /* stda, store double word alternate */
3475187d 4639#ifndef TARGET_SPARC64
0f8a249a
BS
4640 if (IS_IMM)
4641 goto illegal_insn;
4642 if (!supervisor(dc))
4643 goto priv_insn;
3475187d 4644#endif
0f8a249a 4645 if (rd & 1)
d4218d99 4646 goto illegal_insn;
1a2fb1c0 4647 else {
c2bc0e38 4648 save_state(dc, cpu_cond);
6ae20372 4649 gen_stda_asi(cpu_val, cpu_addr, insn, rd);
1a2fb1c0 4650 }
d39c0b99 4651 break;
e80cfcfc 4652#endif
3475187d 4653#ifdef TARGET_SPARC64
0f8a249a 4654 case 0x0e: /* V9 stx */
2cade6a3 4655 gen_address_mask(dc, cpu_addr);
6ae20372 4656 tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a
BS
4657 break;
4658 case 0x1e: /* V9 stxa */
c2bc0e38 4659 save_state(dc, cpu_cond);
6ae20372 4660 gen_st_asi(cpu_val, cpu_addr, insn, 8);
9fd1ae3a 4661 dc->npc = DYNAMIC_PC;
0f8a249a 4662 break;
3475187d 4663#endif
0f8a249a
BS
4664 default:
4665 goto illegal_insn;
4666 }
4667 } else if (xop > 0x23 && xop < 0x28) {
6ae20372 4668 if (gen_trap_ifnofpu(dc, cpu_cond))
a80dde08 4669 goto jmp_insn;
c2bc0e38 4670 save_state(dc, cpu_cond);
0f8a249a 4671 switch (xop) {
b89e94af 4672 case 0x24: /* stf, store fpreg */
2cade6a3 4673 gen_address_mask(dc, cpu_addr);
527067d8
BS
4674 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_fpr[rd]);
4675 tcg_gen_qemu_st32(cpu_tmp0, cpu_addr, dc->mem_idx);
0f8a249a
BS
4676 break;
4677 case 0x25: /* stfsr, V9 stxfsr */
3a3b925d 4678#ifdef TARGET_SPARC64
2cade6a3 4679 gen_address_mask(dc, cpu_addr);
3a3b925d
BS
4680 tcg_gen_ld_i64(cpu_tmp64, cpu_env, offsetof(CPUState, fsr));
4681 if (rd == 1)
4682 tcg_gen_qemu_st64(cpu_tmp64, cpu_addr, dc->mem_idx);
527067d8
BS
4683 else
4684 tcg_gen_qemu_st32(cpu_tmp64, cpu_addr, dc->mem_idx);
3a3b925d
BS
4685#else
4686 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUState, fsr));
6ae20372 4687 tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx);
3a3b925d 4688#endif
0f8a249a 4689 break;
1f587329
BS
4690 case 0x26:
4691#ifdef TARGET_SPARC64
1f587329 4692 /* V9 stqf, store quad fpreg */
2ea815ca 4693 {
a7812ae4 4694 TCGv_i32 r_const;
2ea815ca
BS
4695
4696 CHECK_FPU_FEATURE(dc, FLOAT128);
4697 gen_op_load_fpr_QT0(QFPREG(rd));
4698 r_const = tcg_const_i32(dc->mem_idx);
1295001c 4699 gen_address_mask(dc, cpu_addr);
a7812ae4
PB
4700 gen_helper_stqf(cpu_addr, r_const);
4701 tcg_temp_free_i32(r_const);
2ea815ca 4702 }
1f587329 4703 break;
1f587329
BS
4704#else /* !TARGET_SPARC64 */
4705 /* stdfq, store floating point queue */
4706#if defined(CONFIG_USER_ONLY)
4707 goto illegal_insn;
4708#else
0f8a249a
BS
4709 if (!supervisor(dc))
4710 goto priv_insn;
6ae20372 4711 if (gen_trap_ifnofpu(dc, cpu_cond))
0f8a249a
BS
4712 goto jmp_insn;
4713 goto nfq_insn;
1f587329 4714#endif
0f8a249a 4715#endif
b89e94af 4716 case 0x27: /* stdf, store double fpreg */
2ea815ca 4717 {
a7812ae4 4718 TCGv_i32 r_const;
2ea815ca
BS
4719
4720 gen_op_load_fpr_DT0(DFPREG(rd));
4721 r_const = tcg_const_i32(dc->mem_idx);
1295001c 4722 gen_address_mask(dc, cpu_addr);
a7812ae4
PB
4723 gen_helper_stdf(cpu_addr, r_const);
4724 tcg_temp_free_i32(r_const);
2ea815ca 4725 }
0f8a249a
BS
4726 break;
4727 default:
4728 goto illegal_insn;
4729 }
4730 } else if (xop > 0x33 && xop < 0x3f) {
c2bc0e38 4731 save_state(dc, cpu_cond);
0f8a249a 4732 switch (xop) {
a4d17f19 4733#ifdef TARGET_SPARC64
0f8a249a 4734 case 0x34: /* V9 stfa */
6ae20372 4735 gen_stf_asi(cpu_addr, insn, 4, rd);
0f8a249a 4736 break;
1f587329 4737 case 0x36: /* V9 stqfa */
2ea815ca 4738 {
a7812ae4 4739 TCGv_i32 r_const;
2ea815ca
BS
4740
4741 CHECK_FPU_FEATURE(dc, FLOAT128);
4742 r_const = tcg_const_i32(7);
a7812ae4
PB
4743 gen_helper_check_align(cpu_addr, r_const);
4744 tcg_temp_free_i32(r_const);
2ea815ca
BS
4745 gen_op_load_fpr_QT0(QFPREG(rd));
4746 gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd));
4747 }
1f587329 4748 break;
0f8a249a 4749 case 0x37: /* V9 stdfa */
3391c818 4750 gen_op_load_fpr_DT0(DFPREG(rd));
6ae20372 4751 gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
0f8a249a
BS
4752 break;
4753 case 0x3c: /* V9 casa */
71817e48 4754 gen_cas_asi(cpu_val, cpu_addr, cpu_src2, insn, rd);
6ae20372 4755 gen_movl_TN_reg(rd, cpu_val);
0f8a249a
BS
4756 break;
4757 case 0x3e: /* V9 casxa */
71817e48 4758 gen_casx_asi(cpu_val, cpu_addr, cpu_src2, insn, rd);
6ae20372 4759 gen_movl_TN_reg(rd, cpu_val);
0f8a249a 4760 break;
a4d17f19 4761#else
0f8a249a
BS
4762 case 0x34: /* stc */
4763 case 0x35: /* stcsr */
4764 case 0x36: /* stdcq */
4765 case 0x37: /* stdc */
4766 goto ncp_insn;
4767#endif
4768 default:
4769 goto illegal_insn;
4770 }
dc1a6971 4771 } else
0f8a249a
BS
4772 goto illegal_insn;
4773 }
4774 break;
cf495bcf
FB
4775 }
4776 /* default case for non jump instructions */
72cbca10 4777 if (dc->npc == DYNAMIC_PC) {
0f8a249a
BS
4778 dc->pc = DYNAMIC_PC;
4779 gen_op_next_insn();
72cbca10
FB
4780 } else if (dc->npc == JUMP_PC) {
4781 /* we can do a static jump */
6ae20372 4782 gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
72cbca10
FB
4783 dc->is_br = 1;
4784 } else {
0f8a249a
BS
4785 dc->pc = dc->npc;
4786 dc->npc = dc->npc + 4;
cf495bcf 4787 }
e80cfcfc 4788 jmp_insn:
42a8aa83 4789 goto egress;
cf495bcf 4790 illegal_insn:
2ea815ca 4791 {
a7812ae4 4792 TCGv_i32 r_const;
2ea815ca
BS
4793
4794 save_state(dc, cpu_cond);
4795 r_const = tcg_const_i32(TT_ILL_INSN);
a7812ae4
PB
4796 gen_helper_raise_exception(r_const);
4797 tcg_temp_free_i32(r_const);
2ea815ca
BS
4798 dc->is_br = 1;
4799 }
42a8aa83 4800 goto egress;
64a88d5d 4801 unimp_flush:
2ea815ca 4802 {
a7812ae4 4803 TCGv_i32 r_const;
2ea815ca
BS
4804
4805 save_state(dc, cpu_cond);
4806 r_const = tcg_const_i32(TT_UNIMP_FLUSH);
a7812ae4
PB
4807 gen_helper_raise_exception(r_const);
4808 tcg_temp_free_i32(r_const);
2ea815ca
BS
4809 dc->is_br = 1;
4810 }
42a8aa83 4811 goto egress;
e80cfcfc 4812#if !defined(CONFIG_USER_ONLY)
e8af50a3 4813 priv_insn:
2ea815ca 4814 {
a7812ae4 4815 TCGv_i32 r_const;
2ea815ca
BS
4816
4817 save_state(dc, cpu_cond);
4818 r_const = tcg_const_i32(TT_PRIV_INSN);
a7812ae4
PB
4819 gen_helper_raise_exception(r_const);
4820 tcg_temp_free_i32(r_const);
2ea815ca
BS
4821 dc->is_br = 1;
4822 }
42a8aa83 4823 goto egress;
64a88d5d 4824#endif
e80cfcfc 4825 nfpu_insn:
6ae20372 4826 save_state(dc, cpu_cond);
e80cfcfc
FB
4827 gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
4828 dc->is_br = 1;
42a8aa83 4829 goto egress;
64a88d5d 4830#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
9143e598 4831 nfq_insn:
6ae20372 4832 save_state(dc, cpu_cond);
9143e598
BS
4833 gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
4834 dc->is_br = 1;
42a8aa83 4835 goto egress;
9143e598 4836#endif
fcc72045
BS
4837#ifndef TARGET_SPARC64
4838 ncp_insn:
2ea815ca
BS
4839 {
4840 TCGv r_const;
4841
4842 save_state(dc, cpu_cond);
4843 r_const = tcg_const_i32(TT_NCP_INSN);
a7812ae4 4844 gen_helper_raise_exception(r_const);
2ea815ca
BS
4845 tcg_temp_free(r_const);
4846 dc->is_br = 1;
4847 }
42a8aa83 4848 goto egress;
fcc72045 4849#endif
42a8aa83
RH
4850 egress:
4851 tcg_temp_free(cpu_tmp1);
4852 tcg_temp_free(cpu_tmp2);
7a3f1944
FB
4853}
4854
2cfc5f17
TS
4855static inline void gen_intermediate_code_internal(TranslationBlock * tb,
4856 int spc, CPUSPARCState *env)
7a3f1944 4857{
72cbca10 4858 target_ulong pc_start, last_pc;
cf495bcf
FB
4859 uint16_t *gen_opc_end;
4860 DisasContext dc1, *dc = &dc1;
a1d1bb31 4861 CPUBreakpoint *bp;
e8af50a3 4862 int j, lj = -1;
2e70f6ef
PB
4863 int num_insns;
4864 int max_insns;
cf495bcf
FB
4865
4866 memset(dc, 0, sizeof(DisasContext));
cf495bcf 4867 dc->tb = tb;
72cbca10 4868 pc_start = tb->pc;
cf495bcf 4869 dc->pc = pc_start;
e80cfcfc 4870 last_pc = dc->pc;
72cbca10 4871 dc->npc = (target_ulong) tb->cs_base;
8393617c 4872 dc->cc_op = CC_OP_DYNAMIC;
6f27aba6 4873 dc->mem_idx = cpu_mmu_index(env);
5578ceab
BS
4874 dc->def = env->def;
4875 if ((dc->def->features & CPU_FEATURE_FLOAT))
64a88d5d 4876 dc->fpu_enabled = cpu_fpu_enabled(env);
5578ceab 4877 else
64a88d5d 4878 dc->fpu_enabled = 0;
2cade6a3
BS
4879#ifdef TARGET_SPARC64
4880 dc->address_mask_32bit = env->pstate & PS_AM;
4881#endif
060718c1 4882 dc->singlestep = (env->singlestep_enabled || singlestep);
cf495bcf 4883 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
cf495bcf 4884
a7812ae4
PB
4885 cpu_tmp0 = tcg_temp_new();
4886 cpu_tmp32 = tcg_temp_new_i32();
4887 cpu_tmp64 = tcg_temp_new_i64();
d987963a 4888
a7812ae4 4889 cpu_dst = tcg_temp_local_new();
d987963a
BS
4890
4891 // loads and stores
a7812ae4
PB
4892 cpu_val = tcg_temp_local_new();
4893 cpu_addr = tcg_temp_local_new();
1a2fb1c0 4894
2e70f6ef
PB
4895 num_insns = 0;
4896 max_insns = tb->cflags & CF_COUNT_MASK;
4897 if (max_insns == 0)
4898 max_insns = CF_COUNT_MASK;
4899 gen_icount_start();
cf495bcf 4900 do {
72cf2d4f
BS
4901 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
4902 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
a1d1bb31 4903 if (bp->pc == dc->pc) {
0f8a249a 4904 if (dc->pc != pc_start)
6ae20372 4905 save_state(dc, cpu_cond);
a7812ae4 4906 gen_helper_debug();
57fec1fe 4907 tcg_gen_exit_tb(0);
0f8a249a 4908 dc->is_br = 1;
e80cfcfc 4909 goto exit_gen_loop;
e8af50a3
FB
4910 }
4911 }
4912 }
4913 if (spc) {
93fcfe39 4914 qemu_log("Search PC...\n");
e8af50a3
FB
4915 j = gen_opc_ptr - gen_opc_buf;
4916 if (lj < j) {
4917 lj++;
4918 while (lj < j)
4919 gen_opc_instr_start[lj++] = 0;
4920 gen_opc_pc[lj] = dc->pc;
4921 gen_opc_npc[lj] = dc->npc;
4922 gen_opc_instr_start[lj] = 1;
2e70f6ef 4923 gen_opc_icount[lj] = num_insns;
e8af50a3
FB
4924 }
4925 }
2e70f6ef
PB
4926 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
4927 gen_io_start();
0f8a249a
BS
4928 last_pc = dc->pc;
4929 disas_sparc_insn(dc);
2e70f6ef 4930 num_insns++;
0f8a249a
BS
4931
4932 if (dc->is_br)
4933 break;
4934 /* if the next PC is different, we abort now */
4935 if (dc->pc != (last_pc + 4))
4936 break;
d39c0b99
FB
4937 /* if we reach a page boundary, we stop generation so that the
4938 PC of a TT_TFAULT exception is always in the right page */
4939 if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
4940 break;
e80cfcfc
FB
4941 /* if single step mode, we generate only one instruction and
4942 generate an exception */
060718c1 4943 if (dc->singlestep) {
e80cfcfc
FB
4944 break;
4945 }
cf495bcf 4946 } while ((gen_opc_ptr < gen_opc_end) &&
2e70f6ef
PB
4947 (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32) &&
4948 num_insns < max_insns);
e80cfcfc
FB
4949
4950 exit_gen_loop:
d987963a 4951 tcg_temp_free(cpu_addr);
3f0436fe 4952 tcg_temp_free(cpu_val);
d987963a 4953 tcg_temp_free(cpu_dst);
a7812ae4
PB
4954 tcg_temp_free_i64(cpu_tmp64);
4955 tcg_temp_free_i32(cpu_tmp32);
2ea815ca 4956 tcg_temp_free(cpu_tmp0);
2e70f6ef
PB
4957 if (tb->cflags & CF_LAST_IO)
4958 gen_io_end();
72cbca10 4959 if (!dc->is_br) {
5fafdf24 4960 if (dc->pc != DYNAMIC_PC &&
72cbca10
FB
4961 (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
4962 /* static PC and NPC: we can use direct chaining */
2f5680ee 4963 gen_goto_tb(dc, 0, dc->pc, dc->npc);
72cbca10
FB
4964 } else {
4965 if (dc->pc != DYNAMIC_PC)
2f5680ee 4966 tcg_gen_movi_tl(cpu_pc, dc->pc);
6ae20372 4967 save_npc(dc, cpu_cond);
57fec1fe 4968 tcg_gen_exit_tb(0);
72cbca10
FB
4969 }
4970 }
2e70f6ef 4971 gen_icount_end(tb, num_insns);
cf495bcf 4972 *gen_opc_ptr = INDEX_op_end;
e8af50a3
FB
4973 if (spc) {
4974 j = gen_opc_ptr - gen_opc_buf;
4975 lj++;
4976 while (lj <= j)
4977 gen_opc_instr_start[lj++] = 0;
e8af50a3 4978#if 0
93fcfe39 4979 log_page_dump();
e8af50a3 4980#endif
c3278b7b
FB
4981 gen_opc_jump_pc[0] = dc->jump_pc[0];
4982 gen_opc_jump_pc[1] = dc->jump_pc[1];
e8af50a3 4983 } else {
e80cfcfc 4984 tb->size = last_pc + 4 - pc_start;
2e70f6ef 4985 tb->icount = num_insns;
e8af50a3 4986 }
7a3f1944 4987#ifdef DEBUG_DISAS
8fec2b8c 4988 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
93fcfe39
AL
4989 qemu_log("--------------\n");
4990 qemu_log("IN: %s\n", lookup_symbol(pc_start));
4991 log_target_disas(pc_start, last_pc + 4 - pc_start, 0);
4992 qemu_log("\n");
cf495bcf 4993 }
7a3f1944 4994#endif
7a3f1944
FB
4995}
4996
2cfc5f17 4997void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
7a3f1944 4998{
2cfc5f17 4999 gen_intermediate_code_internal(tb, 0, env);
7a3f1944
FB
5000}
5001
2cfc5f17 5002void gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
7a3f1944 5003{
2cfc5f17 5004 gen_intermediate_code_internal(tb, 1, env);
7a3f1944
FB
5005}
5006
c48fcb47 5007void gen_intermediate_code_init(CPUSPARCState *env)
e80cfcfc 5008{
f5069b26 5009 unsigned int i;
c48fcb47 5010 static int inited;
f5069b26
BS
5011 static const char * const gregnames[8] = {
5012 NULL, // g0 not used
5013 "g1",
5014 "g2",
5015 "g3",
5016 "g4",
5017 "g5",
5018 "g6",
5019 "g7",
5020 };
714547bb
BS
5021 static const char * const fregnames[64] = {
5022 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
5023 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
5024 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
5025 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
5026 "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
5027 "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
5028 "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
5029 "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
5030 };
aaed909a 5031
1a2fb1c0
BS
5032 /* init various static tables */
5033 if (!inited) {
5034 inited = 1;
5035
a7812ae4
PB
5036 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
5037 cpu_regwptr = tcg_global_mem_new_ptr(TCG_AREG0,
5038 offsetof(CPUState, regwptr),
5039 "regwptr");
1a2fb1c0 5040#ifdef TARGET_SPARC64
a7812ae4
PB
5041 cpu_xcc = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, xcc),
5042 "xcc");
5043 cpu_asi = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, asi),
5044 "asi");
5045 cpu_fprs = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, fprs),
5046 "fprs");
5047 cpu_gsr = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, gsr),
255e1fcb 5048 "gsr");
a7812ae4 5049 cpu_tick_cmpr = tcg_global_mem_new(TCG_AREG0,
255e1fcb
BS
5050 offsetof(CPUState, tick_cmpr),
5051 "tick_cmpr");
a7812ae4 5052 cpu_stick_cmpr = tcg_global_mem_new(TCG_AREG0,
255e1fcb
BS
5053 offsetof(CPUState, stick_cmpr),
5054 "stick_cmpr");
a7812ae4 5055 cpu_hstick_cmpr = tcg_global_mem_new(TCG_AREG0,
255e1fcb
BS
5056 offsetof(CPUState, hstick_cmpr),
5057 "hstick_cmpr");
a7812ae4 5058 cpu_hintp = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, hintp),
255e1fcb 5059 "hintp");
a7812ae4
PB
5060 cpu_htba = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, htba),
5061 "htba");
5062 cpu_hver = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, hver),
5063 "hver");
5064 cpu_ssr = tcg_global_mem_new(TCG_AREG0,
255e1fcb 5065 offsetof(CPUState, ssr), "ssr");
a7812ae4 5066 cpu_ver = tcg_global_mem_new(TCG_AREG0,
255e1fcb 5067 offsetof(CPUState, version), "ver");
a7812ae4
PB
5068 cpu_softint = tcg_global_mem_new_i32(TCG_AREG0,
5069 offsetof(CPUState, softint),
5070 "softint");
255e1fcb 5071#else
a7812ae4 5072 cpu_wim = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, wim),
255e1fcb 5073 "wim");
1a2fb1c0 5074#endif
a7812ae4 5075 cpu_cond = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cond),
77f193da 5076 "cond");
a7812ae4 5077 cpu_cc_src = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_src),
dc99a3f2 5078 "cc_src");
a7812ae4 5079 cpu_cc_src2 = tcg_global_mem_new(TCG_AREG0,
d9bdab86
BS
5080 offsetof(CPUState, cc_src2),
5081 "cc_src2");
a7812ae4 5082 cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_dst),
dc99a3f2 5083 "cc_dst");
8393617c
BS
5084 cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, cc_op),
5085 "cc_op");
a7812ae4
PB
5086 cpu_psr = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, psr),
5087 "psr");
5088 cpu_fsr = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, fsr),
87e92502 5089 "fsr");
a7812ae4 5090 cpu_pc = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, pc),
48d5c82b 5091 "pc");
a7812ae4
PB
5092 cpu_npc = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, npc),
5093 "npc");
5094 cpu_y = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, y), "y");
255e1fcb 5095#ifndef CONFIG_USER_ONLY
a7812ae4 5096 cpu_tbr = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, tbr),
255e1fcb
BS
5097 "tbr");
5098#endif
f5069b26 5099 for (i = 1; i < 8; i++)
a7812ae4 5100 cpu_gregs[i] = tcg_global_mem_new(TCG_AREG0,
f5069b26
BS
5101 offsetof(CPUState, gregs[i]),
5102 gregnames[i]);
714547bb 5103 for (i = 0; i < TARGET_FPREGS; i++)
a7812ae4
PB
5104 cpu_fpr[i] = tcg_global_mem_new_i32(TCG_AREG0,
5105 offsetof(CPUState, fpr[i]),
5106 fregnames[i]);
714547bb 5107
c9e03d8f
BS
5108 /* register helpers */
5109
a7812ae4 5110#define GEN_HELPER 2
c9e03d8f 5111#include "helper.h"
1a2fb1c0 5112 }
658138bc 5113}
d2856f1a 5114
e87b7cb0 5115void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
d2856f1a
AJ
5116{
5117 target_ulong npc;
5118 env->pc = gen_opc_pc[pc_pos];
5119 npc = gen_opc_npc[pc_pos];
5120 if (npc == 1) {
5121 /* dynamic NPC: already stored */
5122 } else if (npc == 2) {
d7da2a10
BS
5123 /* jump PC: use 'cond' and the jump targets of the translation */
5124 if (env->cond) {
d2856f1a 5125 env->npc = gen_opc_jump_pc[0];
d7da2a10 5126 } else {
d2856f1a 5127 env->npc = gen_opc_jump_pc[1];
d7da2a10 5128 }
d2856f1a
AJ
5129 } else {
5130 env->npc = npc;
5131 }
14ed7adc
IK
5132
5133 /* flush pending conditional evaluations before exposing cpu state */
5134 if (CC_OP != CC_OP_FLAGS) {
5135 helper_compute_psr();
5136 }
d2856f1a 5137}