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