translate.c 162.1 KB
Newer Older
1 2 3 4
/*
   SPARC translation

   Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
B
bellard 已提交
5
   Copyright (C) 2003-2005 Fabrice Bellard
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/*
   TODO-list:

B
bellard 已提交
25
   Rest of V9 instructions, VIS instructions
B
bellard 已提交
26
   NPC/PC static optimisations (use JUMP_TB when possible)
27
   Optimize synthetic instructions
B
bellard 已提交
28
*/
29 30 31 32 33 34 35 36 37 38

#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>

#include "cpu.h"
#include "exec-all.h"
#include "disas.h"
B
blueswir1 已提交
39
#include "helper.h"
B
bellard 已提交
40
#include "tcg-op.h"
41 42 43

#define DEBUG_DISAS

B
bellard 已提交
44 45 46 47
#define DYNAMIC_PC  1 /* dynamic pc value */
#define JUMP_PC     2 /* dynamic pc value which takes only two values
                         according to jump_pc[T2] */

B
blueswir1 已提交
48 49 50 51 52
/* global register indexes */
static TCGv cpu_env, cpu_T[3], cpu_regwptr;
/* local register indexes (only used inside old micro ops) */
static TCGv cpu_tmp0;

53
typedef struct DisasContext {
B
blueswir1 已提交
54 55
    target_ulong pc;    /* current Program Counter: integer or DYNAMIC_PC */
    target_ulong npc;   /* next PC: integer or DYNAMIC_PC or JUMP_PC */
B
bellard 已提交
56
    target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
57
    int is_br;
58
    int mem_idx;
B
bellard 已提交
59
    int fpu_enabled;
60
    struct TranslationBlock *tb;
61 62
} DisasContext;

B
bellard 已提交
63 64
typedef struct sparc_def_t sparc_def_t;

B
blueswir1 已提交
65 66 67 68 69
struct sparc_def_t {
    const unsigned char *name;
    target_ulong iu_version;
    uint32_t fpu_version;
    uint32_t mmu_version;
70
    uint32_t mmu_bm;
71 72 73 74
    uint32_t mmu_ctpr_mask;
    uint32_t mmu_cxr_mask;
    uint32_t mmu_sfsr_mask;
    uint32_t mmu_trcr_mask;
B
blueswir1 已提交
75 76
};

B
bellard 已提交
77 78
static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name);

79 80 81
extern FILE *logfile;
extern int loglevel;

B
bellard 已提交
82
// This function uses non-native bit order
83 84 85
#define GET_FIELD(X, FROM, TO) \
  ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))

B
bellard 已提交
86 87 88 89 90
// This function uses the order in the manuals, i.e. bit 0 is 2^0
#define GET_FIELD_SP(X, FROM, TO) \
    GET_FIELD(X, 31 - (TO), 31 - (FROM))

#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
B
blueswir1 已提交
91
#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
B
bellard 已提交
92 93

#ifdef TARGET_SPARC64
94
#define DFPREG(r) (((r & 1) << 5) | (r & 0x1e))
B
blueswir1 已提交
95
#define QFPREG(r) (((r & 1) << 5) | (r & 0x1c))
B
bellard 已提交
96
#else
97
#define DFPREG(r) (r & 0x1e)
B
blueswir1 已提交
98
#define QFPREG(r) (r & 0x1c)
B
bellard 已提交
99 100 101 102 103 104 105 106
#endif

static int sign_extend(int x, int len)
{
    len = 32 - len;
    return (x << len) >> len;
}

107 108
#define IS_IMM (insn & (1<<13))

109
static void disas_sparc_insn(DisasContext * dc);
110

B
bellard 已提交
111 112
#ifdef TARGET_SPARC64
#define GEN32(func, NAME) \
B
blueswir1 已提交
113
static GenOpFunc * const NAME ## _table [64] = {                              \
B
bellard 已提交
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
NAME ## 32, 0, NAME ## 34, 0, NAME ## 36, 0, NAME ## 38, 0,                   \
NAME ## 40, 0, NAME ## 42, 0, NAME ## 44, 0, NAME ## 46, 0,                   \
NAME ## 48, 0, NAME ## 50, 0, NAME ## 52, 0, NAME ## 54, 0,                   \
NAME ## 56, 0, NAME ## 58, 0, NAME ## 60, 0, NAME ## 62, 0,                   \
};                                                                            \
static inline void func(int n)                                                \
{                                                                             \
    NAME ## _table[n]();                                                      \
}
#else
132
#define GEN32(func, NAME) \
B
blueswir1 已提交
133
static GenOpFunc *const NAME ## _table [32] = {                               \
134 135 136 137 138 139 140 141 142 143 144 145 146
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
};                                                                            \
static inline void func(int n)                                                \
{                                                                             \
    NAME ## _table[n]();                                                      \
}
B
bellard 已提交
147
#endif
148 149 150 151 152 153 154 155 156 157 158 159

/* floating point registers moves */
GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fprf);
GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fprf);
GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fprf);
GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fprf);

GEN32(gen_op_load_fpr_DT0, gen_op_load_fpr_DT0_fprf);
GEN32(gen_op_load_fpr_DT1, gen_op_load_fpr_DT1_fprf);
GEN32(gen_op_store_DT0_fpr, gen_op_store_DT0_fpr_fprf);
GEN32(gen_op_store_DT1_fpr, gen_op_store_DT1_fpr_fprf);

B
blueswir1 已提交
160 161 162 163 164 165 166
#if defined(CONFIG_USER_ONLY)
GEN32(gen_op_load_fpr_QT0, gen_op_load_fpr_QT0_fprf);
GEN32(gen_op_load_fpr_QT1, gen_op_load_fpr_QT1_fprf);
GEN32(gen_op_store_QT0_fpr, gen_op_store_QT0_fpr_fprf);
GEN32(gen_op_store_QT1_fpr, gen_op_store_QT1_fpr_fprf);
#endif

167 168
/* moves */
#ifdef CONFIG_USER_ONLY
B
bellard 已提交
169
#define supervisor(dc) 0
170
#ifdef TARGET_SPARC64
B
blueswir1 已提交
171
#define hypervisor(dc) 0
172
#endif
B
bellard 已提交
173 174
#define gen_op_ldst(name)        gen_op_##name##_raw()
#else
B
blueswir1 已提交
175
#define supervisor(dc) (dc->mem_idx >= 1)
176 177
#ifdef TARGET_SPARC64
#define hypervisor(dc) (dc->mem_idx == 2)
B
blueswir1 已提交
178 179 180 181 182 183 184
#define OP_LD_TABLE(width)                                              \
    static GenOpFunc * const gen_op_##width[] = {                       \
        &gen_op_##width##_user,                                         \
        &gen_op_##width##_kernel,                                       \
        &gen_op_##width##_hypv,                                         \
    };
#else
B
blueswir1 已提交
185
#define OP_LD_TABLE(width)                                              \
B
blueswir1 已提交
186
    static GenOpFunc * const gen_op_##width[] = {                       \
B
blueswir1 已提交
187 188
        &gen_op_##width##_user,                                         \
        &gen_op_##width##_kernel,                                       \
189
    };
B
bellard 已提交
190
#endif
B
blueswir1 已提交
191 192
#define gen_op_ldst(name)        (*gen_op_##name[dc->mem_idx])()
#endif
193

194
#ifndef CONFIG_USER_ONLY
B
blueswir1 已提交
195 196 197
#ifdef __i386__
OP_LD_TABLE(std);
#endif /* __i386__ */
198 199 200 201
OP_LD_TABLE(stf);
OP_LD_TABLE(stdf);
OP_LD_TABLE(ldf);
OP_LD_TABLE(lddf);
202 203
#endif

B
blueswir1 已提交
204 205 206 207 208
#ifdef TARGET_ABI32
#define ABI32_MASK(addr) tcg_gen_andi_i64(addr, addr, 0xffffffffULL);
#else
#define ABI32_MASK(addr)
#endif
209

B
blueswir1 已提交
210
static inline void gen_movl_simm_T1(int32_t val)
211
{
B
blueswir1 已提交
212
    tcg_gen_movi_tl(cpu_T[1], val);
213 214
}

B
blueswir1 已提交
215
static inline void gen_movl_reg_TN(int reg, TCGv tn)
216
{
B
blueswir1 已提交
217 218 219 220 221 222 223
    if (reg == 0)
        tcg_gen_movi_tl(tn, 0);
    else if (reg < 8)
        tcg_gen_ld_tl(tn, cpu_env, offsetof(CPUState, gregs[reg]));
    else {
        tcg_gen_ld_ptr(cpu_regwptr, cpu_env, offsetof(CPUState, regwptr)); // XXX
        tcg_gen_ld_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
224 225 226
    }
}

B
blueswir1 已提交
227
static inline void gen_movl_reg_T0(int reg)
228
{
B
blueswir1 已提交
229
    gen_movl_reg_TN(reg, cpu_T[0]);
230 231
}

B
blueswir1 已提交
232
static inline void gen_movl_reg_T1(int reg)
233
{
B
blueswir1 已提交
234
    gen_movl_reg_TN(reg, cpu_T[1]);
235 236
}

B
blueswir1 已提交
237 238 239 240 241 242 243
#ifdef __i386__
static inline void gen_movl_reg_T2(int reg)
{
    gen_movl_reg_TN(reg, cpu_T[2]);
}

#endif /* __i386__ */
B
blueswir1 已提交
244
static inline void gen_movl_TN_reg(int reg, TCGv tn)
245
{
B
blueswir1 已提交
246 247 248 249 250 251 252
    if (reg == 0)
        return;
    else if (reg < 8)
        tcg_gen_st_tl(tn, cpu_env, offsetof(CPUState, gregs[reg]));
    else {
        tcg_gen_ld_ptr(cpu_regwptr, cpu_env, offsetof(CPUState, regwptr)); // XXX
        tcg_gen_st_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
253 254 255
    }
}

B
blueswir1 已提交
256
static inline void gen_movl_T0_reg(int reg)
B
bellard 已提交
257
{
B
blueswir1 已提交
258
    gen_movl_TN_reg(reg, cpu_T[0]);
B
bellard 已提交
259 260
}

B
blueswir1 已提交
261
static inline void gen_movl_T1_reg(int reg)
B
bellard 已提交
262
{
B
blueswir1 已提交
263
    gen_movl_TN_reg(reg, cpu_T[1]);
B
bellard 已提交
264 265
}

B
blueswir1 已提交
266
static inline void gen_op_movl_T0_env(size_t offset)
267
{
B
blueswir1 已提交
268
    tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
269 270
}

B
blueswir1 已提交
271
static inline void gen_op_movl_env_T0(size_t offset)
272
{
B
blueswir1 已提交
273
    tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
274 275
}

B
blueswir1 已提交
276
static inline void gen_op_movtl_T0_env(size_t offset)
277
{
B
blueswir1 已提交
278
    tcg_gen_ld_tl(cpu_T[0], cpu_env, offset);
279 280
}

B
blueswir1 已提交
281
static inline void gen_op_movtl_env_T0(size_t offset)
282
{
B
blueswir1 已提交
283
    tcg_gen_st_tl(cpu_T[0], cpu_env, offset);
284 285
}

B
blueswir1 已提交
286
static inline void gen_op_add_T1_T0(void)
287
{
B
blueswir1 已提交
288
    tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
289 290
}

B
blueswir1 已提交
291
static inline void gen_op_or_T1_T0(void)
292
{
B
blueswir1 已提交
293
    tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
294 295
}

B
blueswir1 已提交
296
static inline void gen_op_xor_T1_T0(void)
297
{
B
blueswir1 已提交
298
    tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
299 300
}

B
bellard 已提交
301 302
static inline void gen_jmp_im(target_ulong pc)
{
B
blueswir1 已提交
303 304
    tcg_gen_movi_tl(cpu_tmp0, pc);
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, pc));
B
bellard 已提交
305 306 307 308
}

static inline void gen_movl_npc_im(target_ulong npc)
{
B
blueswir1 已提交
309 310
    tcg_gen_movi_tl(cpu_tmp0, npc);
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUState, npc));
B
bellard 已提交
311 312
}

313
static inline void gen_goto_tb(DisasContext *s, int tb_num,
314 315 316 317 318 319 320 321
                               target_ulong pc, target_ulong npc)
{
    TranslationBlock *tb;

    tb = s->tb;
    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
        (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK))  {
        /* jump to same page: we can use a direct jump */
B
bellard 已提交
322
        tcg_gen_goto_tb(tb_num);
323 324
        gen_jmp_im(pc);
        gen_movl_npc_im(npc);
B
bellard 已提交
325
        tcg_gen_exit_tb((long)tb + tb_num);
326 327 328 329
    } else {
        /* jump to another page: currently not optimized */
        gen_jmp_im(pc);
        gen_movl_npc_im(npc);
B
bellard 已提交
330
        tcg_gen_exit_tb(0);
331 332 333
    }
}

B
blueswir1 已提交
334 335
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
                               target_ulong pc2)
B
bellard 已提交
336 337 338 339 340 341 342
{
    int l1;

    l1 = gen_new_label();

    gen_op_jz_T2_label(l1);

343
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
B
bellard 已提交
344 345

    gen_set_label(l1);
346
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
B
bellard 已提交
347 348
}

B
blueswir1 已提交
349 350
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
                                target_ulong pc2)
B
bellard 已提交
351 352 353 354 355 356 357
{
    int l1;

    l1 = gen_new_label();

    gen_op_jz_T2_label(l1);

358
    gen_goto_tb(dc, 0, pc2, pc1);
B
bellard 已提交
359 360

    gen_set_label(l1);
361
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
B
bellard 已提交
362 363
}

B
blueswir1 已提交
364 365
static inline void gen_branch(DisasContext *dc, target_ulong pc,
                              target_ulong npc)
B
bellard 已提交
366
{
367
    gen_goto_tb(dc, 0, pc, npc);
B
bellard 已提交
368 369
}

B
blueswir1 已提交
370
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2)
B
bellard 已提交
371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389
{
    int l1, l2;

    l1 = gen_new_label();
    l2 = gen_new_label();
    gen_op_jz_T2_label(l1);

    gen_movl_npc_im(npc1);
    gen_op_jmp_label(l2);

    gen_set_label(l1);
    gen_movl_npc_im(npc2);
    gen_set_label(l2);
}

/* call this function before using T2 as it may have been set for a jump */
static inline void flush_T2(DisasContext * dc)
{
    if (dc->npc == JUMP_PC) {
B
blueswir1 已提交
390
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
B
bellard 已提交
391 392 393 394
        dc->npc = DYNAMIC_PC;
    }
}

B
bellard 已提交
395 396 397
static inline void save_npc(DisasContext * dc)
{
    if (dc->npc == JUMP_PC) {
B
blueswir1 已提交
398
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
B
bellard 已提交
399 400
        dc->npc = DYNAMIC_PC;
    } else if (dc->npc != DYNAMIC_PC) {
B
bellard 已提交
401
        gen_movl_npc_im(dc->npc);
B
bellard 已提交
402 403 404 405 406
    }
}

static inline void save_state(DisasContext * dc)
{
B
bellard 已提交
407
    gen_jmp_im(dc->pc);
B
bellard 已提交
408 409 410
    save_npc(dc);
}

B
bellard 已提交
411 412 413
static inline void gen_mov_pc_npc(DisasContext * dc)
{
    if (dc->npc == JUMP_PC) {
B
blueswir1 已提交
414
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
415 416
        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, npc));
        tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, pc));
B
bellard 已提交
417 418
        dc->pc = DYNAMIC_PC;
    } else if (dc->npc == DYNAMIC_PC) {
419 420
        tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, npc));
        tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, pc));
B
bellard 已提交
421 422 423 424 425 426
        dc->pc = DYNAMIC_PC;
    } else {
        dc->pc = dc->npc;
    }
}

427 428 429 430 431 432 433 434
static inline void gen_op_next_insn(void)
{
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, npc));
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, pc));
    tcg_gen_addi_tl(cpu_tmp0, cpu_tmp0, 4);
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, npc));
}

B
bellard 已提交
435 436
static GenOpFunc * const gen_cond[2][16] = {
    {
B
blueswir1 已提交
437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452
        gen_op_eval_bn,
        gen_op_eval_be,
        gen_op_eval_ble,
        gen_op_eval_bl,
        gen_op_eval_bleu,
        gen_op_eval_bcs,
        gen_op_eval_bneg,
        gen_op_eval_bvs,
        gen_op_eval_ba,
        gen_op_eval_bne,
        gen_op_eval_bg,
        gen_op_eval_bge,
        gen_op_eval_bgu,
        gen_op_eval_bcc,
        gen_op_eval_bpos,
        gen_op_eval_bvc,
B
bellard 已提交
453 454 455
    },
    {
#ifdef TARGET_SPARC64
B
blueswir1 已提交
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471
        gen_op_eval_bn,
        gen_op_eval_xbe,
        gen_op_eval_xble,
        gen_op_eval_xbl,
        gen_op_eval_xbleu,
        gen_op_eval_xbcs,
        gen_op_eval_xbneg,
        gen_op_eval_xbvs,
        gen_op_eval_ba,
        gen_op_eval_xbne,
        gen_op_eval_xbg,
        gen_op_eval_xbge,
        gen_op_eval_xbgu,
        gen_op_eval_xbcc,
        gen_op_eval_xbpos,
        gen_op_eval_xbvc,
B
bellard 已提交
472 473 474 475 476 477
#endif
    },
};

static GenOpFunc * const gen_fcond[4][16] = {
    {
B
blueswir1 已提交
478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493
        gen_op_eval_bn,
        gen_op_eval_fbne,
        gen_op_eval_fblg,
        gen_op_eval_fbul,
        gen_op_eval_fbl,
        gen_op_eval_fbug,
        gen_op_eval_fbg,
        gen_op_eval_fbu,
        gen_op_eval_ba,
        gen_op_eval_fbe,
        gen_op_eval_fbue,
        gen_op_eval_fbge,
        gen_op_eval_fbuge,
        gen_op_eval_fble,
        gen_op_eval_fbule,
        gen_op_eval_fbo,
B
bellard 已提交
494 495 496
    },
#ifdef TARGET_SPARC64
    {
B
blueswir1 已提交
497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512
        gen_op_eval_bn,
        gen_op_eval_fbne_fcc1,
        gen_op_eval_fblg_fcc1,
        gen_op_eval_fbul_fcc1,
        gen_op_eval_fbl_fcc1,
        gen_op_eval_fbug_fcc1,
        gen_op_eval_fbg_fcc1,
        gen_op_eval_fbu_fcc1,
        gen_op_eval_ba,
        gen_op_eval_fbe_fcc1,
        gen_op_eval_fbue_fcc1,
        gen_op_eval_fbge_fcc1,
        gen_op_eval_fbuge_fcc1,
        gen_op_eval_fble_fcc1,
        gen_op_eval_fbule_fcc1,
        gen_op_eval_fbo_fcc1,
B
bellard 已提交
513 514
    },
    {
B
blueswir1 已提交
515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530
        gen_op_eval_bn,
        gen_op_eval_fbne_fcc2,
        gen_op_eval_fblg_fcc2,
        gen_op_eval_fbul_fcc2,
        gen_op_eval_fbl_fcc2,
        gen_op_eval_fbug_fcc2,
        gen_op_eval_fbg_fcc2,
        gen_op_eval_fbu_fcc2,
        gen_op_eval_ba,
        gen_op_eval_fbe_fcc2,
        gen_op_eval_fbue_fcc2,
        gen_op_eval_fbge_fcc2,
        gen_op_eval_fbuge_fcc2,
        gen_op_eval_fble_fcc2,
        gen_op_eval_fbule_fcc2,
        gen_op_eval_fbo_fcc2,
B
bellard 已提交
531 532
    },
    {
B
blueswir1 已提交
533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548
        gen_op_eval_bn,
        gen_op_eval_fbne_fcc3,
        gen_op_eval_fblg_fcc3,
        gen_op_eval_fbul_fcc3,
        gen_op_eval_fbl_fcc3,
        gen_op_eval_fbug_fcc3,
        gen_op_eval_fbg_fcc3,
        gen_op_eval_fbu_fcc3,
        gen_op_eval_ba,
        gen_op_eval_fbe_fcc3,
        gen_op_eval_fbue_fcc3,
        gen_op_eval_fbge_fcc3,
        gen_op_eval_fbuge_fcc3,
        gen_op_eval_fble_fcc3,
        gen_op_eval_fbule_fcc3,
        gen_op_eval_fbo_fcc3,
B
bellard 已提交
549 550 551 552 553
    },
#else
    {}, {}, {},
#endif
};
554

B
bellard 已提交
555 556
#ifdef TARGET_SPARC64
static void gen_cond_reg(int cond)
557
{
B
blueswir1 已提交
558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573
        switch (cond) {
        case 0x1:
            gen_op_eval_brz();
            break;
        case 0x2:
            gen_op_eval_brlez();
            break;
        case 0x3:
            gen_op_eval_brlz();
            break;
        case 0x5:
            gen_op_eval_brnz();
            break;
        case 0x6:
            gen_op_eval_brgz();
            break;
574
        default:
B
blueswir1 已提交
575 576 577 578
        case 0x7:
            gen_op_eval_brgez();
            break;
        }
579
}
580 581 582 583 584 585 586 587 588 589 590 591

// Inverted logic
static const int gen_tcg_cond_reg[8] = {
    -1,
    TCG_COND_NE,
    TCG_COND_GT,
    TCG_COND_GE,
    -1,
    TCG_COND_EQ,
    TCG_COND_LE,
    TCG_COND_LT,
};
B
bellard 已提交
592
#endif
593

