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