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