B
bellard 已提交
594
/* XXX: potentially incorrect if dynamic npc */
B
bellard 已提交
595
static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
596
{
597
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
598
    target_ulong target = dc->pc + offset;
599

600
    if (cond == 0x0) {
B
blueswir1 已提交
601 602 603 604 605 606 607 608
        /* unconditional not taken */
        if (a) {
            dc->pc = dc->npc + 4;
            dc->npc = dc->pc + 4;
        } else {
            dc->pc = dc->npc;
            dc->npc = dc->pc + 4;
        }
609
    } else if (cond == 0x8) {
B
blueswir1 已提交
610 611 612 613 614 615 616 617
        /* unconditional taken */
        if (a) {
            dc->pc = target;
            dc->npc = dc->pc + 4;
        } else {
            dc->pc = dc->npc;
            dc->npc = target;
        }
618
    } else {
B
bellard 已提交
619
        flush_T2(dc);
B
bellard 已提交
620
        gen_cond[cc][cond]();
B
blueswir1 已提交
621 622
        if (a) {
            gen_branch_a(dc, target, dc->npc);
623
            dc->is_br = 1;
B
blueswir1 已提交
624
        } else {
625
            dc->pc = dc->npc;
B
bellard 已提交
626 627 628
            dc->jump_pc[0] = target;
            dc->jump_pc[1] = dc->npc + 4;
            dc->npc = JUMP_PC;
B
blueswir1 已提交
629
        }
630
    }
631 632
}

B
bellard 已提交
633
/* XXX: potentially incorrect if dynamic npc */
B
bellard 已提交
634
static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
635 636
{
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
637 638
    target_ulong target = dc->pc + offset;

639
    if (cond == 0x0) {
B
blueswir1 已提交
640 641 642 643 644 645 646 647
        /* unconditional not taken */
        if (a) {
            dc->pc = dc->npc + 4;
            dc->npc = dc->pc + 4;
        } else {
            dc->pc = dc->npc;
            dc->npc = dc->pc + 4;
        }
648
    } else if (cond == 0x8) {
B
blueswir1 已提交
649 650 651 652 653 654 655 656
        /* unconditional taken */
        if (a) {
            dc->pc = target;
            dc->npc = dc->pc + 4;
        } else {
            dc->pc = dc->npc;
            dc->npc = target;
        }
657 658
    } else {
        flush_T2(dc);
B
bellard 已提交
659
        gen_fcond[cc][cond]();
B
blueswir1 已提交
660 661
        if (a) {
            gen_branch_a(dc, target, dc->npc);
662
            dc->is_br = 1;
B
blueswir1 已提交
663
        } else {
664 665 666 667
            dc->pc = dc->npc;
            dc->jump_pc[0] = target;
            dc->jump_pc[1] = dc->npc + 4;
            dc->npc = JUMP_PC;
B
blueswir1 已提交
668
        }
669 670 671
    }
}

B
bellard 已提交
672 673 674
#ifdef TARGET_SPARC64
/* XXX: potentially incorrect if dynamic npc */
static void do_branch_reg(DisasContext * dc, int32_t offset, uint32_t insn)
675
{
B
bellard 已提交
676 677 678 679 680 681
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
    target_ulong target = dc->pc + offset;

    flush_T2(dc);
    gen_cond_reg(cond);
    if (a) {
B
blueswir1 已提交
682 683
        gen_branch_a(dc, target, dc->npc);
        dc->is_br = 1;
B
bellard 已提交
684
    } else {
B
blueswir1 已提交
685 686 687 688
        dc->pc = dc->npc;
        dc->jump_pc[0] = target;
        dc->jump_pc[1] = dc->npc + 4;
        dc->npc = JUMP_PC;
B
bellard 已提交
689
    }
690 691
}

B
bellard 已提交
692
static GenOpFunc * const gen_fcmps[4] = {
693 694 695 696
    helper_fcmps,
    helper_fcmps_fcc1,
    helper_fcmps_fcc2,
    helper_fcmps_fcc3,
B
bellard 已提交
697 698 699
};

static GenOpFunc * const gen_fcmpd[4] = {
700 701 702 703
    helper_fcmpd,
    helper_fcmpd_fcc1,
    helper_fcmpd_fcc2,
    helper_fcmpd_fcc3,
B
bellard 已提交
704
};
705

B
blueswir1 已提交
706 707
#if defined(CONFIG_USER_ONLY)
static GenOpFunc * const gen_fcmpq[4] = {
708 709 710 711
    helper_fcmpq,
    helper_fcmpq_fcc1,
    helper_fcmpq_fcc2,
    helper_fcmpq_fcc3,
B
blueswir1 已提交
712 713 714
};
#endif

715
static GenOpFunc * const gen_fcmpes[4] = {
716 717 718 719
    helper_fcmpes,
    helper_fcmpes_fcc1,
    helper_fcmpes_fcc2,
    helper_fcmpes_fcc3,
720 721 722
};

static GenOpFunc * const gen_fcmped[4] = {
723 724 725 726
    helper_fcmped,
    helper_fcmped_fcc1,
    helper_fcmped_fcc2,
    helper_fcmped_fcc3,
727 728
};

B
blueswir1 已提交
729 730
#if defined(CONFIG_USER_ONLY)
static GenOpFunc * const gen_fcmpeq[4] = {
731 732 733 734
    helper_fcmpeq,
    helper_fcmpeq_fcc1,
    helper_fcmpeq_fcc2,
    helper_fcmpeq_fcc3,
B
blueswir1 已提交
735 736
};
#endif
737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807

static inline void gen_op_fcmps(int fccno)
{
    tcg_gen_helper_0_0(gen_fcmps[fccno]);
}

static inline void gen_op_fcmpd(int fccno)
{
    tcg_gen_helper_0_0(gen_fcmpd[fccno]);
}

#if defined(CONFIG_USER_ONLY)
static inline void gen_op_fcmpq(int fccno)
{
    tcg_gen_helper_0_0(gen_fcmpq[fccno]);
}
#endif

static inline void gen_op_fcmpes(int fccno)
{
    tcg_gen_helper_0_0(gen_fcmpes[fccno]);
}

static inline void gen_op_fcmped(int fccno)
{
    tcg_gen_helper_0_0(gen_fcmped[fccno]);
}

#if defined(CONFIG_USER_ONLY)
static inline void gen_op_fcmpeq(int fccno)
{
    tcg_gen_helper_0_0(gen_fcmpeq[fccno]);
}
#endif

#else

static inline void gen_op_fcmps(int fccno)
{
    tcg_gen_helper_0_0(helper_fcmps);
}

static inline void gen_op_fcmpd(int fccno)
{
    tcg_gen_helper_0_0(helper_fcmpd);
}

#if defined(CONFIG_USER_ONLY)
static inline void gen_op_fcmpq(int fccno)
{
    tcg_gen_helper_0_0(helper_fcmpq);
}
#endif

static inline void gen_op_fcmpes(int fccno)
{
    tcg_gen_helper_0_0(helper_fcmpes);
}

static inline void gen_op_fcmped(int fccno)
{
    tcg_gen_helper_0_0(helper_fcmped);
}

#if defined(CONFIG_USER_ONLY)
static inline void gen_op_fcmpeq(int fccno)
{
    tcg_gen_helper_0_0(helper_fcmpeq);
}
#endif

B
bellard 已提交
808 809
#endif

B
bellard 已提交
810 811 812 813 814 815 816 817 818 819 820 821 822
static int gen_trap_ifnofpu(DisasContext * dc)
{
#if !defined(CONFIG_USER_ONLY)
    if (!dc->fpu_enabled) {
        save_state(dc);
        gen_op_exception(TT_NFPU_INSN);
        dc->is_br = 1;
        return 1;
    }
#endif
    return 0;
}

823 824 825 826 827 828 829 830 831 832 833 834
static inline void gen_op_clear_ieee_excp_and_FTT(void)
{
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fsr));
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, ~(FSR_FTT_MASK | FSR_CEXC_MASK));
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, fsr));
}

static inline void gen_clear_float_exceptions(void)
{
    tcg_gen_helper_0_0(helper_clear_float_exceptions);
}

B
blueswir1 已提交
835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098
/* asi moves */
#ifdef TARGET_SPARC64
static inline void gen_ld_asi(int insn, int size, int sign)
{
    int asi, offset;
    TCGv r_size, r_sign;

    r_size = tcg_temp_new(TCG_TYPE_I32);
    r_sign = tcg_temp_new(TCG_TYPE_I32);
    tcg_gen_movi_i32(r_size, size);
    tcg_gen_movi_i32(r_sign, sign);
    if (IS_IMM) {
        offset = GET_FIELD(insn, 25, 31);
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
        tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUSPARCState, asi));
    } else {
        asi = GET_FIELD(insn, 19, 26);
        tcg_gen_movi_i32(cpu_T[1], asi);
    }
    tcg_gen_helper_1_4(helper_ld_asi, cpu_T[1], cpu_T[0], cpu_T[1], r_size,
                       r_sign);
}

static inline void gen_st_asi(int insn, int size)
{
    int asi, offset;
    TCGv r_asi, r_size;

    r_asi = tcg_temp_new(TCG_TYPE_I32);
    r_size = tcg_temp_new(TCG_TYPE_I32);
    tcg_gen_movi_i32(r_size, size);
    if (IS_IMM) {
        offset = GET_FIELD(insn, 25, 31);
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
    } else {
        asi = GET_FIELD(insn, 19, 26);
        tcg_gen_movi_i32(r_asi, asi);
    }
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], r_asi, r_size);
}

static inline void gen_ldf_asi(int insn, int size, int rd)
{
    int asi, offset;
    TCGv r_asi, r_size, r_rd;

    r_asi = tcg_temp_new(TCG_TYPE_I32);
    r_size = tcg_temp_new(TCG_TYPE_I32);
    r_rd = tcg_temp_new(TCG_TYPE_I32);
    tcg_gen_movi_i32(r_size, size);
    tcg_gen_movi_i32(r_rd, rd);
    if (IS_IMM) {
        offset = GET_FIELD(insn, 25, 31);
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
    } else {
        asi = GET_FIELD(insn, 19, 26);
        tcg_gen_movi_i32(r_asi, asi);
    }
    tcg_gen_helper_0_4(helper_ldf_asi, cpu_T[0], r_asi, r_size, r_rd);
}

static inline void gen_stf_asi(int insn, int size, int rd)
{
    int asi, offset;
    TCGv r_asi, r_size, r_rd;

    r_asi = tcg_temp_new(TCG_TYPE_I32);
    r_size = tcg_temp_new(TCG_TYPE_I32);
    r_rd = tcg_temp_new(TCG_TYPE_I32);
    tcg_gen_movi_i32(r_size, size);
    tcg_gen_movi_i32(r_rd, rd);
    if (IS_IMM) {
        offset = GET_FIELD(insn, 25, 31);
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
    } else {
        asi = GET_FIELD(insn, 19, 26);
        tcg_gen_movi_i32(r_asi, asi);
    }
    tcg_gen_helper_0_4(helper_stf_asi, cpu_T[0], r_asi, r_size, r_rd);
}

static inline void gen_swap_asi(int insn)
{
    int asi, offset;
    TCGv r_size, r_sign, r_temp;

    r_size = tcg_temp_new(TCG_TYPE_I32);
    r_sign = tcg_temp_new(TCG_TYPE_I32);
    r_temp = tcg_temp_new(TCG_TYPE_I32);
    tcg_gen_movi_i32(r_size, 4);
    tcg_gen_movi_i32(r_sign, 0);
    if (IS_IMM) {
        offset = GET_FIELD(insn, 25, 31);
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
        tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUSPARCState, asi));
    } else {
        asi = GET_FIELD(insn, 19, 26);
        tcg_gen_movi_i32(cpu_T[1], asi);
    }
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, cpu_T[0], cpu_T[1], r_size,
                       r_sign);
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], r_size, r_sign);
    tcg_gen_mov_i32(cpu_T[1], r_temp);
}

static inline void gen_ldda_asi(int insn)
{
    int asi, offset;
    TCGv r_size, r_sign, r_dword;

    r_size = tcg_temp_new(TCG_TYPE_I32);
    r_sign = tcg_temp_new(TCG_TYPE_I32);
    r_dword = tcg_temp_new(TCG_TYPE_I64);
    tcg_gen_movi_i32(r_size, 8);
    tcg_gen_movi_i32(r_sign, 0);
    if (IS_IMM) {
        offset = GET_FIELD(insn, 25, 31);
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
        tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUSPARCState, asi));
    } else {
        asi = GET_FIELD(insn, 19, 26);
        tcg_gen_movi_i32(cpu_T[1], asi);
    }
    tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], cpu_T[1], r_size,
                       r_sign);
    tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
    tcg_gen_shri_i64(r_dword, r_dword, 32);
    tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
}

static inline void gen_cas_asi(int insn, int rd)
{
    int asi, offset;
    TCGv r_val1, r_asi;

    r_val1 = tcg_temp_new(TCG_TYPE_I32);
    r_asi = tcg_temp_new(TCG_TYPE_I32);
    gen_movl_reg_TN(rd, r_val1);
    if (IS_IMM) {
        offset = GET_FIELD(insn, 25, 31);
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
    } else {
        asi = GET_FIELD(insn, 19, 26);
        tcg_gen_movi_i32(r_asi, asi);
    }
    tcg_gen_helper_1_4(helper_cas_asi, cpu_T[1], cpu_T[0], r_val1, cpu_T[1],
                       r_asi);
}

static inline void gen_casx_asi(int insn, int rd)
{
    int asi, offset;
    TCGv r_val1, r_asi;

    r_val1 = tcg_temp_new(TCG_TYPE_I64);
    r_asi = tcg_temp_new(TCG_TYPE_I32);
    gen_movl_reg_TN(rd, r_val1);
    if (IS_IMM) {
        offset = GET_FIELD(insn, 25, 31);
        tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
    } else {
        asi = GET_FIELD(insn, 19, 26);
        tcg_gen_movi_i32(r_asi, asi);
    }
    tcg_gen_helper_1_4(helper_casx_asi, cpu_T[1], cpu_T[0], r_val1, cpu_T[1],
                       r_asi);
}

#elif !defined(CONFIG_USER_ONLY)

static inline void gen_ld_asi(int insn, int size, int sign)
{
    int asi;
    TCGv r_size, r_sign, r_dword;

    r_size = tcg_temp_new(TCG_TYPE_I32);
    r_sign = tcg_temp_new(TCG_TYPE_I32);
    r_dword = tcg_temp_new(TCG_TYPE_I64);
    tcg_gen_movi_i32(r_size, size);
    tcg_gen_movi_i32(r_sign, sign);
    asi = GET_FIELD(insn, 19, 26);
    tcg_gen_movi_i32(cpu_T[1], asi);
    tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], cpu_T[1], r_size,
                       r_sign);
    tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
}

static inline void gen_st_asi(int insn, int size)
{
    int asi;
    TCGv r_dword, r_asi, r_size;

    r_dword = tcg_temp_new(TCG_TYPE_I64);
    tcg_gen_extu_i32_i64(r_dword, cpu_T[1]);
    r_asi = tcg_temp_new(TCG_TYPE_I32);
    r_size = tcg_temp_new(TCG_TYPE_I32);
    asi = GET_FIELD(insn, 19, 26);
    tcg_gen_movi_i32(r_asi, asi);
    tcg_gen_movi_i32(r_size, size);
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, r_asi, r_size);
}

static inline void gen_swap_asi(int insn)
{
    int asi;
    TCGv r_size, r_sign, r_temp;

    r_size = tcg_temp_new(TCG_TYPE_I32);
    r_sign = tcg_temp_new(TCG_TYPE_I32);
    r_temp = tcg_temp_new(TCG_TYPE_I32);
    tcg_gen_movi_i32(r_size, 4);
    tcg_gen_movi_i32(r_sign, 0);
    asi = GET_FIELD(insn, 19, 26);
    tcg_gen_movi_i32(cpu_T[1], asi);
    tcg_gen_helper_1_4(helper_ld_asi, r_temp, cpu_T[0], cpu_T[1], r_size,
                       r_sign);
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], cpu_T[1], r_size, r_sign);
    tcg_gen_mov_i32(cpu_T[1], r_temp);
}

static inline void gen_ldda_asi(int insn)
{
    int asi;
    TCGv r_size, r_sign, r_dword;

    r_size = tcg_temp_new(TCG_TYPE_I32);
    r_sign = tcg_temp_new(TCG_TYPE_I32);
    r_dword = tcg_temp_new(TCG_TYPE_I64);
    tcg_gen_movi_i32(r_size, 8);
    tcg_gen_movi_i32(r_sign, 0);
    asi = GET_FIELD(insn, 19, 26);
    tcg_gen_movi_i32(cpu_T[1], asi);
    tcg_gen_helper_1_4(helper_ld_asi, r_dword, cpu_T[0], cpu_T[1], r_size,
                       r_sign);
    tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
    tcg_gen_shri_i64(r_dword, r_dword, 32);
    tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
}
#endif

#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
static inline void gen_ldstub_asi(int insn)
{
    int asi;
    TCGv r_dword, r_asi, r_size;

    gen_ld_asi(insn, 1, 0);

    r_dword = tcg_temp_new(TCG_TYPE_I64);
    r_asi = tcg_temp_new(TCG_TYPE_I32);
    r_size = tcg_temp_new(TCG_TYPE_I32);
    asi = GET_FIELD(insn, 19, 26);
    tcg_gen_movi_i32(r_dword, 0xff);
    tcg_gen_movi_i32(r_asi, asi);
    tcg_gen_movi_i32(r_size, 1);
    tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, r_asi, r_size);
}
#endif

1099 1100 1101 1102 1103 1104 1105
static inline void gen_mov_reg_C(TCGv reg)
{
    tcg_gen_ld_i32(reg, cpu_env, offsetof(CPUSPARCState, psr));
    tcg_gen_shri_i32(reg, reg, 20);
    tcg_gen_andi_i32(reg, reg, 0x1);
}

B
bellard 已提交
1106
/* before an instruction, dc->pc must be static */
1107 1108 1109
static void disas_sparc_insn(DisasContext * dc)
{
    unsigned int insn, opc, rs1, rs2, rd;
1110

B
bellard 已提交
1111
    insn = ldl_code(dc->pc);
1112
    opc = GET_FIELD(insn, 0, 1);
1113

1114 1115
    rd = GET_FIELD(insn, 2, 6);
    switch (opc) {
B
blueswir1 已提交
1116 1117 1118 1119 1120
    case 0:                     /* branches/sethi */
        {
            unsigned int xop = GET_FIELD(insn, 7, 9);
            int32_t target;
            switch (xop) {
B
bellard 已提交
1121
#ifdef TARGET_SPARC64
B
blueswir1 已提交
1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140
            case 0x1:           /* V9 BPcc */
                {
                    int cc;

                    target = GET_FIELD_SP(insn, 0, 18);
                    target = sign_extend(target, 18);
                    target <<= 2;
                    cc = GET_FIELD_SP(insn, 20, 21);
                    if (cc == 0)
                        do_branch(dc, target, insn, 0);
                    else if (cc == 2)
                        do_branch(dc, target, insn, 1);
                    else
                        goto illegal_insn;
                    goto jmp_insn;
                }
            case 0x3:           /* V9 BPr */
                {
                    target = GET_FIELD_SP(insn, 0, 13) |
1141
                        (GET_FIELD_SP(insn, 20, 21) << 14);
B
blueswir1 已提交
1142 1143 1144 1145 1146 1147 1148 1149 1150 1151
                    target = sign_extend(target, 16);
                    target <<= 2;
                    rs1 = GET_FIELD(insn, 13, 17);
                    gen_movl_reg_T0(rs1);
                    do_branch_reg(dc, target, insn);
                    goto jmp_insn;
                }
            case 0x5:           /* V9 FBPcc */
                {
                    int cc = GET_FIELD_SP(insn, 20, 21);
B
bellard 已提交
1152 1153
                    if (gen_trap_ifnofpu(dc))
                        goto jmp_insn;
B
blueswir1 已提交
1154 1155 1156 1157 1158 1159
                    target = GET_FIELD_SP(insn, 0, 18);
                    target = sign_extend(target, 19);
                    target <<= 2;
                    do_fbranch(dc, target, insn, cc);
                    goto jmp_insn;
                }
1160
#else
B
blueswir1 已提交
1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175
            case 0x7:           /* CBN+x */
                {
                    goto ncp_insn;
                }
#endif
            case 0x2:           /* BN+x */
                {
                    target = GET_FIELD(insn, 10, 31);
                    target = sign_extend(target, 22);
                    target <<= 2;
                    do_branch(dc, target, insn, 0);
                    goto jmp_insn;
                }
            case 0x6:           /* FBN+x */
                {
B
bellard 已提交
1176 1177
                    if (gen_trap_ifnofpu(dc))
                        goto jmp_insn;
B
blueswir1 已提交
1178 1179 1180 1181 1182 1183 1184
                    target = GET_FIELD(insn, 10, 31);
                    target = sign_extend(target, 22);
                    target <<= 2;
                    do_fbranch(dc, target, insn, 0);
                    goto jmp_insn;
                }
            case 0x4:           /* SETHI */
B
bellard 已提交
1185 1186
#define OPTIM
#if defined(OPTIM)
B
blueswir1 已提交
1187
                if (rd) { // nop
B
bellard 已提交
1188
#endif
B
blueswir1 已提交
1189
                    uint32_t value = GET_FIELD(insn, 10, 31);
B
blueswir1 已提交
1190
                    tcg_gen_movi_tl(cpu_T[0], value << 10);
B
blueswir1 已提交
1191
                    gen_movl_T0_reg(rd);
B
bellard 已提交
1192
#if defined(OPTIM)
B
blueswir1 已提交
1193
                }
B
bellard 已提交
1194
#endif
B
blueswir1 已提交
1195 1196 1197
                break;
            case 0x0:           /* UNIMPL */
            default:
B
bellard 已提交
1198
                goto illegal_insn;
B
blueswir1 已提交
1199 1200 1201 1202
            }
            break;
        }
        break;
1203
    case 1:
B
blueswir1 已提交
1204 1205
        /*CALL*/ {
            target_long target = GET_FIELDs(insn, 2, 31) << 2;
1206

B
blueswir1 已提交
1207
            tcg_gen_movi_tl(cpu_T[0], dc->pc);
B
blueswir1 已提交
1208 1209
            gen_movl_T0_reg(15);
            target += dc->pc;
B
bellard 已提交
1210
            gen_mov_pc_npc(dc);
B
blueswir1 已提交
1211 1212 1213 1214 1215 1216 1217
            dc->npc = target;
        }
        goto jmp_insn;
    case 2:                     /* FPU & Logical Operations */
        {
            unsigned int xop = GET_FIELD(insn, 7, 12);
            if (xop == 0x3a) {  /* generate trap */
1218
                int cond;
B
bellard 已提交
1219

1220 1221
                rs1 = GET_FIELD(insn, 13, 17);
                gen_movl_reg_T0(rs1);
B
blueswir1 已提交
1222 1223
                if (IS_IMM) {
                    rs2 = GET_FIELD(insn, 25, 31);
B
blueswir1 已提交
1224
                    tcg_gen_addi_tl(cpu_T[0], cpu_T[0], rs2);
1225 1226
                } else {
                    rs2 = GET_FIELD(insn, 27, 31);
B
bellard 已提交
1227
#if defined(OPTIM)
B
blueswir1 已提交
1228
                    if (rs2 != 0) {
B
bellard 已提交
1229
#endif
B
blueswir1 已提交
1230 1231
                        gen_movl_reg_T1(rs2);
                        gen_op_add_T1_T0();
B
bellard 已提交
1232
#if defined(OPTIM)
B
blueswir1 已提交
1233
                    }
B
bellard 已提交
1234
#endif
1235 1236 1237
                }
                cond = GET_FIELD(insn, 3, 6);
                if (cond == 0x8) {
B
bellard 已提交
1238
                    save_state(dc);
B
blueswir1 已提交
1239
                    tcg_gen_helper_0_1(helper_trap, cpu_T[0]);
1240
                } else if (cond != 0) {
B
bellard 已提交
1241
#ifdef TARGET_SPARC64
B
blueswir1 已提交
1242 1243 1244
                    /* V9 icc/xcc */
                    int cc = GET_FIELD_SP(insn, 11, 12);
                    flush_T2(dc);
B
bellard 已提交
1245
                    save_state(dc);
B
blueswir1 已提交
1246 1247 1248 1249 1250 1251
                    if (cc == 0)
                        gen_cond[0][cond]();
                    else if (cc == 2)
                        gen_cond[1][cond]();
                    else
                        goto illegal_insn;
B
bellard 已提交
1252
#else
B
blueswir1 已提交
1253
                    flush_T2(dc);
B
bellard 已提交
1254
                    save_state(dc);
B
blueswir1 已提交
1255
                    gen_cond[0][cond]();
B
bellard 已提交
1256
#endif
B
blueswir1 已提交
1257
                    tcg_gen_helper_0_2(helper_trapcc, cpu_T[0], cpu_T[2]);
1258
                }
B
bellard 已提交
1259
                gen_op_next_insn();
B
bellard 已提交
1260
                tcg_gen_exit_tb(0);
B
bellard 已提交
1261 1262
                dc->is_br = 1;
                goto jmp_insn;
1263 1264 1265 1266
            } else if (xop == 0x28) {
                rs1 = GET_FIELD(insn, 13, 17);
                switch(rs1) {
                case 0: /* rdy */
1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277
#ifndef TARGET_SPARC64
                case 0x01 ... 0x0e: /* undefined in the SPARCv8
                                       manual, rdy on the microSPARC
                                       II */
                case 0x0f:          /* stbar in the SPARCv8 manual,
                                       rdy on the microSPARC II */
                case 0x10 ... 0x1f: /* implementation-dependent in the
                                       SPARCv8 manual, rdy on the
                                       microSPARC II */
#endif
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, y));
1278 1279
                    gen_movl_T0_reg(rd);
                    break;
B
bellard 已提交
1280
#ifdef TARGET_SPARC64
B
blueswir1 已提交
1281
                case 0x2: /* V9 rdccr */
B
bellard 已提交
1282 1283 1284
                    gen_op_rdccr();
                    gen_movl_T0_reg(rd);
                    break;
B
blueswir1 已提交
1285 1286
                case 0x3: /* V9 rdasi */
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, asi));
B
bellard 已提交
1287 1288
                    gen_movl_T0_reg(rd);
                    break;
B
blueswir1 已提交
1289
                case 0x4: /* V9 rdtick */
B
blueswir1 已提交
1290 1291 1292 1293 1294 1295 1296 1297 1298 1299
                    {
                        TCGv r_tickptr;

                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                       offsetof(CPUState, tick));
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_T[0],
                                           r_tickptr);
                        gen_movl_T0_reg(rd);
                    }
