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