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