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