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