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