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