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