B
bellard 已提交
1300
                    break;
B
blueswir1 已提交
1301
                case 0x5: /* V9 rdpc */
B
blueswir1 已提交
1302
                    tcg_gen_movi_tl(cpu_T[0], dc->pc);
B
blueswir1 已提交
1303 1304 1305 1306
                    gen_movl_T0_reg(rd);
                    break;
                case 0x6: /* V9 rdfprs */
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, fprs));
B
bellard 已提交
1307 1308
                    gen_movl_T0_reg(rd);
                    break;
1309 1310
                case 0xf: /* V9 membar */
                    break; /* no effect */
B
blueswir1 已提交
1311
                case 0x13: /* Graphics Status */
B
bellard 已提交
1312 1313
                    if (gen_trap_ifnofpu(dc))
                        goto jmp_insn;
B
blueswir1 已提交
1314
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, gsr));
B
bellard 已提交
1315 1316
                    gen_movl_T0_reg(rd);
                    break;
B
blueswir1 已提交
1317 1318
                case 0x17: /* Tick compare */
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, tick_cmpr));
B
bellard 已提交
1319 1320
                    gen_movl_T0_reg(rd);
                    break;
B
blueswir1 已提交
1321
                case 0x18: /* System tick */
B
blueswir1 已提交
1322 1323 1324 1325 1326 1327 1328 1329 1330 1331
                    {
                        TCGv r_tickptr;

                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                       offsetof(CPUState, stick));
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_T[0],
                                           r_tickptr);
                        gen_movl_T0_reg(rd);
                    }
B
bellard 已提交
1332
                    break;
B
blueswir1 已提交
1333 1334
                case 0x19: /* System tick compare */
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, stick_cmpr));
B
bellard 已提交
1335 1336
                    gen_movl_T0_reg(rd);
                    break;
B
blueswir1 已提交
1337 1338 1339 1340 1341 1342
                case 0x10: /* Performance Control */
                case 0x11: /* Performance Instrumentation Counter */
                case 0x12: /* Dispatch Control */
                case 0x14: /* Softint set, WO */
                case 0x15: /* Softint clear, WO */
                case 0x16: /* Softint write */
B
bellard 已提交
1343 1344
#endif
                default:
1345 1346
                    goto illegal_insn;
                }
1347
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
1348
            } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
B
bellard 已提交
1349
#ifndef TARGET_SPARC64
B
blueswir1 已提交
1350 1351
                if (!supervisor(dc))
                    goto priv_insn;
B
blueswir1 已提交
1352
                tcg_gen_helper_1_0(helper_rdpsr, cpu_T[0]);
B
blueswir1 已提交
1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379
#else
                if (!hypervisor(dc))
                    goto priv_insn;
                rs1 = GET_FIELD(insn, 13, 17);
                switch (rs1) {
                case 0: // hpstate
                    // gen_op_rdhpstate();
                    break;
                case 1: // htstate
                    // gen_op_rdhtstate();
                    break;
                case 3: // hintp
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, hintp));
                    break;
                case 5: // htba
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, htba));
                    break;
                case 6: // hver
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, hver));
                    break;
                case 31: // hstick_cmpr
                    gen_op_movl_env_T0(offsetof(CPUSPARCState, hstick_cmpr));
                    break;
                default:
                    goto illegal_insn;
                }
#endif
1380 1381
                gen_movl_T0_reg(rd);
                break;
B
bellard 已提交
1382
            } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
B
blueswir1 已提交
1383 1384
                if (!supervisor(dc))
                    goto priv_insn;
B
bellard 已提交
1385 1386
#ifdef TARGET_SPARC64
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
1387 1388
                switch (rs1) {
                case 0: // tpc
1389 1390 1391 1392 1393 1394 1395 1396 1397
                    {
                        TCGv r_tsptr;

                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                       offsetof(CPUState, tsptr));
                        tcg_gen_ld_tl(cpu_T[0], r_tsptr,
                                      offsetof(trap_state, tpc));
                    }
B
blueswir1 已提交
1398 1399
                    break;
                case 1: // tnpc
1400 1401 1402 1403 1404 1405 1406 1407 1408
                    {
                        TCGv r_tsptr;

                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                       offsetof(CPUState, tsptr));
                        tcg_gen_ld_tl(cpu_T[0], r_tsptr,
                                      offsetof(trap_state, tnpc));
                    }
B
blueswir1 已提交
1409 1410
                    break;
                case 2: // tstate
1411 1412 1413 1414 1415 1416 1417 1418 1419
                    {
                        TCGv r_tsptr;

                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                       offsetof(CPUState, tsptr));
                        tcg_gen_ld_tl(cpu_T[0], r_tsptr,
                                      offsetof(trap_state, tstate));
                    }
B
blueswir1 已提交
1420 1421
                    break;
                case 3: // tt
1422 1423 1424 1425 1426 1427 1428 1429 1430
                    {
                        TCGv r_tsptr;

                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                       offsetof(CPUState, tsptr));
                        tcg_gen_ld_i32(cpu_T[0], r_tsptr,
                                       offsetof(trap_state, tt));
                    }
B
blueswir1 已提交
1431 1432
                    break;
                case 4: // tick
B
blueswir1 已提交
1433 1434 1435 1436 1437 1438 1439 1440 1441 1442
                    {
                        TCGv r_tickptr;

                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                       offsetof(CPUState, tick));
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_T[0],
                                           r_tickptr);
                        gen_movl_T0_reg(rd);
                    }
B
blueswir1 已提交
1443 1444 1445 1446 1447
                    break;
                case 5: // tba
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
                    break;
                case 6: // pstate
B
blueswir1 已提交
1448
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, pstate));
B
blueswir1 已提交
1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473
                    break;
                case 7: // tl
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, tl));
                    break;
                case 8: // pil
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, psrpil));
                    break;
                case 9: // cwp
                    gen_op_rdcwp();
                    break;
                case 10: // cansave
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, cansave));
                    break;
                case 11: // canrestore
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, canrestore));
                    break;
                case 12: // cleanwin
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, cleanwin));
                    break;
                case 13: // otherwin
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, otherwin));
                    break;
                case 14: // wstate
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, wstate));
                    break;
B
blueswir1 已提交
1474 1475 1476 1477 1478 1479 1480 1481
                case 16: // UA2005 gl
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, gl));
                    break;
                case 26: // UA2005 strand status
                    if (!hypervisor(dc))
                        goto priv_insn;
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, ssr));
                    break;
B
blueswir1 已提交
1482 1483 1484 1485 1486 1487 1488
                case 31: // ver
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, version));
                    break;
                case 15: // fq
                default:
                    goto illegal_insn;
                }
B
bellard 已提交
1489
#else
B
blueswir1 已提交
1490
                gen_op_movl_T0_env(offsetof(CPUSPARCState, wim));
B
bellard 已提交
1491
#endif
1492 1493
                gen_movl_T0_reg(rd);
                break;
B
bellard 已提交
1494 1495
            } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
#ifdef TARGET_SPARC64
B
blueswir1 已提交
1496
                gen_op_flushw();
B
bellard 已提交
1497
#else
B
blueswir1 已提交
1498 1499 1500
                if (!supervisor(dc))
                    goto priv_insn;
                gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
1501
                gen_movl_T0_reg(rd);
B
bellard 已提交
1502
#endif
1503 1504
                break;
#endif
B
blueswir1 已提交
1505
            } else if (xop == 0x34) {   /* FPU Operations */
B
bellard 已提交
1506 1507
                if (gen_trap_ifnofpu(dc))
                    goto jmp_insn;
B
blueswir1 已提交
1508
                gen_op_clear_ieee_excp_and_FTT();
1509
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523
                rs2 = GET_FIELD(insn, 27, 31);
                xop = GET_FIELD(insn, 18, 26);
                switch (xop) {
                    case 0x1: /* fmovs */
                        gen_op_load_fpr_FT0(rs2);
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x5: /* fnegs */
                        gen_op_load_fpr_FT1(rs2);
                        gen_op_fnegs();
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x9: /* fabss */
                        gen_op_load_fpr_FT1(rs2);
1524
                        tcg_gen_helper_0_0(helper_fabss);
B
blueswir1 已提交
1525 1526 1527 1528
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x29: /* fsqrts */
                        gen_op_load_fpr_FT1(rs2);
1529 1530 1531
                        gen_clear_float_exceptions();
                        tcg_gen_helper_0_0(helper_fsqrts);
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1532 1533 1534 1535
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x2a: /* fsqrtd */
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1536 1537 1538
                        gen_clear_float_exceptions();
                        tcg_gen_helper_0_0(helper_fsqrtd);
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1539 1540 1541
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x2b: /* fsqrtq */
B
blueswir1 已提交
1542 1543
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1544 1545 1546
                        gen_clear_float_exceptions();
                        tcg_gen_helper_0_0(helper_fsqrtq);
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1547 1548 1549
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
B
blueswir1 已提交
1550
                        goto nfpu_insn;
B
blueswir1 已提交
1551
#endif
B
blueswir1 已提交
1552 1553 1554
                    case 0x41:
                        gen_op_load_fpr_FT0(rs1);
                        gen_op_load_fpr_FT1(rs2);
1555
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1556
                        gen_op_fadds();
1557
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1558 1559 1560 1561 1562
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x42:
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1563
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1564
                        gen_op_faddd();
1565
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1566 1567 1568
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x43: /* faddq */
B
blueswir1 已提交
1569 1570 1571
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1572
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1573
                        gen_op_faddq();
1574
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1575 1576 1577
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
B
blueswir1 已提交
1578
                        goto nfpu_insn;
B
blueswir1 已提交
1579
#endif
B
blueswir1 已提交
1580 1581 1582
                    case 0x45:
                        gen_op_load_fpr_FT0(rs1);
                        gen_op_load_fpr_FT1(rs2);
1583
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1584
                        gen_op_fsubs();
1585
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1586 1587 1588 1589 1590
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x46:
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1591
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1592
                        gen_op_fsubd();
1593
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1594 1595 1596
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x47: /* fsubq */
B
blueswir1 已提交
1597 1598 1599
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1600
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1601
                        gen_op_fsubq();
1602
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1603 1604 1605
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
B
blueswir1 已提交
1606
                        goto nfpu_insn;
B
blueswir1 已提交
1607
#endif
B
blueswir1 已提交
1608 1609 1610
                    case 0x49:
                        gen_op_load_fpr_FT0(rs1);
                        gen_op_load_fpr_FT1(rs2);
1611
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1612
                        gen_op_fmuls();
1613
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1614 1615 1616 1617 1618
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x4a:
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1619
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1620
                        gen_op_fmuld();
1621
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
1622
                        gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
1623 1624
                        break;
                    case 0x4b: /* fmulq */
B
blueswir1 已提交
1625 1626 1627
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1628
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1629
                        gen_op_fmulq();
1630
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1631 1632 1633
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
B
blueswir1 已提交
1634
                        goto nfpu_insn;
B
blueswir1 已提交
1635
#endif
B
blueswir1 已提交
1636 1637 1638
                    case 0x4d:
                        gen_op_load_fpr_FT0(rs1);
                        gen_op_load_fpr_FT1(rs2);
1639
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1640
                        gen_op_fdivs();
1641
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1642 1643 1644 1645 1646
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x4e:
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1647
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1648
                        gen_op_fdivd();
1649
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1650 1651 1652
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x4f: /* fdivq */
B
blueswir1 已提交
1653 1654 1655
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1656
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1657
                        gen_op_fdivq();
1658
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1659 1660 1661
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
B
blueswir1 已提交
1662
                        goto nfpu_insn;
B
blueswir1 已提交
1663
#endif
B
blueswir1 已提交
1664 1665 1666
                    case 0x69:
                        gen_op_load_fpr_FT0(rs1);
                        gen_op_load_fpr_FT1(rs2);
1667
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1668
                        gen_op_fsmuld();
1669
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1670 1671 1672
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x6e: /* fdmulq */
B
blueswir1 已提交
1673 1674 1675
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1676
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1677
                        gen_op_fdmulq();
1678
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1679 1680 1681
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
B
blueswir1 已提交
1682
                        goto nfpu_insn;
B
blueswir1 已提交
1683
#endif
B
blueswir1 已提交
1684 1685
                    case 0xc4:
                        gen_op_load_fpr_FT1(rs2);
1686
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1687
                        gen_op_fitos();
1688
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1689 1690 1691 1692
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0xc6:
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1693
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1694
                        gen_op_fdtos();
1695
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1696 1697 1698
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0xc7: /* fqtos */
B
blueswir1 已提交
1699 1700
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1701
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1702
                        gen_op_fqtos();
1703
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1704 1705 1706
                        gen_op_store_FT0_fpr(rd);
                        break;
#else
B
blueswir1 已提交
1707
                        goto nfpu_insn;
B
blueswir1 已提交
1708
#endif
B
blueswir1 已提交
1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719
                    case 0xc8:
                        gen_op_load_fpr_FT1(rs2);
                        gen_op_fitod();
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0xc9:
                        gen_op_load_fpr_FT1(rs2);
                        gen_op_fstod();
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0xcb: /* fqtod */
B
blueswir1 已提交
1720 1721
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1722
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1723
                        gen_op_fqtod();
1724
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1725 1726 1727
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
#else
B
blueswir1 已提交
1728
                        goto nfpu_insn;
B
blueswir1 已提交
1729
#endif
B
blueswir1 已提交
1730
                    case 0xcc: /* fitoq */
B
blueswir1 已提交
1731 1732 1733 1734 1735 1736
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_FT1(rs2);
                        gen_op_fitoq();
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
B
blueswir1 已提交
1737
                        goto nfpu_insn;
B
blueswir1 已提交
1738
#endif
B
blueswir1 已提交
1739
                    case 0xcd: /* fstoq */
B
blueswir1 已提交
1740 1741 1742 1743 1744 1745
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_FT1(rs2);
                        gen_op_fstoq();
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
B
blueswir1 已提交
1746
                        goto nfpu_insn;
B
blueswir1 已提交
1747
#endif
B
blueswir1 已提交
1748
                    case 0xce: /* fdtoq */
B
blueswir1 已提交
1749 1750 1751 1752 1753 1754
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_DT1(DFPREG(rs2));
                        gen_op_fdtoq();
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
B
blueswir1 已提交
1755
                        goto nfpu_insn;
B
blueswir1 已提交
1756
#endif
B
blueswir1 已提交
1757 1758
                    case 0xd1:
                        gen_op_load_fpr_FT1(rs2);
1759
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1760
                        gen_op_fstoi();
1761
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1762 1763 1764
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0xd2:
1765
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1766
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1767
                        gen_op_fdtoi();
1768
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1769 1770 1771
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0xd3: /* fqtoi */
B
blueswir1 已提交
1772 1773
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1774
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1775
                        gen_op_fqtoi();
1776
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1777 1778 1779
                        gen_op_store_FT0_fpr(rd);
                        break;
#else
B
blueswir1 已提交
1780
                        goto nfpu_insn;
B
blueswir1 已提交
1781
#endif
B
bellard 已提交
1782
#ifdef TARGET_SPARC64
B
blueswir1 已提交
1783 1784 1785 1786
                    case 0x2: /* V9 fmovd */
                        gen_op_load_fpr_DT0(DFPREG(rs2));
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
B
blueswir1 已提交
1787 1788 1789 1790 1791 1792 1793 1794
                    case 0x3: /* V9 fmovq */
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT0(QFPREG(rs2));
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
                        goto nfpu_insn;
#endif
B
blueswir1 已提交
1795 1796 1797 1798 1799
                    case 0x6: /* V9 fnegd */
                        gen_op_load_fpr_DT1(DFPREG(rs2));
                        gen_op_fnegd();
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
B
blueswir1 已提交
1800 1801 1802 1803 1804 1805 1806 1807 1808
                    case 0x7: /* V9 fnegq */
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT1(QFPREG(rs2));
                        gen_op_fnegq();
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
                        goto nfpu_insn;
#endif
B
blueswir1 已提交
1809 1810
                    case 0xa: /* V9 fabsd */
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1811
                        tcg_gen_helper_0_0(helper_fabsd);
B
blueswir1 已提交
1812 1813
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
B
blueswir1 已提交
1814 1815 1816
                    case 0xb: /* V9 fabsq */
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1817
                        tcg_gen_helper_0_0(helper_fabsq);
B
blueswir1 已提交
1818 1819 1820 1821 1822
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
                        goto nfpu_insn;
#endif
B
blueswir1 已提交
1823 1824
                    case 0x81: /* V9 fstox */
                        gen_op_load_fpr_FT1(rs2);
1825
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1826
                        gen_op_fstox();
1827
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1828 1829 1830 1831
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x82: /* V9 fdtox */
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1832
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1833
                        gen_op_fdtox();
1834
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1835 1836
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
B
blueswir1 已提交
1837 1838 1839
                    case 0x83: /* V9 fqtox */
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1840
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1841
                        gen_op_fqtox();
1842
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1843 1844 1845 1846 1847
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
#else
                        goto nfpu_insn;
#endif
B
blueswir1 已提交
1848 1849
                    case 0x84: /* V9 fxtos */
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1850
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1851
                        gen_op_fxtos();
1852
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1853 1854 1855 1856
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x88: /* V9 fxtod */
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1857
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1858
                        gen_op_fxtod();
1859
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1860 1861 1862
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x8c: /* V9 fxtoq */
B
blueswir1 已提交
1863 1864
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1865
                        gen_clear_float_exceptions();
B
blueswir1 已提交
1866
                        gen_op_fxtoq();
1867
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
1868 1869 1870
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
B
blueswir1 已提交
1871
                        goto nfpu_insn;
B
blueswir1 已提交
1872
#endif
B
blueswir1 已提交
1873 1874 1875 1876 1877
#endif
                    default:
                        goto illegal_insn;
                }
            } else if (xop == 0x35) {   /* FPU Operations */
B
bellard 已提交
1878
#ifdef TARGET_SPARC64
B
blueswir1 已提交
1879
                int cond;
B
bellard 已提交
1880
#endif
B
bellard 已提交
1881 1882
                if (gen_trap_ifnofpu(dc))
                    goto jmp_insn;
B
blueswir1 已提交
1883
                gen_op_clear_ieee_excp_and_FTT();
1884
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
1885 1886
                rs2 = GET_FIELD(insn, 27, 31);
                xop = GET_FIELD(insn, 18, 26);
B
bellard 已提交
1887
#ifdef TARGET_SPARC64
B
blueswir1 已提交
1888
                if ((xop & 0x11f) == 0x005) { // V9 fmovsr
B
blueswir1 已提交
1889 1890 1891 1892 1893
                    TCGv r_zero;
                    int l1;

                    l1 = gen_new_label();
                    r_zero = tcg_temp_new(TCG_TYPE_TL);
B
blueswir1 已提交
1894 1895 1896
                    cond = GET_FIELD_SP(insn, 14, 17);
                    rs1 = GET_FIELD(insn, 13, 17);
                    gen_movl_reg_T0(rs1);
B
blueswir1 已提交
1897 1898 1899
                    tcg_gen_movi_tl(r_zero, 0);
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0], r_zero, l1);
                    gen_op_load_fpr_FT1(rs2);
