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