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