B
blueswir1 已提交
1900
                    gen_op_store_FT0_fpr(rd);
B
blueswir1 已提交
1901
                    gen_set_label(l1);
B
blueswir1 已提交
1902 1903
                    break;
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
B
blueswir1 已提交
1904 1905 1906 1907 1908
                    TCGv r_zero;
                    int l1;

                    l1 = gen_new_label();
                    r_zero = tcg_temp_new(TCG_TYPE_TL);
B
blueswir1 已提交
1909 1910 1911
                    cond = GET_FIELD_SP(insn, 14, 17);
                    rs1 = GET_FIELD(insn, 13, 17);
                    gen_movl_reg_T0(rs1);
B
blueswir1 已提交
1912 1913 1914
                    tcg_gen_movi_tl(r_zero, 0);
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0], r_zero, l1);
                    gen_op_load_fpr_DT1(DFPREG(rs2));
1915
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
1916
                    gen_set_label(l1);
B
blueswir1 已提交
1917 1918
                    break;
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
B
blueswir1 已提交
1919
#if defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
1920 1921 1922 1923 1924
                    TCGv r_zero;
                    int l1;

                    l1 = gen_new_label();
                    r_zero = tcg_temp_new(TCG_TYPE_TL);
B
blueswir1 已提交
1925 1926 1927
                    cond = GET_FIELD_SP(insn, 14, 17);
                    rs1 = GET_FIELD(insn, 13, 17);
                    gen_movl_reg_T0(rs1);
B
blueswir1 已提交
1928 1929 1930
                    tcg_gen_movi_tl(r_zero, 0);
                    tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0], r_zero, l1);
                    gen_op_load_fpr_QT1(QFPREG(rs2));
B
blueswir1 已提交
1931
                    gen_op_store_QT0_fpr(QFPREG(rd));
B
blueswir1 已提交
1932
                    gen_set_label(l1);
B
blueswir1 已提交
1933 1934
                    break;
#else
B
blueswir1 已提交
1935
                    goto nfpu_insn;
B
blueswir1 已提交
1936
#endif
B
blueswir1 已提交
1937 1938 1939
                }
#endif
                switch (xop) {
B
bellard 已提交
1940
#ifdef TARGET_SPARC64
B
blueswir1 已提交
1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951
                    case 0x001: /* V9 fmovscc %fcc0 */
                        cond = GET_FIELD_SP(insn, 14, 17);
                        gen_op_load_fpr_FT0(rd);
                        gen_op_load_fpr_FT1(rs2);
                        flush_T2(dc);
                        gen_fcond[0][cond]();
                        gen_op_fmovs_cc();
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x002: /* V9 fmovdcc %fcc0 */
                        cond = GET_FIELD_SP(insn, 14, 17);
1952 1953
                        gen_op_load_fpr_DT0(DFPREG(rd));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
1954 1955 1956
                        flush_T2(dc);
                        gen_fcond[0][cond]();
                        gen_op_fmovd_cc();
1957
                        gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
1958 1959
                        break;
                    case 0x003: /* V9 fmovqcc %fcc0 */
B
blueswir1 已提交
1960 1961 1962 1963 1964 1965 1966 1967 1968 1969
#if defined(CONFIG_USER_ONLY)
                        cond = GET_FIELD_SP(insn, 14, 17);
                        gen_op_load_fpr_QT0(QFPREG(rd));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
                        flush_T2(dc);
                        gen_fcond[0][cond]();
                        gen_op_fmovq_cc();
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
B
blueswir1 已提交
1970
                        goto nfpu_insn;
B
blueswir1 已提交
1971
#endif
B
blueswir1 已提交
1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982
                    case 0x041: /* V9 fmovscc %fcc1 */
                        cond = GET_FIELD_SP(insn, 14, 17);
                        gen_op_load_fpr_FT0(rd);
                        gen_op_load_fpr_FT1(rs2);
                        flush_T2(dc);
                        gen_fcond[1][cond]();
                        gen_op_fmovs_cc();
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x042: /* V9 fmovdcc %fcc1 */
                        cond = GET_FIELD_SP(insn, 14, 17);
1983 1984
                        gen_op_load_fpr_DT0(DFPREG(rd));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
1985 1986 1987
                        flush_T2(dc);
                        gen_fcond[1][cond]();
                        gen_op_fmovd_cc();
1988
                        gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
1989 1990
                        break;
                    case 0x043: /* V9 fmovqcc %fcc1 */
B
blueswir1 已提交
1991 1992 1993 1994 1995 1996 1997 1998 1999 2000
#if defined(CONFIG_USER_ONLY)
                        cond = GET_FIELD_SP(insn, 14, 17);
                        gen_op_load_fpr_QT0(QFPREG(rd));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
                        flush_T2(dc);
                        gen_fcond[1][cond]();
                        gen_op_fmovq_cc();
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
B
blueswir1 已提交
2001
                        goto nfpu_insn;
B
blueswir1 已提交
2002
#endif
B
blueswir1 已提交
2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013
                    case 0x081: /* V9 fmovscc %fcc2 */
                        cond = GET_FIELD_SP(insn, 14, 17);
                        gen_op_load_fpr_FT0(rd);
                        gen_op_load_fpr_FT1(rs2);
                        flush_T2(dc);
                        gen_fcond[2][cond]();
                        gen_op_fmovs_cc();
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x082: /* V9 fmovdcc %fcc2 */
                        cond = GET_FIELD_SP(insn, 14, 17);
2014 2015
                        gen_op_load_fpr_DT0(DFPREG(rd));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2016 2017 2018
                        flush_T2(dc);
                        gen_fcond[2][cond]();
                        gen_op_fmovd_cc();
2019
                        gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2020 2021
                        break;
                    case 0x083: /* V9 fmovqcc %fcc2 */
B
blueswir1 已提交
2022 2023 2024 2025 2026 2027 2028 2029 2030 2031
#if defined(CONFIG_USER_ONLY)
                        cond = GET_FIELD_SP(insn, 14, 17);
                        gen_op_load_fpr_QT0(rd);
                        gen_op_load_fpr_QT1(rs2);
                        flush_T2(dc);
                        gen_fcond[2][cond]();
                        gen_op_fmovq_cc();
                        gen_op_store_QT0_fpr(rd);
                        break;
#else
B
blueswir1 已提交
2032
                        goto nfpu_insn;
B
blueswir1 已提交
2033
#endif
B
blueswir1 已提交
2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044
                    case 0x0c1: /* V9 fmovscc %fcc3 */
                        cond = GET_FIELD_SP(insn, 14, 17);
                        gen_op_load_fpr_FT0(rd);
                        gen_op_load_fpr_FT1(rs2);
                        flush_T2(dc);
                        gen_fcond[3][cond]();
                        gen_op_fmovs_cc();
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x0c2: /* V9 fmovdcc %fcc3 */
                        cond = GET_FIELD_SP(insn, 14, 17);
2045 2046
                        gen_op_load_fpr_DT0(DFPREG(rd));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2047 2048 2049
                        flush_T2(dc);
                        gen_fcond[3][cond]();
                        gen_op_fmovd_cc();
2050
                        gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2051 2052
                        break;
                    case 0x0c3: /* V9 fmovqcc %fcc3 */
B
blueswir1 已提交
2053 2054 2055 2056 2057 2058 2059 2060 2061 2062
#if defined(CONFIG_USER_ONLY)
                        cond = GET_FIELD_SP(insn, 14, 17);
                        gen_op_load_fpr_QT0(QFPREG(rd));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
                        flush_T2(dc);
                        gen_fcond[3][cond]();
                        gen_op_fmovq_cc();
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
B
blueswir1 已提交
2063
                        goto nfpu_insn;
B
blueswir1 已提交
2064
#endif
B
blueswir1 已提交
2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075
                    case 0x101: /* V9 fmovscc %icc */
                        cond = GET_FIELD_SP(insn, 14, 17);
                        gen_op_load_fpr_FT0(rd);
                        gen_op_load_fpr_FT1(rs2);
                        flush_T2(dc);
                        gen_cond[0][cond]();
                        gen_op_fmovs_cc();
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x102: /* V9 fmovdcc %icc */
                        cond = GET_FIELD_SP(insn, 14, 17);
2076 2077
                        gen_op_load_fpr_DT0(DFPREG(rd));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2078 2079 2080
                        flush_T2(dc);
                        gen_cond[0][cond]();
                        gen_op_fmovd_cc();
2081
                        gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2082 2083
                        break;
                    case 0x103: /* V9 fmovqcc %icc */
B
blueswir1 已提交
2084 2085 2086 2087 2088 2089 2090 2091 2092 2093
#if defined(CONFIG_USER_ONLY)
                        cond = GET_FIELD_SP(insn, 14, 17);
                        gen_op_load_fpr_QT0(rd);
                        gen_op_load_fpr_QT1(rs2);
                        flush_T2(dc);
                        gen_cond[0][cond]();
                        gen_op_fmovq_cc();
                        gen_op_store_QT0_fpr(rd);
                        break;
#else
B
blueswir1 已提交
2094
                        goto nfpu_insn;
B
blueswir1 已提交
2095
#endif
B
blueswir1 已提交
2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106
                    case 0x181: /* V9 fmovscc %xcc */
                        cond = GET_FIELD_SP(insn, 14, 17);
                        gen_op_load_fpr_FT0(rd);
                        gen_op_load_fpr_FT1(rs2);
                        flush_T2(dc);
                        gen_cond[1][cond]();
                        gen_op_fmovs_cc();
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x182: /* V9 fmovdcc %xcc */
                        cond = GET_FIELD_SP(insn, 14, 17);
2107 2108
                        gen_op_load_fpr_DT0(DFPREG(rd));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2109 2110 2111
                        flush_T2(dc);
                        gen_cond[1][cond]();
                        gen_op_fmovd_cc();
2112
                        gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2113 2114
                        break;
                    case 0x183: /* V9 fmovqcc %xcc */
B
blueswir1 已提交
2115 2116 2117 2118 2119 2120 2121 2122 2123 2124
#if defined(CONFIG_USER_ONLY)
                        cond = GET_FIELD_SP(insn, 14, 17);
                        gen_op_load_fpr_QT0(rd);
                        gen_op_load_fpr_QT1(rs2);
                        flush_T2(dc);
                        gen_cond[1][cond]();
                        gen_op_fmovq_cc();
                        gen_op_store_QT0_fpr(rd);
                        break;
#else
B
blueswir1 已提交
2125 2126
                        goto nfpu_insn;
#endif
B
blueswir1 已提交
2127 2128
#endif
                    case 0x51: /* fcmps, V9 %fcc */
B
blueswir1 已提交
2129 2130
                        gen_op_load_fpr_FT0(rs1);
                        gen_op_load_fpr_FT1(rs2);
2131
                        gen_op_fcmps(rd & 3);
B
blueswir1 已提交
2132
                        break;
B
blueswir1 已提交
2133
                    case 0x52: /* fcmpd, V9 %fcc */
B
blueswir1 已提交
2134 2135
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2136
                        gen_op_fcmpd(rd & 3);
B
blueswir1 已提交
2137
                        break;
B
blueswir1 已提交
2138 2139 2140 2141
                    case 0x53: /* fcmpq, V9 %fcc */
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2142
                        gen_op_fcmpq(rd & 3);
B
blueswir1 已提交
2143 2144
                        break;
#else /* !defined(CONFIG_USER_ONLY) */
B
blueswir1 已提交
2145
                        goto nfpu_insn;
B
blueswir1 已提交
2146
#endif
B
blueswir1 已提交
2147 2148 2149
                    case 0x55: /* fcmpes, V9 %fcc */
                        gen_op_load_fpr_FT0(rs1);
                        gen_op_load_fpr_FT1(rs2);
2150
                        gen_op_fcmpes(rd & 3);
B
blueswir1 已提交
2151 2152 2153 2154
                        break;
                    case 0x56: /* fcmped, V9 %fcc */
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2155
                        gen_op_fcmped(rd & 3);
B
blueswir1 已提交
2156
                        break;
B
blueswir1 已提交
2157 2158 2159 2160
                    case 0x57: /* fcmpeq, V9 %fcc */
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2161
                        gen_op_fcmpeq(rd & 3);
B
blueswir1 已提交
2162 2163
                        break;
#else/* !defined(CONFIG_USER_ONLY) */
B
blueswir1 已提交
2164
                        goto nfpu_insn;
B
blueswir1 已提交
2165
#endif
B
blueswir1 已提交
2166 2167 2168
                    default:
                        goto illegal_insn;
                }
B
bellard 已提交
2169
#if defined(OPTIM)
B
blueswir1 已提交
2170 2171
            } else if (xop == 0x2) {
                // clr/mov shortcut
B
bellard 已提交
2172 2173

                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
2174
                if (rs1 == 0) {
B
blueswir1 已提交
2175
                    // or %g0, x, y -> mov T0, x; mov y, T0
B
blueswir1 已提交
2176 2177
                    if (IS_IMM) {       /* immediate */
                        rs2 = GET_FIELDs(insn, 19, 31);
B
blueswir1 已提交
2178
                        tcg_gen_movi_tl(cpu_T[0], (int)rs2);
B
blueswir1 已提交
2179 2180
                    } else {            /* register */
                        rs2 = GET_FIELD(insn, 27, 31);
B
blueswir1 已提交
2181
                        gen_movl_reg_T0(rs2);
B
blueswir1 已提交
2182 2183 2184 2185 2186
                    }
                } else {
                    gen_movl_reg_T0(rs1);
                    if (IS_IMM) {       /* immediate */
                        rs2 = GET_FIELDs(insn, 19, 31);
B
blueswir1 已提交
2187
                        tcg_gen_ori_tl(cpu_T[0], cpu_T[0], (int)rs2);
B
blueswir1 已提交
2188 2189 2190 2191 2192 2193 2194 2195 2196
                    } else {            /* register */
                        // or x, %g0, y -> mov T1, x; mov y, T1
                        rs2 = GET_FIELD(insn, 27, 31);
                        if (rs2 != 0) {
                            gen_movl_reg_T1(rs2);
                            gen_op_or_T1_T0();
                        }
                    }
                }
B
blueswir1 已提交
2197
                gen_movl_T0_reg(rd);
B
bellard 已提交
2198 2199
#endif
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2200
            } else if (xop == 0x25) { /* sll, V9 sllx */
B
bellard 已提交
2201
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
2202 2203
                gen_movl_reg_T0(rs1);
                if (IS_IMM) {   /* immediate */
B
bellard 已提交
2204
                    rs2 = GET_FIELDs(insn, 20, 31);
B
blueswir1 已提交
2205 2206 2207 2208 2209 2210
                    if (insn & (1 << 12)) {
                        tcg_gen_shli_i64(cpu_T[0], cpu_T[0], rs2 & 0x3f);
                    } else {
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
                        tcg_gen_shli_i64(cpu_T[0], cpu_T[0], rs2 & 0x1f);
                    }
B
blueswir1 已提交
2211
                } else {                /* register */
B
bellard 已提交
2212 2213
                    rs2 = GET_FIELD(insn, 27, 31);
                    gen_movl_reg_T1(rs2);
B
blueswir1 已提交
2214 2215 2216 2217 2218 2219 2220 2221
                    if (insn & (1 << 12)) {
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x3f);
                        tcg_gen_shl_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
                    } else {
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x1f);
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
                        tcg_gen_shl_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
                    }
B
bellard 已提交
2222
                }
B
blueswir1 已提交
2223 2224
                gen_movl_T0_reg(rd);
            } else if (xop == 0x26) { /* srl, V9 srlx */
B
bellard 已提交
2225
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
2226 2227
                gen_movl_reg_T0(rs1);
                if (IS_IMM) {   /* immediate */
B
bellard 已提交
2228
                    rs2 = GET_FIELDs(insn, 20, 31);
B
blueswir1 已提交
2229 2230 2231 2232 2233 2234
                    if (insn & (1 << 12)) {
                        tcg_gen_shri_i64(cpu_T[0], cpu_T[0], rs2 & 0x3f);
                    } else {
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
                        tcg_gen_shri_i64(cpu_T[0], cpu_T[0], rs2 & 0x1f);
                    }
B
blueswir1 已提交
2235
                } else {                /* register */
B
bellard 已提交
2236 2237
                    rs2 = GET_FIELD(insn, 27, 31);
                    gen_movl_reg_T1(rs2);
B
blueswir1 已提交
2238 2239 2240 2241 2242 2243 2244 2245
                    if (insn & (1 << 12)) {
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x3f);
                        tcg_gen_shr_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
                    } else {
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x1f);
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
                        tcg_gen_shr_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
                    }
B
bellard 已提交
2246
                }
B
blueswir1 已提交
2247 2248
                gen_movl_T0_reg(rd);
            } else if (xop == 0x27) { /* sra, V9 srax */
B
bellard 已提交
2249
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
2250 2251
                gen_movl_reg_T0(rs1);
                if (IS_IMM) {   /* immediate */
B
bellard 已提交
2252
                    rs2 = GET_FIELDs(insn, 20, 31);
B
blueswir1 已提交
2253 2254 2255 2256 2257 2258 2259
                    if (insn & (1 << 12)) {
                        tcg_gen_sari_i64(cpu_T[0], cpu_T[0], rs2 & 0x3f);
                    } else {
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
                        tcg_gen_ext_i32_i64(cpu_T[0], cpu_T[0]);
                        tcg_gen_sari_i64(cpu_T[0], cpu_T[0], rs2 & 0x1f);
                    }
B
blueswir1 已提交
2260
                } else {                /* register */
B
bellard 已提交
2261 2262
                    rs2 = GET_FIELD(insn, 27, 31);
                    gen_movl_reg_T1(rs2);
B
blueswir1 已提交
2263 2264 2265 2266 2267 2268 2269 2270
                    if (insn & (1 << 12)) {
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x3f);
                        tcg_gen_sar_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
                    } else {
                        tcg_gen_andi_i64(cpu_T[1], cpu_T[1], 0x1f);
                        tcg_gen_andi_i64(cpu_T[0], cpu_T[0], 0xffffffffULL);
                        tcg_gen_sar_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
                    }
B
bellard 已提交
2271
                }
B
blueswir1 已提交
2272
                gen_movl_T0_reg(rd);
