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