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