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