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