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