B
bellard 已提交
2273
#endif
2274
            } else if (xop < 0x36) {
B
bellard 已提交
2275
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
2276 2277
                gen_movl_reg_T0(rs1);
                if (IS_IMM) {   /* immediate */
2278
                    rs2 = GET_FIELDs(insn, 19, 31);
B
bellard 已提交
2279
                    gen_movl_simm_T1(rs2);
B
blueswir1 已提交
2280
                } else {                /* register */
2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292
                    rs2 = GET_FIELD(insn, 27, 31);
                    gen_movl_reg_T1(rs2);
                }
                if (xop < 0x20) {
                    switch (xop & ~0x10) {
                    case 0x0:
                        if (xop & 0x10)
                            gen_op_add_T1_T0_cc();
                        else
                            gen_op_add_T1_T0();
                        break;
                    case 0x1:
B
blueswir1 已提交
2293
                        tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2294 2295 2296 2297
                        if (xop & 0x10)
                            gen_op_logic_T0_cc();
                        break;
                    case 0x2:
B
blueswir1 已提交
2298
                        tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
B
blueswir1 已提交
2299 2300 2301
                        if (xop & 0x10)
                            gen_op_logic_T0_cc();
                        break;
2302
                    case 0x3:
B
blueswir1 已提交
2303
                        tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2304 2305 2306 2307 2308 2309 2310
                        if (xop & 0x10)
                            gen_op_logic_T0_cc();
                        break;
                    case 0x4:
                        if (xop & 0x10)
                            gen_op_sub_T1_T0_cc();
                        else
B
blueswir1 已提交
2311
                            tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329
                        break;
                    case 0x5:
                        gen_op_andn_T1_T0();
                        if (xop & 0x10)
                            gen_op_logic_T0_cc();
                        break;
                    case 0x6:
                        gen_op_orn_T1_T0();
                        if (xop & 0x10)
                            gen_op_logic_T0_cc();
                        break;
                    case 0x7:
                        gen_op_xnor_T1_T0();
                        if (xop & 0x10)
                            gen_op_logic_T0_cc();
                        break;
                    case 0x8:
                        if (xop & 0x10)
2330
                            gen_op_addx_T1_T0_cc();
2331 2332 2333 2334 2335
                        else {
                            gen_mov_reg_C(cpu_tmp0);
                            tcg_gen_add_tl(cpu_T[1], cpu_T[1], cpu_tmp0);
                            tcg_gen_add_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
                        }
2336
                        break;
P
pbrook 已提交
2337
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2338
                    case 0x9: /* V9 mulx */
B
blueswir1 已提交
2339
                        tcg_gen_mul_i64(cpu_T[0], cpu_T[0], cpu_T[1]);
P
pbrook 已提交
2340 2341
                        break;
#endif
2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353
                    case 0xa:
                        gen_op_umul_T1_T0();
                        if (xop & 0x10)
                            gen_op_logic_T0_cc();
                        break;
                    case 0xb:
                        gen_op_smul_T1_T0();
                        if (xop & 0x10)
                            gen_op_logic_T0_cc();
                        break;
                    case 0xc:
                        if (xop & 0x10)
2354
                            gen_op_subx_T1_T0_cc();
2355 2356 2357 2358 2359
                        else {
                            gen_mov_reg_C(cpu_tmp0);
                            tcg_gen_add_tl(cpu_T[1], cpu_T[1], cpu_tmp0);
                            tcg_gen_sub_tl(cpu_T[0], cpu_T[0], cpu_T[1]);
                        }
2360
                        break;
P
pbrook 已提交
2361
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2362
                    case 0xd: /* V9 udivx */
P
pbrook 已提交
2363 2364 2365
                        gen_op_udivx_T1_T0();
                        break;
#endif
2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378
                    case 0xe:
                        gen_op_udiv_T1_T0();
                        if (xop & 0x10)
                            gen_op_div_cc();
                        break;
                    case 0xf:
                        gen_op_sdiv_T1_T0();
                        if (xop & 0x10)
                            gen_op_div_cc();
                        break;
                    default:
                        goto illegal_insn;
                    }
B
blueswir1 已提交
2379
                    gen_movl_T0_reg(rd);
2380 2381
                } else {
                    switch (xop) {
B
blueswir1 已提交
2382 2383 2384 2385 2386 2387 2388 2389 2390
                    case 0x20: /* taddcc */
                        gen_op_tadd_T1_T0_cc();
                        gen_movl_T0_reg(rd);
                        break;
                    case 0x21: /* tsubcc */
                        gen_op_tsub_T1_T0_cc();
                        gen_movl_T0_reg(rd);
                        break;
                    case 0x22: /* taddcctv */
2391
                        save_state(dc);
B
blueswir1 已提交
2392 2393 2394 2395
                        gen_op_tadd_T1_T0_ccTV();
                        gen_movl_T0_reg(rd);
                        break;
                    case 0x23: /* tsubcctv */
2396
                        save_state(dc);
B
blueswir1 已提交
2397 2398 2399
                        gen_op_tsub_T1_T0_ccTV();
                        gen_movl_T0_reg(rd);
                        break;
2400 2401 2402 2403
                    case 0x24: /* mulscc */
                        gen_op_mulscc_T1_T0();
                        gen_movl_T0_reg(rd);
                        break;
B
bellard 已提交
2404
#ifndef TARGET_SPARC64
B
blueswir1 已提交
2405
                    case 0x25:  /* sll */
B
blueswir1 已提交
2406 2407
                        tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0x1f);
                        tcg_gen_shl_i32(cpu_T[0], cpu_T[0], cpu_T[1]);
2408 2409
                        gen_movl_T0_reg(rd);
                        break;
B
bellard 已提交
2410
                    case 0x26:  /* srl */
B
blueswir1 已提交
2411 2412
                        tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0x1f);
                        tcg_gen_shr_i32(cpu_T[0], cpu_T[0], cpu_T[1]);
2413 2414
                        gen_movl_T0_reg(rd);
                        break;
B
bellard 已提交
2415
                    case 0x27:  /* sra */
B
blueswir1 已提交
2416 2417
                        tcg_gen_andi_i32(cpu_T[1], cpu_T[1], 0x1f);
                        tcg_gen_sar_i32(cpu_T[0], cpu_T[0], cpu_T[1]);
2418 2419
                        gen_movl_T0_reg(rd);
                        break;
B
bellard 已提交
2420
#endif
2421 2422 2423
                    case 0x30:
                        {
                            switch(rd) {
B
bellard 已提交
2424
                            case 0: /* wry */
B
blueswir1 已提交
2425 2426
                                gen_op_xor_T1_T0();
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, y));
2427
                                break;
2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438
#ifndef TARGET_SPARC64
                            case 0x01 ... 0x0f: /* undefined in the
                                                   SPARCv8 manual, nop
                                                   on the microSPARC
                                                   II */
                            case 0x10 ... 0x1f: /* implementation-dependent
                                                   in the SPARCv8
                                                   manual, nop on the
                                                   microSPARC II */
                                break;
#else
B
blueswir1 已提交
2439
                            case 0x2: /* V9 wrccr */
B
blueswir1 已提交
2440
                                gen_op_xor_T1_T0();
B
bellard 已提交
2441
                                gen_op_wrccr();
B
blueswir1 已提交
2442 2443
                                break;
                            case 0x3: /* V9 wrasi */
B
blueswir1 已提交
2444
                                gen_op_xor_T1_T0();
B
blueswir1 已提交
2445 2446 2447 2448 2449
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, asi));
                                break;
                            case 0x6: /* V9 wrfprs */
                                gen_op_xor_T1_T0();
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, fprs));
2450 2451
                                save_state(dc);
                                gen_op_next_insn();
B
bellard 已提交
2452
                                tcg_gen_exit_tb(0);
2453
                                dc->is_br = 1;
B
blueswir1 已提交
2454 2455
                                break;
                            case 0xf: /* V9 sir, nop if user */
B
bellard 已提交
2456
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
2457
                                if (supervisor(dc))
B
blueswir1 已提交
2458
                                    ; // XXX
B
bellard 已提交
2459
#endif
B
blueswir1 已提交
2460 2461
                                break;
                            case 0x13: /* Graphics Status */
B
bellard 已提交
2462 2463
                                if (gen_trap_ifnofpu(dc))
                                    goto jmp_insn;
B
blueswir1 已提交
2464
                                gen_op_xor_T1_T0();
B
blueswir1 已提交
2465 2466 2467
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, gsr));
                                break;
                            case 0x17: /* Tick compare */
B
bellard 已提交
2468
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
2469 2470
                                if (!supervisor(dc))
                                    goto illegal_insn;
B
bellard 已提交
2471
#endif
B
blueswir1 已提交
2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483
                                {
                                    TCGv r_tickptr;

                                    gen_op_xor_T1_T0();
                                    gen_op_movtl_env_T0(offsetof(CPUSPARCState,
                                                                 tick_cmpr));
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, tick));
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
                                                       r_tickptr, cpu_T[0]);
                                }
B
blueswir1 已提交
2484 2485
                                break;
                            case 0x18: /* System tick */
B
bellard 已提交
2486
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
2487 2488
                                if (!supervisor(dc))
                                    goto illegal_insn;
B
bellard 已提交
2489
#endif
B
blueswir1 已提交
2490 2491 2492 2493 2494 2495 2496 2497 2498 2499
                                {
                                    TCGv r_tickptr;

                                    gen_op_xor_T1_T0();
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, stick));
                                    tcg_gen_helper_0_2(helper_tick_set_count,
                                                       r_tickptr, cpu_T[0]);
                                }
B
blueswir1 已提交
2500 2501
                                break;
                            case 0x19: /* System tick compare */
B
bellard 已提交
2502
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
2503 2504
                                if (!supervisor(dc))
                                    goto illegal_insn;
B
bellard 已提交
2505
#endif
B
blueswir1 已提交
2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517
                                {
                                    TCGv r_tickptr;

                                    gen_op_xor_T1_T0();
                                    gen_op_movtl_env_T0(offsetof(CPUSPARCState,
                                                                 stick_cmpr));
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, stick));
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
                                                       r_tickptr, cpu_T[0]);
                                }
B
blueswir1 已提交
2518
                                break;
B
bellard 已提交
2519

B
blueswir1 已提交
2520 2521 2522 2523 2524 2525
                            case 0x10: /* Performance Control */
                            case 0x11: /* Performance Instrumentation Counter */
                            case 0x12: /* Dispatch Control */
                            case 0x14: /* Softint set */
                            case 0x15: /* Softint clear */
                            case 0x16: /* Softint write */
B
bellard 已提交
2526
#endif
B
bellard 已提交
2527
                            default:
2528 2529 2530 2531
                                goto illegal_insn;
                            }
                        }
                        break;
2532
#if !defined(CONFIG_USER_ONLY)
2533
                    case 0x31: /* wrpsr, V9 saved, restored */
2534
                        {
B
blueswir1 已提交
2535 2536
                            if (!supervisor(dc))
                                goto priv_insn;
B
bellard 已提交
2537
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2538 2539 2540 2541 2542 2543 2544
                            switch (rd) {
                            case 0:
                                gen_op_saved();
                                break;
                            case 1:
                                gen_op_restored();
                                break;
B
blueswir1 已提交
2545 2546 2547 2548 2549
                            case 2: /* UA2005 allclean */
                            case 3: /* UA2005 otherw */
                            case 4: /* UA2005 normalw */
                            case 5: /* UA2005 invalw */
                                // XXX
B
blueswir1 已提交
2550
                            default:
B
bellard 已提交
2551 2552 2553
                                goto illegal_insn;
                            }
#else
2554
                            gen_op_xor_T1_T0();
B
blueswir1 已提交
2555
                            tcg_gen_helper_0_1(helper_wrpsr, cpu_T[0]);
B
bellard 已提交
2556 2557
                            save_state(dc);
                            gen_op_next_insn();
B
bellard 已提交
2558
                            tcg_gen_exit_tb(0);
B
blueswir1 已提交
2559
                            dc->is_br = 1;
B
bellard 已提交
2560
#endif
2561 2562
                        }
                        break;
2563
                    case 0x32: /* wrwim, V9 wrpr */
2564
                        {
B
blueswir1 已提交
2565 2566
                            if (!supervisor(dc))
                                goto priv_insn;
2567
                            gen_op_xor_T1_T0();
B
bellard 已提交
2568
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2569 2570
                            switch (rd) {
                            case 0: // tpc
2571 2572 2573 2574 2575 2576 2577 2578 2579
                                {
                                    TCGv r_tsptr;

                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                                   offsetof(CPUState, tsptr));
                                    tcg_gen_st_tl(cpu_T[0], r_tsptr,
                                                  offsetof(trap_state, tpc));
                                }
B
blueswir1 已提交
2580 2581
                                break;
                            case 1: // tnpc
2582 2583 2584 2585 2586 2587 2588 2589 2590
                                {
                                    TCGv r_tsptr;

                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                                   offsetof(CPUState, tsptr));
                                    tcg_gen_st_tl(cpu_T[0], r_tsptr,
                                                  offsetof(trap_state, tnpc));
                                }
B
blueswir1 已提交
2591 2592
                                break;
                            case 2: // tstate
2593 2594 2595 2596 2597 2598 2599 2600 2601
                                {
                                    TCGv r_tsptr;

                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                                   offsetof(CPUState, tsptr));
                                    tcg_gen_st_tl(cpu_T[0], r_tsptr,
                                                  offsetof(trap_state, tstate));
                                }
B
blueswir1 已提交
2602 2603
                                break;
                            case 3: // tt
2604 2605 2606 2607 2608 2609 2610 2611 2612
                                {
                                    TCGv r_tsptr;

                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                                   offsetof(CPUState, tsptr));
                                    tcg_gen_st_i32(cpu_T[0], r_tsptr,
                                                   offsetof(trap_state, tt));
                                }
B
blueswir1 已提交
2613 2614
                                break;
                            case 4: // tick
B
blueswir1 已提交
2615 2616 2617 2618 2619 2620 2621 2622 2623
                                {
                                    TCGv r_tickptr;

                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, tick));
                                    tcg_gen_helper_0_2(helper_tick_set_count,
                                                       r_tickptr, cpu_T[0]);
                                }
B
blueswir1 已提交
2624 2625 2626 2627 2628
                                break;
                            case 5: // tba
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
                                break;
                            case 6: // pstate
P
pbrook 已提交
2629
                                save_state(dc);
B
blueswir1 已提交
2630
                                tcg_gen_helper_0_1(helper_wrpstate, cpu_T[0]);
P
pbrook 已提交
2631
                                gen_op_next_insn();
B
bellard 已提交
2632
                                tcg_gen_exit_tb(0);
P
pbrook 已提交
2633
                                dc->is_br = 1;
B
blueswir1 已提交
2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658
                                break;
                            case 7: // tl
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, tl));
                                break;
                            case 8: // pil
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, psrpil));
                                break;
                            case 9: // cwp
                                gen_op_wrcwp();
                                break;
                            case 10: // cansave
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, cansave));
                                break;
                            case 11: // canrestore
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, canrestore));
                                break;
                            case 12: // cleanwin
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, cleanwin));
                                break;
                            case 13: // otherwin
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, otherwin));
                                break;
                            case 14: // wstate
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, wstate));
                                break;
B
blueswir1 已提交
2659 2660 2661 2662 2663 2664 2665 2666
                            case 16: // UA2005 gl
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, gl));
                                break;
                            case 26: // UA2005 strand status
                                if (!hypervisor(dc))
                                    goto priv_insn;
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, ssr));
                                break;
B
blueswir1 已提交
2667 2668 2669
                            default:
                                goto illegal_insn;
                            }
B
bellard 已提交
2670
#else
B
blueswir1 已提交
2671 2672
                            tcg_gen_andi_i32(cpu_T[0], cpu_T[0], ((1 << NWINDOWS) - 1));
                            gen_op_movl_env_T0(offsetof(CPUSPARCState, wim));
B
bellard 已提交
2673
#endif
2674 2675
                        }
                        break;
B
blueswir1 已提交
2676
                    case 0x33: /* wrtbr, UA2005 wrhpr */
2677
                        {
B
blueswir1 已提交
2678
#ifndef TARGET_SPARC64
B
blueswir1 已提交
2679 2680
                            if (!supervisor(dc))
                                goto priv_insn;
2681
                            gen_op_xor_T1_T0();
B
blueswir1 已提交
2682 2683 2684 2685 2686 2687 2688 2689 2690 2691
                            gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
#else
                            if (!hypervisor(dc))
                                goto priv_insn;
                            gen_op_xor_T1_T0();
                            switch (rd) {
                            case 0: // hpstate
                                // XXX gen_op_wrhpstate();
                                save_state(dc);
                                gen_op_next_insn();
B
bellard 已提交
2692
                                tcg_gen_exit_tb(0);
B
blueswir1 已提交
2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704
                                dc->is_br = 1;
                                break;
                            case 1: // htstate
                                // XXX gen_op_wrhtstate();
                                break;
                            case 3: // hintp
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, hintp));
                                break;
                            case 5: // htba
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, htba));
                                break;
                            case 31: // hstick_cmpr
B
blueswir1 已提交
2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715
                                {
                                    TCGv r_tickptr;

                                    gen_op_movtl_env_T0(offsetof(CPUSPARCState,
                                                                 hstick_cmpr));
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, hstick));
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
                                                       r_tickptr, cpu_T[0]);
                                }
B
blueswir1 已提交
2716 2717 2718 2719 2720 2721
                                break;
                            case 6: // hver readonly
                            default:
                                goto illegal_insn;
                            }
#endif
2722 2723 2724
                        }
                        break;
#endif
B
bellard 已提交
2725
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2726 2727 2728 2729
                    case 0x2c: /* V9 movcc */
                        {
                            int cc = GET_FIELD_SP(insn, 11, 12);
                            int cond = GET_FIELD_SP(insn, 14, 17);
2730 2731 2732
                            TCGv r_zero;
                            int l1;

B
blueswir1 已提交
2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743
                            flush_T2(dc);
                            if (insn & (1 << 18)) {
                                if (cc == 0)
                                    gen_cond[0][cond]();
                                else if (cc == 2)
                                    gen_cond[1][cond]();
                                else
                                    goto illegal_insn;
                            } else {
                                gen_fcond[cc][cond]();
                            }
2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758

                            l1 = gen_new_label();

                            r_zero = tcg_temp_new(TCG_TYPE_TL);
                            tcg_gen_movi_tl(r_zero, 0);
                            tcg_gen_brcond_tl(TCG_COND_EQ, cpu_T[2], r_zero, l1);
                            if (IS_IMM) {       /* immediate */
                                rs2 = GET_FIELD_SPs(insn, 0, 10);
                                gen_movl_simm_T1(rs2);
                            } else {
                                rs2 = GET_FIELD_SP(insn, 0, 4);
                                gen_movl_reg_T1(rs2);
                            }
                            gen_movl_T1_reg(rd);
                            gen_set_label(l1);
B
blueswir1 已提交
2759 2760 2761
                            break;
                        }
                    case 0x2d: /* V9 sdivx */
B
bellard 已提交
2762
                        gen_op_sdivx_T1_T0();
B
blueswir1 已提交
2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775
                        gen_movl_T0_reg(rd);
                        break;
                    case 0x2e: /* V9 popc */
                        {
                            if (IS_IMM) {       /* immediate */
                                rs2 = GET_FIELD_SPs(insn, 0, 12);
                                gen_movl_simm_T1(rs2);
                                // XXX optimize: popc(constant)
                            }
                            else {
                                rs2 = GET_FIELD_SP(insn, 0, 4);
                                gen_movl_reg_T1(rs2);
                            }
B
blueswir1 已提交
2776 2777
                            tcg_gen_helper_1_1(helper_popc, cpu_T[0],
                                               cpu_T[1]);
B
blueswir1 已提交
2778 2779 2780 2781 2782
                            gen_movl_T0_reg(rd);
                        }
                    case 0x2f: /* V9 movr */
                        {
                            int cond = GET_FIELD_SP(insn, 10, 12);
2783 2784 2785
                            TCGv r_zero;
                            int l1;

B
blueswir1 已提交
2786 2787
                            rs1 = GET_FIELD(insn, 13, 17);
                            gen_movl_reg_T0(rs1);
2788 2789 2790 2791 2792 2793

                            l1 = gen_new_label();

                            r_zero = tcg_temp_new(TCG_TYPE_TL);
                            tcg_gen_movi_tl(r_zero, 0);
                            tcg_gen_brcond_tl(gen_tcg_cond_reg[cond], cpu_T[0], r_zero, l1);
B
blueswir1 已提交
2794 2795 2796
                            if (IS_IMM) {       /* immediate */
                                rs2 = GET_FIELD_SPs(insn, 0, 9);
                                gen_movl_simm_T1(rs2);
2797
                            } else {
B
blueswir1 已提交
2798 2799 2800
                                rs2 = GET_FIELD_SP(insn, 0, 4);
                                gen_movl_reg_T1(rs2);
                            }
2801 2802
                            gen_movl_T1_reg(rd);
                            gen_set_label(l1);
B
blueswir1 已提交
2803 2804 2805 2806 2807 2808 2809
                            break;
                        }
#endif
                    default:
                        goto illegal_insn;
                    }
                }
2810 2811 2812 2813 2814
            } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
#ifdef TARGET_SPARC64
                int opf = GET_FIELD_SP(insn, 5, 13);
                rs1 = GET_FIELD(insn, 13, 17);
                rs2 = GET_FIELD(insn, 27, 31);
B
blueswir1 已提交
2815 2816
                if (gen_trap_ifnofpu(dc))
                    goto jmp_insn;
