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