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