2817 2818

                switch (opf) {
B
blueswir1 已提交
2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850
                case 0x000: /* VIS I edge8cc */
                case 0x001: /* VIS II edge8n */
                case 0x002: /* VIS I edge8lcc */
                case 0x003: /* VIS II edge8ln */
                case 0x004: /* VIS I edge16cc */
                case 0x005: /* VIS II edge16n */
                case 0x006: /* VIS I edge16lcc */
                case 0x007: /* VIS II edge16ln */
                case 0x008: /* VIS I edge32cc */
                case 0x009: /* VIS II edge32n */
                case 0x00a: /* VIS I edge32lcc */
                case 0x00b: /* VIS II edge32ln */
                    // XXX
                    goto illegal_insn;
                case 0x010: /* VIS I array8 */
                    gen_movl_reg_T0(rs1);
                    gen_movl_reg_T1(rs2);
                    gen_op_array8();
                    gen_movl_T0_reg(rd);
                    break;
                case 0x012: /* VIS I array16 */
                    gen_movl_reg_T0(rs1);
                    gen_movl_reg_T1(rs2);
                    gen_op_array16();
                    gen_movl_T0_reg(rd);
                    break;
                case 0x014: /* VIS I array32 */
                    gen_movl_reg_T0(rs1);
                    gen_movl_reg_T1(rs2);
                    gen_op_array32();
                    gen_movl_T0_reg(rd);
                    break;
2851 2852 2853 2854 2855 2856
                case 0x018: /* VIS I alignaddr */
                    gen_movl_reg_T0(rs1);
                    gen_movl_reg_T1(rs2);
                    gen_op_alignaddr();
                    gen_movl_T0_reg(rd);
                    break;
B
blueswir1 已提交
2857
                case 0x019: /* VIS II bmask */
2858 2859
                case 0x01a: /* VIS I alignaddrl */
                    // XXX
B
blueswir1 已提交
2860 2861
                    goto illegal_insn;
                case 0x020: /* VIS I fcmple16 */
2862 2863
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2864
                    gen_op_fcmple16();
2865
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2866 2867
                    break;
                case 0x022: /* VIS I fcmpne16 */
2868 2869
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2870
                    gen_op_fcmpne16();
2871
                    gen_op_store_DT0_fpr(DFPREG(rd));
2872
                    break;
B
blueswir1 已提交
2873
                case 0x024: /* VIS I fcmple32 */
2874 2875
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2876
                    gen_op_fcmple32();
2877
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2878 2879
                    break;
                case 0x026: /* VIS I fcmpne32 */
2880 2881
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2882
                    gen_op_fcmpne32();
2883
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2884 2885
                    break;
                case 0x028: /* VIS I fcmpgt16 */
2886 2887
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2888
                    gen_op_fcmpgt16();
2889
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2890 2891
                    break;
                case 0x02a: /* VIS I fcmpeq16 */
2892 2893
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2894
                    gen_op_fcmpeq16();
2895
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2896 2897
                    break;
                case 0x02c: /* VIS I fcmpgt32 */
2898 2899
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2900
                    gen_op_fcmpgt32();
2901
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2902 2903
                    break;
                case 0x02e: /* VIS I fcmpeq32 */
2904 2905
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2906
                    gen_op_fcmpeq32();
2907
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2908 2909
                    break;
                case 0x031: /* VIS I fmul8x16 */
2910 2911
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2912
                    gen_op_fmul8x16();
2913
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2914 2915
                    break;
                case 0x033: /* VIS I fmul8x16au */
2916 2917
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2918
                    gen_op_fmul8x16au();
2919
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2920 2921
                    break;
                case 0x035: /* VIS I fmul8x16al */
2922 2923
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2924
                    gen_op_fmul8x16al();
2925
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2926 2927
                    break;
                case 0x036: /* VIS I fmul8sux16 */
2928 2929
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2930
                    gen_op_fmul8sux16();
2931
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2932 2933
                    break;
                case 0x037: /* VIS I fmul8ulx16 */
2934 2935
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2936
                    gen_op_fmul8ulx16();
2937
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2938 2939
                    break;
                case 0x038: /* VIS I fmuld8sux16 */
2940 2941
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2942
                    gen_op_fmuld8sux16();
2943
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2944 2945
                    break;
                case 0x039: /* VIS I fmuld8ulx16 */
2946 2947
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2948
                    gen_op_fmuld8ulx16();
2949
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2950 2951 2952 2953 2954 2955 2956
                    break;
                case 0x03a: /* VIS I fpack32 */
                case 0x03b: /* VIS I fpack16 */
                case 0x03d: /* VIS I fpackfix */
                case 0x03e: /* VIS I pdist */
                    // XXX
                    goto illegal_insn;
2957
                case 0x048: /* VIS I faligndata */
2958 2959
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2960
                    gen_op_faligndata();
2961
                    gen_op_store_DT0_fpr(DFPREG(rd));
2962
                    break;
B
blueswir1 已提交
2963
                case 0x04b: /* VIS I fpmerge */
2964 2965
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2966
                    gen_op_fpmerge();
2967
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2968 2969 2970 2971 2972
                    break;
                case 0x04c: /* VIS II bshuffle */
                    // XXX
                    goto illegal_insn;
                case 0x04d: /* VIS I fexpand */
2973 2974
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2975
                    gen_op_fexpand();
2976
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2977 2978
                    break;
                case 0x050: /* VIS I fpadd16 */
2979 2980
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2981
                    gen_op_fpadd16();
2982
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2983 2984 2985 2986 2987 2988 2989 2990
                    break;
                case 0x051: /* VIS I fpadd16s */
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
                    gen_op_fpadd16s();
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x052: /* VIS I fpadd32 */
2991 2992
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2993
                    gen_op_fpadd32();
2994
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2995 2996 2997 2998 2999 3000 3001 3002
                    break;
                case 0x053: /* VIS I fpadd32s */
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
                    gen_op_fpadd32s();
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x054: /* VIS I fpsub16 */
3003 3004
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
3005
                    gen_op_fpsub16();
3006
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3007 3008 3009 3010 3011 3012 3013 3014
                    break;
                case 0x055: /* VIS I fpsub16s */
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
                    gen_op_fpsub16s();
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x056: /* VIS I fpsub32 */
3015 3016
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
3017
                    gen_op_fpadd32();
3018
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3019 3020 3021 3022 3023 3024 3025
                    break;
                case 0x057: /* VIS I fpsub32s */
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
                    gen_op_fpsub32s();
                    gen_op_store_FT0_fpr(rd);
                    break;
3026 3027
                case 0x060: /* VIS I fzero */
                    gen_op_movl_DT0_0();
3028
                    gen_op_store_DT0_fpr(DFPREG(rd));
3029 3030 3031 3032 3033
                    break;
                case 0x061: /* VIS I fzeros */
                    gen_op_movl_FT0_0();
                    gen_op_store_FT0_fpr(rd);
                    break;
B
blueswir1 已提交
3034
                case 0x062: /* VIS I fnor */
3035 3036
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
3037
                    gen_op_fnor();
3038
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3039 3040 3041 3042 3043 3044 3045 3046
                    break;
                case 0x063: /* VIS I fnors */
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
                    gen_op_fnors();
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x064: /* VIS I fandnot2 */
3047 3048
                    gen_op_load_fpr_DT1(DFPREG(rs1));
                    gen_op_load_fpr_DT0(DFPREG(rs2));
B
blueswir1 已提交
3049
                    gen_op_fandnot();
3050
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3051 3052 3053 3054 3055 3056 3057 3058
                    break;
                case 0x065: /* VIS I fandnot2s */
                    gen_op_load_fpr_FT1(rs1);
                    gen_op_load_fpr_FT0(rs2);
                    gen_op_fandnots();
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x066: /* VIS I fnot2 */
3059
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
3060
                    gen_op_fnot();
3061
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3062 3063 3064 3065 3066 3067 3068
                    break;
                case 0x067: /* VIS I fnot2s */
                    gen_op_load_fpr_FT1(rs2);
                    gen_op_fnot();
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x068: /* VIS I fandnot1 */
3069 3070
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
3071
                    gen_op_fandnot();
3072
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3073 3074 3075 3076 3077 3078 3079 3080
                    break;
                case 0x069: /* VIS I fandnot1s */
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
                    gen_op_fandnots();
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x06a: /* VIS I fnot1 */
3081
                    gen_op_load_fpr_DT1(DFPREG(rs1));
B
blueswir1 已提交
3082
                    gen_op_fnot();
3083
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3084 3085 3086 3087 3088 3089 3090
                    break;
                case 0x06b: /* VIS I fnot1s */
                    gen_op_load_fpr_FT1(rs1);
                    gen_op_fnot();
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x06c: /* VIS I fxor */
3091 3092
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
3093
                    gen_op_fxor();
3094
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3095 3096 3097 3098 3099 3100 3101 3102
                    break;
                case 0x06d: /* VIS I fxors */
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
                    gen_op_fxors();
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x06e: /* VIS I fnand */
3103 3104
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
3105
                    gen_op_fnand();
3106
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3107 3108 3109 3110 3111 3112 3113 3114
                    break;
                case 0x06f: /* VIS I fnands */
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
                    gen_op_fnands();
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x070: /* VIS I fand */
3115 3116
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
3117
                    gen_op_fand();
3118
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3119 3120 3121 3122 3123 3124 3125 3126
                    break;
                case 0x071: /* VIS I fands */
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
                    gen_op_fands();
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x072: /* VIS I fxnor */
3127 3128
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
3129
                    gen_op_fxnor();
3130
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3131 3132 3133 3134 3135 3136 3137
                    break;
                case 0x073: /* VIS I fxnors */
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
                    gen_op_fxnors();
                    gen_op_store_FT0_fpr(rd);
                    break;
3138
                case 0x074: /* VIS I fsrc1 */
3139 3140
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_store_DT0_fpr(DFPREG(rd));
3141 3142 3143 3144 3145
                    break;
                case 0x075: /* VIS I fsrc1s */
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_store_FT0_fpr(rd);
                    break;
B
blueswir1 已提交
3146
                case 0x076: /* VIS I fornot2 */
3147 3148
                    gen_op_load_fpr_DT1(DFPREG(rs1));
                    gen_op_load_fpr_DT0(DFPREG(rs2));
B
blueswir1 已提交
3149
                    gen_op_fornot();
3150
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3151 3152 3153 3154 3155 3156 3157
                    break;
                case 0x077: /* VIS I fornot2s */
                    gen_op_load_fpr_FT1(rs1);
                    gen_op_load_fpr_FT0(rs2);
                    gen_op_fornots();
                    gen_op_store_FT0_fpr(rd);
                    break;
3158
                case 0x078: /* VIS I fsrc2 */
3159 3160
                    gen_op_load_fpr_DT0(DFPREG(rs2));
                    gen_op_store_DT0_fpr(DFPREG(rd));
3161 3162 3163 3164 3165
                    break;
                case 0x079: /* VIS I fsrc2s */
                    gen_op_load_fpr_FT0(rs2);
                    gen_op_store_FT0_fpr(rd);
                    break;
B
blueswir1 已提交
3166
                case 0x07a: /* VIS I fornot1 */
3167 3168
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
3169
                    gen_op_fornot();
3170
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3171 3172 3173 3174 3175 3176 3177 3178
                    break;
                case 0x07b: /* VIS I fornot1s */
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
                    gen_op_fornots();
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x07c: /* VIS I for */
3179 3180
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
3181
                    gen_op_for();
3182
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3183 3184 3185 3186 3187 3188 3189
                    break;
                case 0x07d: /* VIS I fors */
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
                    gen_op_fors();
                    gen_op_store_FT0_fpr(rd);
                    break;
3190 3191
                case 0x07e: /* VIS I fone */
                    gen_op_movl_DT0_1();
3192
                    gen_op_store_DT0_fpr(DFPREG(rd));
3193 3194 3195 3196 3197
                    break;
                case 0x07f: /* VIS I fones */
                    gen_op_movl_FT0_1();
                    gen_op_store_FT0_fpr(rd);
                    break;
B
blueswir1 已提交
3198 3199 3200 3201
                case 0x080: /* VIS I shutdown */
                case 0x081: /* VIS II siam */
                    // XXX
                    goto illegal_insn;
3202 3203 3204 3205
                default:
                    goto illegal_insn;
                }
#else
B
blueswir1 已提交
3206
                goto ncp_insn;
3207 3208
#endif
            } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
3209
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3210
                goto illegal_insn;
3211
#else
B
blueswir1 已提交
3212
                goto ncp_insn;
3213
#endif
B
bellard 已提交
3214
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3215
            } else if (xop == 0x39) { /* V9 return */
B
bellard 已提交
3216
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
3217
                save_state(dc);
B
blueswir1 已提交
3218 3219 3220
                gen_movl_reg_T0(rs1);
                if (IS_IMM) {   /* immediate */
                    rs2 = GET_FIELDs(insn, 19, 31);
B
blueswir1 已提交
3221
                    tcg_gen_addi_tl(cpu_T[0], cpu_T[0], (int)rs2);
B
blueswir1 已提交
3222
                } else {                /* register */
B
bellard 已提交
3223 3224
                    rs2 = GET_FIELD(insn, 27, 31);
#if defined(OPTIM)
B
blueswir1 已提交
3225
                    if (rs2) {
B
bellard 已提交
3226
#endif
B
blueswir1 已提交
3227 3228
                        gen_movl_reg_T1(rs2);
                        gen_op_add_T1_T0();
B
bellard 已提交
3229
#if defined(OPTIM)
B
blueswir1 已提交
3230
                    }
B
bellard 已提交
3231 3232
#endif
                }
B
blueswir1 已提交
3233 3234
                gen_op_restore();
                gen_mov_pc_npc(dc);
B
blueswir1 已提交
3235
                gen_op_check_align_T0_3();
B
blueswir1 已提交
3236
                tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, npc));
B
blueswir1 已提交
3237 3238
                dc->npc = DYNAMIC_PC;
                goto jmp_insn;
B
bellard 已提交
3239
#endif
B
blueswir1 已提交
3240
            } else {
B
bellard 已提交
3241
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
3242 3243 3244
                gen_movl_reg_T0(rs1);
                if (IS_IMM) {   /* immediate */
                    rs2 = GET_FIELDs(insn, 19, 31);
B
blueswir1 已提交
3245
                    tcg_gen_addi_tl(cpu_T[0], cpu_T[0], (int)rs2);
B
blueswir1 已提交
3246
                } else {                /* register */
B
bellard 已提交
3247 3248
                    rs2 = GET_FIELD(insn, 27, 31);
#if defined(OPTIM)
B
blueswir1 已提交
3249
                    if (rs2) {
B
bellard 已提交
3250
#endif
B
blueswir1 已提交
3251 3252
                        gen_movl_reg_T1(rs2);
                        gen_op_add_T1_T0();
B
bellard 已提交
3253
#if defined(OPTIM)
B
blueswir1 已提交
3254
                    }
3255
#endif
3256
                }
B
blueswir1 已提交
3257 3258 3259 3260
                switch (xop) {
                case 0x38:      /* jmpl */
                    {
                        if (rd != 0) {
B
blueswir1 已提交
3261
                            tcg_gen_movi_tl(cpu_T[1], dc->pc);
B
blueswir1 已提交
3262 3263
                            gen_movl_T1_reg(rd);
                        }
B
bellard 已提交
3264
                        gen_mov_pc_npc(dc);
B
blueswir1 已提交
3265
                        gen_op_check_align_T0_3();
B
blueswir1 已提交
3266
                        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, npc));
B
blueswir1 已提交
3267 3268 3269
                        dc->npc = DYNAMIC_PC;
                    }
                    goto jmp_insn;
B
bellard 已提交
3270
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
B
blueswir1 已提交
3271 3272 3273 3274
                case 0x39:      /* rett, V9 return */
                    {
                        if (!supervisor(dc))
                            goto priv_insn;
B
bellard 已提交
3275
                        gen_mov_pc_npc(dc);
B
blueswir1 已提交
3276
                        gen_op_check_align_T0_3();
B
blueswir1 已提交
3277
                        tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUSPARCState, npc));
B
blueswir1 已提交
3278
                        dc->npc = DYNAMIC_PC;
B
blueswir1 已提交
3279
                        tcg_gen_helper_0_0(helper_rett);
B
blueswir1 已提交
3280 3281 3282 3283
                    }
                    goto jmp_insn;
#endif
                case 0x3b: /* flush */
B
blueswir1 已提交
3284
                    tcg_gen_helper_0_1(helper_flush, cpu_T[0]);
B
blueswir1 已提交
3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295
                    break;
                case 0x3c:      /* save */
                    save_state(dc);
                    gen_op_save();
                    gen_movl_T0_reg(rd);
                    break;
                case 0x3d:      /* restore */
                    save_state(dc);
                    gen_op_restore();
                    gen_movl_T0_reg(rd);
                    break;
B
bellard 已提交
3296
#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
B
blueswir1 已提交
3297 3298 3299 3300 3301 3302 3303 3304
                case 0x3e:      /* V9 done/retry */
                    {
                        switch (rd) {
                        case 0:
                            if (!supervisor(dc))
                                goto priv_insn;
                            dc->npc = DYNAMIC_PC;
                            dc->pc = DYNAMIC_PC;
B
blueswir1 已提交
3305
                            tcg_gen_helper_0_0(helper_done);
B
blueswir1 已提交
3306 3307 3308 3309 3310 3311
                            goto jmp_insn;
                        case 1:
                            if (!supervisor(dc))
                                goto priv_insn;
                            dc->npc = DYNAMIC_PC;
                            dc->pc = DYNAMIC_PC;
B
blueswir1 已提交
3312
                            tcg_gen_helper_0_0(helper_retry);
B
blueswir1 已提交
3313 3314 3315 3316 3317 3318 3319 3320 3321 3322
                            goto jmp_insn;
                        default:
                            goto illegal_insn;
                        }
                    }
                    break;
#endif
                default:
                    goto illegal_insn;
                }
3323
            }
B
blueswir1 已提交
3324 3325 3326 3327 3328 3329 3330
            break;
        }
        break;
    case 3:                     /* load/store instructions */
        {
            unsigned int xop = GET_FIELD(insn, 7, 12);
            rs1 = GET_FIELD(insn, 13, 17);
3331
            save_state(dc);
B
blueswir1 已提交
3332
            gen_movl_reg_T0(rs1);
3333 3334 3335 3336 3337 3338
            if (xop == 0x3c || xop == 0x3e)
            {
                rs2 = GET_FIELD(insn, 27, 31);
                gen_movl_reg_T1(rs2);
            }
            else if (IS_IMM) {       /* immediate */
B
blueswir1 已提交
3339
                rs2 = GET_FIELDs(insn, 19, 31);
B
blueswir1 已提交
3340
                tcg_gen_addi_tl(cpu_T[0], cpu_T[0], (int)rs2);
B
blueswir1 已提交
3341 3342
            } else {            /* register */
                rs2 = GET_FIELD(insn, 27, 31);
B
bellard 已提交
3343
#if defined(OPTIM)
B
blueswir1 已提交
3344
                if (rs2 != 0) {
B
bellard 已提交
3345
#endif
B
blueswir1 已提交
3346 3347
                    gen_movl_reg_T1(rs2);
                    gen_op_add_T1_T0();
B
bellard 已提交
3348
#if defined(OPTIM)
B
blueswir1 已提交
3349
                }
B
bellard 已提交
3350
#endif
B
blueswir1 已提交
3351
            }
B
blueswir1 已提交
3352 3353 3354
            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
                (xop > 0x17 && xop <= 0x1d ) ||
                (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
B
blueswir1 已提交
3355
                switch (xop) {
B
blueswir1 已提交
3356
                case 0x0:       /* load unsigned word */
B
blueswir1 已提交
3357
                    gen_op_check_align_T0_3();
B
blueswir1 已提交
3358 3359
                    ABI32_MASK(cpu_T[0]);
                    tcg_gen_qemu_ld32u(cpu_T[1], cpu_T[0], dc->mem_idx);
B
blueswir1 已提交
3360 3361
                    break;
                case 0x1:       /* load unsigned byte */
B
blueswir1 已提交
3362 3363
                    ABI32_MASK(cpu_T[0]);
                    tcg_gen_qemu_ld8u(cpu_T[1], cpu_T[0], dc->mem_idx);
B
blueswir1 已提交
3364 3365
                    break;
                case 0x2:       /* load unsigned halfword */
B
blueswir1 已提交
3366
                    gen_op_check_align_T0_1();
B
blueswir1 已提交
3367 3368
                    ABI32_MASK(cpu_T[0]);
                    tcg_gen_qemu_ld16u(cpu_T[1], cpu_T[0], dc->mem_idx);
B
blueswir1 已提交
3369 3370 3371
                    break;
                case 0x3:       /* load double word */
                    if (rd & 1)
3372
                        goto illegal_insn;
B
blueswir1 已提交
3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384
                    else {
                        TCGv r_dword;

                        r_dword = tcg_temp_new(TCG_TYPE_I64);
                        gen_op_check_align_T0_7();
                        ABI32_MASK(cpu_T[0]);
                        tcg_gen_qemu_ld64(r_dword, cpu_T[0], dc->mem_idx);
                        tcg_gen_trunc_i64_i32(cpu_T[0], r_dword);
                        gen_movl_T0_reg(rd + 1);
                        tcg_gen_shri_i64(r_dword, r_dword, 32);
                        tcg_gen_trunc_i64_i32(cpu_T[1], r_dword);
                    }
B
blueswir1 已提交
3385 3386
                    break;
                case 0x9:       /* load signed byte */
B
blueswir1 已提交
3387 3388
                    ABI32_MASK(cpu_T[0]);
                    tcg_gen_qemu_ld8s(cpu_T[1], cpu_T[0], dc->mem_idx);
B
blueswir1 已提交
3389 3390
                    break;
                case 0xa:       /* load signed halfword */
B
blueswir1 已提交
3391
                    gen_op_check_align_T0_1();
B
blueswir1 已提交
3392 3393
                    ABI32_MASK(cpu_T[0]);
                    tcg_gen_qemu_ld16s(cpu_T[1], cpu_T[0], dc->mem_idx);
B
blueswir1 已提交
3394 3395
                    break;
                case 0xd:       /* ldstub -- XXX: should be atomically */
B
blueswir1 已提交
3396 3397 3398 3399
                    tcg_gen_movi_i32(cpu_tmp0, 0xff);
                    ABI32_MASK(cpu_T[0]);
                    tcg_gen_qemu_ld8s(cpu_T[1], cpu_T[0], dc->mem_idx);
                    tcg_gen_qemu_st8(cpu_tmp0, cpu_T[0], dc->mem_idx);
B
blueswir1 已提交
3400 3401
                    break;
                case 0x0f:      /* swap register with memory. Also atomically */
B
blueswir1 已提交
3402
                    gen_op_check_align_T0_3();
B
blueswir1 已提交
3403
                    gen_movl_reg_T1(rd);
B
blueswir1 已提交
3404 3405 3406 3407
                    ABI32_MASK(cpu_T[0]);
                    tcg_gen_qemu_ld32u(cpu_tmp0, cpu_T[0], dc->mem_idx);
                    tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], dc->mem_idx);
                    tcg_gen_mov_i32(cpu_T[1], cpu_tmp0);
B
blueswir1 已提交
3408
                    break;
B
bellard 已提交
3409
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
B
blueswir1 已提交
3410
                case 0x10:      /* load word alternate */
B
bellard 已提交
3411
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3412 3413 3414 3415
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
blueswir1 已提交
3416
#endif
B
blueswir1 已提交
3417
                    gen_op_check_align_T0_3();
3418
                    gen_ld_asi(insn, 4, 0);
B
blueswir1 已提交
3419 3420
                    break;
                case 0x11:      /* load unsigned byte alternate */
B
bellard 已提交
3421
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3422 3423 3424 3425 3426
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
#endif
3427
                    gen_ld_asi(insn, 1, 0);
B
blueswir1 已提交
3428 3429
                    break;
                case 0x12:      /* load unsigned halfword alternate */
B
bellard 已提交
3430
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3431 3432 3433 3434
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
bellard 已提交
3435
#endif
B
blueswir1 已提交
3436
                    gen_op_check_align_T0_1();
3437
                    gen_ld_asi(insn, 2, 0);
B
blueswir1 已提交
3438 3439
                    break;
                case 0x13:      /* load double word alternate */
B
bellard 已提交
3440
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3441 3442 3443 3444
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
bellard 已提交
3445
#endif
B
blueswir1 已提交
3446
                    if (rd & 1)
3447
                        goto illegal_insn;
B
blueswir1 已提交
3448
                    gen_op_check_align_T0_7();
3449
                    gen_ldda_asi(insn);
B
blueswir1 已提交
3450 3451 3452
                    gen_movl_T0_reg(rd + 1);
                    break;
                case 0x19:      /* load signed byte alternate */
B
bellard 已提交
3453
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3454 3455 3456 3457 3458
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
#endif
3459
                    gen_ld_asi(insn, 1, 1);
B
blueswir1 已提交
3460 3461
                    break;
                case 0x1a:      /* load signed halfword alternate */
B
bellard 已提交
3462
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3463 3464 3465 3466
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
bellard 已提交
3467
#endif
B
blueswir1 已提交
3468
                    gen_op_check_align_T0_1();
3469
                    gen_ld_asi(insn, 2, 1);
B
blueswir1 已提交
3470 3471
                    break;
                case 0x1d:      /* ldstuba -- XXX: should be atomically */
B
bellard 已提交
3472
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3473 3474 3475 3476 3477
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
#endif
3478
                    gen_ldstub_asi(insn);
B
blueswir1 已提交
3479 3480
                    break;
                case 0x1f:      /* swap reg with alt. memory. Also atomically */
B
bellard 已提交
3481
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3482 3483 3484 3485
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
blueswir1 已提交
3486
#endif
B
blueswir1 已提交
3487
                    gen_op_check_align_T0_3();
3488 3489
                    gen_movl_reg_T1(rd);
                    gen_swap_asi(insn);
B
blueswir1 已提交
3490
                    break;
B
bellard 已提交
3491 3492

#ifndef TARGET_SPARC64
B
blueswir1 已提交
3493 3494 3495 3496
                case 0x30: /* ldc */
                case 0x31: /* ldcsr */
                case 0x33: /* lddc */
                    goto ncp_insn;
B
bellard 已提交
3497 3498 3499
#endif
#endif
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3500
                case 0x08: /* V9 ldsw */
B
blueswir1 已提交
3501
                    gen_op_check_align_T0_3();
B
blueswir1 已提交
3502 3503
                    ABI32_MASK(cpu_T[0]);
                    tcg_gen_qemu_ld32s(cpu_T[1], cpu_T[0], dc->mem_idx);
B
blueswir1 已提交
3504 3505
                    break;
                case 0x0b: /* V9 ldx */
B
blueswir1 已提交
3506
                    gen_op_check_align_T0_7();
B
blueswir1 已提交
3507 3508
                    ABI32_MASK(cpu_T[0]);
                    tcg_gen_qemu_ld64(cpu_T[1], cpu_T[0], dc->mem_idx);
B
blueswir1 已提交
3509 3510
                    break;
                case 0x18: /* V9 ldswa */
B
blueswir1 已提交
3511
                    gen_op_check_align_T0_3();
3512
                    gen_ld_asi(insn, 4, 1);
B
blueswir1 已提交
3513 3514
                    break;
                case 0x1b: /* V9 ldxa */
B
blueswir1 已提交
3515
                    gen_op_check_align_T0_7();
3516
                    gen_ld_asi(insn, 8, 0);
B
blueswir1 已提交
3517 3518 3519 3520
                    break;
                case 0x2d: /* V9 prefetch, no effect */
                    goto skip_move;
                case 0x30: /* V9 ldfa */
B
blueswir1 已提交
3521
                    gen_op_check_align_T0_3();
3522
                    gen_ldf_asi(insn, 4, rd);
3523
                    goto skip_move;
B
blueswir1 已提交
3524
                case 0x33: /* V9 lddfa */
3525
                    gen_op_check_align_T0_3();
3526
                    gen_ldf_asi(insn, 8, DFPREG(rd));
3527
                    goto skip_move;
B
blueswir1 已提交
3528 3529 3530
                case 0x3d: /* V9 prefetcha, no effect */
                    goto skip_move;
                case 0x32: /* V9 ldqfa */
B
blueswir1 已提交
3531 3532
#if defined(CONFIG_USER_ONLY)
                    gen_op_check_align_T0_3();
3533
                    gen_ldf_asi(insn, 16, QFPREG(rd));
B
blueswir1 已提交
3534 3535
                    goto skip_move;
#else
B
blueswir1 已提交
3536
                    goto nfpu_insn;
B
blueswir1 已提交
3537
#endif
B
blueswir1 已提交
3538 3539 3540 3541 3542
#endif
                default:
                    goto illegal_insn;
                }
                gen_movl_T1_reg(rd);
