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