]> git.proxmox.com Git - qemu.git/blame - target-sparc/translate.c
fixing keymap for Windows keys (Stefano Stabellini)
[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{
ab508019 1718 TCGv r_asi, r_size;
a7ec4229
BS
1719
1720 gen_movl_reg_TN(rd + 1, cpu_tmp0);
ab508019 1721 tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, hi);
4af984a7 1722 r_asi = gen_get_asi(insn, addr);
2ea815ca
BS
1723 r_size = tcg_const_i32(8);
1724 tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi, r_size);
1725 tcg_temp_free(r_size);
1726 tcg_temp_free(r_asi);
1a2fb1c0
BS
1727}
1728
77f193da
BS
1729static inline void gen_cas_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
1730 int rd)
1a2fb1c0 1731{
1a2fb1c0
BS
1732 TCGv r_val1, r_asi;
1733
ef28fd86 1734 r_val1 = tcg_temp_new(TCG_TYPE_TL);
1a2fb1c0 1735 gen_movl_reg_TN(rd, r_val1);
4af984a7
BS
1736 r_asi = gen_get_asi(insn, addr);
1737 tcg_gen_helper_1_4(helper_cas_asi, dst, addr, r_val1, val2, r_asi);
2ea815ca
BS
1738 tcg_temp_free(r_asi);
1739 tcg_temp_free(r_val1);
1a2fb1c0
BS
1740}
1741
77f193da
BS
1742static inline void gen_casx_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
1743 int rd)
1a2fb1c0 1744{
8911f501 1745 TCGv r_asi;
1a2fb1c0 1746
8911f501 1747 gen_movl_reg_TN(rd, cpu_tmp64);
4af984a7
BS
1748 r_asi = gen_get_asi(insn, addr);
1749 tcg_gen_helper_1_4(helper_casx_asi, dst, addr, cpu_tmp64, val2, r_asi);
2ea815ca 1750 tcg_temp_free(r_asi);
1a2fb1c0
BS
1751}
1752
1753#elif !defined(CONFIG_USER_ONLY)
1754
77f193da
BS
1755static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
1756 int sign)
1a2fb1c0 1757{
2ea815ca 1758 TCGv r_asi, r_size, r_sign;
1a2fb1c0 1759
2ea815ca
BS
1760 r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1761 r_size = tcg_const_i32(size);
1762 r_sign = tcg_const_i32(sign);
1763 tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
1764 tcg_temp_free(r_sign);
1765 tcg_temp_free(r_size);
1766 tcg_temp_free(r_asi);
4af984a7 1767 tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1a2fb1c0
BS
1768}
1769
4af984a7 1770static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1a2fb1c0 1771{
2ea815ca 1772 TCGv r_asi, r_size;
1a2fb1c0 1773
4af984a7 1774 tcg_gen_extu_tl_i64(cpu_tmp64, src);
2ea815ca
BS
1775 r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1776 r_size = tcg_const_i32(size);
1777 tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi, r_size);
1778 tcg_temp_free(r_size);
1779 tcg_temp_free(r_asi);
1a2fb1c0
BS
1780}
1781
4af984a7 1782static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1a2fb1c0 1783{
2ea815ca 1784 TCGv r_asi, r_size, r_sign;
1a2fb1c0 1785
2ea815ca
BS
1786 r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1787 r_size = tcg_const_i32(4);
1788 r_sign = tcg_const_i32(0);
1789 tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
1790 tcg_temp_free(r_sign);
1791 tcg_gen_helper_0_4(helper_st_asi, addr, dst, r_asi, r_size);
1792 tcg_temp_free(r_size);
1793 tcg_temp_free(r_asi);
8d96d209 1794 tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1a2fb1c0
BS
1795}
1796
db166940 1797static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
1a2fb1c0 1798{
2ea815ca 1799 TCGv r_asi, r_size, r_sign;
1a2fb1c0 1800
2ea815ca
BS
1801 r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1802 r_size = tcg_const_i32(8);
1803 r_sign = tcg_const_i32(0);
1804 tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
1805 tcg_temp_free(r_sign);
1806 tcg_temp_free(r_size);
1807 tcg_temp_free(r_asi);
db166940
BS
1808 tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
1809 gen_movl_TN_reg(rd + 1, cpu_tmp0);
8911f501 1810 tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
4af984a7 1811 tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
db166940 1812 gen_movl_TN_reg(rd, hi);
0425bee5
BS
1813}
1814
4af984a7 1815static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
0425bee5 1816{
ab508019 1817 TCGv r_asi, r_size;
a7ec4229
BS
1818
1819 gen_movl_reg_TN(rd + 1, cpu_tmp0);
ab508019 1820 tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, hi);
2ea815ca
BS
1821 r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1822 r_size = tcg_const_i32(8);
1823 tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi, r_size);
1824 tcg_temp_free(r_size);
1825 tcg_temp_free(r_asi);
1a2fb1c0
BS
1826}
1827#endif
1828
1829#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4af984a7 1830static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
1a2fb1c0 1831{
2ea815ca 1832 TCGv r_val, r_asi, r_size;
1a2fb1c0 1833
4af984a7 1834 gen_ld_asi(dst, addr, insn, 1, 0);
1a2fb1c0 1835
2ea815ca
BS
1836 r_val = tcg_const_i64(0xffULL);
1837 r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
1838 r_size = tcg_const_i32(1);
1839 tcg_gen_helper_0_4(helper_st_asi, addr, r_val, r_asi, r_size);
1840 tcg_temp_free(r_size);
1841 tcg_temp_free(r_asi);
1842 tcg_temp_free(r_val);
1a2fb1c0
BS
1843}
1844#endif
1845
9322a4bf
BS
1846static inline TCGv get_src1(unsigned int insn, TCGv def)
1847{
1848 TCGv r_rs1 = def;
1849 unsigned int rs1;
1850
1851 rs1 = GET_FIELD(insn, 13, 17);
1852 if (rs1 == 0)
5c6a0628 1853 r_rs1 = tcg_const_tl(0); // XXX how to free?
9322a4bf 1854 else if (rs1 < 8)
5c6a0628 1855 r_rs1 = cpu_gregs[rs1];
9322a4bf
BS
1856 else
1857 tcg_gen_ld_tl(def, cpu_regwptr, (rs1 - 8) * sizeof(target_ulong));
1858 return r_rs1;
1859}
1860
a49d9390
BS
1861static inline TCGv get_src2(unsigned int insn, TCGv def)
1862{
1863 TCGv r_rs2 = def;
1864 unsigned int rs2;
1865
1866 if (IS_IMM) { /* immediate */
1867 rs2 = GET_FIELDs(insn, 19, 31);
2ea815ca 1868 r_rs2 = tcg_const_tl((int)rs2); // XXX how to free?
a49d9390
BS
1869 } else { /* register */
1870 rs2 = GET_FIELD(insn, 27, 31);
1871 if (rs2 == 0)
2ea815ca 1872 r_rs2 = tcg_const_tl(0); // XXX how to free?
a49d9390
BS
1873 else if (rs2 < 8)
1874 r_rs2 = cpu_gregs[rs2];
1875 else
1876 tcg_gen_ld_tl(def, cpu_regwptr, (rs2 - 8) * sizeof(target_ulong));
1877 }
1878 return r_rs2;
1879}
1880
64a88d5d 1881#define CHECK_IU_FEATURE(dc, FEATURE) \
5578ceab 1882 if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
64a88d5d
BS
1883 goto illegal_insn;
1884#define CHECK_FPU_FEATURE(dc, FEATURE) \
5578ceab 1885 if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
64a88d5d
BS
1886 goto nfpu_insn;
1887
0bee699e 1888/* before an instruction, dc->pc must be static */
cf495bcf
FB
1889static void disas_sparc_insn(DisasContext * dc)
1890{
1891 unsigned int insn, opc, rs1, rs2, rd;
7a3f1944 1892
a8c768c0
BS
1893 if (unlikely(loglevel & CPU_LOG_TB_OP))
1894 tcg_gen_debug_insn_start(dc->pc);
0fa85d43 1895 insn = ldl_code(dc->pc);
cf495bcf 1896 opc = GET_FIELD(insn, 0, 1);
7a3f1944 1897
cf495bcf 1898 rd = GET_FIELD(insn, 2, 6);
6ae20372 1899
5c6a0628
BS
1900 cpu_src1 = tcg_temp_new(TCG_TYPE_TL); // const
1901 cpu_src2 = tcg_temp_new(TCG_TYPE_TL); // const
6ae20372 1902
cf495bcf 1903 switch (opc) {
0f8a249a
BS
1904 case 0: /* branches/sethi */
1905 {
1906 unsigned int xop = GET_FIELD(insn, 7, 9);
1907 int32_t target;
1908 switch (xop) {
3475187d 1909#ifdef TARGET_SPARC64
0f8a249a
BS
1910 case 0x1: /* V9 BPcc */
1911 {
1912 int cc;
1913
1914 target = GET_FIELD_SP(insn, 0, 18);
1915 target = sign_extend(target, 18);
1916 target <<= 2;
1917 cc = GET_FIELD_SP(insn, 20, 21);
1918 if (cc == 0)
6ae20372 1919 do_branch(dc, target, insn, 0, cpu_cond);
0f8a249a 1920 else if (cc == 2)
6ae20372 1921 do_branch(dc, target, insn, 1, cpu_cond);
0f8a249a
BS
1922 else
1923 goto illegal_insn;
1924 goto jmp_insn;
1925 }
1926 case 0x3: /* V9 BPr */
1927 {
1928 target = GET_FIELD_SP(insn, 0, 13) |
13846e70 1929 (GET_FIELD_SP(insn, 20, 21) << 14);
0f8a249a
BS
1930 target = sign_extend(target, 16);
1931 target <<= 2;
9322a4bf 1932 cpu_src1 = get_src1(insn, cpu_src1);
6ae20372 1933 do_branch_reg(dc, target, insn, cpu_cond, cpu_src1);
0f8a249a
BS
1934 goto jmp_insn;
1935 }
1936 case 0x5: /* V9 FBPcc */
1937 {
1938 int cc = GET_FIELD_SP(insn, 20, 21);
6ae20372 1939 if (gen_trap_ifnofpu(dc, cpu_cond))
a80dde08 1940 goto jmp_insn;
0f8a249a
BS
1941 target = GET_FIELD_SP(insn, 0, 18);
1942 target = sign_extend(target, 19);
1943 target <<= 2;
6ae20372 1944 do_fbranch(dc, target, insn, cc, cpu_cond);
0f8a249a
BS
1945 goto jmp_insn;
1946 }
a4d17f19 1947#else
0f8a249a
BS
1948 case 0x7: /* CBN+x */
1949 {
1950 goto ncp_insn;
1951 }
1952#endif
1953 case 0x2: /* BN+x */
1954 {
1955 target = GET_FIELD(insn, 10, 31);
1956 target = sign_extend(target, 22);
1957 target <<= 2;
6ae20372 1958 do_branch(dc, target, insn, 0, cpu_cond);
0f8a249a
BS
1959 goto jmp_insn;
1960 }
1961 case 0x6: /* FBN+x */
1962 {
6ae20372 1963 if (gen_trap_ifnofpu(dc, cpu_cond))
a80dde08 1964 goto jmp_insn;
0f8a249a
BS
1965 target = GET_FIELD(insn, 10, 31);
1966 target = sign_extend(target, 22);
1967 target <<= 2;
6ae20372 1968 do_fbranch(dc, target, insn, 0, cpu_cond);
0f8a249a
BS
1969 goto jmp_insn;
1970 }
1971 case 0x4: /* SETHI */
0f8a249a 1972 if (rd) { // nop
0f8a249a 1973 uint32_t value = GET_FIELD(insn, 10, 31);
2ea815ca
BS
1974 TCGv r_const;
1975
1976 r_const = tcg_const_tl(value << 10);
1977 gen_movl_TN_reg(rd, r_const);
1978 tcg_temp_free(r_const);
0f8a249a 1979 }
0f8a249a
BS
1980 break;
1981 case 0x0: /* UNIMPL */
1982 default:
3475187d 1983 goto illegal_insn;
0f8a249a
BS
1984 }
1985 break;
1986 }
1987 break;
cf495bcf 1988 case 1:
0f8a249a
BS
1989 /*CALL*/ {
1990 target_long target = GET_FIELDs(insn, 2, 31) << 2;
2ea815ca 1991 TCGv r_const;
cf495bcf 1992
2ea815ca
BS
1993 r_const = tcg_const_tl(dc->pc);
1994 gen_movl_TN_reg(15, r_const);
1995 tcg_temp_free(r_const);
0f8a249a 1996 target += dc->pc;
6ae20372 1997 gen_mov_pc_npc(dc, cpu_cond);
0f8a249a
BS
1998 dc->npc = target;
1999 }
2000 goto jmp_insn;
2001 case 2: /* FPU & Logical Operations */
2002 {
2003 unsigned int xop = GET_FIELD(insn, 7, 12);
2004 if (xop == 0x3a) { /* generate trap */
cf495bcf 2005 int cond;
3475187d 2006
9322a4bf 2007 cpu_src1 = get_src1(insn, cpu_src1);
0f8a249a
BS
2008 if (IS_IMM) {
2009 rs2 = GET_FIELD(insn, 25, 31);
6ae20372 2010 tcg_gen_addi_tl(cpu_dst, cpu_src1, rs2);
cf495bcf
FB
2011 } else {
2012 rs2 = GET_FIELD(insn, 27, 31);
0f8a249a 2013 if (rs2 != 0) {
6ae20372
BS
2014 gen_movl_reg_TN(rs2, cpu_src2);
2015 tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
6f551262
BS
2016 } else
2017 tcg_gen_mov_tl(cpu_dst, cpu_src1);
cf495bcf 2018 }
cf495bcf
FB
2019 cond = GET_FIELD(insn, 3, 6);
2020 if (cond == 0x8) {
6ae20372
BS
2021 save_state(dc, cpu_cond);
2022 tcg_gen_helper_0_1(helper_trap, cpu_dst);
af7bf89b 2023 } else if (cond != 0) {
748b9d8e 2024 TCGv r_cond = tcg_temp_new(TCG_TYPE_TL);
3475187d 2025#ifdef TARGET_SPARC64
0f8a249a
BS
2026 /* V9 icc/xcc */
2027 int cc = GET_FIELD_SP(insn, 11, 12);
748b9d8e 2028
6ae20372 2029 save_state(dc, cpu_cond);
0f8a249a 2030 if (cc == 0)
748b9d8e 2031 gen_cond(r_cond, 0, cond);
0f8a249a 2032 else if (cc == 2)
748b9d8e 2033 gen_cond(r_cond, 1, cond);
0f8a249a
BS
2034 else
2035 goto illegal_insn;
3475187d 2036#else
6ae20372 2037 save_state(dc, cpu_cond);
748b9d8e 2038 gen_cond(r_cond, 0, cond);
3475187d 2039#endif
6ae20372 2040 tcg_gen_helper_0_2(helper_trapcc, cpu_dst, r_cond);
2ea815ca 2041 tcg_temp_free(r_cond);
cf495bcf 2042 }
a80dde08 2043 gen_op_next_insn();
57fec1fe 2044 tcg_gen_exit_tb(0);
a80dde08
FB
2045 dc->is_br = 1;
2046 goto jmp_insn;
cf495bcf
FB
2047 } else if (xop == 0x28) {
2048 rs1 = GET_FIELD(insn, 13, 17);
2049 switch(rs1) {
2050 case 0: /* rdy */
65fe7b09
BS
2051#ifndef TARGET_SPARC64
2052 case 0x01 ... 0x0e: /* undefined in the SPARCv8
2053 manual, rdy on the microSPARC
2054 II */
2055 case 0x0f: /* stbar in the SPARCv8 manual,
2056 rdy on the microSPARC II */
2057 case 0x10 ... 0x1f: /* implementation-dependent in the
2058 SPARCv8 manual, rdy on the
2059 microSPARC II */
2060#endif
255e1fcb 2061 gen_movl_TN_reg(rd, cpu_y);
cf495bcf 2062 break;
3475187d 2063#ifdef TARGET_SPARC64
0f8a249a 2064 case 0x2: /* V9 rdccr */
6ae20372
BS
2065 tcg_gen_helper_1_0(helper_rdccr, cpu_dst);
2066 gen_movl_TN_reg(rd, cpu_dst);
3475187d 2067 break;
0f8a249a 2068 case 0x3: /* V9 rdasi */
255e1fcb 2069 tcg_gen_ext_i32_tl(cpu_dst, cpu_asi);
6ae20372 2070 gen_movl_TN_reg(rd, cpu_dst);
3475187d 2071 break;
0f8a249a 2072 case 0x4: /* V9 rdtick */
ccd4a219
BS
2073 {
2074 TCGv r_tickptr;
2075
2076 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2077 tcg_gen_ld_ptr(r_tickptr, cpu_env,
2078 offsetof(CPUState, tick));
6ae20372 2079 tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst,
ccd4a219 2080 r_tickptr);
2ea815ca 2081 tcg_temp_free(r_tickptr);
6ae20372 2082 gen_movl_TN_reg(rd, cpu_dst);
ccd4a219 2083 }
3475187d 2084 break;
0f8a249a 2085 case 0x5: /* V9 rdpc */
2ea815ca
BS
2086 {
2087 TCGv r_const;
2088
2089 r_const = tcg_const_tl(dc->pc);
2090 gen_movl_TN_reg(rd, r_const);
2091 tcg_temp_free(r_const);
2092 }
0f8a249a
BS
2093 break;
2094 case 0x6: /* V9 rdfprs */
255e1fcb 2095 tcg_gen_ext_i32_tl(cpu_dst, cpu_fprs);
6ae20372 2096 gen_movl_TN_reg(rd, cpu_dst);
3475187d 2097 break;
65fe7b09
BS
2098 case 0xf: /* V9 membar */
2099 break; /* no effect */
0f8a249a 2100 case 0x13: /* Graphics Status */
6ae20372 2101 if (gen_trap_ifnofpu(dc, cpu_cond))
725cb90b 2102 goto jmp_insn;
255e1fcb 2103 gen_movl_TN_reg(rd, cpu_gsr);
725cb90b 2104 break;
0f8a249a 2105 case 0x17: /* Tick compare */
255e1fcb 2106 gen_movl_TN_reg(rd, cpu_tick_cmpr);
83469015 2107 break;
0f8a249a 2108 case 0x18: /* System tick */
ccd4a219
BS
2109 {
2110 TCGv r_tickptr;
2111
2112 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2113 tcg_gen_ld_ptr(r_tickptr, cpu_env,
2114 offsetof(CPUState, stick));
6ae20372 2115 tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst,
ccd4a219 2116 r_tickptr);
2ea815ca 2117 tcg_temp_free(r_tickptr);
6ae20372 2118 gen_movl_TN_reg(rd, cpu_dst);
ccd4a219 2119 }
83469015 2120 break;
0f8a249a 2121 case 0x19: /* System tick compare */
255e1fcb 2122 gen_movl_TN_reg(rd, cpu_stick_cmpr);
83469015 2123 break;
0f8a249a
BS
2124 case 0x10: /* Performance Control */
2125 case 0x11: /* Performance Instrumentation Counter */
2126 case 0x12: /* Dispatch Control */
2127 case 0x14: /* Softint set, WO */
2128 case 0x15: /* Softint clear, WO */
2129 case 0x16: /* Softint write */
3475187d
FB
2130#endif
2131 default:
cf495bcf
FB
2132 goto illegal_insn;
2133 }
e8af50a3 2134#if !defined(CONFIG_USER_ONLY)
e9ebed4d 2135 } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
3475187d 2136#ifndef TARGET_SPARC64
0f8a249a
BS
2137 if (!supervisor(dc))
2138 goto priv_insn;
6ae20372 2139 tcg_gen_helper_1_0(helper_rdpsr, cpu_dst);
e9ebed4d 2140#else
fb79ceb9 2141 CHECK_IU_FEATURE(dc, HYPV);
e9ebed4d
BS
2142 if (!hypervisor(dc))
2143 goto priv_insn;
2144 rs1 = GET_FIELD(insn, 13, 17);
2145 switch (rs1) {
2146 case 0: // hpstate
2147 // gen_op_rdhpstate();
2148 break;
2149 case 1: // htstate
2150 // gen_op_rdhtstate();
2151 break;
2152 case 3: // hintp
255e1fcb 2153 tcg_gen_mov_tl(cpu_dst, cpu_hintp);
e9ebed4d
BS
2154 break;
2155 case 5: // htba
255e1fcb 2156 tcg_gen_mov_tl(cpu_dst, cpu_htba);
e9ebed4d
BS
2157 break;
2158 case 6: // hver
255e1fcb 2159 tcg_gen_mov_tl(cpu_dst, cpu_hver);
e9ebed4d
BS
2160 break;
2161 case 31: // hstick_cmpr
255e1fcb 2162 tcg_gen_mov_tl(cpu_dst, cpu_hstick_cmpr);
e9ebed4d
BS
2163 break;
2164 default:
2165 goto illegal_insn;
2166 }
2167#endif
6ae20372 2168 gen_movl_TN_reg(rd, cpu_dst);
e8af50a3 2169 break;
3475187d 2170 } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
0f8a249a
BS
2171 if (!supervisor(dc))
2172 goto priv_insn;
3475187d
FB
2173#ifdef TARGET_SPARC64
2174 rs1 = GET_FIELD(insn, 13, 17);
0f8a249a
BS
2175 switch (rs1) {
2176 case 0: // tpc
375ee38b
BS
2177 {
2178 TCGv r_tsptr;
2179
2180 r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2181 tcg_gen_ld_ptr(r_tsptr, cpu_env,
2182 offsetof(CPUState, tsptr));
ece43b8d 2183 tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
375ee38b 2184 offsetof(trap_state, tpc));
2ea815ca 2185 tcg_temp_free(r_tsptr);
375ee38b 2186 }
0f8a249a
BS
2187 break;
2188 case 1: // tnpc
375ee38b
BS
2189 {
2190 TCGv r_tsptr;
2191
2192 r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2193 tcg_gen_ld_ptr(r_tsptr, cpu_env,
2194 offsetof(CPUState, tsptr));
ece43b8d 2195 tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
375ee38b 2196 offsetof(trap_state, tnpc));
2ea815ca 2197 tcg_temp_free(r_tsptr);
375ee38b 2198 }
0f8a249a
BS
2199 break;
2200 case 2: // tstate
375ee38b
BS
2201 {
2202 TCGv r_tsptr;
2203
2204 r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2205 tcg_gen_ld_ptr(r_tsptr, cpu_env,
2206 offsetof(CPUState, tsptr));
ece43b8d 2207 tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
375ee38b 2208 offsetof(trap_state, tstate));
2ea815ca 2209 tcg_temp_free(r_tsptr);
375ee38b 2210 }
0f8a249a
BS
2211 break;
2212 case 3: // tt
375ee38b
BS
2213 {
2214 TCGv r_tsptr;
2215
2216 r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
2217 tcg_gen_ld_ptr(r_tsptr, cpu_env,
2218 offsetof(CPUState, tsptr));
ece43b8d 2219 tcg_gen_ld_i32(cpu_tmp0, r_tsptr,
375ee38b 2220 offsetof(trap_state, tt));
2ea815ca 2221 tcg_temp_free(r_tsptr);
375ee38b 2222 }
0f8a249a
BS
2223 break;
2224 case 4: // tick
ccd4a219
BS
2225 {
2226 TCGv r_tickptr;
2227
2228 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
2229 tcg_gen_ld_ptr(r_tickptr, cpu_env,
2230 offsetof(CPUState, tick));
ece43b8d 2231 tcg_gen_helper_1_1(helper_tick_get_count, cpu_tmp0,
ccd4a219 2232 r_tickptr);
ece43b8d 2233 gen_movl_TN_reg(rd, cpu_tmp0);
2ea815ca 2234 tcg_temp_free(r_tickptr);
ccd4a219 2235 }
0f8a249a
BS
2236 break;
2237 case 5: // tba
255e1fcb 2238 tcg_gen_mov_tl(cpu_tmp0, cpu_tbr);
0f8a249a
BS
2239 break;
2240 case 6: // pstate
77f193da
BS
2241 tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2242 offsetof(CPUSPARCState, pstate));
ece43b8d 2243 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
0f8a249a
BS
2244 break;
2245 case 7: // tl
77f193da
BS
2246 tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2247 offsetof(CPUSPARCState, tl));
ece43b8d 2248 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
0f8a249a
BS
2249 break;
2250 case 8: // pil
77f193da
BS
2251 tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2252 offsetof(CPUSPARCState, psrpil));
ece43b8d 2253 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
0f8a249a
BS
2254 break;
2255 case 9: // cwp
ece43b8d 2256 tcg_gen_helper_1_0(helper_rdcwp, cpu_tmp0);
0f8a249a
BS
2257 break;
2258 case 10: // cansave
77f193da
BS
2259 tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2260 offsetof(CPUSPARCState, cansave));
ece43b8d 2261 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
0f8a249a
BS
2262 break;
2263 case 11: // canrestore
77f193da
BS
2264 tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2265 offsetof(CPUSPARCState, canrestore));
ece43b8d 2266 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
0f8a249a
BS
2267 break;
2268 case 12: // cleanwin
77f193da
BS
2269 tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2270 offsetof(CPUSPARCState, cleanwin));
ece43b8d 2271 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
0f8a249a
BS
2272 break;
2273 case 13: // otherwin
77f193da
BS
2274 tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2275 offsetof(CPUSPARCState, otherwin));
ece43b8d 2276 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
0f8a249a
BS
2277 break;
2278 case 14: // wstate
77f193da
BS
2279 tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2280 offsetof(CPUSPARCState, wstate));
ece43b8d 2281 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
0f8a249a 2282 break;
e9ebed4d 2283 case 16: // UA2005 gl
fb79ceb9 2284 CHECK_IU_FEATURE(dc, GL);
77f193da
BS
2285 tcg_gen_ld_i32(cpu_tmp32, cpu_env,
2286 offsetof(CPUSPARCState, gl));
ece43b8d 2287 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
e9ebed4d
BS
2288 break;
2289 case 26: // UA2005 strand status
fb79ceb9 2290 CHECK_IU_FEATURE(dc, HYPV);
e9ebed4d
BS
2291 if (!hypervisor(dc))
2292 goto priv_insn;
255e1fcb 2293 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_ssr);
e9ebed4d 2294 break;
0f8a249a 2295 case 31: // ver
255e1fcb 2296 tcg_gen_mov_tl(cpu_tmp0, cpu_ver);
0f8a249a
BS
2297 break;
2298 case 15: // fq
2299 default:
2300 goto illegal_insn;
2301 }
3475187d 2302#else
255e1fcb 2303 tcg_gen_ext_i32_tl(cpu_tmp0, cpu_wim);
3475187d 2304#endif
ece43b8d 2305 gen_movl_TN_reg(rd, cpu_tmp0);
e8af50a3 2306 break;
3475187d
FB
2307 } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
2308#ifdef TARGET_SPARC64
c5f2f668 2309 save_state(dc, cpu_cond);
72a9747b 2310 tcg_gen_helper_0_0(helper_flushw);
3475187d 2311#else
0f8a249a
BS
2312 if (!supervisor(dc))
2313 goto priv_insn;
255e1fcb 2314 gen_movl_TN_reg(rd, cpu_tbr);
3475187d 2315#endif
e8af50a3
FB
2316 break;
2317#endif
0f8a249a 2318 } else if (xop == 0x34) { /* FPU Operations */
6ae20372 2319 if (gen_trap_ifnofpu(dc, cpu_cond))
a80dde08 2320 goto jmp_insn;
0f8a249a 2321 gen_op_clear_ieee_excp_and_FTT();
e8af50a3 2322 rs1 = GET_FIELD(insn, 13, 17);
0f8a249a
BS
2323 rs2 = GET_FIELD(insn, 27, 31);
2324 xop = GET_FIELD(insn, 18, 26);
2325 switch (xop) {
2326 case 0x1: /* fmovs */
714547bb 2327 tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);
0f8a249a
BS
2328 break;
2329 case 0x5: /* fnegs */
714547bb
BS
2330 tcg_gen_helper_1_1(helper_fnegs, cpu_fpr[rd],
2331 cpu_fpr[rs2]);
0f8a249a
BS
2332 break;
2333 case 0x9: /* fabss */
714547bb
BS
2334 tcg_gen_helper_1_1(helper_fabss, cpu_fpr[rd],
2335 cpu_fpr[rs2]);
0f8a249a
BS
2336 break;
2337 case 0x29: /* fsqrts */
64a88d5d 2338 CHECK_FPU_FEATURE(dc, FSQRT);
7e8c2b6c 2339 gen_clear_float_exceptions();
714547bb
BS
2340 tcg_gen_helper_1_1(helper_fsqrts, cpu_tmp32,
2341 cpu_fpr[rs2]);
7e8c2b6c 2342 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
714547bb 2343 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
0f8a249a
BS
2344 break;
2345 case 0x2a: /* fsqrtd */
64a88d5d 2346 CHECK_FPU_FEATURE(dc, FSQRT);
0f8a249a 2347 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c
BS
2348 gen_clear_float_exceptions();
2349 tcg_gen_helper_0_0(helper_fsqrtd);
2350 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2351 gen_op_store_DT0_fpr(DFPREG(rd));
2352 break;
2353 case 0x2b: /* fsqrtq */
64a88d5d 2354 CHECK_FPU_FEATURE(dc, FLOAT128);
1f587329 2355 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c
BS
2356 gen_clear_float_exceptions();
2357 tcg_gen_helper_0_0(helper_fsqrtq);
2358 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2359 gen_op_store_QT0_fpr(QFPREG(rd));
2360 break;
714547bb 2361 case 0x41: /* fadds */
7e8c2b6c 2362 gen_clear_float_exceptions();
714547bb
BS
2363 tcg_gen_helper_1_2(helper_fadds, cpu_tmp32,
2364 cpu_fpr[rs1], cpu_fpr[rs2]);
7e8c2b6c 2365 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
714547bb 2366 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
0f8a249a
BS
2367 break;
2368 case 0x42:
2369 gen_op_load_fpr_DT0(DFPREG(rs1));
2370 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2371 gen_clear_float_exceptions();
44e7757c 2372 tcg_gen_helper_0_0(helper_faddd);
7e8c2b6c 2373 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2374 gen_op_store_DT0_fpr(DFPREG(rd));
2375 break;
2376 case 0x43: /* faddq */
64a88d5d 2377 CHECK_FPU_FEATURE(dc, FLOAT128);
1f587329
BS
2378 gen_op_load_fpr_QT0(QFPREG(rs1));
2379 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2380 gen_clear_float_exceptions();
44e7757c 2381 tcg_gen_helper_0_0(helper_faddq);
7e8c2b6c 2382 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2383 gen_op_store_QT0_fpr(QFPREG(rd));
2384 break;
714547bb 2385 case 0x45: /* fsubs */
7e8c2b6c 2386 gen_clear_float_exceptions();
714547bb
BS
2387 tcg_gen_helper_1_2(helper_fsubs, cpu_tmp32,
2388 cpu_fpr[rs1], cpu_fpr[rs2]);
7e8c2b6c 2389 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
714547bb 2390 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
0f8a249a
BS
2391 break;
2392 case 0x46:
2393 gen_op_load_fpr_DT0(DFPREG(rs1));
2394 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2395 gen_clear_float_exceptions();
44e7757c 2396 tcg_gen_helper_0_0(helper_fsubd);
7e8c2b6c 2397 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2398 gen_op_store_DT0_fpr(DFPREG(rd));
2399 break;
2400 case 0x47: /* fsubq */
64a88d5d 2401 CHECK_FPU_FEATURE(dc, FLOAT128);
1f587329
BS
2402 gen_op_load_fpr_QT0(QFPREG(rs1));
2403 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2404 gen_clear_float_exceptions();
44e7757c 2405 tcg_gen_helper_0_0(helper_fsubq);
7e8c2b6c 2406 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2407 gen_op_store_QT0_fpr(QFPREG(rd));
2408 break;
64a88d5d
BS
2409 case 0x49: /* fmuls */
2410 CHECK_FPU_FEATURE(dc, FMUL);
7e8c2b6c 2411 gen_clear_float_exceptions();
714547bb
BS
2412 tcg_gen_helper_1_2(helper_fmuls, cpu_tmp32,
2413 cpu_fpr[rs1], cpu_fpr[rs2]);
7e8c2b6c 2414 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
714547bb 2415 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
0f8a249a 2416 break;
64a88d5d
BS
2417 case 0x4a: /* fmuld */
2418 CHECK_FPU_FEATURE(dc, FMUL);
0f8a249a
BS
2419 gen_op_load_fpr_DT0(DFPREG(rs1));
2420 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2421 gen_clear_float_exceptions();
44e7757c 2422 tcg_gen_helper_0_0(helper_fmuld);
7e8c2b6c 2423 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2382dc6b 2424 gen_op_store_DT0_fpr(DFPREG(rd));
0f8a249a
BS
2425 break;
2426 case 0x4b: /* fmulq */
64a88d5d
BS
2427 CHECK_FPU_FEATURE(dc, FLOAT128);
2428 CHECK_FPU_FEATURE(dc, FMUL);
1f587329
BS
2429 gen_op_load_fpr_QT0(QFPREG(rs1));
2430 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2431 gen_clear_float_exceptions();
44e7757c 2432 tcg_gen_helper_0_0(helper_fmulq);
7e8c2b6c 2433 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2434 gen_op_store_QT0_fpr(QFPREG(rd));
2435 break;
714547bb 2436 case 0x4d: /* fdivs */
7e8c2b6c 2437 gen_clear_float_exceptions();
714547bb
BS
2438 tcg_gen_helper_1_2(helper_fdivs, cpu_tmp32,
2439 cpu_fpr[rs1], cpu_fpr[rs2]);
7e8c2b6c 2440 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
714547bb 2441 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
0f8a249a
BS
2442 break;
2443 case 0x4e:
2444 gen_op_load_fpr_DT0(DFPREG(rs1));
2445 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2446 gen_clear_float_exceptions();
44e7757c 2447 tcg_gen_helper_0_0(helper_fdivd);
7e8c2b6c 2448 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2449 gen_op_store_DT0_fpr(DFPREG(rd));
2450 break;
2451 case 0x4f: /* fdivq */
64a88d5d 2452 CHECK_FPU_FEATURE(dc, FLOAT128);
1f587329
BS
2453 gen_op_load_fpr_QT0(QFPREG(rs1));
2454 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2455 gen_clear_float_exceptions();
44e7757c 2456 tcg_gen_helper_0_0(helper_fdivq);
7e8c2b6c 2457 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2458 gen_op_store_QT0_fpr(QFPREG(rd));
2459 break;
d84763bc 2460 case 0x69: /* fsmuld */
e30b4678 2461 CHECK_FPU_FEATURE(dc, FSMULD);
7e8c2b6c 2462 gen_clear_float_exceptions();
d84763bc
BS
2463 tcg_gen_helper_0_2(helper_fsmuld, cpu_fpr[rs1],
2464 cpu_fpr[rs2]);
7e8c2b6c 2465 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2466 gen_op_store_DT0_fpr(DFPREG(rd));
2467 break;
2468 case 0x6e: /* fdmulq */
64a88d5d 2469 CHECK_FPU_FEATURE(dc, FLOAT128);
1f587329
BS
2470 gen_op_load_fpr_DT0(DFPREG(rs1));
2471 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2472 gen_clear_float_exceptions();
44e7757c 2473 tcg_gen_helper_0_0(helper_fdmulq);
7e8c2b6c 2474 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2475 gen_op_store_QT0_fpr(QFPREG(rd));
2476 break;
714547bb 2477 case 0xc4: /* fitos */
7e8c2b6c 2478 gen_clear_float_exceptions();
714547bb
BS
2479 tcg_gen_helper_1_1(helper_fitos, cpu_tmp32,
2480 cpu_fpr[rs2]);
7e8c2b6c 2481 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
714547bb 2482 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
0f8a249a 2483 break;
d84763bc 2484 case 0xc6: /* fdtos */
0f8a249a 2485 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2486 gen_clear_float_exceptions();
d84763bc 2487 tcg_gen_helper_1_0(helper_fdtos, cpu_tmp32);
7e8c2b6c 2488 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
d84763bc 2489 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
0f8a249a
BS
2490 break;
2491 case 0xc7: /* fqtos */
64a88d5d 2492 CHECK_FPU_FEATURE(dc, FLOAT128);
1f587329 2493 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2494 gen_clear_float_exceptions();
c5d04e99 2495 tcg_gen_helper_1_0(helper_fqtos, cpu_tmp32);
7e8c2b6c 2496 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
c5d04e99 2497 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
1f587329 2498 break;
d84763bc
BS
2499 case 0xc8: /* fitod */
2500 tcg_gen_helper_0_1(helper_fitod, cpu_fpr[rs2]);
0f8a249a
BS
2501 gen_op_store_DT0_fpr(DFPREG(rd));
2502 break;
d84763bc
BS
2503 case 0xc9: /* fstod */
2504 tcg_gen_helper_0_1(helper_fstod, cpu_fpr[rs2]);
0f8a249a
BS
2505 gen_op_store_DT0_fpr(DFPREG(rd));
2506 break;
2507 case 0xcb: /* fqtod */
64a88d5d 2508 CHECK_FPU_FEATURE(dc, FLOAT128);
1f587329 2509 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2510 gen_clear_float_exceptions();
44e7757c 2511 tcg_gen_helper_0_0(helper_fqtod);
7e8c2b6c 2512 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2513 gen_op_store_DT0_fpr(DFPREG(rd));
2514 break;
0f8a249a 2515 case 0xcc: /* fitoq */
64a88d5d 2516 CHECK_FPU_FEATURE(dc, FLOAT128);
c5d04e99 2517 tcg_gen_helper_0_1(helper_fitoq, cpu_fpr[rs2]);
1f587329
BS
2518 gen_op_store_QT0_fpr(QFPREG(rd));
2519 break;
0f8a249a 2520 case 0xcd: /* fstoq */
64a88d5d 2521 CHECK_FPU_FEATURE(dc, FLOAT128);
c5d04e99 2522 tcg_gen_helper_0_1(helper_fstoq, cpu_fpr[rs2]);
1f587329
BS
2523 gen_op_store_QT0_fpr(QFPREG(rd));
2524 break;
0f8a249a 2525 case 0xce: /* fdtoq */
64a88d5d 2526 CHECK_FPU_FEATURE(dc, FLOAT128);
1f587329 2527 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 2528 tcg_gen_helper_0_0(helper_fdtoq);
1f587329
BS
2529 gen_op_store_QT0_fpr(QFPREG(rd));
2530 break;
714547bb 2531 case 0xd1: /* fstoi */
7e8c2b6c 2532 gen_clear_float_exceptions();
714547bb
BS
2533 tcg_gen_helper_1_1(helper_fstoi, cpu_tmp32,
2534 cpu_fpr[rs2]);
7e8c2b6c 2535 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
714547bb 2536 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
0f8a249a 2537 break;
d84763bc 2538 case 0xd2: /* fdtoi */
2382dc6b 2539 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2540 gen_clear_float_exceptions();
d84763bc 2541 tcg_gen_helper_1_0(helper_fdtoi, cpu_tmp32);
7e8c2b6c 2542 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
d84763bc 2543 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
0f8a249a
BS
2544 break;
2545 case 0xd3: /* fqtoi */
64a88d5d 2546 CHECK_FPU_FEATURE(dc, FLOAT128);
1f587329 2547 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2548 gen_clear_float_exceptions();
c5d04e99 2549 tcg_gen_helper_1_0(helper_fqtoi, cpu_tmp32);
7e8c2b6c 2550 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
c5d04e99 2551 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
1f587329 2552 break;
3475187d 2553#ifdef TARGET_SPARC64
0f8a249a 2554 case 0x2: /* V9 fmovd */
714547bb
BS
2555 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)],
2556 cpu_fpr[DFPREG(rs2)]);
2557 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1],
2558 cpu_fpr[DFPREG(rs2) + 1]);
0f8a249a 2559 break;
1f587329 2560 case 0x3: /* V9 fmovq */
64a88d5d 2561 CHECK_FPU_FEATURE(dc, FLOAT128);
714547bb
BS
2562 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)],
2563 cpu_fpr[QFPREG(rs2)]);
2564 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1],
2565 cpu_fpr[QFPREG(rs2) + 1]);
2566 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2],
2567 cpu_fpr[QFPREG(rs2) + 2]);
2568 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3],
2569 cpu_fpr[QFPREG(rs2) + 3]);
1f587329 2570 break;
0f8a249a
BS
2571 case 0x6: /* V9 fnegd */
2572 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 2573 tcg_gen_helper_0_0(helper_fnegd);
0f8a249a
BS
2574 gen_op_store_DT0_fpr(DFPREG(rd));
2575 break;
1f587329 2576 case 0x7: /* V9 fnegq */
64a88d5d 2577 CHECK_FPU_FEATURE(dc, FLOAT128);
1f587329 2578 gen_op_load_fpr_QT1(QFPREG(rs2));
44e7757c 2579 tcg_gen_helper_0_0(helper_fnegq);
1f587329
BS
2580 gen_op_store_QT0_fpr(QFPREG(rd));
2581 break;
0f8a249a
BS
2582 case 0xa: /* V9 fabsd */
2583 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2584 tcg_gen_helper_0_0(helper_fabsd);
0f8a249a
BS
2585 gen_op_store_DT0_fpr(DFPREG(rd));
2586 break;
1f587329 2587 case 0xb: /* V9 fabsq */
64a88d5d 2588 CHECK_FPU_FEATURE(dc, FLOAT128);
1f587329 2589 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2590 tcg_gen_helper_0_0(helper_fabsq);
1f587329
BS
2591 gen_op_store_QT0_fpr(QFPREG(rd));
2592 break;
0f8a249a 2593 case 0x81: /* V9 fstox */
7e8c2b6c 2594 gen_clear_float_exceptions();
d84763bc 2595 tcg_gen_helper_0_1(helper_fstox, cpu_fpr[rs2]);
7e8c2b6c 2596 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2597 gen_op_store_DT0_fpr(DFPREG(rd));
2598 break;
2599 case 0x82: /* V9 fdtox */
2600 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2601 gen_clear_float_exceptions();
44e7757c 2602 tcg_gen_helper_0_0(helper_fdtox);
7e8c2b6c 2603 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2604 gen_op_store_DT0_fpr(DFPREG(rd));
2605 break;
1f587329 2606 case 0x83: /* V9 fqtox */
64a88d5d 2607 CHECK_FPU_FEATURE(dc, FLOAT128);
1f587329 2608 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2609 gen_clear_float_exceptions();
44e7757c 2610 tcg_gen_helper_0_0(helper_fqtox);
7e8c2b6c 2611 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2612 gen_op_store_DT0_fpr(DFPREG(rd));
2613 break;
0f8a249a
BS
2614 case 0x84: /* V9 fxtos */
2615 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2616 gen_clear_float_exceptions();
d84763bc 2617 tcg_gen_helper_1_0(helper_fxtos, cpu_tmp32);
7e8c2b6c 2618 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
d84763bc 2619 tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
0f8a249a
BS
2620 break;
2621 case 0x88: /* V9 fxtod */
2622 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2623 gen_clear_float_exceptions();
44e7757c 2624 tcg_gen_helper_0_0(helper_fxtod);
7e8c2b6c 2625 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
0f8a249a
BS
2626 gen_op_store_DT0_fpr(DFPREG(rd));
2627 break;
0f8a249a 2628 case 0x8c: /* V9 fxtoq */
64a88d5d 2629 CHECK_FPU_FEATURE(dc, FLOAT128);
1f587329 2630 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2631 gen_clear_float_exceptions();
44e7757c 2632 tcg_gen_helper_0_0(helper_fxtoq);
7e8c2b6c 2633 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1f587329
BS
2634 gen_op_store_QT0_fpr(QFPREG(rd));
2635 break;
0f8a249a
BS
2636#endif
2637 default:
2638 goto illegal_insn;
2639 }
2640 } else if (xop == 0x35) { /* FPU Operations */
3475187d 2641#ifdef TARGET_SPARC64
0f8a249a 2642 int cond;
3475187d 2643#endif
6ae20372 2644 if (gen_trap_ifnofpu(dc, cpu_cond))
a80dde08 2645 goto jmp_insn;
0f8a249a 2646 gen_op_clear_ieee_excp_and_FTT();
cf495bcf 2647 rs1 = GET_FIELD(insn, 13, 17);
0f8a249a
BS
2648 rs2 = GET_FIELD(insn, 27, 31);
2649 xop = GET_FIELD(insn, 18, 26);
3475187d 2650#ifdef TARGET_SPARC64
0f8a249a 2651 if ((xop & 0x11f) == 0x005) { // V9 fmovsr
dcf24905
BS
2652 int l1;
2653
2654 l1 = gen_new_label();
0f8a249a 2655 cond = GET_FIELD_SP(insn, 14, 17);
9322a4bf 2656 cpu_src1 = get_src1(insn, cpu_src1);
cb63669a
PB
2657 tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2658 0, l1);
714547bb 2659 tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);
dcf24905 2660 gen_set_label(l1);
0f8a249a
BS
2661 break;
2662 } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
dcf24905
BS
2663 int l1;
2664
2665 l1 = gen_new_label();
0f8a249a 2666 cond = GET_FIELD_SP(insn, 14, 17);
9322a4bf 2667 cpu_src1 = get_src1(insn, cpu_src1);
cb63669a
PB
2668 tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2669 0, l1);
714547bb
BS
2670 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)]);
2671 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], cpu_fpr[DFPREG(rs2) + 1]);
dcf24905 2672 gen_set_label(l1);
0f8a249a
BS
2673 break;
2674 } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
dcf24905
BS
2675 int l1;
2676
64a88d5d 2677 CHECK_FPU_FEATURE(dc, FLOAT128);
dcf24905 2678 l1 = gen_new_label();
1f587329 2679 cond = GET_FIELD_SP(insn, 14, 17);
9322a4bf 2680 cpu_src1 = get_src1(insn, cpu_src1);
cb63669a
PB
2681 tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
2682 0, l1);
714547bb
BS
2683 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], cpu_fpr[QFPREG(rs2)]);
2684 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], cpu_fpr[QFPREG(rs2) + 1]);
2685 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], cpu_fpr[QFPREG(rs2) + 2]);
2686 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], cpu_fpr[QFPREG(rs2) + 3]);
dcf24905 2687 gen_set_label(l1);
1f587329 2688 break;
0f8a249a
BS
2689 }
2690#endif
2691 switch (xop) {
3475187d 2692#ifdef TARGET_SPARC64
714547bb 2693#define FMOVSCC(fcc) \
19f329ad 2694 { \
0425bee5 2695 TCGv r_cond; \
19f329ad
BS
2696 int l1; \
2697 \
2698 l1 = gen_new_label(); \
19f329ad 2699 r_cond = tcg_temp_new(TCG_TYPE_TL); \
19f329ad
BS
2700 cond = GET_FIELD_SP(insn, 14, 17); \
2701 gen_fcond(r_cond, fcc, cond); \
cb63669a
PB
2702 tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
2703 0, l1); \
714547bb
BS
2704 tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]); \
2705 gen_set_label(l1); \
2706 tcg_temp_free(r_cond); \
2707 }
2708#define FMOVDCC(fcc) \
2709 { \
2710 TCGv r_cond; \
2711 int l1; \
2712 \
2713 l1 = gen_new_label(); \
2714 r_cond = tcg_temp_new(TCG_TYPE_TL); \
2715 cond = GET_FIELD_SP(insn, 14, 17); \
2716 gen_fcond(r_cond, fcc, cond); \
2717 tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
2718 0, l1); \
2719 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], \
2720 cpu_fpr[DFPREG(rs2)]); \
2721 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], \
2722 cpu_fpr[DFPREG(rs2) + 1]); \
2723 gen_set_label(l1); \
2724 tcg_temp_free(r_cond); \
2725 }
2726#define FMOVQCC(fcc) \
2727 { \
2728 TCGv r_cond; \
2729 int l1; \
2730 \
2731 l1 = gen_new_label(); \
2732 r_cond = tcg_temp_new(TCG_TYPE_TL); \
2733 cond = GET_FIELD_SP(insn, 14, 17); \
2734 gen_fcond(r_cond, fcc, cond); \
2735 tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
2736 0, l1); \
2737 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], \
2738 cpu_fpr[QFPREG(rs2)]); \
2739 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], \
2740 cpu_fpr[QFPREG(rs2) + 1]); \
2741 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], \
2742 cpu_fpr[QFPREG(rs2) + 2]); \
2743 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], \
2744 cpu_fpr[QFPREG(rs2) + 3]); \
19f329ad 2745 gen_set_label(l1); \
2ea815ca 2746 tcg_temp_free(r_cond); \
19f329ad 2747 }
0f8a249a 2748 case 0x001: /* V9 fmovscc %fcc0 */
714547bb 2749 FMOVSCC(0);
0f8a249a
BS
2750 break;
2751 case 0x002: /* V9 fmovdcc %fcc0 */
714547bb 2752 FMOVDCC(0);
0f8a249a
BS
2753 break;
2754 case 0x003: /* V9 fmovqcc %fcc0 */
64a88d5d 2755 CHECK_FPU_FEATURE(dc, FLOAT128);
714547bb 2756 FMOVQCC(0);
1f587329 2757 break;
0f8a249a 2758 case 0x041: /* V9 fmovscc %fcc1 */
714547bb 2759 FMOVSCC(1);
0f8a249a
BS
2760 break;
2761 case 0x042: /* V9 fmovdcc %fcc1 */
714547bb 2762 FMOVDCC(1);
0f8a249a
BS
2763 break;
2764 case 0x043: /* V9 fmovqcc %fcc1 */
64a88d5d 2765 CHECK_FPU_FEATURE(dc, FLOAT128);
714547bb 2766 FMOVQCC(1);
1f587329 2767 break;
0f8a249a 2768 case 0x081: /* V9 fmovscc %fcc2 */
714547bb 2769 FMOVSCC(2);
0f8a249a
BS
2770 break;
2771 case 0x082: /* V9 fmovdcc %fcc2 */
714547bb 2772 FMOVDCC(2);
0f8a249a
BS
2773 break;
2774 case 0x083: /* V9 fmovqcc %fcc2 */
64a88d5d 2775 CHECK_FPU_FEATURE(dc, FLOAT128);
714547bb 2776 FMOVQCC(2);
1f587329 2777 break;
0f8a249a 2778 case 0x0c1: /* V9 fmovscc %fcc3 */
714547bb 2779 FMOVSCC(3);
0f8a249a
BS
2780 break;
2781 case 0x0c2: /* V9 fmovdcc %fcc3 */
714547bb 2782 FMOVDCC(3);
0f8a249a
BS
2783 break;
2784 case 0x0c3: /* V9 fmovqcc %fcc3 */
64a88d5d 2785 CHECK_FPU_FEATURE(dc, FLOAT128);
714547bb 2786 FMOVQCC(3);
1f587329 2787 break;
714547bb
BS
2788#undef FMOVSCC
2789#undef FMOVDCC
2790#undef FMOVQCC
19f329ad
BS
2791#define FMOVCC(size_FDQ, icc) \
2792 { \
0425bee5 2793 TCGv r_cond; \
19f329ad
BS
2794 int l1; \
2795 \
2796 l1 = gen_new_label(); \
19f329ad 2797 r_cond = tcg_temp_new(TCG_TYPE_TL); \
19f329ad
BS
2798 cond = GET_FIELD_SP(insn, 14, 17); \
2799 gen_cond(r_cond, icc, cond); \
cb63669a
PB
2800 tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
2801 0, l1); \
77f193da
BS
2802 glue(glue(gen_op_load_fpr_, size_FDQ), T0) \
2803 (glue(size_FDQ, FPREG(rs2))); \
2804 glue(glue(gen_op_store_, size_FDQ), T0_fpr) \
2805 (glue(size_FDQ, FPREG(rd))); \
19f329ad 2806 gen_set_label(l1); \
2ea815ca 2807 tcg_temp_free(r_cond); \
19f329ad 2808 }
714547bb
BS
2809#define FMOVSCC(icc) \
2810 { \
2811 TCGv r_cond; \
2812 int l1; \
2813 \
2814 l1 = gen_new_label(); \
2815 r_cond = tcg_temp_new(TCG_TYPE_TL); \
2816 cond = GET_FIELD_SP(insn, 14, 17); \
2817 gen_cond(r_cond, icc, cond); \
2818 tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
2819 0, l1); \
2820 tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]); \
2821 gen_set_label(l1); \
2822 tcg_temp_free(r_cond); \
2823 }
2824#define FMOVDCC(icc) \
2825 { \
2826 TCGv r_cond; \
2827 int l1; \
2828 \
2829 l1 = gen_new_label(); \
2830 r_cond = tcg_temp_new(TCG_TYPE_TL); \
2831 cond = GET_FIELD_SP(insn, 14, 17); \
2832 gen_cond(r_cond, icc, cond); \
2833 tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
2834 0, l1); \
2835 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], \
2836 cpu_fpr[DFPREG(rs2)]); \
2837 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], \
2838 cpu_fpr[DFPREG(rs2) + 1]); \
2839 gen_set_label(l1); \
2840 tcg_temp_free(r_cond); \
2841 }
2842#define FMOVQCC(icc) \
2843 { \
2844 TCGv r_cond; \
2845 int l1; \
2846 \
2847 l1 = gen_new_label(); \
2848 r_cond = tcg_temp_new(TCG_TYPE_TL); \
2849 cond = GET_FIELD_SP(insn, 14, 17); \
2850 gen_cond(r_cond, icc, cond); \
2851 tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \
2852 0, l1); \
2853 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], \
2854 cpu_fpr[QFPREG(rs2)]); \
2855 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], \
2856 cpu_fpr[QFPREG(rs2) + 1]); \
2857 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], \
2858 cpu_fpr[QFPREG(rs2) + 2]); \
2859 tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], \
2860 cpu_fpr[QFPREG(rs2) + 3]); \
2861 gen_set_label(l1); \
2862 tcg_temp_free(r_cond); \
2863 }
19f329ad 2864
0f8a249a 2865 case 0x101: /* V9 fmovscc %icc */
714547bb 2866 FMOVSCC(0);
0f8a249a
BS
2867 break;
2868 case 0x102: /* V9 fmovdcc %icc */
714547bb 2869 FMOVDCC(0);
0f8a249a 2870 case 0x103: /* V9 fmovqcc %icc */
64a88d5d 2871 CHECK_FPU_FEATURE(dc, FLOAT128);
714547bb 2872 FMOVQCC(0);
1f587329 2873 break;
0f8a249a 2874 case 0x181: /* V9 fmovscc %xcc */
714547bb 2875 FMOVSCC(1);
0f8a249a
BS
2876 break;
2877 case 0x182: /* V9 fmovdcc %xcc */
714547bb 2878 FMOVDCC(1);
0f8a249a
BS
2879 break;
2880 case 0x183: /* V9 fmovqcc %xcc */
64a88d5d 2881 CHECK_FPU_FEATURE(dc, FLOAT128);
714547bb 2882 FMOVQCC(1);
1f587329 2883 break;
714547bb
BS
2884#undef FMOVSCC
2885#undef FMOVDCC
2886#undef FMOVQCC
1f587329
BS
2887#endif
2888 case 0x51: /* fcmps, V9 %fcc */
714547bb 2889 gen_op_fcmps(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]);
0f8a249a 2890 break;
1f587329 2891 case 0x52: /* fcmpd, V9 %fcc */
0f8a249a
BS
2892 gen_op_load_fpr_DT0(DFPREG(rs1));
2893 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2894 gen_op_fcmpd(rd & 3);
0f8a249a 2895 break;
1f587329 2896 case 0x53: /* fcmpq, V9 %fcc */
64a88d5d 2897 CHECK_FPU_FEATURE(dc, FLOAT128);
1f587329
BS
2898 gen_op_load_fpr_QT0(QFPREG(rs1));
2899 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2900 gen_op_fcmpq(rd & 3);
1f587329 2901 break;
0f8a249a 2902 case 0x55: /* fcmpes, V9 %fcc */
714547bb 2903 gen_op_fcmpes(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]);
0f8a249a
BS
2904 break;
2905 case 0x56: /* fcmped, V9 %fcc */
2906 gen_op_load_fpr_DT0(DFPREG(rs1));
2907 gen_op_load_fpr_DT1(DFPREG(rs2));
7e8c2b6c 2908 gen_op_fcmped(rd & 3);
0f8a249a 2909 break;
1f587329 2910 case 0x57: /* fcmpeq, V9 %fcc */
64a88d5d 2911 CHECK_FPU_FEATURE(dc, FLOAT128);
1f587329
BS
2912 gen_op_load_fpr_QT0(QFPREG(rs1));
2913 gen_op_load_fpr_QT1(QFPREG(rs2));
7e8c2b6c 2914 gen_op_fcmpeq(rd & 3);
1f587329 2915 break;
0f8a249a
BS
2916 default:
2917 goto illegal_insn;
2918 }
0f8a249a
BS
2919 } else if (xop == 0x2) {
2920 // clr/mov shortcut
e80cfcfc
FB
2921
2922 rs1 = GET_FIELD(insn, 13, 17);
0f8a249a 2923 if (rs1 == 0) {
1a2fb1c0 2924 // or %g0, x, y -> mov T0, x; mov y, T0
0f8a249a 2925 if (IS_IMM) { /* immediate */
2ea815ca
BS
2926 TCGv r_const;
2927
0f8a249a 2928 rs2 = GET_FIELDs(insn, 19, 31);
2ea815ca
BS
2929 r_const = tcg_const_tl((int)rs2);
2930 gen_movl_TN_reg(rd, r_const);
2931 tcg_temp_free(r_const);
0f8a249a
BS
2932 } else { /* register */
2933 rs2 = GET_FIELD(insn, 27, 31);
6ae20372 2934 gen_movl_reg_TN(rs2, cpu_dst);
9c6c6662 2935 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a 2936 }
0f8a249a 2937 } else {
9322a4bf 2938 cpu_src1 = get_src1(insn, cpu_src1);
0f8a249a 2939 if (IS_IMM) { /* immediate */
0f8a249a 2940 rs2 = GET_FIELDs(insn, 19, 31);
6ae20372 2941 tcg_gen_ori_tl(cpu_dst, cpu_src1, (int)rs2);
9c6c6662 2942 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a
BS
2943 } else { /* register */
2944 // or x, %g0, y -> mov T1, x; mov y, T1
2945 rs2 = GET_FIELD(insn, 27, 31);
2946 if (rs2 != 0) {
6ae20372
BS
2947 gen_movl_reg_TN(rs2, cpu_src2);
2948 tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
9c6c6662 2949 gen_movl_TN_reg(rd, cpu_dst);
6f551262 2950 } else
9c6c6662 2951 gen_movl_TN_reg(rd, cpu_src1);
0f8a249a 2952 }
0f8a249a 2953 }
83469015 2954#ifdef TARGET_SPARC64
0f8a249a 2955 } else if (xop == 0x25) { /* sll, V9 sllx */
9322a4bf 2956 cpu_src1 = get_src1(insn, cpu_src1);
0f8a249a 2957 if (IS_IMM) { /* immediate */
83469015 2958 rs2 = GET_FIELDs(insn, 20, 31);
1a2fb1c0 2959 if (insn & (1 << 12)) {
6ae20372 2960 tcg_gen_shli_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
1a2fb1c0 2961 } else {
01b1fa6d 2962 tcg_gen_shli_i64(cpu_dst, cpu_src1, rs2 & 0x1f);
1a2fb1c0 2963 }
0f8a249a 2964 } else { /* register */
83469015 2965 rs2 = GET_FIELD(insn, 27, 31);
6ae20372 2966 gen_movl_reg_TN(rs2, cpu_src2);
1a2fb1c0 2967 if (insn & (1 << 12)) {
6ae20372 2968 tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
1a2fb1c0 2969 } else {
6ae20372 2970 tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
1a2fb1c0 2971 }
01b1fa6d 2972 tcg_gen_shl_i64(cpu_dst, cpu_src1, cpu_tmp0);
83469015 2973 }
6ae20372 2974 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a 2975 } else if (xop == 0x26) { /* srl, V9 srlx */
9322a4bf 2976 cpu_src1 = get_src1(insn, cpu_src1);
0f8a249a 2977 if (IS_IMM) { /* immediate */
83469015 2978 rs2 = GET_FIELDs(insn, 20, 31);
1a2fb1c0 2979 if (insn & (1 << 12)) {
6ae20372 2980 tcg_gen_shri_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
1a2fb1c0 2981 } else {
6ae20372
BS
2982 tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2983 tcg_gen_shri_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
1a2fb1c0 2984 }
0f8a249a 2985 } else { /* register */
83469015 2986 rs2 = GET_FIELD(insn, 27, 31);
6ae20372 2987 gen_movl_reg_TN(rs2, cpu_src2);
1a2fb1c0 2988 if (insn & (1 << 12)) {
6ae20372
BS
2989 tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
2990 tcg_gen_shr_i64(cpu_dst, cpu_src1, cpu_tmp0);
1a2fb1c0 2991 } else {
6ae20372
BS
2992 tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
2993 tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
2994 tcg_gen_shr_i64(cpu_dst, cpu_dst, cpu_tmp0);
1a2fb1c0 2995 }
83469015 2996 }
6ae20372 2997 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a 2998 } else if (xop == 0x27) { /* sra, V9 srax */
9322a4bf 2999 cpu_src1 = get_src1(insn, cpu_src1);
0f8a249a 3000 if (IS_IMM) { /* immediate */
83469015 3001 rs2 = GET_FIELDs(insn, 20, 31);
1a2fb1c0 3002 if (insn & (1 << 12)) {
6ae20372 3003 tcg_gen_sari_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
1a2fb1c0 3004 } else {
6ae20372
BS
3005 tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
3006 tcg_gen_ext_i32_i64(cpu_dst, cpu_dst);
3007 tcg_gen_sari_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
1a2fb1c0 3008 }
0f8a249a 3009 } else { /* register */
83469015 3010 rs2 = GET_FIELD(insn, 27, 31);
6ae20372 3011 gen_movl_reg_TN(rs2, cpu_src2);
1a2fb1c0 3012 if (insn & (1 << 12)) {
6ae20372
BS
3013 tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
3014 tcg_gen_sar_i64(cpu_dst, cpu_src1, cpu_tmp0);
1a2fb1c0 3015 } else {
6ae20372
BS
3016 tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
3017 tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
01b1fa6d 3018 tcg_gen_ext_i32_i64(cpu_dst, cpu_dst);
6ae20372 3019 tcg_gen_sar_i64(cpu_dst, cpu_dst, cpu_tmp0);
1a2fb1c0 3020 }
83469015 3021 }
6ae20372 3022 gen_movl_TN_reg(rd, cpu_dst);
e80cfcfc 3023#endif
fcc72045 3024 } else if (xop < 0x36) {
9322a4bf 3025 cpu_src1 = get_src1(insn, cpu_src1);
a49d9390 3026 cpu_src2 = get_src2(insn, cpu_src2);
cf495bcf
FB
3027 if (xop < 0x20) {
3028 switch (xop & ~0x10) {
3029 case 0x0:
3030 if (xop & 0x10)
6ae20372 3031 gen_op_add_cc(cpu_dst, cpu_src1, cpu_src2);
cf495bcf 3032 else
6ae20372 3033 tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
cf495bcf
FB
3034 break;
3035 case 0x1:
6ae20372 3036 tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_src2);
cf495bcf 3037 if (xop & 0x10)
6ae20372 3038 gen_op_logic_cc(cpu_dst);
cf495bcf
FB
3039 break;
3040 case 0x2:
6ae20372 3041 tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
0f8a249a 3042 if (xop & 0x10)
6ae20372 3043 gen_op_logic_cc(cpu_dst);
0f8a249a 3044 break;
cf495bcf 3045 case 0x3:
6ae20372 3046 tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
cf495bcf 3047 if (xop & 0x10)
6ae20372 3048 gen_op_logic_cc(cpu_dst);
cf495bcf
FB
3049 break;
3050 case 0x4:
3051 if (xop & 0x10)
6ae20372 3052 gen_op_sub_cc(cpu_dst, cpu_src1, cpu_src2);
cf495bcf 3053 else
6ae20372 3054 tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_src2);
cf495bcf
FB
3055 break;
3056 case 0x5:
6ae20372
BS
3057 tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
3058 tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_tmp0);
cf495bcf 3059 if (xop & 0x10)
6ae20372 3060 gen_op_logic_cc(cpu_dst);
cf495bcf
FB
3061 break;
3062 case 0x6:
6ae20372
BS
3063 tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
3064 tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_tmp0);
cf495bcf 3065 if (xop & 0x10)
6ae20372 3066 gen_op_logic_cc(cpu_dst);
cf495bcf
FB
3067 break;
3068 case 0x7:
6ae20372
BS
3069 tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
3070 tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_tmp0);
cf495bcf 3071 if (xop & 0x10)
6ae20372 3072 gen_op_logic_cc(cpu_dst);
cf495bcf
FB
3073 break;
3074 case 0x8:
cf495bcf 3075 if (xop & 0x10)
6ae20372 3076 gen_op_addx_cc(cpu_dst, cpu_src1, cpu_src2);
38bc628b 3077 else {
dc99a3f2 3078 gen_mov_reg_C(cpu_tmp0, cpu_psr);
6ae20372
BS
3079 tcg_gen_add_tl(cpu_tmp0, cpu_src2, cpu_tmp0);
3080 tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_tmp0);
38bc628b 3081 }
cf495bcf 3082 break;
ded3ab80 3083#ifdef TARGET_SPARC64
0f8a249a 3084 case 0x9: /* V9 mulx */
6ae20372 3085 tcg_gen_mul_i64(cpu_dst, cpu_src1, cpu_src2);
ded3ab80
PB
3086 break;
3087#endif
cf495bcf 3088 case 0xa:
64a88d5d 3089 CHECK_IU_FEATURE(dc, MUL);
6ae20372 3090 gen_op_umul(cpu_dst, cpu_src1, cpu_src2);
cf495bcf 3091 if (xop & 0x10)
6ae20372 3092 gen_op_logic_cc(cpu_dst);
cf495bcf
FB
3093 break;
3094 case 0xb:
64a88d5d 3095 CHECK_IU_FEATURE(dc, MUL);
6ae20372 3096 gen_op_smul(cpu_dst, cpu_src1, cpu_src2);
cf495bcf 3097 if (xop & 0x10)
6ae20372 3098 gen_op_logic_cc(cpu_dst);
cf495bcf
FB
3099 break;
3100 case 0xc:
cf495bcf 3101 if (xop & 0x10)
6ae20372 3102 gen_op_subx_cc(cpu_dst, cpu_src1, cpu_src2);
38bc628b 3103 else {
dc99a3f2 3104 gen_mov_reg_C(cpu_tmp0, cpu_psr);
6ae20372
BS
3105 tcg_gen_add_tl(cpu_tmp0, cpu_src2, cpu_tmp0);
3106 tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_tmp0);
38bc628b 3107 }
cf495bcf 3108 break;
ded3ab80 3109#ifdef TARGET_SPARC64
0f8a249a 3110 case 0xd: /* V9 udivx */
07bf2857
BS
3111 tcg_gen_mov_tl(cpu_cc_src, cpu_src1);
3112 tcg_gen_mov_tl(cpu_cc_src2, cpu_src2);
3113 gen_trap_ifdivzero_tl(cpu_cc_src2);
3114 tcg_gen_divu_i64(cpu_dst, cpu_cc_src, cpu_cc_src2);
ded3ab80
PB
3115 break;
3116#endif
cf495bcf 3117 case 0xe:
64a88d5d 3118 CHECK_IU_FEATURE(dc, DIV);
77f193da
BS
3119 tcg_gen_helper_1_2(helper_udiv, cpu_dst, cpu_src1,
3120 cpu_src2);
cf495bcf 3121 if (xop & 0x10)
6ae20372 3122 gen_op_div_cc(cpu_dst);
cf495bcf
FB
3123 break;
3124 case 0xf:
64a88d5d 3125 CHECK_IU_FEATURE(dc, DIV);
77f193da
BS
3126 tcg_gen_helper_1_2(helper_sdiv, cpu_dst, cpu_src1,
3127 cpu_src2);
cf495bcf 3128 if (xop & 0x10)
6ae20372 3129 gen_op_div_cc(cpu_dst);
cf495bcf
FB
3130 break;
3131 default:
3132 goto illegal_insn;
3133 }
6ae20372 3134 gen_movl_TN_reg(rd, cpu_dst);
cf495bcf
FB
3135 } else {
3136 switch (xop) {
0f8a249a 3137 case 0x20: /* taddcc */
6ae20372
BS
3138 gen_op_tadd_cc(cpu_dst, cpu_src1, cpu_src2);
3139 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a
BS
3140 break;
3141 case 0x21: /* tsubcc */
6ae20372
BS
3142 gen_op_tsub_cc(cpu_dst, cpu_src1, cpu_src2);
3143 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a
BS
3144 break;
3145 case 0x22: /* taddcctv */
6ae20372
BS
3146 save_state(dc, cpu_cond);
3147 gen_op_tadd_ccTV(cpu_dst, cpu_src1, cpu_src2);
3148 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a
BS
3149 break;
3150 case 0x23: /* tsubcctv */
6ae20372
BS
3151 save_state(dc, cpu_cond);
3152 gen_op_tsub_ccTV(cpu_dst, cpu_src1, cpu_src2);
3153 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a 3154 break;
cf495bcf 3155 case 0x24: /* mulscc */
6ae20372
BS
3156 gen_op_mulscc(cpu_dst, cpu_src1, cpu_src2);
3157 gen_movl_TN_reg(rd, cpu_dst);
cf495bcf 3158 break;
83469015 3159#ifndef TARGET_SPARC64
0f8a249a 3160 case 0x25: /* sll */
e35298cd
BS
3161 if (IS_IMM) { /* immediate */
3162 rs2 = GET_FIELDs(insn, 20, 31);
3163 tcg_gen_shli_tl(cpu_dst, cpu_src1, rs2 & 0x1f);
3164 } else { /* register */
3165 tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3166 tcg_gen_shl_tl(cpu_dst, cpu_src1, cpu_tmp0);
3167 }
6ae20372 3168 gen_movl_TN_reg(rd, cpu_dst);
cf495bcf 3169 break;
83469015 3170 case 0x26: /* srl */
e35298cd
BS
3171 if (IS_IMM) { /* immediate */
3172 rs2 = GET_FIELDs(insn, 20, 31);
3173 tcg_gen_shri_tl(cpu_dst, cpu_src1, rs2 & 0x1f);
3174 } else { /* register */
3175 tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3176 tcg_gen_shr_tl(cpu_dst, cpu_src1, cpu_tmp0);
3177 }
6ae20372 3178 gen_movl_TN_reg(rd, cpu_dst);
cf495bcf 3179 break;
83469015 3180 case 0x27: /* sra */
e35298cd
BS
3181 if (IS_IMM) { /* immediate */
3182 rs2 = GET_FIELDs(insn, 20, 31);
3183 tcg_gen_sari_tl(cpu_dst, cpu_src1, rs2 & 0x1f);
3184 } else { /* register */
3185 tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
3186 tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0);
3187 }
6ae20372 3188 gen_movl_TN_reg(rd, cpu_dst);
cf495bcf 3189 break;
83469015 3190#endif
cf495bcf
FB
3191 case 0x30:
3192 {
cf495bcf 3193 switch(rd) {
3475187d 3194 case 0: /* wry */
5068cbd9
BS
3195 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
3196 tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
cf495bcf 3197 break;
65fe7b09
BS
3198#ifndef TARGET_SPARC64
3199 case 0x01 ... 0x0f: /* undefined in the
3200 SPARCv8 manual, nop
3201 on the microSPARC
3202 II */
3203 case 0x10 ... 0x1f: /* implementation-dependent
3204 in the SPARCv8
3205 manual, nop on the
3206 microSPARC II */
3207 break;
3208#else
0f8a249a 3209 case 0x2: /* V9 wrccr */
6ae20372
BS
3210 tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3211 tcg_gen_helper_0_1(helper_wrccr, cpu_dst);
0f8a249a
BS
3212 break;
3213 case 0x3: /* V9 wrasi */
6ae20372 3214 tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
255e1fcb 3215 tcg_gen_trunc_tl_i32(cpu_asi, cpu_dst);
0f8a249a
BS
3216 break;
3217 case 0x6: /* V9 wrfprs */
6ae20372 3218 tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
255e1fcb 3219 tcg_gen_trunc_tl_i32(cpu_fprs, cpu_dst);
6ae20372 3220 save_state(dc, cpu_cond);
3299908c 3221 gen_op_next_insn();
57fec1fe 3222 tcg_gen_exit_tb(0);
3299908c 3223 dc->is_br = 1;
0f8a249a
BS
3224 break;
3225 case 0xf: /* V9 sir, nop if user */
3475187d 3226#if !defined(CONFIG_USER_ONLY)
0f8a249a 3227 if (supervisor(dc))
1a2fb1c0 3228 ; // XXX
3475187d 3229#endif
0f8a249a
BS
3230 break;
3231 case 0x13: /* Graphics Status */
6ae20372 3232 if (gen_trap_ifnofpu(dc, cpu_cond))
725cb90b 3233 goto jmp_insn;
255e1fcb 3234 tcg_gen_xor_tl(cpu_gsr, cpu_src1, cpu_src2);
0f8a249a
BS
3235 break;
3236 case 0x17: /* Tick compare */
83469015 3237#if !defined(CONFIG_USER_ONLY)
0f8a249a
BS
3238 if (!supervisor(dc))
3239 goto illegal_insn;
83469015 3240#endif
ccd4a219
BS
3241 {
3242 TCGv r_tickptr;
3243
255e1fcb 3244 tcg_gen_xor_tl(cpu_tick_cmpr, cpu_src1,
6ae20372 3245 cpu_src2);
ccd4a219
BS
3246 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3247 tcg_gen_ld_ptr(r_tickptr, cpu_env,
3248 offsetof(CPUState, tick));
3249 tcg_gen_helper_0_2(helper_tick_set_limit,
255e1fcb 3250 r_tickptr, cpu_tick_cmpr);
2ea815ca 3251 tcg_temp_free(r_tickptr);
ccd4a219 3252 }
0f8a249a
BS
3253 break;
3254 case 0x18: /* System tick */
83469015 3255#if !defined(CONFIG_USER_ONLY)
0f8a249a
BS
3256 if (!supervisor(dc))
3257 goto illegal_insn;
83469015 3258#endif
ccd4a219
BS
3259 {
3260 TCGv r_tickptr;
3261
6ae20372
BS
3262 tcg_gen_xor_tl(cpu_dst, cpu_src1,
3263 cpu_src2);
ccd4a219
BS
3264 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3265 tcg_gen_ld_ptr(r_tickptr, cpu_env,
3266 offsetof(CPUState, stick));
3267 tcg_gen_helper_0_2(helper_tick_set_count,
6ae20372 3268 r_tickptr, cpu_dst);
2ea815ca 3269 tcg_temp_free(r_tickptr);
ccd4a219 3270 }
0f8a249a
BS
3271 break;
3272 case 0x19: /* System tick compare */
83469015 3273#if !defined(CONFIG_USER_ONLY)
0f8a249a
BS
3274 if (!supervisor(dc))
3275 goto illegal_insn;
3475187d 3276#endif
ccd4a219
BS
3277 {
3278 TCGv r_tickptr;
3279
255e1fcb 3280 tcg_gen_xor_tl(cpu_stick_cmpr, cpu_src1,
6ae20372 3281 cpu_src2);
ccd4a219
BS
3282 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3283 tcg_gen_ld_ptr(r_tickptr, cpu_env,
3284 offsetof(CPUState, stick));
3285 tcg_gen_helper_0_2(helper_tick_set_limit,
255e1fcb 3286 r_tickptr, cpu_stick_cmpr);
2ea815ca 3287 tcg_temp_free(r_tickptr);
ccd4a219 3288 }
0f8a249a 3289 break;
83469015 3290
0f8a249a 3291 case 0x10: /* Performance Control */
77f193da
BS
3292 case 0x11: /* Performance Instrumentation
3293 Counter */
0f8a249a
BS
3294 case 0x12: /* Dispatch Control */
3295 case 0x14: /* Softint set */
3296 case 0x15: /* Softint clear */
3297 case 0x16: /* Softint write */
83469015 3298#endif
3475187d 3299 default:
cf495bcf
FB
3300 goto illegal_insn;
3301 }
3302 }
3303 break;
e8af50a3 3304#if !defined(CONFIG_USER_ONLY)
af7bf89b 3305 case 0x31: /* wrpsr, V9 saved, restored */
e8af50a3 3306 {
0f8a249a
BS
3307 if (!supervisor(dc))
3308 goto priv_insn;
3475187d 3309#ifdef TARGET_SPARC64
0f8a249a
BS
3310 switch (rd) {
3311 case 0:
72a9747b 3312 tcg_gen_helper_0_0(helper_saved);
0f8a249a
BS
3313 break;
3314 case 1:
72a9747b 3315 tcg_gen_helper_0_0(helper_restored);
0f8a249a 3316 break;
e9ebed4d
BS
3317 case 2: /* UA2005 allclean */
3318 case 3: /* UA2005 otherw */
3319 case 4: /* UA2005 normalw */
3320 case 5: /* UA2005 invalw */
3321 // XXX
0f8a249a 3322 default:
3475187d
FB
3323 goto illegal_insn;
3324 }
3325#else
6ae20372
BS
3326 tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3327 tcg_gen_helper_0_1(helper_wrpsr, cpu_dst);
3328 save_state(dc, cpu_cond);
9e61bde5 3329 gen_op_next_insn();
57fec1fe 3330 tcg_gen_exit_tb(0);
0f8a249a 3331 dc->is_br = 1;
3475187d 3332#endif
e8af50a3
FB
3333 }
3334 break;
af7bf89b 3335 case 0x32: /* wrwim, V9 wrpr */
e8af50a3 3336 {
0f8a249a
BS
3337 if (!supervisor(dc))
3338 goto priv_insn;
ece43b8d 3339 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
3475187d 3340#ifdef TARGET_SPARC64
0f8a249a
BS
3341 switch (rd) {
3342 case 0: // tpc
375ee38b
BS
3343 {
3344 TCGv r_tsptr;
3345
3346 r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3347 tcg_gen_ld_ptr(r_tsptr, cpu_env,
3348 offsetof(CPUState, tsptr));
ece43b8d 3349 tcg_gen_st_tl(cpu_tmp0, r_tsptr,
375ee38b 3350 offsetof(trap_state, tpc));
2ea815ca 3351 tcg_temp_free(r_tsptr);
375ee38b 3352 }
0f8a249a
BS
3353 break;
3354 case 1: // tnpc
375ee38b
BS
3355 {
3356 TCGv r_tsptr;
3357
3358 r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3359 tcg_gen_ld_ptr(r_tsptr, cpu_env,
3360 offsetof(CPUState, tsptr));
ece43b8d 3361 tcg_gen_st_tl(cpu_tmp0, r_tsptr,
375ee38b 3362 offsetof(trap_state, tnpc));
2ea815ca 3363 tcg_temp_free(r_tsptr);
375ee38b 3364 }
0f8a249a
BS
3365 break;
3366 case 2: // tstate
375ee38b
BS
3367 {
3368 TCGv r_tsptr;
3369
3370 r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3371 tcg_gen_ld_ptr(r_tsptr, cpu_env,
3372 offsetof(CPUState, tsptr));
ece43b8d 3373 tcg_gen_st_tl(cpu_tmp0, r_tsptr,
77f193da
BS
3374 offsetof(trap_state,
3375 tstate));
2ea815ca 3376 tcg_temp_free(r_tsptr);
375ee38b 3377 }
0f8a249a
BS
3378 break;
3379 case 3: // tt
375ee38b
BS
3380 {
3381 TCGv r_tsptr;
3382
3383 r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
3384 tcg_gen_ld_ptr(r_tsptr, cpu_env,
3385 offsetof(CPUState, tsptr));
ece43b8d 3386 tcg_gen_st_i32(cpu_tmp0, r_tsptr,
375ee38b 3387 offsetof(trap_state, tt));
2ea815ca 3388 tcg_temp_free(r_tsptr);
375ee38b 3389 }
0f8a249a
BS
3390 break;
3391 case 4: // tick
ccd4a219
BS
3392 {
3393 TCGv r_tickptr;
3394
3395 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3396 tcg_gen_ld_ptr(r_tickptr, cpu_env,
3397 offsetof(CPUState, tick));
3398 tcg_gen_helper_0_2(helper_tick_set_count,
ece43b8d 3399 r_tickptr, cpu_tmp0);
2ea815ca 3400 tcg_temp_free(r_tickptr);
ccd4a219 3401 }
0f8a249a
BS
3402 break;
3403 case 5: // tba
255e1fcb 3404 tcg_gen_mov_tl(cpu_tbr, cpu_tmp0);
0f8a249a
BS
3405 break;
3406 case 6: // pstate
6ae20372 3407 save_state(dc, cpu_cond);
ece43b8d 3408 tcg_gen_helper_0_1(helper_wrpstate, cpu_tmp0);
ded3ab80 3409 gen_op_next_insn();
57fec1fe 3410 tcg_gen_exit_tb(0);
ded3ab80 3411 dc->is_br = 1;
0f8a249a
BS
3412 break;
3413 case 7: // tl
ece43b8d 3414 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
77f193da
BS
3415 tcg_gen_st_i32(cpu_tmp32, cpu_env,
3416 offsetof(CPUSPARCState, tl));
0f8a249a
BS
3417 break;
3418 case 8: // pil
ece43b8d 3419 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
77f193da
BS
3420 tcg_gen_st_i32(cpu_tmp32, cpu_env,
3421 offsetof(CPUSPARCState,
3422 psrpil));
0f8a249a
BS
3423 break;
3424 case 9: // cwp
ece43b8d 3425 tcg_gen_helper_0_1(helper_wrcwp, cpu_tmp0);
0f8a249a
BS
3426 break;
3427 case 10: // cansave
ece43b8d 3428 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
77f193da
BS
3429 tcg_gen_st_i32(cpu_tmp32, cpu_env,
3430 offsetof(CPUSPARCState,
3431 cansave));
0f8a249a
BS
3432 break;
3433 case 11: // canrestore
ece43b8d 3434 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
77f193da
BS
3435 tcg_gen_st_i32(cpu_tmp32, cpu_env,
3436 offsetof(CPUSPARCState,
3437 canrestore));
0f8a249a
BS
3438 break;
3439 case 12: // cleanwin
ece43b8d 3440 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
77f193da
BS
3441 tcg_gen_st_i32(cpu_tmp32, cpu_env,
3442 offsetof(CPUSPARCState,
3443 cleanwin));
0f8a249a
BS
3444 break;
3445 case 13: // otherwin
ece43b8d 3446 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
77f193da
BS
3447 tcg_gen_st_i32(cpu_tmp32, cpu_env,
3448 offsetof(CPUSPARCState,
3449 otherwin));
0f8a249a
BS
3450 break;
3451 case 14: // wstate
ece43b8d 3452 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
77f193da
BS
3453 tcg_gen_st_i32(cpu_tmp32, cpu_env,
3454 offsetof(CPUSPARCState,
3455 wstate));
0f8a249a 3456 break;
e9ebed4d 3457 case 16: // UA2005 gl
fb79ceb9 3458 CHECK_IU_FEATURE(dc, GL);
ece43b8d 3459 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
77f193da
BS
3460 tcg_gen_st_i32(cpu_tmp32, cpu_env,
3461 offsetof(CPUSPARCState, gl));
e9ebed4d
BS
3462 break;
3463 case 26: // UA2005 strand status
fb79ceb9 3464 CHECK_IU_FEATURE(dc, HYPV);
e9ebed4d
BS
3465 if (!hypervisor(dc))
3466 goto priv_insn;
255e1fcb 3467 tcg_gen_trunc_tl_i32(cpu_ssr, cpu_tmp0);
e9ebed4d 3468 break;
0f8a249a
BS
3469 default:
3470 goto illegal_insn;
3471 }
3475187d 3472#else
ece43b8d 3473 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
c93e7817
BS
3474 if (dc->def->nwindows != 32)
3475 tcg_gen_andi_tl(cpu_tmp32, cpu_tmp32,
3476 (1 << dc->def->nwindows) - 1);
255e1fcb 3477 tcg_gen_mov_i32(cpu_wim, cpu_tmp32);
3475187d 3478#endif
e8af50a3
FB
3479 }
3480 break;
e9ebed4d 3481 case 0x33: /* wrtbr, UA2005 wrhpr */
e8af50a3 3482 {
e9ebed4d 3483#ifndef TARGET_SPARC64
0f8a249a
BS
3484 if (!supervisor(dc))
3485 goto priv_insn;
255e1fcb 3486 tcg_gen_xor_tl(cpu_tbr, cpu_src1, cpu_src2);
e9ebed4d 3487#else
fb79ceb9 3488 CHECK_IU_FEATURE(dc, HYPV);
e9ebed4d
BS
3489 if (!hypervisor(dc))
3490 goto priv_insn;
ece43b8d 3491 tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
e9ebed4d
BS
3492 switch (rd) {
3493 case 0: // hpstate
3494 // XXX gen_op_wrhpstate();
6ae20372 3495 save_state(dc, cpu_cond);
e9ebed4d 3496 gen_op_next_insn();
57fec1fe 3497 tcg_gen_exit_tb(0);
e9ebed4d
BS
3498 dc->is_br = 1;
3499 break;
3500 case 1: // htstate
3501 // XXX gen_op_wrhtstate();
3502 break;
3503 case 3: // hintp
255e1fcb 3504 tcg_gen_mov_tl(cpu_hintp, cpu_tmp0);
e9ebed4d
BS
3505 break;
3506 case 5: // htba
255e1fcb 3507 tcg_gen_mov_tl(cpu_htba, cpu_tmp0);
e9ebed4d
BS
3508 break;
3509 case 31: // hstick_cmpr
ccd4a219
BS
3510 {
3511 TCGv r_tickptr;
3512
255e1fcb 3513 tcg_gen_mov_tl(cpu_hstick_cmpr, cpu_tmp0);
ccd4a219
BS
3514 r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
3515 tcg_gen_ld_ptr(r_tickptr, cpu_env,
3516 offsetof(CPUState, hstick));
3517 tcg_gen_helper_0_2(helper_tick_set_limit,
255e1fcb 3518 r_tickptr, cpu_hstick_cmpr);
2ea815ca 3519 tcg_temp_free(r_tickptr);
ccd4a219 3520 }
e9ebed4d
BS
3521 break;
3522 case 6: // hver readonly
3523 default:
3524 goto illegal_insn;
3525 }
3526#endif
e8af50a3
FB
3527 }
3528 break;
3529#endif
3475187d 3530#ifdef TARGET_SPARC64
0f8a249a
BS
3531 case 0x2c: /* V9 movcc */
3532 {
3533 int cc = GET_FIELD_SP(insn, 11, 12);
3534 int cond = GET_FIELD_SP(insn, 14, 17);
748b9d8e 3535 TCGv r_cond;
00f219bf
BS
3536 int l1;
3537
748b9d8e 3538 r_cond = tcg_temp_new(TCG_TYPE_TL);
0f8a249a
BS
3539 if (insn & (1 << 18)) {
3540 if (cc == 0)
748b9d8e 3541 gen_cond(r_cond, 0, cond);
0f8a249a 3542 else if (cc == 2)
748b9d8e 3543 gen_cond(r_cond, 1, cond);
0f8a249a
BS
3544 else
3545 goto illegal_insn;
3546 } else {
748b9d8e 3547 gen_fcond(r_cond, cc, cond);
0f8a249a 3548 }
00f219bf
BS
3549
3550 l1 = gen_new_label();
3551
cb63669a 3552 tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
00f219bf 3553 if (IS_IMM) { /* immediate */
2ea815ca
BS
3554 TCGv r_const;
3555
00f219bf 3556 rs2 = GET_FIELD_SPs(insn, 0, 10);
2ea815ca
BS
3557 r_const = tcg_const_tl((int)rs2);
3558 gen_movl_TN_reg(rd, r_const);
3559 tcg_temp_free(r_const);
00f219bf
BS
3560 } else {
3561 rs2 = GET_FIELD_SP(insn, 0, 4);
9c6c6662
BS
3562 gen_movl_reg_TN(rs2, cpu_tmp0);
3563 gen_movl_TN_reg(rd, cpu_tmp0);
00f219bf 3564 }
00f219bf 3565 gen_set_label(l1);
2ea815ca 3566 tcg_temp_free(r_cond);
0f8a249a
BS
3567 break;
3568 }
3569 case 0x2d: /* V9 sdivx */
6ae20372
BS
3570 gen_op_sdivx(cpu_dst, cpu_src1, cpu_src2);
3571 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a
BS
3572 break;
3573 case 0x2e: /* V9 popc */
3574 {
a49d9390 3575 cpu_src2 = get_src2(insn, cpu_src2);
6ae20372
BS
3576 tcg_gen_helper_1_1(helper_popc, cpu_dst,
3577 cpu_src2);
3578 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a
BS
3579 }
3580 case 0x2f: /* V9 movr */
3581 {
3582 int cond = GET_FIELD_SP(insn, 10, 12);
00f219bf
BS
3583 int l1;
3584
9322a4bf 3585 cpu_src1 = get_src1(insn, cpu_src1);
00f219bf
BS
3586
3587 l1 = gen_new_label();
3588
cb63669a
PB
3589 tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond],
3590 cpu_src1, 0, l1);
0f8a249a 3591 if (IS_IMM) { /* immediate */
2ea815ca
BS
3592 TCGv r_const;
3593
0f8a249a 3594 rs2 = GET_FIELD_SPs(insn, 0, 9);
2ea815ca
BS
3595 r_const = tcg_const_tl((int)rs2);
3596 gen_movl_TN_reg(rd, r_const);
3597 tcg_temp_free(r_const);
00f219bf 3598 } else {
0f8a249a 3599 rs2 = GET_FIELD_SP(insn, 0, 4);
9c6c6662
BS
3600 gen_movl_reg_TN(rs2, cpu_tmp0);
3601 gen_movl_TN_reg(rd, cpu_tmp0);
0f8a249a 3602 }
00f219bf 3603 gen_set_label(l1);
0f8a249a
BS
3604 break;
3605 }
3606#endif
3607 default:
3608 goto illegal_insn;
3609 }
3610 }
3299908c
BS
3611 } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
3612#ifdef TARGET_SPARC64
3613 int opf = GET_FIELD_SP(insn, 5, 13);
3614 rs1 = GET_FIELD(insn, 13, 17);
3615 rs2 = GET_FIELD(insn, 27, 31);
6ae20372 3616 if (gen_trap_ifnofpu(dc, cpu_cond))
e9ebed4d 3617 goto jmp_insn;
3299908c
BS
3618
3619 switch (opf) {
e9ebed4d
BS
3620 case 0x000: /* VIS I edge8cc */
3621 case 0x001: /* VIS II edge8n */
3622 case 0x002: /* VIS I edge8lcc */
3623 case 0x003: /* VIS II edge8ln */
3624 case 0x004: /* VIS I edge16cc */
3625 case 0x005: /* VIS II edge16n */
3626 case 0x006: /* VIS I edge16lcc */
3627 case 0x007: /* VIS II edge16ln */
3628 case 0x008: /* VIS I edge32cc */
3629 case 0x009: /* VIS II edge32n */
3630 case 0x00a: /* VIS I edge32lcc */
3631 case 0x00b: /* VIS II edge32ln */
3632 // XXX
3633 goto illegal_insn;
3634 case 0x010: /* VIS I array8 */
64a88d5d 3635 CHECK_FPU_FEATURE(dc, VIS1);
9322a4bf 3636 cpu_src1 = get_src1(insn, cpu_src1);
6ae20372
BS
3637 gen_movl_reg_TN(rs2, cpu_src2);
3638 tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
3639 cpu_src2);
3640 gen_movl_TN_reg(rd, cpu_dst);
e9ebed4d
BS
3641 break;
3642 case 0x012: /* VIS I array16 */
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 tcg_gen_shli_i64(cpu_dst, cpu_dst, 1);
3649 gen_movl_TN_reg(rd, cpu_dst);
e9ebed4d
BS
3650 break;
3651 case 0x014: /* VIS I array32 */
64a88d5d 3652 CHECK_FPU_FEATURE(dc, VIS1);
9322a4bf 3653 cpu_src1 = get_src1(insn, cpu_src1);
6ae20372
BS
3654 gen_movl_reg_TN(rs2, cpu_src2);
3655 tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
3656 cpu_src2);
3657 tcg_gen_shli_i64(cpu_dst, cpu_dst, 2);
3658 gen_movl_TN_reg(rd, cpu_dst);
e9ebed4d 3659 break;
3299908c 3660 case 0x018: /* VIS I alignaddr */
64a88d5d 3661 CHECK_FPU_FEATURE(dc, VIS1);
9322a4bf 3662 cpu_src1 = get_src1(insn, cpu_src1);
6ae20372
BS
3663 gen_movl_reg_TN(rs2, cpu_src2);
3664 tcg_gen_helper_1_2(helper_alignaddr, cpu_dst, cpu_src1,
3665 cpu_src2);
3666 gen_movl_TN_reg(rd, cpu_dst);
3299908c 3667 break;
e9ebed4d 3668 case 0x019: /* VIS II bmask */
3299908c 3669 case 0x01a: /* VIS I alignaddrl */
3299908c 3670 // XXX
e9ebed4d
BS
3671 goto illegal_insn;
3672 case 0x020: /* VIS I fcmple16 */
64a88d5d 3673 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3674 gen_op_load_fpr_DT0(DFPREG(rs1));
3675 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3676 tcg_gen_helper_0_0(helper_fcmple16);
2382dc6b 3677 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3678 break;
3679 case 0x022: /* VIS I fcmpne16 */
64a88d5d 3680 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3681 gen_op_load_fpr_DT0(DFPREG(rs1));
3682 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3683 tcg_gen_helper_0_0(helper_fcmpne16);
2382dc6b 3684 gen_op_store_DT0_fpr(DFPREG(rd));
3299908c 3685 break;
e9ebed4d 3686 case 0x024: /* VIS I fcmple32 */
64a88d5d 3687 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3688 gen_op_load_fpr_DT0(DFPREG(rs1));
3689 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3690 tcg_gen_helper_0_0(helper_fcmple32);
2382dc6b 3691 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3692 break;
3693 case 0x026: /* VIS I fcmpne32 */
64a88d5d 3694 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3695 gen_op_load_fpr_DT0(DFPREG(rs1));
3696 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3697 tcg_gen_helper_0_0(helper_fcmpne32);
2382dc6b 3698 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3699 break;
3700 case 0x028: /* VIS I fcmpgt16 */
64a88d5d 3701 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3702 gen_op_load_fpr_DT0(DFPREG(rs1));
3703 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3704 tcg_gen_helper_0_0(helper_fcmpgt16);
2382dc6b 3705 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3706 break;
3707 case 0x02a: /* VIS I fcmpeq16 */
64a88d5d 3708 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3709 gen_op_load_fpr_DT0(DFPREG(rs1));
3710 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3711 tcg_gen_helper_0_0(helper_fcmpeq16);
2382dc6b 3712 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3713 break;
3714 case 0x02c: /* VIS I fcmpgt32 */
64a88d5d 3715 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3716 gen_op_load_fpr_DT0(DFPREG(rs1));
3717 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3718 tcg_gen_helper_0_0(helper_fcmpgt32);
2382dc6b 3719 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3720 break;
3721 case 0x02e: /* VIS I fcmpeq32 */
64a88d5d 3722 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3723 gen_op_load_fpr_DT0(DFPREG(rs1));
3724 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3725 tcg_gen_helper_0_0(helper_fcmpeq32);
2382dc6b 3726 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3727 break;
3728 case 0x031: /* VIS I fmul8x16 */
64a88d5d 3729 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3730 gen_op_load_fpr_DT0(DFPREG(rs1));
3731 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3732 tcg_gen_helper_0_0(helper_fmul8x16);
2382dc6b 3733 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3734 break;
3735 case 0x033: /* VIS I fmul8x16au */
64a88d5d 3736 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3737 gen_op_load_fpr_DT0(DFPREG(rs1));
3738 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3739 tcg_gen_helper_0_0(helper_fmul8x16au);
2382dc6b 3740 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3741 break;
3742 case 0x035: /* VIS I fmul8x16al */
64a88d5d 3743 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3744 gen_op_load_fpr_DT0(DFPREG(rs1));
3745 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3746 tcg_gen_helper_0_0(helper_fmul8x16al);
2382dc6b 3747 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3748 break;
3749 case 0x036: /* VIS I fmul8sux16 */
64a88d5d 3750 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3751 gen_op_load_fpr_DT0(DFPREG(rs1));
3752 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3753 tcg_gen_helper_0_0(helper_fmul8sux16);
2382dc6b 3754 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3755 break;
3756 case 0x037: /* VIS I fmul8ulx16 */
64a88d5d 3757 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3758 gen_op_load_fpr_DT0(DFPREG(rs1));
3759 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3760 tcg_gen_helper_0_0(helper_fmul8ulx16);
2382dc6b 3761 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3762 break;
3763 case 0x038: /* VIS I fmuld8sux16 */
64a88d5d 3764 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3765 gen_op_load_fpr_DT0(DFPREG(rs1));
3766 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3767 tcg_gen_helper_0_0(helper_fmuld8sux16);
2382dc6b 3768 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3769 break;
3770 case 0x039: /* VIS I fmuld8ulx16 */
64a88d5d 3771 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3772 gen_op_load_fpr_DT0(DFPREG(rs1));
3773 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3774 tcg_gen_helper_0_0(helper_fmuld8ulx16);
2382dc6b 3775 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3776 break;
3777 case 0x03a: /* VIS I fpack32 */
3778 case 0x03b: /* VIS I fpack16 */
3779 case 0x03d: /* VIS I fpackfix */
3780 case 0x03e: /* VIS I pdist */
3781 // XXX
3782 goto illegal_insn;
3299908c 3783 case 0x048: /* VIS I faligndata */
64a88d5d 3784 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3785 gen_op_load_fpr_DT0(DFPREG(rs1));
3786 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3787 tcg_gen_helper_0_0(helper_faligndata);
2382dc6b 3788 gen_op_store_DT0_fpr(DFPREG(rd));
3299908c 3789 break;
e9ebed4d 3790 case 0x04b: /* VIS I fpmerge */
64a88d5d 3791 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3792 gen_op_load_fpr_DT0(DFPREG(rs1));
3793 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3794 tcg_gen_helper_0_0(helper_fpmerge);
2382dc6b 3795 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3796 break;
3797 case 0x04c: /* VIS II bshuffle */
3798 // XXX
3799 goto illegal_insn;
3800 case 0x04d: /* VIS I fexpand */
64a88d5d 3801 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3802 gen_op_load_fpr_DT0(DFPREG(rs1));
3803 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3804 tcg_gen_helper_0_0(helper_fexpand);
2382dc6b 3805 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3806 break;
3807 case 0x050: /* VIS I fpadd16 */
64a88d5d 3808 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3809 gen_op_load_fpr_DT0(DFPREG(rs1));
3810 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3811 tcg_gen_helper_0_0(helper_fpadd16);
2382dc6b 3812 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3813 break;
3814 case 0x051: /* VIS I fpadd16s */
64a88d5d 3815 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d
BS
3816 tcg_gen_helper_1_2(helper_fpadd16s, cpu_fpr[rd],
3817 cpu_fpr[rs1], cpu_fpr[rs2]);
e9ebed4d
BS
3818 break;
3819 case 0x052: /* VIS I fpadd32 */
64a88d5d 3820 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3821 gen_op_load_fpr_DT0(DFPREG(rs1));
3822 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3823 tcg_gen_helper_0_0(helper_fpadd32);
2382dc6b 3824 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3825 break;
3826 case 0x053: /* VIS I fpadd32s */
64a88d5d 3827 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d
BS
3828 tcg_gen_helper_1_2(helper_fpadd32s, cpu_fpr[rd],
3829 cpu_fpr[rs1], cpu_fpr[rs2]);
e9ebed4d
BS
3830 break;
3831 case 0x054: /* VIS I fpsub16 */
64a88d5d 3832 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3833 gen_op_load_fpr_DT0(DFPREG(rs1));
3834 gen_op_load_fpr_DT1(DFPREG(rs2));
44e7757c 3835 tcg_gen_helper_0_0(helper_fpsub16);
2382dc6b 3836 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3837 break;
3838 case 0x055: /* VIS I fpsub16s */
64a88d5d 3839 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d
BS
3840 tcg_gen_helper_1_2(helper_fpsub16s, cpu_fpr[rd],
3841 cpu_fpr[rs1], cpu_fpr[rs2]);
e9ebed4d
BS
3842 break;
3843 case 0x056: /* VIS I fpsub32 */
64a88d5d 3844 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
3845 gen_op_load_fpr_DT0(DFPREG(rs1));
3846 gen_op_load_fpr_DT1(DFPREG(rs2));
510aba20 3847 tcg_gen_helper_0_0(helper_fpsub32);
2382dc6b 3848 gen_op_store_DT0_fpr(DFPREG(rd));
e9ebed4d
BS
3849 break;
3850 case 0x057: /* VIS I fpsub32s */
64a88d5d 3851 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d
BS
3852 tcg_gen_helper_1_2(helper_fpsub32s, cpu_fpr[rd],
3853 cpu_fpr[rs1], cpu_fpr[rs2]);
e9ebed4d 3854 break;
3299908c 3855 case 0x060: /* VIS I fzero */
64a88d5d 3856 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d
BS
3857 tcg_gen_movi_i32(cpu_fpr[DFPREG(rd)], 0);
3858 tcg_gen_movi_i32(cpu_fpr[DFPREG(rd) + 1], 0);
3299908c
BS
3859 break;
3860 case 0x061: /* VIS I fzeros */
64a88d5d 3861 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d 3862 tcg_gen_movi_i32(cpu_fpr[rd], 0);
3299908c 3863 break;
e9ebed4d 3864 case 0x062: /* VIS I fnor */
64a88d5d 3865 CHECK_FPU_FEATURE(dc, VIS1);
e2ea21b3
BS
3866 tcg_gen_or_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1)],
3867 cpu_fpr[DFPREG(rs2)]);
3868 tcg_gen_xori_i32(cpu_fpr[DFPREG(rd)], cpu_tmp32, -1);
3869 tcg_gen_or_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1) + 1],
3870 cpu_fpr[DFPREG(rs2) + 1]);
3871 tcg_gen_xori_i32(cpu_fpr[DFPREG(rd) + 1], cpu_tmp32, -1);
e9ebed4d
BS
3872 break;
3873 case 0x063: /* VIS I fnors */
64a88d5d 3874 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d
BS
3875 tcg_gen_or_i32(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
3876 tcg_gen_xori_i32(cpu_fpr[rd], cpu_tmp32, -1);
e9ebed4d
BS
3877 break;
3878 case 0x064: /* VIS I fandnot2 */
64a88d5d 3879 CHECK_FPU_FEATURE(dc, VIS1);
e2ea21b3
BS
3880 tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1)], -1);
3881 tcg_gen_and_i32(cpu_fpr[DFPREG(rd)], cpu_tmp32,
3882 cpu_fpr[DFPREG(rs2)]);
3883 tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1) + 1], -1);
3884 tcg_gen_and_i32(cpu_fpr[DFPREG(rd) + 1], cpu_tmp32,
3885 cpu_fpr[DFPREG(rs2) + 1]);
e9ebed4d
BS
3886 break;
3887 case 0x065: /* VIS I fandnot2s */
64a88d5d 3888 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d
BS
3889 tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[rs1], -1);
3890 tcg_gen_and_i32(cpu_fpr[rd], cpu_tmp32, cpu_fpr[rs2]);
e9ebed4d
BS
3891 break;
3892 case 0x066: /* VIS I fnot2 */
64a88d5d 3893 CHECK_FPU_FEATURE(dc, VIS1);
e2ea21b3
BS
3894 tcg_gen_xori_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)],
3895 -1);
3896 tcg_gen_xori_i32(cpu_fpr[DFPREG(rd) + 1],
3897 cpu_fpr[DFPREG(rs2) + 1], -1);
e9ebed4d
BS
3898 break;
3899 case 0x067: /* VIS I fnot2s */
64a88d5d 3900 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d 3901 tcg_gen_xori_i32(cpu_fpr[rd], cpu_fpr[rs2], -1);
e9ebed4d
BS
3902 break;
3903 case 0x068: /* VIS I fandnot1 */
64a88d5d 3904 CHECK_FPU_FEATURE(dc, VIS1);
e2ea21b3
BS
3905 tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs2)], -1);
3906 tcg_gen_and_i32(cpu_fpr[DFPREG(rd)], cpu_tmp32,
3907 cpu_fpr[DFPREG(rs1)]);
3908 tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs2)], -1);
3909 tcg_gen_and_i32(cpu_fpr[DFPREG(rd) + 1], cpu_tmp32,
3910 cpu_fpr[DFPREG(rs1) + 1]);
e9ebed4d
BS
3911 break;
3912 case 0x069: /* VIS I fandnot1s */
64a88d5d 3913 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d
BS
3914 tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[rs2], -1);
3915 tcg_gen_and_i32(cpu_fpr[rd], cpu_tmp32, cpu_fpr[rs1]);
e9ebed4d
BS
3916 break;
3917 case 0x06a: /* VIS I fnot1 */
64a88d5d 3918 CHECK_FPU_FEATURE(dc, VIS1);
e2ea21b3
BS
3919 tcg_gen_xori_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
3920 -1);
3921 tcg_gen_xori_i32(cpu_fpr[DFPREG(rd) + 1],
3922 cpu_fpr[DFPREG(rs1) + 1], -1);
e9ebed4d
BS
3923 break;
3924 case 0x06b: /* VIS I fnot1s */
64a88d5d 3925 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d 3926 tcg_gen_xori_i32(cpu_fpr[rd], cpu_fpr[rs1], -1);
e9ebed4d
BS
3927 break;
3928 case 0x06c: /* VIS I fxor */
64a88d5d 3929 CHECK_FPU_FEATURE(dc, VIS1);
e2ea21b3
BS
3930 tcg_gen_xor_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
3931 cpu_fpr[DFPREG(rs2)]);
3932 tcg_gen_xor_i32(cpu_fpr[DFPREG(rd) + 1],
3933 cpu_fpr[DFPREG(rs1) + 1],
3934 cpu_fpr[DFPREG(rs2) + 1]);
e9ebed4d
BS
3935 break;
3936 case 0x06d: /* VIS I fxors */
64a88d5d 3937 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d 3938 tcg_gen_xor_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
e9ebed4d
BS
3939 break;
3940 case 0x06e: /* VIS I fnand */
64a88d5d 3941 CHECK_FPU_FEATURE(dc, VIS1);
e2ea21b3
BS
3942 tcg_gen_and_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1)],
3943 cpu_fpr[DFPREG(rs2)]);
3944 tcg_gen_xori_i32(cpu_fpr[DFPREG(rd)], cpu_tmp32, -1);
3945 tcg_gen_and_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1) + 1],
3946 cpu_fpr[DFPREG(rs2) + 1]);
3947 tcg_gen_xori_i32(cpu_fpr[DFPREG(rd) + 1], cpu_tmp32, -1);
e9ebed4d
BS
3948 break;
3949 case 0x06f: /* VIS I fnands */
64a88d5d 3950 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d
BS
3951 tcg_gen_and_i32(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
3952 tcg_gen_xori_i32(cpu_fpr[rd], cpu_tmp32, -1);
e9ebed4d
BS
3953 break;
3954 case 0x070: /* VIS I fand */
64a88d5d 3955 CHECK_FPU_FEATURE(dc, VIS1);
e2ea21b3
BS
3956 tcg_gen_and_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
3957 cpu_fpr[DFPREG(rs2)]);
3958 tcg_gen_and_i32(cpu_fpr[DFPREG(rd) + 1],
3959 cpu_fpr[DFPREG(rs1) + 1],
3960 cpu_fpr[DFPREG(rs2) + 1]);
e9ebed4d
BS
3961 break;
3962 case 0x071: /* VIS I fands */
64a88d5d 3963 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d 3964 tcg_gen_and_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
e9ebed4d
BS
3965 break;
3966 case 0x072: /* VIS I fxnor */
64a88d5d 3967 CHECK_FPU_FEATURE(dc, VIS1);
e2ea21b3
BS
3968 tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs2)], -1);
3969 tcg_gen_xor_i32(cpu_fpr[DFPREG(rd)], cpu_tmp32,
3970 cpu_fpr[DFPREG(rs1)]);
3971 tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs2) + 1], -1);
3972 tcg_gen_xor_i32(cpu_fpr[DFPREG(rd) + 1], cpu_tmp32,
3973 cpu_fpr[DFPREG(rs1) + 1]);
e9ebed4d
BS
3974 break;
3975 case 0x073: /* VIS I fxnors */
64a88d5d 3976 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d
BS
3977 tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[rs2], -1);
3978 tcg_gen_xor_i32(cpu_fpr[rd], cpu_tmp32, cpu_fpr[rs1]);
e9ebed4d 3979 break;
3299908c 3980 case 0x074: /* VIS I fsrc1 */
64a88d5d 3981 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d
BS
3982 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)]);
3983 tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1],
3984 cpu_fpr[DFPREG(rs1) + 1]);
3299908c
BS
3985 break;
3986 case 0x075: /* VIS I fsrc1s */
64a88d5d 3987 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d 3988 tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs1]);
3299908c 3989 break;
e9ebed4d 3990 case 0x076: /* VIS I fornot2 */
64a88d5d 3991 CHECK_FPU_FEATURE(dc, VIS1);
e2ea21b3
BS
3992 tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1)], -1);
3993 tcg_gen_or_i32(cpu_fpr[DFPREG(rd)], cpu_tmp32,
3994 cpu_fpr[DFPREG(rs2)]);
3995 tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs1) + 1], -1);
3996 tcg_gen_or_i32(cpu_fpr[DFPREG(rd) + 1], cpu_tmp32,
3997 cpu_fpr[DFPREG(rs2) + 1]);
e9ebed4d
BS
3998 break;
3999 case 0x077: /* VIS I fornot2s */
64a88d5d 4000 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d
BS
4001 tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[rs1], -1);
4002 tcg_gen_or_i32(cpu_fpr[rd], cpu_tmp32, cpu_fpr[rs2]);
e9ebed4d 4003 break;
3299908c 4004 case 0x078: /* VIS I fsrc2 */
64a88d5d 4005 CHECK_FPU_FEATURE(dc, VIS1);
2382dc6b
BS
4006 gen_op_load_fpr_DT0(DFPREG(rs2));
4007 gen_op_store_DT0_fpr(DFPREG(rd));
3299908c
BS
4008 break;
4009 case 0x079: /* VIS I fsrc2s */
64a88d5d 4010 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d 4011 tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);
3299908c 4012 break;
e9ebed4d 4013 case 0x07a: /* VIS I fornot1 */
64a88d5d 4014 CHECK_FPU_FEATURE(dc, VIS1);
e2ea21b3
BS
4015 tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs2)], -1);
4016 tcg_gen_or_i32(cpu_fpr[DFPREG(rd)], cpu_tmp32,
4017 cpu_fpr[DFPREG(rs1)]);
4018 tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs2) + 1], -1);
4019 tcg_gen_or_i32(cpu_fpr[DFPREG(rd) + 1], cpu_tmp32,
4020 cpu_fpr[DFPREG(rs1) + 1]);
e9ebed4d
BS
4021 break;
4022 case 0x07b: /* VIS I fornot1s */
64a88d5d 4023 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d
BS
4024 tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[rs2], -1);
4025 tcg_gen_or_i32(cpu_fpr[rd], cpu_tmp32, cpu_fpr[rs1]);
e9ebed4d
BS
4026 break;
4027 case 0x07c: /* VIS I for */
64a88d5d 4028 CHECK_FPU_FEATURE(dc, VIS1);
e2ea21b3
BS
4029 tcg_gen_or_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
4030 cpu_fpr[DFPREG(rs2)]);
4031 tcg_gen_or_i32(cpu_fpr[DFPREG(rd) + 1],
4032 cpu_fpr[DFPREG(rs1) + 1],
4033 cpu_fpr[DFPREG(rs2) + 1]);
e9ebed4d
BS
4034 break;
4035 case 0x07d: /* VIS I fors */
64a88d5d 4036 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d 4037 tcg_gen_or_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
e9ebed4d 4038 break;
3299908c 4039 case 0x07e: /* VIS I fone */
64a88d5d 4040 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d
BS
4041 tcg_gen_movi_i32(cpu_fpr[DFPREG(rd)], -1);
4042 tcg_gen_movi_i32(cpu_fpr[DFPREG(rd) + 1], -1);
3299908c
BS
4043 break;
4044 case 0x07f: /* VIS I fones */
64a88d5d 4045 CHECK_FPU_FEATURE(dc, VIS1);
1d01299d 4046 tcg_gen_movi_i32(cpu_fpr[rd], -1);
3299908c 4047 break;
e9ebed4d
BS
4048 case 0x080: /* VIS I shutdown */
4049 case 0x081: /* VIS II siam */
4050 // XXX
4051 goto illegal_insn;
3299908c
BS
4052 default:
4053 goto illegal_insn;
4054 }
4055#else
0f8a249a 4056 goto ncp_insn;
3299908c
BS
4057#endif
4058 } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
fcc72045 4059#ifdef TARGET_SPARC64
0f8a249a 4060 goto illegal_insn;
fcc72045 4061#else
0f8a249a 4062 goto ncp_insn;
fcc72045 4063#endif
3475187d 4064#ifdef TARGET_SPARC64
0f8a249a 4065 } else if (xop == 0x39) { /* V9 return */
2ea815ca
BS
4066 TCGv r_const;
4067
6ae20372 4068 save_state(dc, cpu_cond);
9322a4bf 4069 cpu_src1 = get_src1(insn, cpu_src1);
0f8a249a
BS
4070 if (IS_IMM) { /* immediate */
4071 rs2 = GET_FIELDs(insn, 19, 31);
6ae20372 4072 tcg_gen_addi_tl(cpu_dst, cpu_src1, (int)rs2);
0f8a249a 4073 } else { /* register */
3475187d 4074 rs2 = GET_FIELD(insn, 27, 31);
0f8a249a 4075 if (rs2) {
6ae20372
BS
4076 gen_movl_reg_TN(rs2, cpu_src2);
4077 tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
6f551262
BS
4078 } else
4079 tcg_gen_mov_tl(cpu_dst, cpu_src1);
3475187d 4080 }
72a9747b 4081 tcg_gen_helper_0_0(helper_restore);
6ae20372 4082 gen_mov_pc_npc(dc, cpu_cond);
2ea815ca
BS
4083 r_const = tcg_const_i32(3);
4084 tcg_gen_helper_0_2(helper_check_align, cpu_dst, r_const);
4085 tcg_temp_free(r_const);
6ae20372 4086 tcg_gen_mov_tl(cpu_npc, cpu_dst);
0f8a249a
BS
4087 dc->npc = DYNAMIC_PC;
4088 goto jmp_insn;
3475187d 4089#endif
0f8a249a 4090 } else {
9322a4bf 4091 cpu_src1 = get_src1(insn, cpu_src1);
0f8a249a
BS
4092 if (IS_IMM) { /* immediate */
4093 rs2 = GET_FIELDs(insn, 19, 31);
6ae20372 4094 tcg_gen_addi_tl(cpu_dst, cpu_src1, (int)rs2);
0f8a249a 4095 } else { /* register */
e80cfcfc 4096 rs2 = GET_FIELD(insn, 27, 31);
0f8a249a 4097 if (rs2) {
6ae20372
BS
4098 gen_movl_reg_TN(rs2, cpu_src2);
4099 tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
6f551262
BS
4100 } else
4101 tcg_gen_mov_tl(cpu_dst, cpu_src1);
cf495bcf 4102 }
0f8a249a
BS
4103 switch (xop) {
4104 case 0x38: /* jmpl */
4105 {
2ea815ca
BS
4106 TCGv r_const;
4107
4108 r_const = tcg_const_tl(dc->pc);
4109 gen_movl_TN_reg(rd, r_const);
4110 tcg_temp_free(r_const);
6ae20372 4111 gen_mov_pc_npc(dc, cpu_cond);
2ea815ca 4112 r_const = tcg_const_i32(3);
77f193da 4113 tcg_gen_helper_0_2(helper_check_align, cpu_dst,
2ea815ca
BS
4114 r_const);
4115 tcg_temp_free(r_const);
6ae20372 4116 tcg_gen_mov_tl(cpu_npc, cpu_dst);
0f8a249a
BS
4117 dc->npc = DYNAMIC_PC;
4118 }
4119 goto jmp_insn;
3475187d 4120#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
0f8a249a
BS
4121 case 0x39: /* rett, V9 return */
4122 {
2ea815ca
BS
4123 TCGv r_const;
4124
0f8a249a
BS
4125 if (!supervisor(dc))
4126 goto priv_insn;
6ae20372 4127 gen_mov_pc_npc(dc, cpu_cond);
2ea815ca 4128 r_const = tcg_const_i32(3);
77f193da 4129 tcg_gen_helper_0_2(helper_check_align, cpu_dst,
2ea815ca
BS
4130 r_const);
4131 tcg_temp_free(r_const);
6ae20372 4132 tcg_gen_mov_tl(cpu_npc, cpu_dst);
0f8a249a 4133 dc->npc = DYNAMIC_PC;
1a2fb1c0 4134 tcg_gen_helper_0_0(helper_rett);
0f8a249a
BS
4135 }
4136 goto jmp_insn;
4137#endif
4138 case 0x3b: /* flush */
5578ceab 4139 if (!((dc)->def->features & CPU_FEATURE_FLUSH))
64a88d5d 4140 goto unimp_flush;
6ae20372 4141 tcg_gen_helper_0_1(helper_flush, cpu_dst);
0f8a249a
BS
4142 break;
4143 case 0x3c: /* save */
6ae20372 4144 save_state(dc, cpu_cond);
72a9747b 4145 tcg_gen_helper_0_0(helper_save);
6ae20372 4146 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a
BS
4147 break;
4148 case 0x3d: /* restore */
6ae20372 4149 save_state(dc, cpu_cond);
72a9747b 4150 tcg_gen_helper_0_0(helper_restore);
6ae20372 4151 gen_movl_TN_reg(rd, cpu_dst);
0f8a249a 4152 break;
3475187d 4153#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
0f8a249a
BS
4154 case 0x3e: /* V9 done/retry */
4155 {
4156 switch (rd) {
4157 case 0:
4158 if (!supervisor(dc))
4159 goto priv_insn;
4160 dc->npc = DYNAMIC_PC;
4161 dc->pc = DYNAMIC_PC;
1a2fb1c0 4162 tcg_gen_helper_0_0(helper_done);
0f8a249a
BS
4163 goto jmp_insn;
4164 case 1:
4165 if (!supervisor(dc))
4166 goto priv_insn;
4167 dc->npc = DYNAMIC_PC;
4168 dc->pc = DYNAMIC_PC;
1a2fb1c0 4169 tcg_gen_helper_0_0(helper_retry);
0f8a249a
BS
4170 goto jmp_insn;
4171 default:
4172 goto illegal_insn;
4173 }
4174 }
4175 break;
4176#endif
4177 default:
4178 goto illegal_insn;
4179 }
cf495bcf 4180 }
0f8a249a
BS
4181 break;
4182 }
4183 break;
4184 case 3: /* load/store instructions */
4185 {
4186 unsigned int xop = GET_FIELD(insn, 7, 12);
9322a4bf 4187
9322a4bf 4188 cpu_src1 = get_src1(insn, cpu_src1);
71817e48 4189 if (xop == 0x3c || xop == 0x3e) { // V9 casa/casxa
81ad8ba2 4190 rs2 = GET_FIELD(insn, 27, 31);
6ae20372 4191 gen_movl_reg_TN(rs2, cpu_src2);
71817e48
BS
4192 tcg_gen_mov_tl(cpu_addr, cpu_src1);
4193 } else if (IS_IMM) { /* immediate */
0f8a249a 4194 rs2 = GET_FIELDs(insn, 19, 31);
6ae20372 4195 tcg_gen_addi_tl(cpu_addr, cpu_src1, (int)rs2);
0f8a249a
BS
4196 } else { /* register */
4197 rs2 = GET_FIELD(insn, 27, 31);
0f8a249a 4198 if (rs2 != 0) {
6ae20372
BS
4199 gen_movl_reg_TN(rs2, cpu_src2);
4200 tcg_gen_add_tl(cpu_addr, cpu_src1, cpu_src2);
6f551262
BS
4201 } else
4202 tcg_gen_mov_tl(cpu_addr, cpu_src1);
0f8a249a 4203 }
2f2ecb83
BS
4204 if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
4205 (xop > 0x17 && xop <= 0x1d ) ||
4206 (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
0f8a249a 4207 switch (xop) {
1a2fb1c0 4208 case 0x0: /* load unsigned word */
2cade6a3 4209 gen_address_mask(dc, cpu_addr);
6ae20372 4210 tcg_gen_qemu_ld32u(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a
BS
4211 break;
4212 case 0x1: /* load unsigned byte */
2cade6a3 4213 gen_address_mask(dc, cpu_addr);
6ae20372 4214 tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a
BS
4215 break;
4216 case 0x2: /* load unsigned halfword */
2cade6a3 4217 gen_address_mask(dc, cpu_addr);
6ae20372 4218 tcg_gen_qemu_ld16u(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a
BS
4219 break;
4220 case 0x3: /* load double word */
0f8a249a 4221 if (rd & 1)
d4218d99 4222 goto illegal_insn;
1a2fb1c0 4223 else {
2ea815ca
BS
4224 TCGv r_const;
4225
c2bc0e38 4226 save_state(dc, cpu_cond);
2ea815ca 4227 r_const = tcg_const_i32(7);
d987963a 4228 tcg_gen_helper_0_2(helper_check_align, cpu_addr,
2ea815ca
BS
4229 r_const); // XXX remove
4230 tcg_temp_free(r_const);
2cade6a3 4231 gen_address_mask(dc, cpu_addr);
6ae20372 4232 tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
32b6c812
BS
4233 tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
4234 tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffffULL);
4235 gen_movl_TN_reg(rd + 1, cpu_tmp0);
8911f501 4236 tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
6ae20372
BS
4237 tcg_gen_trunc_i64_tl(cpu_val, cpu_tmp64);
4238 tcg_gen_andi_tl(cpu_val, cpu_val, 0xffffffffULL);
1a2fb1c0 4239 }
0f8a249a
BS
4240 break;
4241 case 0x9: /* load signed byte */
2cade6a3 4242 gen_address_mask(dc, cpu_addr);
6ae20372 4243 tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a
BS
4244 break;
4245 case 0xa: /* load signed halfword */
2cade6a3 4246 gen_address_mask(dc, cpu_addr);
6ae20372 4247 tcg_gen_qemu_ld16s(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a
BS
4248 break;
4249 case 0xd: /* ldstub -- XXX: should be atomically */
2ea815ca
BS
4250 {
4251 TCGv r_const;
4252
2cade6a3 4253 gen_address_mask(dc, cpu_addr);
2ea815ca
BS
4254 tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
4255 r_const = tcg_const_tl(0xff);
4256 tcg_gen_qemu_st8(r_const, cpu_addr, dc->mem_idx);
4257 tcg_temp_free(r_const);
4258 }
0f8a249a 4259 break;
77f193da
BS
4260 case 0x0f: /* swap register with memory. Also
4261 atomically */
64a88d5d 4262 CHECK_IU_FEATURE(dc, SWAP);
6ae20372 4263 gen_movl_reg_TN(rd, cpu_val);
2cade6a3 4264 gen_address_mask(dc, cpu_addr);
6ae20372
BS
4265 tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
4266 tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
4267 tcg_gen_extu_i32_tl(cpu_val, cpu_tmp32);
0f8a249a 4268 break;
3475187d 4269#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
0f8a249a 4270 case 0x10: /* load word alternate */
3475187d 4271#ifndef TARGET_SPARC64
0f8a249a
BS
4272 if (IS_IMM)
4273 goto illegal_insn;
4274 if (!supervisor(dc))
4275 goto priv_insn;
6ea4a6c8 4276#endif
c2bc0e38 4277 save_state(dc, cpu_cond);
6ae20372 4278 gen_ld_asi(cpu_val, cpu_addr, insn, 4, 0);
0f8a249a
BS
4279 break;
4280 case 0x11: /* load unsigned byte alternate */
3475187d 4281#ifndef TARGET_SPARC64
0f8a249a
BS
4282 if (IS_IMM)
4283 goto illegal_insn;
4284 if (!supervisor(dc))
4285 goto priv_insn;
4286#endif
c2bc0e38 4287 save_state(dc, cpu_cond);
6ae20372 4288 gen_ld_asi(cpu_val, cpu_addr, insn, 1, 0);
0f8a249a
BS
4289 break;
4290 case 0x12: /* load unsigned halfword alternate */
3475187d 4291#ifndef TARGET_SPARC64
0f8a249a
BS
4292 if (IS_IMM)
4293 goto illegal_insn;
4294 if (!supervisor(dc))
4295 goto priv_insn;
3475187d 4296#endif
c2bc0e38 4297 save_state(dc, cpu_cond);
6ae20372 4298 gen_ld_asi(cpu_val, cpu_addr, insn, 2, 0);
0f8a249a
BS
4299 break;
4300 case 0x13: /* load double word alternate */
3475187d 4301#ifndef TARGET_SPARC64
0f8a249a
BS
4302 if (IS_IMM)
4303 goto illegal_insn;
4304 if (!supervisor(dc))
4305 goto priv_insn;
3475187d 4306#endif
0f8a249a 4307 if (rd & 1)
d4218d99 4308 goto illegal_insn;
c2bc0e38 4309 save_state(dc, cpu_cond);
db166940
BS
4310 gen_ldda_asi(cpu_val, cpu_addr, insn, rd);
4311 goto skip_move;
0f8a249a 4312 case 0x19: /* load signed byte alternate */
3475187d 4313#ifndef TARGET_SPARC64
0f8a249a
BS
4314 if (IS_IMM)
4315 goto illegal_insn;
4316 if (!supervisor(dc))
4317 goto priv_insn;
4318#endif
c2bc0e38 4319 save_state(dc, cpu_cond);
6ae20372 4320 gen_ld_asi(cpu_val, cpu_addr, insn, 1, 1);
0f8a249a
BS
4321 break;
4322 case 0x1a: /* load signed halfword alternate */
3475187d 4323#ifndef TARGET_SPARC64
0f8a249a
BS
4324 if (IS_IMM)
4325 goto illegal_insn;
4326 if (!supervisor(dc))
4327 goto priv_insn;
3475187d 4328#endif
c2bc0e38 4329 save_state(dc, cpu_cond);
6ae20372 4330 gen_ld_asi(cpu_val, cpu_addr, insn, 2, 1);
0f8a249a
BS
4331 break;
4332 case 0x1d: /* ldstuba -- XXX: should be atomically */
3475187d 4333#ifndef TARGET_SPARC64
0f8a249a
BS
4334 if (IS_IMM)
4335 goto illegal_insn;
4336 if (!supervisor(dc))
4337 goto priv_insn;
4338#endif
c2bc0e38 4339 save_state(dc, cpu_cond);
6ae20372 4340 gen_ldstub_asi(cpu_val, cpu_addr, insn);
0f8a249a 4341 break;
77f193da
BS
4342 case 0x1f: /* swap reg with alt. memory. Also
4343 atomically */
64a88d5d 4344 CHECK_IU_FEATURE(dc, SWAP);
3475187d 4345#ifndef TARGET_SPARC64
0f8a249a
BS
4346 if (IS_IMM)
4347 goto illegal_insn;
4348 if (!supervisor(dc))
4349 goto priv_insn;
6ea4a6c8 4350#endif
c2bc0e38 4351 save_state(dc, cpu_cond);
6ae20372
BS
4352 gen_movl_reg_TN(rd, cpu_val);
4353 gen_swap_asi(cpu_val, cpu_addr, insn);
0f8a249a 4354 break;
3475187d
FB
4355
4356#ifndef TARGET_SPARC64
0f8a249a
BS
4357 case 0x30: /* ldc */
4358 case 0x31: /* ldcsr */
4359 case 0x33: /* lddc */
4360 goto ncp_insn;
3475187d
FB
4361#endif
4362#endif
4363#ifdef TARGET_SPARC64
0f8a249a 4364 case 0x08: /* V9 ldsw */
2cade6a3 4365 gen_address_mask(dc, cpu_addr);
6ae20372 4366 tcg_gen_qemu_ld32s(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a
BS
4367 break;
4368 case 0x0b: /* V9 ldx */
2cade6a3 4369 gen_address_mask(dc, cpu_addr);
6ae20372 4370 tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a
BS
4371 break;
4372 case 0x18: /* V9 ldswa */
c2bc0e38 4373 save_state(dc, cpu_cond);
6ae20372 4374 gen_ld_asi(cpu_val, cpu_addr, insn, 4, 1);
0f8a249a
BS
4375 break;
4376 case 0x1b: /* V9 ldxa */
c2bc0e38 4377 save_state(dc, cpu_cond);
6ae20372 4378 gen_ld_asi(cpu_val, cpu_addr, insn, 8, 0);
0f8a249a
BS
4379 break;
4380 case 0x2d: /* V9 prefetch, no effect */
4381 goto skip_move;
4382 case 0x30: /* V9 ldfa */
c2bc0e38 4383 save_state(dc, cpu_cond);
6ae20372 4384 gen_ldf_asi(cpu_addr, insn, 4, rd);
81ad8ba2 4385 goto skip_move;
0f8a249a 4386 case 0x33: /* V9 lddfa */
c2bc0e38 4387 save_state(dc, cpu_cond);
6ae20372 4388 gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd));
81ad8ba2 4389 goto skip_move;
0f8a249a
BS
4390 case 0x3d: /* V9 prefetcha, no effect */
4391 goto skip_move;
4392 case 0x32: /* V9 ldqfa */
64a88d5d 4393 CHECK_FPU_FEATURE(dc, FLOAT128);
c2bc0e38 4394 save_state(dc, cpu_cond);
6ae20372 4395 gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd));
1f587329 4396 goto skip_move;
0f8a249a
BS
4397#endif
4398 default:
4399 goto illegal_insn;
4400 }
6ae20372 4401 gen_movl_TN_reg(rd, cpu_val);
db166940 4402#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
0f8a249a 4403 skip_move: ;
3475187d 4404#endif
0f8a249a 4405 } else if (xop >= 0x20 && xop < 0x24) {
6ae20372 4406 if (gen_trap_ifnofpu(dc, cpu_cond))
a80dde08 4407 goto jmp_insn;
c2bc0e38 4408 save_state(dc, cpu_cond);
0f8a249a
BS
4409 switch (xop) {
4410 case 0x20: /* load fpreg */
2cade6a3 4411 gen_address_mask(dc, cpu_addr);
714547bb 4412 tcg_gen_qemu_ld32u(cpu_fpr[rd], cpu_addr, dc->mem_idx);
0f8a249a 4413 break;
3a3b925d
BS
4414 case 0x21: /* ldfsr, V9 ldxfsr */
4415#ifdef TARGET_SPARC64
2cade6a3 4416 gen_address_mask(dc, cpu_addr);
3a3b925d
BS
4417 if (rd == 1) {
4418 tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
4419 tcg_gen_helper_0_1(helper_ldxfsr, cpu_tmp64);
4420 } else
4421#else
4422 {
4423 tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
4424 tcg_gen_helper_0_1(helper_ldfsr, cpu_tmp32);
4425 }
4426#endif
0f8a249a
BS
4427 break;
4428 case 0x22: /* load quad fpreg */
2ea815ca
BS
4429 {
4430 TCGv r_const;
4431
4432 CHECK_FPU_FEATURE(dc, FLOAT128);
4433 r_const = tcg_const_i32(dc->mem_idx);
4434 tcg_gen_helper_0_2(helper_ldqf, cpu_addr, r_const);
4435 tcg_temp_free(r_const);
4436 gen_op_store_QT0_fpr(QFPREG(rd));
4437 }
1f587329 4438 break;
0f8a249a 4439 case 0x23: /* load double fpreg */
2ea815ca
BS
4440 {
4441 TCGv r_const;
4442
4443 r_const = tcg_const_i32(dc->mem_idx);
4444 tcg_gen_helper_0_2(helper_lddf, cpu_addr, r_const);
4445 tcg_temp_free(r_const);
4446 gen_op_store_DT0_fpr(DFPREG(rd));
4447 }
0f8a249a
BS
4448 break;
4449 default:
4450 goto illegal_insn;
4451 }
4452 } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) || \
4453 xop == 0xe || xop == 0x1e) {
6ae20372 4454 gen_movl_reg_TN(rd, cpu_val);
0f8a249a 4455 switch (xop) {
1a2fb1c0 4456 case 0x4: /* store word */
2cade6a3 4457 gen_address_mask(dc, cpu_addr);
6ae20372 4458 tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a 4459 break;
1a2fb1c0 4460 case 0x5: /* store byte */
2cade6a3 4461 gen_address_mask(dc, cpu_addr);
6ae20372 4462 tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a 4463 break;
1a2fb1c0 4464 case 0x6: /* store halfword */
2cade6a3 4465 gen_address_mask(dc, cpu_addr);
6ae20372 4466 tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a 4467 break;
1a2fb1c0 4468 case 0x7: /* store double word */
0f8a249a 4469 if (rd & 1)
d4218d99 4470 goto illegal_insn;
1a2fb1c0 4471 else {
ab508019 4472 TCGv r_const;
1a2fb1c0 4473
c2bc0e38 4474 save_state(dc, cpu_cond);
2cade6a3 4475 gen_address_mask(dc, cpu_addr);
2ea815ca 4476 r_const = tcg_const_i32(7);
c2bc0e38 4477 tcg_gen_helper_0_2(helper_check_align, cpu_addr,
2ea815ca
BS
4478 r_const); // XXX remove
4479 tcg_temp_free(r_const);
a7ec4229 4480 gen_movl_reg_TN(rd + 1, cpu_tmp0);
ab508019 4481 tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, cpu_val);
6ae20372 4482 tcg_gen_qemu_st64(cpu_tmp64, cpu_addr, dc->mem_idx);
7fa76c0b 4483 }
0f8a249a 4484 break;
3475187d 4485#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1a2fb1c0 4486 case 0x14: /* store word alternate */
3475187d 4487#ifndef TARGET_SPARC64
0f8a249a
BS
4488 if (IS_IMM)
4489 goto illegal_insn;
4490 if (!supervisor(dc))
4491 goto priv_insn;
6ea4a6c8 4492#endif
c2bc0e38 4493 save_state(dc, cpu_cond);
6ae20372 4494 gen_st_asi(cpu_val, cpu_addr, insn, 4);
d39c0b99 4495 break;
1a2fb1c0 4496 case 0x15: /* store byte alternate */
3475187d 4497#ifndef TARGET_SPARC64
0f8a249a
BS
4498 if (IS_IMM)
4499 goto illegal_insn;
4500 if (!supervisor(dc))
4501 goto priv_insn;
3475187d 4502#endif
c2bc0e38 4503 save_state(dc, cpu_cond);
6ae20372 4504 gen_st_asi(cpu_val, cpu_addr, insn, 1);
d39c0b99 4505 break;
1a2fb1c0 4506 case 0x16: /* store halfword alternate */
3475187d 4507#ifndef TARGET_SPARC64
0f8a249a
BS
4508 if (IS_IMM)
4509 goto illegal_insn;
4510 if (!supervisor(dc))
4511 goto priv_insn;
6ea4a6c8 4512#endif
c2bc0e38 4513 save_state(dc, cpu_cond);
6ae20372 4514 gen_st_asi(cpu_val, cpu_addr, insn, 2);
d39c0b99 4515 break;
1a2fb1c0 4516 case 0x17: /* store double word alternate */
3475187d 4517#ifndef TARGET_SPARC64
0f8a249a
BS
4518 if (IS_IMM)
4519 goto illegal_insn;
4520 if (!supervisor(dc))
4521 goto priv_insn;
3475187d 4522#endif
0f8a249a 4523 if (rd & 1)
d4218d99 4524 goto illegal_insn;
1a2fb1c0 4525 else {
c2bc0e38 4526 save_state(dc, cpu_cond);
6ae20372 4527 gen_stda_asi(cpu_val, cpu_addr, insn, rd);
1a2fb1c0 4528 }
d39c0b99 4529 break;
e80cfcfc 4530#endif
3475187d 4531#ifdef TARGET_SPARC64
0f8a249a 4532 case 0x0e: /* V9 stx */
2cade6a3 4533 gen_address_mask(dc, cpu_addr);
6ae20372 4534 tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx);
0f8a249a
BS
4535 break;
4536 case 0x1e: /* V9 stxa */
c2bc0e38 4537 save_state(dc, cpu_cond);
6ae20372 4538 gen_st_asi(cpu_val, cpu_addr, insn, 8);
0f8a249a 4539 break;
3475187d 4540#endif
0f8a249a
BS
4541 default:
4542 goto illegal_insn;
4543 }
4544 } else if (xop > 0x23 && xop < 0x28) {
6ae20372 4545 if (gen_trap_ifnofpu(dc, cpu_cond))
a80dde08 4546 goto jmp_insn;
c2bc0e38 4547 save_state(dc, cpu_cond);
0f8a249a 4548 switch (xop) {
ce8536e2 4549 case 0x24: /* store fpreg */
2cade6a3 4550 gen_address_mask(dc, cpu_addr);
714547bb 4551 tcg_gen_qemu_st32(cpu_fpr[rd], cpu_addr, dc->mem_idx);
0f8a249a
BS
4552 break;
4553 case 0x25: /* stfsr, V9 stxfsr */
3a3b925d 4554#ifdef TARGET_SPARC64
2cade6a3 4555 gen_address_mask(dc, cpu_addr);
3a3b925d
BS
4556 tcg_gen_ld_i64(cpu_tmp64, cpu_env, offsetof(CPUState, fsr));
4557 if (rd == 1)
4558 tcg_gen_qemu_st64(cpu_tmp64, cpu_addr, dc->mem_idx);
4559 else {
4560 tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp64);
4561 tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx);
4562 }
4563#else
4564 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUState, fsr));
6ae20372 4565 tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx);
3a3b925d 4566#endif
0f8a249a 4567 break;
1f587329
BS
4568 case 0x26:
4569#ifdef TARGET_SPARC64
1f587329 4570 /* V9 stqf, store quad fpreg */
2ea815ca
BS
4571 {
4572 TCGv r_const;
4573
4574 CHECK_FPU_FEATURE(dc, FLOAT128);
4575 gen_op_load_fpr_QT0(QFPREG(rd));
4576 r_const = tcg_const_i32(dc->mem_idx);
4577 tcg_gen_helper_0_2(helper_stqf, cpu_addr, r_const);
4578 tcg_temp_free(r_const);
4579 }
1f587329 4580 break;
1f587329
BS
4581#else /* !TARGET_SPARC64 */
4582 /* stdfq, store floating point queue */
4583#if defined(CONFIG_USER_ONLY)
4584 goto illegal_insn;
4585#else
0f8a249a
BS
4586 if (!supervisor(dc))
4587 goto priv_insn;
6ae20372 4588 if (gen_trap_ifnofpu(dc, cpu_cond))
0f8a249a
BS
4589 goto jmp_insn;
4590 goto nfq_insn;
1f587329 4591#endif
0f8a249a 4592#endif
7fa76c0b 4593 case 0x27: /* store double fpreg */
2ea815ca
BS
4594 {
4595 TCGv r_const;
4596
4597 gen_op_load_fpr_DT0(DFPREG(rd));
4598 r_const = tcg_const_i32(dc->mem_idx);
4599 tcg_gen_helper_0_2(helper_stdf, cpu_addr, r_const);
4600 tcg_temp_free(r_const);
4601 }
0f8a249a
BS
4602 break;
4603 default:
4604 goto illegal_insn;
4605 }
4606 } else if (xop > 0x33 && xop < 0x3f) {
c2bc0e38 4607 save_state(dc, cpu_cond);
0f8a249a 4608 switch (xop) {
a4d17f19 4609#ifdef TARGET_SPARC64
0f8a249a 4610 case 0x34: /* V9 stfa */
6ae20372 4611 gen_stf_asi(cpu_addr, insn, 4, rd);
0f8a249a 4612 break;
1f587329 4613 case 0x36: /* V9 stqfa */
2ea815ca
BS
4614 {
4615 TCGv r_const;
4616
4617 CHECK_FPU_FEATURE(dc, FLOAT128);
4618 r_const = tcg_const_i32(7);
4619 tcg_gen_helper_0_2(helper_check_align, cpu_addr,
4620 r_const);
4621 tcg_temp_free(r_const);
4622 gen_op_load_fpr_QT0(QFPREG(rd));
4623 gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd));
4624 }
1f587329 4625 break;
0f8a249a 4626 case 0x37: /* V9 stdfa */
3391c818 4627 gen_op_load_fpr_DT0(DFPREG(rd));
6ae20372 4628 gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
0f8a249a
BS
4629 break;
4630 case 0x3c: /* V9 casa */
71817e48 4631 gen_cas_asi(cpu_val, cpu_addr, cpu_src2, insn, rd);
6ae20372 4632 gen_movl_TN_reg(rd, cpu_val);
0f8a249a
BS
4633 break;
4634 case 0x3e: /* V9 casxa */
71817e48 4635 gen_casx_asi(cpu_val, cpu_addr, cpu_src2, insn, rd);
6ae20372 4636 gen_movl_TN_reg(rd, cpu_val);
0f8a249a 4637 break;
a4d17f19 4638#else
0f8a249a
BS
4639 case 0x34: /* stc */
4640 case 0x35: /* stcsr */
4641 case 0x36: /* stdcq */
4642 case 0x37: /* stdc */
4643 goto ncp_insn;
4644#endif
4645 default:
4646 goto illegal_insn;
4647 }
e8af50a3 4648 }
0f8a249a
BS
4649 else
4650 goto illegal_insn;
4651 }
4652 break;
cf495bcf
FB
4653 }
4654 /* default case for non jump instructions */
72cbca10 4655 if (dc->npc == DYNAMIC_PC) {
0f8a249a
BS
4656 dc->pc = DYNAMIC_PC;
4657 gen_op_next_insn();
72cbca10
FB
4658 } else if (dc->npc == JUMP_PC) {
4659 /* we can do a static jump */
6ae20372 4660 gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
72cbca10
FB
4661 dc->is_br = 1;
4662 } else {
0f8a249a
BS
4663 dc->pc = dc->npc;
4664 dc->npc = dc->npc + 4;
cf495bcf 4665 }
e80cfcfc 4666 jmp_insn:
cf495bcf
FB
4667 return;
4668 illegal_insn:
2ea815ca
BS
4669 {
4670 TCGv r_const;
4671
4672 save_state(dc, cpu_cond);
4673 r_const = tcg_const_i32(TT_ILL_INSN);
4674 tcg_gen_helper_0_1(raise_exception, r_const);
4675 tcg_temp_free(r_const);
4676 dc->is_br = 1;
4677 }
e8af50a3 4678 return;
64a88d5d 4679 unimp_flush:
2ea815ca
BS
4680 {
4681 TCGv r_const;
4682
4683 save_state(dc, cpu_cond);
4684 r_const = tcg_const_i32(TT_UNIMP_FLUSH);
4685 tcg_gen_helper_0_1(raise_exception, r_const);
4686 tcg_temp_free(r_const);
4687 dc->is_br = 1;
4688 }
64a88d5d 4689 return;
e80cfcfc 4690#if !defined(CONFIG_USER_ONLY)
e8af50a3 4691 priv_insn:
2ea815ca
BS
4692 {
4693 TCGv r_const;
4694
4695 save_state(dc, cpu_cond);
4696 r_const = tcg_const_i32(TT_PRIV_INSN);
4697 tcg_gen_helper_0_1(raise_exception, r_const);
4698 tcg_temp_free(r_const);
4699 dc->is_br = 1;
4700 }
e80cfcfc 4701 return;
64a88d5d 4702#endif
e80cfcfc 4703 nfpu_insn:
6ae20372 4704 save_state(dc, cpu_cond);
e80cfcfc
FB
4705 gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
4706 dc->is_br = 1;
fcc72045 4707 return;
64a88d5d 4708#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
9143e598 4709 nfq_insn:
6ae20372 4710 save_state(dc, cpu_cond);
9143e598
BS
4711 gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
4712 dc->is_br = 1;
4713 return;
4714#endif
fcc72045
BS
4715#ifndef TARGET_SPARC64
4716 ncp_insn:
2ea815ca
BS
4717 {
4718 TCGv r_const;
4719
4720 save_state(dc, cpu_cond);
4721 r_const = tcg_const_i32(TT_NCP_INSN);
4722 tcg_gen_helper_0_1(raise_exception, r_const);
4723 tcg_temp_free(r_const);
4724 dc->is_br = 1;
4725 }
fcc72045
BS
4726 return;
4727#endif
7a3f1944
FB
4728}
4729
2cfc5f17
TS
4730static inline void gen_intermediate_code_internal(TranslationBlock * tb,
4731 int spc, CPUSPARCState *env)
7a3f1944 4732{
72cbca10 4733 target_ulong pc_start, last_pc;
cf495bcf
FB
4734 uint16_t *gen_opc_end;
4735 DisasContext dc1, *dc = &dc1;
e8af50a3 4736 int j, lj = -1;
2e70f6ef
PB
4737 int num_insns;
4738 int max_insns;
cf495bcf
FB
4739
4740 memset(dc, 0, sizeof(DisasContext));
cf495bcf 4741 dc->tb = tb;
72cbca10 4742 pc_start = tb->pc;
cf495bcf 4743 dc->pc = pc_start;
e80cfcfc 4744 last_pc = dc->pc;
72cbca10 4745 dc->npc = (target_ulong) tb->cs_base;
6f27aba6 4746 dc->mem_idx = cpu_mmu_index(env);
5578ceab
BS
4747 dc->def = env->def;
4748 if ((dc->def->features & CPU_FEATURE_FLOAT))
64a88d5d 4749 dc->fpu_enabled = cpu_fpu_enabled(env);
5578ceab 4750 else
64a88d5d 4751 dc->fpu_enabled = 0;
2cade6a3
BS
4752#ifdef TARGET_SPARC64
4753 dc->address_mask_32bit = env->pstate & PS_AM;
4754#endif
cf495bcf 4755 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
cf495bcf 4756
1a2fb1c0 4757 cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
8911f501
BS
4758 cpu_tmp32 = tcg_temp_new(TCG_TYPE_I32);
4759 cpu_tmp64 = tcg_temp_new(TCG_TYPE_I64);
d987963a
BS
4760
4761 cpu_dst = tcg_temp_local_new(TCG_TYPE_TL);
4762
4763 // loads and stores
3f0436fe 4764 cpu_val = tcg_temp_local_new(TCG_TYPE_TL);
d987963a 4765 cpu_addr = tcg_temp_local_new(TCG_TYPE_TL);
1a2fb1c0 4766
2e70f6ef
PB
4767 num_insns = 0;
4768 max_insns = tb->cflags & CF_COUNT_MASK;
4769 if (max_insns == 0)
4770 max_insns = CF_COUNT_MASK;
4771 gen_icount_start();
cf495bcf 4772 do {
e8af50a3
FB
4773 if (env->nb_breakpoints > 0) {
4774 for(j = 0; j < env->nb_breakpoints; j++) {
4775 if (env->breakpoints[j] == dc->pc) {
0f8a249a 4776 if (dc->pc != pc_start)
6ae20372 4777 save_state(dc, cpu_cond);
1a2fb1c0 4778 tcg_gen_helper_0_0(helper_debug);
57fec1fe 4779 tcg_gen_exit_tb(0);
0f8a249a 4780 dc->is_br = 1;
e80cfcfc 4781 goto exit_gen_loop;
e8af50a3
FB
4782 }
4783 }
4784 }
4785 if (spc) {
4786 if (loglevel > 0)
4787 fprintf(logfile, "Search PC...\n");
4788 j = gen_opc_ptr - gen_opc_buf;
4789 if (lj < j) {
4790 lj++;
4791 while (lj < j)
4792 gen_opc_instr_start[lj++] = 0;
4793 gen_opc_pc[lj] = dc->pc;
4794 gen_opc_npc[lj] = dc->npc;
4795 gen_opc_instr_start[lj] = 1;
2e70f6ef 4796 gen_opc_icount[lj] = num_insns;
e8af50a3
FB
4797 }
4798 }
2e70f6ef
PB
4799 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
4800 gen_io_start();
0f8a249a
BS
4801 last_pc = dc->pc;
4802 disas_sparc_insn(dc);
2e70f6ef 4803 num_insns++;
0f8a249a
BS
4804
4805 if (dc->is_br)
4806 break;
4807 /* if the next PC is different, we abort now */
4808 if (dc->pc != (last_pc + 4))
4809 break;
d39c0b99
FB
4810 /* if we reach a page boundary, we stop generation so that the
4811 PC of a TT_TFAULT exception is always in the right page */
4812 if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
4813 break;
e80cfcfc
FB
4814 /* if single step mode, we generate only one instruction and
4815 generate an exception */
4816 if (env->singlestep_enabled) {
2f5680ee 4817 tcg_gen_movi_tl(cpu_pc, dc->pc);
57fec1fe 4818 tcg_gen_exit_tb(0);
e80cfcfc
FB
4819 break;
4820 }
cf495bcf 4821 } while ((gen_opc_ptr < gen_opc_end) &&
2e70f6ef
PB
4822 (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32) &&
4823 num_insns < max_insns);
e80cfcfc
FB
4824
4825 exit_gen_loop:
d987963a 4826 tcg_temp_free(cpu_addr);
3f0436fe 4827 tcg_temp_free(cpu_val);
d987963a 4828 tcg_temp_free(cpu_dst);
2ea815ca
BS
4829 tcg_temp_free(cpu_tmp64);
4830 tcg_temp_free(cpu_tmp32);
4831 tcg_temp_free(cpu_tmp0);
2e70f6ef
PB
4832 if (tb->cflags & CF_LAST_IO)
4833 gen_io_end();
72cbca10 4834 if (!dc->is_br) {
5fafdf24 4835 if (dc->pc != DYNAMIC_PC &&
72cbca10
FB
4836 (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
4837 /* static PC and NPC: we can use direct chaining */
2f5680ee 4838 gen_goto_tb(dc, 0, dc->pc, dc->npc);
72cbca10
FB
4839 } else {
4840 if (dc->pc != DYNAMIC_PC)
2f5680ee 4841 tcg_gen_movi_tl(cpu_pc, dc->pc);
6ae20372 4842 save_npc(dc, cpu_cond);
57fec1fe 4843 tcg_gen_exit_tb(0);
72cbca10
FB
4844 }
4845 }
2e70f6ef 4846 gen_icount_end(tb, num_insns);
cf495bcf 4847 *gen_opc_ptr = INDEX_op_end;
e8af50a3
FB
4848 if (spc) {
4849 j = gen_opc_ptr - gen_opc_buf;
4850 lj++;
4851 while (lj <= j)
4852 gen_opc_instr_start[lj++] = 0;
e8af50a3
FB
4853#if 0
4854 if (loglevel > 0) {
4855 page_dump(logfile);
4856 }
4857#endif
c3278b7b
FB
4858 gen_opc_jump_pc[0] = dc->jump_pc[0];
4859 gen_opc_jump_pc[1] = dc->jump_pc[1];
e8af50a3 4860 } else {
e80cfcfc 4861 tb->size = last_pc + 4 - pc_start;
2e70f6ef 4862 tb->icount = num_insns;
e8af50a3 4863 }
7a3f1944 4864#ifdef DEBUG_DISAS
e19e89a5 4865 if (loglevel & CPU_LOG_TB_IN_ASM) {
0f8a249a
BS
4866 fprintf(logfile, "--------------\n");
4867 fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
4868 target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
4869 fprintf(logfile, "\n");
cf495bcf 4870 }
7a3f1944 4871#endif
7a3f1944
FB
4872}
4873
2cfc5f17 4874void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
7a3f1944 4875{
2cfc5f17 4876 gen_intermediate_code_internal(tb, 0, env);
7a3f1944
FB
4877}
4878
2cfc5f17 4879void gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
7a3f1944 4880{
2cfc5f17 4881 gen_intermediate_code_internal(tb, 1, env);
7a3f1944
FB
4882}
4883
c48fcb47 4884void gen_intermediate_code_init(CPUSPARCState *env)
e80cfcfc 4885{
f5069b26 4886 unsigned int i;
c48fcb47 4887 static int inited;
f5069b26
BS
4888 static const char * const gregnames[8] = {
4889 NULL, // g0 not used
4890 "g1",
4891 "g2",
4892 "g3",
4893 "g4",
4894 "g5",
4895 "g6",
4896 "g7",
4897 };
714547bb
BS
4898 static const char * const fregnames[64] = {
4899 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
4900 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
4901 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
4902 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
4903 "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
4904 "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
4905 "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
4906 "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
4907 };
aaed909a 4908
1a2fb1c0
BS
4909 /* init various static tables */
4910 if (!inited) {
4911 inited = 1;
4912
1a2fb1c0 4913 cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
db4a4ea4
BS
4914 cpu_regwptr = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
4915 offsetof(CPUState, regwptr),
4916 "regwptr");
1a2fb1c0 4917#ifdef TARGET_SPARC64
dc99a3f2
BS
4918 cpu_xcc = tcg_global_mem_new(TCG_TYPE_I32,
4919 TCG_AREG0, offsetof(CPUState, xcc),
4920 "xcc");
255e1fcb
BS
4921 cpu_asi = tcg_global_mem_new(TCG_TYPE_I32,
4922 TCG_AREG0, offsetof(CPUState, asi),
4923 "asi");
4924 cpu_fprs = tcg_global_mem_new(TCG_TYPE_I32,
4925 TCG_AREG0, offsetof(CPUState, fprs),
4926 "fprs");
4927 cpu_gsr = tcg_global_mem_new(TCG_TYPE_TL,
4928 TCG_AREG0, offsetof(CPUState, gsr),
4929 "gsr");
4930 cpu_tick_cmpr = tcg_global_mem_new(TCG_TYPE_TL,
4931 TCG_AREG0,
4932 offsetof(CPUState, tick_cmpr),
4933 "tick_cmpr");
4934 cpu_stick_cmpr = tcg_global_mem_new(TCG_TYPE_TL,
4935 TCG_AREG0,
4936 offsetof(CPUState, stick_cmpr),
4937 "stick_cmpr");
4938 cpu_hstick_cmpr = tcg_global_mem_new(TCG_TYPE_TL,
4939 TCG_AREG0,
4940 offsetof(CPUState, hstick_cmpr),
4941 "hstick_cmpr");
4942 cpu_hintp = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4943 offsetof(CPUState, hintp),
4944 "hintp");
4945 cpu_htba = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4946 offsetof(CPUState, htba),
4947 "htba");
4948 cpu_hver = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4949 offsetof(CPUState, hver),
4950 "hver");
4951 cpu_ssr = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4952 offsetof(CPUState, ssr), "ssr");
4953 cpu_ver = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4954 offsetof(CPUState, version), "ver");
4955#else
4956 cpu_wim = tcg_global_mem_new(TCG_TYPE_I32,
4957 TCG_AREG0, offsetof(CPUState, wim),
4958 "wim");
1a2fb1c0 4959#endif
7c60cc4b 4960 cpu_cond = tcg_global_mem_new(TCG_TYPE_TL,
77f193da
BS
4961 TCG_AREG0, offsetof(CPUState, cond),
4962 "cond");
dc99a3f2
BS
4963 cpu_cc_src = tcg_global_mem_new(TCG_TYPE_TL,
4964 TCG_AREG0, offsetof(CPUState, cc_src),
4965 "cc_src");
d9bdab86
BS
4966 cpu_cc_src2 = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4967 offsetof(CPUState, cc_src2),
4968 "cc_src2");
dc99a3f2
BS
4969 cpu_cc_dst = tcg_global_mem_new(TCG_TYPE_TL,
4970 TCG_AREG0, offsetof(CPUState, cc_dst),
4971 "cc_dst");
4972 cpu_psr = tcg_global_mem_new(TCG_TYPE_I32,
4973 TCG_AREG0, offsetof(CPUState, psr),
4974 "psr");
87e92502
BS
4975 cpu_fsr = tcg_global_mem_new(TCG_TYPE_TL,
4976 TCG_AREG0, offsetof(CPUState, fsr),
4977 "fsr");
48d5c82b
BS
4978 cpu_pc = tcg_global_mem_new(TCG_TYPE_TL,
4979 TCG_AREG0, offsetof(CPUState, pc),
4980 "pc");
4981 cpu_npc = tcg_global_mem_new(TCG_TYPE_TL,
4982 TCG_AREG0, offsetof(CPUState, npc),
4983 "npc");
255e1fcb
BS
4984 cpu_y = tcg_global_mem_new(TCG_TYPE_TL,
4985 TCG_AREG0, offsetof(CPUState, y), "y");
4986#ifndef CONFIG_USER_ONLY
4987 cpu_tbr = tcg_global_mem_new(TCG_TYPE_TL,
4988 TCG_AREG0, offsetof(CPUState, tbr),
4989 "tbr");
4990#endif
f5069b26
BS
4991 for (i = 1; i < 8; i++)
4992 cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
4993 offsetof(CPUState, gregs[i]),
4994 gregnames[i]);
714547bb
BS
4995 for (i = 0; i < TARGET_FPREGS; i++)
4996 cpu_fpr[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
4997 offsetof(CPUState, fpr[i]),
4998 fregnames[i]);
4999
c9e03d8f
BS
5000 /* register helpers */
5001
5002#undef DEF_HELPER
5003#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
5004#include "helper.h"
1a2fb1c0 5005 }
658138bc 5006}
d2856f1a
AJ
5007
5008void gen_pc_load(CPUState *env, TranslationBlock *tb,
5009 unsigned long searched_pc, int pc_pos, void *puc)
5010{
5011 target_ulong npc;
5012 env->pc = gen_opc_pc[pc_pos];
5013 npc = gen_opc_npc[pc_pos];
5014 if (npc == 1) {
5015 /* dynamic NPC: already stored */
5016 } else if (npc == 2) {
5017 target_ulong t2 = (target_ulong)(unsigned long)puc;
5018 /* jump PC: use T2 and the jump targets of the translation */
5019 if (t2)
5020 env->npc = gen_opc_jump_pc[0];
5021 else
5022 env->npc = gen_opc_jump_pc[1];
5023 } else {
5024 env->npc = npc;
5025 }
5026}