B
bellard 已提交
3543
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3544
            skip_move: ;
B
bellard 已提交
3545
#endif
B
blueswir1 已提交
3546
            } else if (xop >= 0x20 && xop < 0x24) {
B
bellard 已提交
3547 3548
                if (gen_trap_ifnofpu(dc))
                    goto jmp_insn;
B
blueswir1 已提交
3549 3550
                switch (xop) {
                case 0x20:      /* load fpreg */
B
blueswir1 已提交
3551
                    gen_op_check_align_T0_3();
B
blueswir1 已提交
3552 3553 3554 3555
                    gen_op_ldst(ldf);
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x21:      /* load fsr */
B
blueswir1 已提交
3556
                    gen_op_check_align_T0_3();
B
blueswir1 已提交
3557 3558
                    gen_op_ldst(ldf);
                    gen_op_ldfsr();
3559
                    tcg_gen_helper_0_0(helper_ldfsr);
B
blueswir1 已提交
3560 3561
                    break;
                case 0x22:      /* load quad fpreg */
B
blueswir1 已提交
3562 3563 3564 3565 3566 3567
#if defined(CONFIG_USER_ONLY)
                    gen_op_check_align_T0_7();
                    gen_op_ldst(ldqf);
                    gen_op_store_QT0_fpr(QFPREG(rd));
                    break;
#else
B
blueswir1 已提交
3568
                    goto nfpu_insn;
B
blueswir1 已提交
3569
#endif
B
blueswir1 已提交
3570
                case 0x23:      /* load double fpreg */
B
blueswir1 已提交
3571
                    gen_op_check_align_T0_7();
B
blueswir1 已提交
3572 3573 3574 3575 3576 3577 3578 3579 3580 3581
                    gen_op_ldst(lddf);
                    gen_op_store_DT0_fpr(DFPREG(rd));
                    break;
                default:
                    goto illegal_insn;
                }
            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) || \
                       xop == 0xe || xop == 0x1e) {
                gen_movl_reg_T1(rd);
                switch (xop) {
B
blueswir1 已提交
3582
                case 0x4: /* store word */
B
blueswir1 已提交
3583
                    gen_op_check_align_T0_3();
B
blueswir1 已提交
3584 3585
                    ABI32_MASK(cpu_T[0]);
                    tcg_gen_qemu_st32(cpu_T[1], cpu_T[0], dc->mem_idx);
B
blueswir1 已提交
3586
                    break;
B
blueswir1 已提交
3587 3588 3589
                case 0x5: /* store byte */
                    ABI32_MASK(cpu_T[0]);
                    tcg_gen_qemu_st8(cpu_T[1], cpu_T[0], dc->mem_idx);
B
blueswir1 已提交
3590
                    break;
B
blueswir1 已提交
3591
                case 0x6: /* store halfword */
B
blueswir1 已提交
3592
                    gen_op_check_align_T0_1();
B
blueswir1 已提交
3593 3594
                    ABI32_MASK(cpu_T[0]);
                    tcg_gen_qemu_st16(cpu_T[1], cpu_T[0], dc->mem_idx);
B
blueswir1 已提交
3595
                    break;
B
blueswir1 已提交
3596
                case 0x7: /* store double word */
B
blueswir1 已提交
3597
                    if (rd & 1)
3598
                        goto illegal_insn;
B
blueswir1 已提交
3599
#ifndef __i386__
B
blueswir1 已提交
3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610
                    else {
                        TCGv r_dword, r_low;

                        gen_op_check_align_T0_7();
                        r_dword = tcg_temp_new(TCG_TYPE_I64);
                        r_low = tcg_temp_new(TCG_TYPE_I32);
                        gen_movl_reg_TN(rd + 1, r_low);
                        tcg_gen_helper_1_2(helper_pack64, r_dword, cpu_T[1],
                                           r_low);
                        tcg_gen_qemu_st64(r_dword, cpu_T[0], dc->mem_idx);
                    }
B
blueswir1 已提交
3611 3612 3613 3614 3615 3616
#else /* __i386__ */
                    gen_op_check_align_T0_7();
                    flush_T2(dc);
                    gen_movl_reg_T2(rd + 1);
                    gen_op_ldst(std);
#endif /* __i386__ */
B
blueswir1 已提交
3617
                    break;
B
bellard 已提交
3618
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
B
blueswir1 已提交
3619
                case 0x14: /* store word alternate */
B
bellard 已提交
3620
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3621 3622 3623 3624
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
blueswir1 已提交
3625 3626
#endif
                    gen_op_check_align_T0_3();
3627
                    gen_st_asi(insn, 4);
B
bellard 已提交
3628
                    break;
B
blueswir1 已提交
3629
                case 0x15: /* store byte alternate */
B
bellard 已提交
3630
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3631 3632 3633 3634
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
bellard 已提交
3635
#endif
3636
                    gen_st_asi(insn, 1);
B
bellard 已提交
3637
                    break;
B
blueswir1 已提交
3638
                case 0x16: /* store halfword alternate */
B
bellard 已提交
3639
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3640 3641 3642 3643
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
blueswir1 已提交
3644 3645
#endif
                    gen_op_check_align_T0_1();
3646
                    gen_st_asi(insn, 2);
B
bellard 已提交
3647
                    break;
B
blueswir1 已提交
3648
                case 0x17: /* store double word alternate */
B
bellard 已提交
3649
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3650 3651 3652 3653
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
bellard 已提交
3654
#endif
B
blueswir1 已提交
3655
                    if (rd & 1)
3656
                        goto illegal_insn;
B
blueswir1 已提交
3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684
                    else {
                        int asi;
                        TCGv r_dword, r_temp, r_size;

                        gen_op_check_align_T0_7();
                        r_dword = tcg_temp_new(TCG_TYPE_I64);
                        r_temp = tcg_temp_new(TCG_TYPE_I32);
                        r_size = tcg_temp_new(TCG_TYPE_I32);
                        gen_movl_reg_TN(rd + 1, r_temp);
                        tcg_gen_helper_1_2(helper_pack64, r_dword, cpu_T[1],
                                           r_temp);
#ifdef TARGET_SPARC64
                        if (IS_IMM) {
                            int offset;

                            offset = GET_FIELD(insn, 25, 31);
                            tcg_gen_addi_tl(cpu_T[0], cpu_T[0], offset);
                            tcg_gen_ld_i32(r_dword, cpu_env, offsetof(CPUSPARCState, asi));
                        } else {
#endif
                            asi = GET_FIELD(insn, 19, 26);
                            tcg_gen_movi_i32(r_temp, asi);
#ifdef TARGET_SPARC64
                        }
#endif
                        tcg_gen_movi_i32(r_size, 8);
                        tcg_gen_helper_0_4(helper_st_asi, cpu_T[0], r_dword, r_temp, r_size);
                    }
B
bellard 已提交
3685
                    break;
B
bellard 已提交
3686
#endif
B
bellard 已提交
3687
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3688
                case 0x0e: /* V9 stx */
B
blueswir1 已提交
3689
                    gen_op_check_align_T0_7();
B
blueswir1 已提交
3690 3691
                    ABI32_MASK(cpu_T[0]);
                    tcg_gen_qemu_st64(cpu_T[1], cpu_T[0], dc->mem_idx);
B
blueswir1 已提交
3692 3693
                    break;
                case 0x1e: /* V9 stxa */
B
blueswir1 已提交
3694
                    gen_op_check_align_T0_7();
3695
                    gen_st_asi(insn, 8);
B
blueswir1 已提交
3696
                    break;
B
bellard 已提交
3697
#endif
B
blueswir1 已提交
3698 3699 3700 3701
                default:
                    goto illegal_insn;
                }
            } else if (xop > 0x23 && xop < 0x28) {
B
bellard 已提交
3702 3703
                if (gen_trap_ifnofpu(dc))
                    goto jmp_insn;
B
blueswir1 已提交
3704 3705
                switch (xop) {
                case 0x24:
B
blueswir1 已提交
3706
                    gen_op_check_align_T0_3();
3707
                    gen_op_load_fpr_FT0(rd);
B
blueswir1 已提交
3708 3709 3710
                    gen_op_ldst(stf);
                    break;
                case 0x25: /* stfsr, V9 stxfsr */
B
blueswir1 已提交
3711 3712 3713
#ifdef CONFIG_USER_ONLY
                    gen_op_check_align_T0_3();
#endif
B
blueswir1 已提交
3714 3715 3716
                    gen_op_stfsr();
                    gen_op_ldst(stf);
                    break;
B
blueswir1 已提交
3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732
                case 0x26:
#ifdef TARGET_SPARC64
#if defined(CONFIG_USER_ONLY)
                    /* V9 stqf, store quad fpreg */
                    gen_op_check_align_T0_7();
                    gen_op_load_fpr_QT0(QFPREG(rd));
                    gen_op_ldst(stqf);
                    break;
#else
                    goto nfpu_insn;
#endif
#else /* !TARGET_SPARC64 */
                    /* stdfq, store floating point queue */
#if defined(CONFIG_USER_ONLY)
                    goto illegal_insn;
#else
B
blueswir1 已提交
3733 3734 3735 3736 3737
                    if (!supervisor(dc))
                        goto priv_insn;
                    if (gen_trap_ifnofpu(dc))
                        goto jmp_insn;
                    goto nfq_insn;
B
blueswir1 已提交
3738
#endif
B
blueswir1 已提交
3739 3740
#endif
                case 0x27:
B
blueswir1 已提交
3741
                    gen_op_check_align_T0_7();
B
bellard 已提交
3742
                    gen_op_load_fpr_DT0(DFPREG(rd));
B
blueswir1 已提交
3743 3744 3745 3746 3747 3748 3749
                    gen_op_ldst(stdf);
                    break;
                default:
                    goto illegal_insn;
                }
            } else if (xop > 0x33 && xop < 0x3f) {
                switch (xop) {
3750
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3751
                case 0x34: /* V9 stfa */
B
blueswir1 已提交
3752
                    gen_op_check_align_T0_3();
3753
                    gen_op_load_fpr_FT0(rd);
3754
                    gen_stf_asi(insn, 4, rd);
B
blueswir1 已提交
3755
                    break;
B
blueswir1 已提交
3756 3757 3758 3759
                case 0x36: /* V9 stqfa */
#if defined(CONFIG_USER_ONLY)
                    gen_op_check_align_T0_7();
                    gen_op_load_fpr_QT0(QFPREG(rd));
3760
                    gen_stf_asi(insn, 16, QFPREG(rd));
B
blueswir1 已提交
3761 3762 3763 3764
                    break;
#else
                    goto nfpu_insn;
#endif
B
blueswir1 已提交
3765
                case 0x37: /* V9 stdfa */
3766 3767
                    gen_op_check_align_T0_3();
                    gen_op_load_fpr_DT0(DFPREG(rd));
3768
                    gen_stf_asi(insn, 8, DFPREG(rd));
B
blueswir1 已提交
3769 3770
                    break;
                case 0x3c: /* V9 casa */
B
blueswir1 已提交
3771
                    gen_op_check_align_T0_3();
B
blueswir1 已提交
3772
                    gen_cas_asi(insn, rd);
3773
                    gen_movl_T1_reg(rd);
B
blueswir1 已提交
3774 3775
                    break;
                case 0x3e: /* V9 casxa */
B
blueswir1 已提交
3776
                    gen_op_check_align_T0_7();
B
blueswir1 已提交
3777
                    gen_casx_asi(insn, rd);
3778
                    gen_movl_T1_reg(rd);
B
blueswir1 已提交
3779
                    break;
3780
#else
B
blueswir1 已提交
3781 3782 3783 3784 3785 3786 3787 3788 3789
                case 0x34: /* stc */
                case 0x35: /* stcsr */
                case 0x36: /* stdcq */
                case 0x37: /* stdc */
                    goto ncp_insn;
#endif
                default:
                    goto illegal_insn;
                }
3790
            }
B
blueswir1 已提交
3791 3792 3793 3794
            else
                goto illegal_insn;
        }
        break;
3795 3796
    }
    /* default case for non jump instructions */
B
bellard 已提交
3797
    if (dc->npc == DYNAMIC_PC) {
B
blueswir1 已提交
3798 3799
        dc->pc = DYNAMIC_PC;
        gen_op_next_insn();
B
bellard 已提交
3800 3801
    } else if (dc->npc == JUMP_PC) {
        /* we can do a static jump */
B
blueswir1 已提交
3802
        gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1]);
B
bellard 已提交
3803 3804
        dc->is_br = 1;
    } else {
B
blueswir1 已提交
3805 3806
        dc->pc = dc->npc;
        dc->npc = dc->npc + 4;
3807
    }
B
bellard 已提交
3808
 jmp_insn:
3809 3810
    return;
 illegal_insn:
B
bellard 已提交
3811
    save_state(dc);
3812 3813
    gen_op_exception(TT_ILL_INSN);
    dc->is_br = 1;
3814
    return;
B
bellard 已提交
3815
#if !defined(CONFIG_USER_ONLY)
3816 3817 3818 3819
 priv_insn:
    save_state(dc);
    gen_op_exception(TT_PRIV_INSN);
    dc->is_br = 1;
B
bellard 已提交
3820 3821 3822 3823 3824
    return;
 nfpu_insn:
    save_state(dc);
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
    dc->is_br = 1;
3825
    return;
B
blueswir1 已提交
3826
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3827 3828 3829 3830 3831 3832
 nfq_insn:
    save_state(dc);
    gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
    dc->is_br = 1;
    return;
#endif
B
blueswir1 已提交
3833
#endif
3834 3835 3836 3837 3838 3839 3840
#ifndef TARGET_SPARC64
 ncp_insn:
    save_state(dc);
    gen_op_exception(TT_NCP_INSN);
    dc->is_br = 1;
    return;
#endif
3841 3842
}

B
blueswir1 已提交
3843 3844 3845 3846
static void tcg_macro_func(TCGContext *s, int macro_id, const int *dead_args)
{
}

3847
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
B
blueswir1 已提交
3848
                                                 int spc, CPUSPARCState *env)
3849
{
B
bellard 已提交
3850
    target_ulong pc_start, last_pc;
3851 3852
    uint16_t *gen_opc_end;
    DisasContext dc1, *dc = &dc1;
3853
    int j, lj = -1;
3854 3855 3856

    memset(dc, 0, sizeof(DisasContext));
    dc->tb = tb;
B
bellard 已提交
3857
    pc_start = tb->pc;
3858
    dc->pc = pc_start;
B
bellard 已提交
3859
    last_pc = dc->pc;
B
bellard 已提交
3860
    dc->npc = (target_ulong) tb->cs_base;
B
blueswir1 已提交
3861 3862
    dc->mem_idx = cpu_mmu_index(env);
    dc->fpu_enabled = cpu_fpu_enabled(env);
3863 3864
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;

B
blueswir1 已提交
3865 3866 3867
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
    cpu_regwptr = tcg_temp_new(TCG_TYPE_PTR); // XXX

3868
    do {
3869 3870 3871
        if (env->nb_breakpoints > 0) {
            for(j = 0; j < env->nb_breakpoints; j++) {
                if (env->breakpoints[j] == dc->pc) {
B
blueswir1 已提交
3872 3873
                    if (dc->pc != pc_start)
                        save_state(dc);
B
blueswir1 已提交
3874
                    tcg_gen_helper_0_0(helper_debug);
B
bellard 已提交
3875
                    tcg_gen_exit_tb(0);
B
blueswir1 已提交
3876
                    dc->is_br = 1;
B
bellard 已提交
3877
                    goto exit_gen_loop;
3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893
                }
            }
        }
        if (spc) {
            if (loglevel > 0)
                fprintf(logfile, "Search PC...\n");
            j = gen_opc_ptr - gen_opc_buf;
            if (lj < j) {
                lj++;
                while (lj < j)
                    gen_opc_instr_start[lj++] = 0;
                gen_opc_pc[lj] = dc->pc;
                gen_opc_npc[lj] = dc->npc;
                gen_opc_instr_start[lj] = 1;
            }
        }
B
blueswir1 已提交
3894 3895 3896 3897 3898 3899 3900 3901
        last_pc = dc->pc;
        disas_sparc_insn(dc);

        if (dc->is_br)
            break;
        /* if the next PC is different, we abort now */
        if (dc->pc != (last_pc + 4))
            break;
B
bellard 已提交
3902 3903 3904 3905
        /* if we reach a page boundary, we stop generation so that the
           PC of a TT_TFAULT exception is always in the right page */
        if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
            break;
B
bellard 已提交
3906 3907 3908
        /* if single step mode, we generate only one instruction and
           generate an exception */
        if (env->singlestep_enabled) {
B
bellard 已提交
3909
            gen_jmp_im(dc->pc);
B
bellard 已提交
3910
            tcg_gen_exit_tb(0);
B
bellard 已提交
3911 3912
            break;
        }
3913
    } while ((gen_opc_ptr < gen_opc_end) &&
B
blueswir1 已提交
3914
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
B
bellard 已提交
3915 3916

 exit_gen_loop:
B
bellard 已提交
3917
    if (!dc->is_br) {
3918
        if (dc->pc != DYNAMIC_PC &&
B
bellard 已提交
3919 3920
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
            /* static PC and NPC: we can use direct chaining */
B
blueswir1 已提交
3921
            gen_branch(dc, dc->pc, dc->npc);
B
bellard 已提交
3922 3923
        } else {
            if (dc->pc != DYNAMIC_PC)
B
bellard 已提交
3924
                gen_jmp_im(dc->pc);
B
bellard 已提交
3925
            save_npc(dc);
B
bellard 已提交
3926
            tcg_gen_exit_tb(0);
B
bellard 已提交
3927 3928
        }
    }
3929
    *gen_opc_ptr = INDEX_op_end;
3930 3931 3932 3933 3934 3935 3936 3937 3938 3939
    if (spc) {
        j = gen_opc_ptr - gen_opc_buf;
        lj++;
        while (lj <= j)
            gen_opc_instr_start[lj++] = 0;
#if 0
        if (loglevel > 0) {
            page_dump(logfile);
        }
#endif
3940 3941
        gen_opc_jump_pc[0] = dc->jump_pc[0];
        gen_opc_jump_pc[1] = dc->jump_pc[1];
3942
    } else {
B
bellard 已提交
3943
        tb->size = last_pc + 4 - pc_start;
3944
    }
3945
#ifdef DEBUG_DISAS
B
bellard 已提交
3946
    if (loglevel & CPU_LOG_TB_IN_ASM) {
B
blueswir1 已提交
3947 3948 3949 3950
        fprintf(logfile, "--------------\n");
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
        target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
        fprintf(logfile, "\n");
3951
    }
3952
#endif
3953
    return 0;
3954 3955
}

3956
int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
3957
{
3958
    return gen_intermediate_code_internal(tb, 0, env);
3959 3960
}

3961
int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
3962
{
3963
    return gen_intermediate_code_internal(tb, 1, env);
3964 3965
}

B
bellard 已提交
3966 3967
void cpu_reset(CPUSPARCState *env)
{
B
bellard 已提交
3968
    tlb_flush(env, 1);
3969 3970 3971
    env->cwp = 0;
    env->wim = 1;
    env->regwptr = env->regbase + (env->cwp * 16);
3972
#if defined(CONFIG_USER_ONLY)
3973
    env->user_mode_only = 1;
3974
#ifdef TARGET_SPARC64
3975 3976 3977 3978
    env->cleanwin = NWINDOWS - 2;
    env->cansave = NWINDOWS - 2;
    env->pstate = PS_RMO | PS_PEF | PS_IE;
    env->asi = 0x82; // Primary no-fault
3979
#endif
3980
#else
B
blueswir1 已提交
3981
    env->psret = 0;
3982
    env->psrs = 1;
B
bellard 已提交
3983
    env->psrps = 1;
B
bellard 已提交
3984
#ifdef TARGET_SPARC64
B
bellard 已提交
3985
    env->pstate = PS_PRIV;
B
blueswir1 已提交
3986
    env->hpstate = HS_PRIV;
B
bellard 已提交
3987
    env->pc = 0x1fff0000000ULL;
3988
    env->tsptr = &env->ts[env->tl];
B
bellard 已提交
3989
#else
B
blueswir1 已提交
3990
    env->pc = 0;
B
blueswir1 已提交
3991
    env->mmuregs[0] &= ~(MMU_E | MMU_NF);
3992
    env->mmuregs[0] |= env->mmu_bm;
B
bellard 已提交
3993
#endif
B
bellard 已提交
3994
    env->npc = env->pc + 4;
3995
#endif
B
bellard 已提交
3996 3997
}

B
bellard 已提交
3998
CPUSPARCState *cpu_sparc_init(const char *cpu_model)
B
bellard 已提交
3999 4000
{
    CPUSPARCState *env;
B
bellard 已提交
4001
    const sparc_def_t *def;
B
blueswir1 已提交
4002
    static int inited;
B
bellard 已提交
4003 4004 4005 4006

    def = cpu_sparc_find_by_name(cpu_model);
    if (!def)
        return NULL;
B
bellard 已提交
4007

B
bellard 已提交
4008 4009
    env = qemu_mallocz(sizeof(CPUSPARCState));
    if (!env)
B
blueswir1 已提交
4010
        return NULL;
B
bellard 已提交
4011
    cpu_exec_init(env);
4012
    env->cpu_model_str = cpu_model;
B
bellard 已提交
4013 4014 4015 4016
    env->version = def->iu_version;
    env->fsr = def->fpu_version;
#if !defined(TARGET_SPARC64)
    env->mmu_bm = def->mmu_bm;
4017 4018 4019 4020
    env->mmu_ctpr_mask = def->mmu_ctpr_mask;
    env->mmu_cxr_mask = def->mmu_cxr_mask;
    env->mmu_sfsr_mask = def->mmu_sfsr_mask;
    env->mmu_trcr_mask = def->mmu_trcr_mask;
B
bellard 已提交
4021 4022 4023
    env->mmuregs[0] |= def->mmu_version;
    cpu_sparc_set_id(env, 0);
#endif
B
blueswir1 已提交
4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045

    /* init various static tables */
    if (!inited) {
        inited = 1;

        tcg_set_macro_func(&tcg_ctx, tcg_macro_func);
        cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
        //#if TARGET_LONG_BITS > HOST_LONG_BITS
#ifdef TARGET_SPARC64
        cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
                                      TCG_AREG0, offsetof(CPUState, t0), "T0");
        cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
                                      TCG_AREG0, offsetof(CPUState, t1), "T1");
        cpu_T[2] = tcg_global_mem_new(TCG_TYPE_TL,
                                      TCG_AREG0, offsetof(CPUState, t2), "T2");
#else
        cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
        cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
        cpu_T[2] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T2");
#endif
    }

B
bellard 已提交
4046 4047 4048 4049 4050 4051 4052 4053 4054 4055
    cpu_reset(env);
    
    return env;
}

void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
{
#if !defined(TARGET_SPARC64)
    env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
#endif
4056 4057
}

B
blueswir1 已提交
4058 4059
static const sparc_def_t sparc_defs[] = {
#ifdef TARGET_SPARC64
B
blueswir1 已提交
4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094
    {
        .name = "Fujitsu Sparc64",
        .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)
                       | (MAXTL << 8) | (NWINDOWS - 1)),
        .fpu_version = 0x00000000,
        .mmu_version = 0,
    },
    {
        .name = "Fujitsu Sparc64 III",
        .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)
                       | (MAXTL << 8) | (NWINDOWS - 1)),
        .fpu_version = 0x00000000,
        .mmu_version = 0,
    },
    {
        .name = "Fujitsu Sparc64 IV",
        .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)
                       | (MAXTL << 8) | (NWINDOWS - 1)),
        .fpu_version = 0x00000000,
        .mmu_version = 0,
    },
    {
        .name = "Fujitsu Sparc64 V",
        .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)
                       | (MAXTL << 8) | (NWINDOWS - 1)),
        .fpu_version = 0x00000000,
        .mmu_version = 0,
    },
    {
        .name = "TI UltraSparc I",
        .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)
                       | (MAXTL << 8) | (NWINDOWS - 1)),
        .fpu_version = 0x00000000,
        .mmu_version = 0,
    },
B
blueswir1 已提交
4095 4096
    {
        .name = "TI UltraSparc II",
B
blueswir1 已提交
4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160
        .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)
                       | (MAXTL << 8) | (NWINDOWS - 1)),
        .fpu_version = 0x00000000,
        .mmu_version = 0,
    },
    {
        .name = "TI UltraSparc IIi",
        .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)
                       | (MAXTL << 8) | (NWINDOWS - 1)),
        .fpu_version = 0x00000000,
        .mmu_version = 0,
    },
    {
        .name = "TI UltraSparc IIe",
        .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)
                       | (MAXTL << 8) | (NWINDOWS - 1)),
        .fpu_version = 0x00000000,
        .mmu_version = 0,
    },
    {
        .name = "Sun UltraSparc III",
        .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)
                       | (MAXTL << 8) | (NWINDOWS - 1)),
        .fpu_version = 0x00000000,
        .mmu_version = 0,
    },
    {
        .name = "Sun UltraSparc III Cu",
        .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)
                       | (MAXTL << 8) | (NWINDOWS - 1)),
        .fpu_version = 0x00000000,
        .mmu_version = 0,
    },
    {
        .name = "Sun UltraSparc IIIi",
        .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)
                       | (MAXTL << 8) | (NWINDOWS - 1)),
        .fpu_version = 0x00000000,
        .mmu_version = 0,
    },
    {
        .name = "Sun UltraSparc IV",
        .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)
                       | (MAXTL << 8) | (NWINDOWS - 1)),
        .fpu_version = 0x00000000,
        .mmu_version = 0,
    },
    {
        .name = "Sun UltraSparc IV+",
        .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)
                       | (MAXTL << 8) | (NWINDOWS - 1)),
        .fpu_version = 0x00000000,
        .mmu_version = 0,
    },
    {
        .name = "Sun UltraSparc IIIi+",
        .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)
                       | (MAXTL << 8) | (NWINDOWS - 1)),
        .fpu_version = 0x00000000,
        .mmu_version = 0,
    },
    {
        .name = "NEC UltraSparc I",
        .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)
B
blueswir1 已提交
4161 4162 4163 4164 4165
                       | (MAXTL << 8) | (NWINDOWS - 1)),
        .fpu_version = 0x00000000,
        .mmu_version = 0,
    },
#else
B
blueswir1 已提交
4166 4167 4168 4169 4170 4171
    {
        .name = "Fujitsu MB86900",
        .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
        .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
        .mmu_bm = 0x00004000,
4172 4173 4174 4175
        .mmu_ctpr_mask = 0x007ffff0,
        .mmu_cxr_mask = 0x0000003f,
        .mmu_sfsr_mask = 0xffffffff,
        .mmu_trcr_mask = 0xffffffff,
B
blueswir1 已提交
4176
    },
B
blueswir1 已提交
4177 4178 4179 4180 4181
    {
        .name = "Fujitsu MB86904",
        .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
        .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
4182
        .mmu_bm = 0x00004000,
4183 4184 4185 4186
        .mmu_ctpr_mask = 0x00ffffc0,
        .mmu_cxr_mask = 0x000000ff,
        .mmu_sfsr_mask = 0x00016fff,
        .mmu_trcr_mask = 0x00ffffff,
B
blueswir1 已提交
4187
    },
B
blueswir1 已提交
4188
    {
B
blueswir1 已提交
4189 4190 4191 4192
        .name = "Fujitsu MB86907",
        .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
        .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
4193
        .mmu_bm = 0x00004000,
4194 4195 4196 4197
        .mmu_ctpr_mask = 0xffffffc0,
        .mmu_cxr_mask = 0x000000ff,
        .mmu_sfsr_mask = 0x00016fff,
        .mmu_trcr_mask = 0xffffffff,
B
blueswir1 已提交
4198
    },
B
blueswir1 已提交
4199 4200 4201 4202 4203 4204
    {
        .name = "LSI L64811",
        .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
        .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
        .mmu_version = 0x10 << 24,
        .mmu_bm = 0x00004000,
4205 4206 4207 4208
        .mmu_ctpr_mask = 0x007ffff0,
        .mmu_cxr_mask = 0x0000003f,
        .mmu_sfsr_mask = 0xffffffff,
        .mmu_trcr_mask = 0xffffffff,
B
blueswir1 已提交
4209 4210 4211 4212 4213 4214 4215
    },
    {
        .name = "Cypress CY7C601",
        .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
        .mmu_version = 0x10 << 24,
        .mmu_bm = 0x00004000,
4216 4217 4218 4219
        .mmu_ctpr_mask = 0x007ffff0,
        .mmu_cxr_mask = 0x0000003f,
        .mmu_sfsr_mask = 0xffffffff,
        .mmu_trcr_mask = 0xffffffff,
B
blueswir1 已提交
4220 4221 4222 4223 4224 4225 4226
    },
    {
        .name = "Cypress CY7C611",
        .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
        .mmu_version = 0x10 << 24,
        .mmu_bm = 0x00004000,
4227 4228 4229 4230
        .mmu_ctpr_mask = 0x007ffff0,
        .mmu_cxr_mask = 0x0000003f,
        .mmu_sfsr_mask = 0xffffffff,
        .mmu_trcr_mask = 0xffffffff,
B
blueswir1 已提交
4231 4232 4233 4234 4235 4236 4237
    },
    {
        .name = "TI SuperSparc II",
        .iu_version = 0x40000000,
        .fpu_version = 0 << 17,
        .mmu_version = 0x04000000,
        .mmu_bm = 0x00002000,
4238 4239 4240 4241
        .mmu_ctpr_mask = 0xffffffc0,
        .mmu_cxr_mask = 0x0000ffff,
        .mmu_sfsr_mask = 0xffffffff,
        .mmu_trcr_mask = 0xffffffff,
B
blueswir1 已提交
4242
    },
B
blueswir1 已提交
4243 4244 4245 4246 4247
    {
        .name = "TI MicroSparc I",
        .iu_version = 0x41000000,
        .fpu_version = 4 << 17,
        .mmu_version = 0x41000000,
4248
        .mmu_bm = 0x00004000,
4249 4250 4251 4252
        .mmu_ctpr_mask = 0x007ffff0,
        .mmu_cxr_mask = 0x0000003f,
        .mmu_sfsr_mask = 0x00016fff,
        .mmu_trcr_mask = 0x0000003f,
B
blueswir1 已提交
4253 4254
    },
    {
B
blueswir1 已提交
4255 4256 4257 4258 4259
        .name = "TI MicroSparc II",
        .iu_version = 0x42000000,
        .fpu_version = 4 << 17,
        .mmu_version = 0x02000000,
        .mmu_bm = 0x00004000,
4260 4261 4262 4263
        .mmu_ctpr_mask = 0x00ffffc0,
        .mmu_cxr_mask = 0x000000ff,
        .mmu_sfsr_mask = 0x00016bff,
        .mmu_trcr_mask = 0x00ffffff,
B
blueswir1 已提交
4264 4265 4266 4267 4268 4269 4270
    },
    {
        .name = "TI MicroSparc IIep",
        .iu_version = 0x42000000,
        .fpu_version = 4 << 17,
        .mmu_version = 0x04000000,
        .mmu_bm = 0x00004000,
4271 4272 4273 4274
        .mmu_ctpr_mask = 0x00ffffc0,
        .mmu_cxr_mask = 0x000000ff,
        .mmu_sfsr_mask = 0x00016bff,
        .mmu_trcr_mask = 0x00ffffff,
B
blueswir1 已提交
4275 4276 4277 4278
    },
    {
        .name = "TI SuperSparc 51",
        .iu_version = 0x43000000,
B
blueswir1 已提交
4279 4280
        .fpu_version = 0 << 17,
        .mmu_version = 0x04000000,
4281
        .mmu_bm = 0x00002000,
4282 4283 4284 4285
        .mmu_ctpr_mask = 0xffffffc0,
        .mmu_cxr_mask = 0x0000ffff,
        .mmu_sfsr_mask = 0xffffffff,
        .mmu_trcr_mask = 0xffffffff,
B
blueswir1 已提交
4286 4287
    },
    {
B
blueswir1 已提交
4288 4289 4290 4291 4292
        .name = "TI SuperSparc 61",
        .iu_version = 0x44000000,
        .fpu_version = 0 << 17,
        .mmu_version = 0x04000000,
        .mmu_bm = 0x00002000,
4293 4294 4295 4296
        .mmu_ctpr_mask = 0xffffffc0,
        .mmu_cxr_mask = 0x0000ffff,
        .mmu_sfsr_mask = 0xffffffff,
        .mmu_trcr_mask = 0xffffffff,
B
blueswir1 已提交
4297 4298 4299
    },
    {
        .name = "Ross RT625",
B
blueswir1 已提交
4300 4301
        .iu_version = 0x1e000000,
        .fpu_version = 1 << 17,
B
blueswir1 已提交
4302 4303
        .mmu_version = 0x1e000000,
        .mmu_bm = 0x00004000,
4304 4305 4306 4307
        .mmu_ctpr_mask = 0x007ffff0,
        .mmu_cxr_mask = 0x0000003f,
        .mmu_sfsr_mask = 0xffffffff,
        .mmu_trcr_mask = 0xffffffff,
B
blueswir1 已提交
4308 4309 4310 4311 4312 4313 4314
    },
    {
        .name = "Ross RT620",
        .iu_version = 0x1f000000,
        .fpu_version = 1 << 17,
        .mmu_version = 0x1f000000,
        .mmu_bm = 0x00004000,
4315 4316 4317 4318
        .mmu_ctpr_mask = 0x007ffff0,
        .mmu_cxr_mask = 0x0000003f,
        .mmu_sfsr_mask = 0xffffffff,
        .mmu_trcr_mask = 0xffffffff,
B
blueswir1 已提交
4319 4320 4321 4322 4323 4324 4325
    },
    {
        .name = "BIT B5010",
        .iu_version = 0x20000000,
        .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
        .mmu_version = 0x20000000,
        .mmu_bm = 0x00004000,
4326 4327 4328 4329
        .mmu_ctpr_mask = 0x007ffff0,
        .mmu_cxr_mask = 0x0000003f,
        .mmu_sfsr_mask = 0xffffffff,
        .mmu_trcr_mask = 0xffffffff,
B
blueswir1 已提交
4330 4331 4332 4333 4334 4335 4336
    },
    {
        .name = "Matsushita MN10501",
        .iu_version = 0x50000000,
        .fpu_version = 0 << 17,
        .mmu_version = 0x50000000,
        .mmu_bm = 0x00004000,
4337 4338 4339 4340
        .mmu_ctpr_mask = 0x007ffff0,
        .mmu_cxr_mask = 0x0000003f,
        .mmu_sfsr_mask = 0xffffffff,
        .mmu_trcr_mask = 0xffffffff,
B
blueswir1 已提交
4341 4342 4343 4344 4345 4346 4347
    },
    {
        .name = "Weitek W8601",
        .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
        .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
        .mmu_version = 0x10 << 24,
        .mmu_bm = 0x00004000,
4348 4349 4350 4351
        .mmu_ctpr_mask = 0x007ffff0,
        .mmu_cxr_mask = 0x0000003f,
        .mmu_sfsr_mask = 0xffffffff,
        .mmu_trcr_mask = 0xffffffff,
B
blueswir1 已提交
4352 4353 4354 4355 4356 4357 4358
    },
    {
        .name = "LEON2",
        .iu_version = 0xf2000000,
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
        .mmu_version = 0xf2000000,
        .mmu_bm = 0x00004000,
4359 4360 4361 4362
        .mmu_ctpr_mask = 0x007ffff0,
        .mmu_cxr_mask = 0x0000003f,
        .mmu_sfsr_mask = 0xffffffff,
        .mmu_trcr_mask = 0xffffffff,
B
blueswir1 已提交
4363 4364 4365 4366 4367 4368
    },
    {
        .name = "LEON3",
        .iu_version = 0xf3000000,
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
        .mmu_version = 0xf3000000,
4369
        .mmu_bm = 0x00004000,
4370 4371 4372 4373
        .mmu_ctpr_mask = 0x007ffff0,
        .mmu_cxr_mask = 0x0000003f,
        .mmu_sfsr_mask = 0xffffffff,
        .mmu_trcr_mask = 0xffffffff,
B
blueswir1 已提交
4374
    },
B
blueswir1 已提交
4375 4376 4377
#endif
};

B
bellard 已提交
4378
static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name)
B
blueswir1 已提交
4379 4380 4381 4382 4383
{
    unsigned int i;

    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
        if (strcasecmp(name, sparc_defs[i].name) == 0) {
B
bellard 已提交
4384
            return &sparc_defs[i];
B
blueswir1 已提交
4385 4386
        }
    }
B
bellard 已提交
4387
    return NULL;
B
blueswir1 已提交
4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402
}

void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
{
    unsigned int i;

    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
        (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x\n",
                       sparc_defs[i].name,
                       sparc_defs[i].iu_version,
                       sparc_defs[i].fpu_version,
                       sparc_defs[i].mmu_version);
    }
}

4403 4404
#define GET_FLAG(a,b) ((env->psr & a)?b:'-')

4405
void cpu_dump_state(CPUState *env, FILE *f,
B
bellard 已提交
4406 4407
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                    int flags)
4408
{
4409 4410
    int i, x;

4411
    cpu_fprintf(f, "pc: " TARGET_FMT_lx "  npc: " TARGET_FMT_lx "\n", env->pc, env->npc);
B
bellard 已提交
4412
    cpu_fprintf(f, "General Registers:\n");
4413
    for (i = 0; i < 4; i++)
B
blueswir1 已提交
4414
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
B
bellard 已提交
4415
    cpu_fprintf(f, "\n");
4416
    for (; i < 8; i++)
B
blueswir1 已提交
4417
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
B
bellard 已提交
4418
    cpu_fprintf(f, "\nCurrent Register Window:\n");
4419
    for (x = 0; x < 3; x++) {
B
blueswir1 已提交
4420 4421 4422 4423 4424 4425 4426 4427 4428 4429
        for (i = 0; i < 4; i++)
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
                    (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
                    env->regwptr[i + x * 8]);
        cpu_fprintf(f, "\n");
        for (; i < 8; i++)
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
                    (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
                    env->regwptr[i + x * 8]);
        cpu_fprintf(f, "\n");
4430
    }
B
bellard 已提交
4431
    cpu_fprintf(f, "\nFloating Point Registers:\n");
4432 4433
    for (i = 0; i < 32; i++) {
        if ((i & 3) == 0)
B
bellard 已提交
4434 4435
            cpu_fprintf(f, "%%f%02d:", i);
        cpu_fprintf(f, " %016lf", env->fpr[i]);
4436
        if ((i & 3) == 3)
B
bellard 已提交
4437
            cpu_fprintf(f, "\n");
4438
    }
P
pbrook 已提交
4439
#ifdef TARGET_SPARC64
4440
    cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d fprs: %d\n",
B
blueswir1 已提交
4441
                env->pstate, GET_CCR(env), env->asi, env->tl, env->fprs);
P
pbrook 已提交
4442
    cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d cleanwin %d cwp %d\n",
B
blueswir1 已提交
4443 4444
                env->cansave, env->canrestore, env->otherwin, env->wstate,
                env->cleanwin, NWINDOWS - 1 - env->cwp);
P
pbrook 已提交
4445
#else
B
bellard 已提交
4446
    cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n", GET_PSR(env),
B
blueswir1 已提交
4447 4448 4449 4450
            GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
            GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
            env->psrs?'S':'-', env->psrps?'P':'-',
            env->psret?'E':'-', env->wim);
P
pbrook 已提交
4451
#endif
B
bellard 已提交
4452
    cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env));
4453
}
B
bellard 已提交
4454

B
bellard 已提交
4455
#if defined(CONFIG_USER_ONLY)
4456
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
B
bellard 已提交
4457 4458 4459
{
    return addr;
}
B
bellard 已提交
4460

B
bellard 已提交
4461
#else
4462 4463
extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
                                 int *access_index, target_ulong address, int rw,
4464
                                 int mmu_idx);
B
bellard 已提交
4465

4466
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
B
bellard 已提交
4467
{
4468
    target_phys_addr_t phys_addr;
B
bellard 已提交
4469 4470
    int prot, access_index;

4471 4472 4473 4474
    if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2,
                             MMU_KERNEL_IDX) != 0)
        if (get_physical_address(env, &phys_addr, &prot, &access_index, addr,
                                 0, MMU_KERNEL_IDX) != 0)
4475
            return -1;
4476 4477
    if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED)
        return -1;
B
bellard 已提交
4478 4479 4480 4481
    return phys_addr;
}
#endif

B
bellard 已提交
4482 4483 4484 4485 4486
void helper_flush(target_ulong addr)
{
    addr &= ~7;
    tb_invalidate_page_range(addr, addr + 8);
}