translate.c 138.4 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
bellard 已提交
39
#include "tcg-op.h"
40 41 42

#define DEBUG_DISAS

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

47
typedef struct DisasContext {
B
blueswir1 已提交
48 49
    target_ulong pc;    /* current Program Counter: integer or DYNAMIC_PC */
    target_ulong npc;   /* next PC: integer or DYNAMIC_PC or JUMP_PC */
B
bellard 已提交
50
    target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
51
    int is_br;
52
    int mem_idx;
B
bellard 已提交
53
    int fpu_enabled;
54
    struct TranslationBlock *tb;
55 56
} DisasContext;

B
bellard 已提交
57 58
typedef struct sparc_def_t sparc_def_t;

B
blueswir1 已提交
59 60 61 62 63
struct sparc_def_t {
    const unsigned char *name;
    target_ulong iu_version;
    uint32_t fpu_version;
    uint32_t mmu_version;
64
    uint32_t mmu_bm;
B
blueswir1 已提交
65 66
};

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

69 70 71
extern FILE *logfile;
extern int loglevel;

B
bellard 已提交
72
// This function uses non-native bit order
73 74 75
#define GET_FIELD(X, FROM, TO) \
  ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))

B
bellard 已提交
76 77 78 79 80
// 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 已提交
81
#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
B
bellard 已提交
82 83

#ifdef TARGET_SPARC64
84
#define DFPREG(r) (((r & 1) << 5) | (r & 0x1e))
B
blueswir1 已提交
85
#define QFPREG(r) (((r & 1) << 5) | (r & 0x1c))
B
bellard 已提交
86
#else
87
#define DFPREG(r) (r & 0x1e)
B
blueswir1 已提交
88
#define QFPREG(r) (r & 0x1c)
B
bellard 已提交
89 90 91 92 93 94 95 96
#endif

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

97 98
#define IS_IMM (insn & (1<<13))

99
static void disas_sparc_insn(DisasContext * dc);
100

B
blueswir1 已提交
101
static GenOpFunc * const gen_op_movl_TN_reg[2][32] = {
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
    {
     gen_op_movl_g0_T0,
     gen_op_movl_g1_T0,
     gen_op_movl_g2_T0,
     gen_op_movl_g3_T0,
     gen_op_movl_g4_T0,
     gen_op_movl_g5_T0,
     gen_op_movl_g6_T0,
     gen_op_movl_g7_T0,
     gen_op_movl_o0_T0,
     gen_op_movl_o1_T0,
     gen_op_movl_o2_T0,
     gen_op_movl_o3_T0,
     gen_op_movl_o4_T0,
     gen_op_movl_o5_T0,
     gen_op_movl_o6_T0,
     gen_op_movl_o7_T0,
     gen_op_movl_l0_T0,
     gen_op_movl_l1_T0,
     gen_op_movl_l2_T0,
     gen_op_movl_l3_T0,
     gen_op_movl_l4_T0,
     gen_op_movl_l5_T0,
     gen_op_movl_l6_T0,
     gen_op_movl_l7_T0,
     gen_op_movl_i0_T0,
     gen_op_movl_i1_T0,
     gen_op_movl_i2_T0,
     gen_op_movl_i3_T0,
     gen_op_movl_i4_T0,
     gen_op_movl_i5_T0,
     gen_op_movl_i6_T0,
     gen_op_movl_i7_T0,
     },
    {
     gen_op_movl_g0_T1,
     gen_op_movl_g1_T1,
     gen_op_movl_g2_T1,
     gen_op_movl_g3_T1,
     gen_op_movl_g4_T1,
     gen_op_movl_g5_T1,
     gen_op_movl_g6_T1,
     gen_op_movl_g7_T1,
     gen_op_movl_o0_T1,
     gen_op_movl_o1_T1,
     gen_op_movl_o2_T1,
     gen_op_movl_o3_T1,
     gen_op_movl_o4_T1,
     gen_op_movl_o5_T1,
     gen_op_movl_o6_T1,
     gen_op_movl_o7_T1,
     gen_op_movl_l0_T1,
     gen_op_movl_l1_T1,
     gen_op_movl_l2_T1,
     gen_op_movl_l3_T1,
     gen_op_movl_l4_T1,
     gen_op_movl_l5_T1,
     gen_op_movl_l6_T1,
     gen_op_movl_l7_T1,
     gen_op_movl_i0_T1,
     gen_op_movl_i1_T1,
     gen_op_movl_i2_T1,
     gen_op_movl_i3_T1,
     gen_op_movl_i4_T1,
     gen_op_movl_i5_T1,
     gen_op_movl_i6_T1,
     gen_op_movl_i7_T1,
     }
170 171
};

B
blueswir1 已提交
172
static GenOpFunc * const gen_op_movl_reg_TN[3][32] = {
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
    {
     gen_op_movl_T0_g0,
     gen_op_movl_T0_g1,
     gen_op_movl_T0_g2,
     gen_op_movl_T0_g3,
     gen_op_movl_T0_g4,
     gen_op_movl_T0_g5,
     gen_op_movl_T0_g6,
     gen_op_movl_T0_g7,
     gen_op_movl_T0_o0,
     gen_op_movl_T0_o1,
     gen_op_movl_T0_o2,
     gen_op_movl_T0_o3,
     gen_op_movl_T0_o4,
     gen_op_movl_T0_o5,
     gen_op_movl_T0_o6,
     gen_op_movl_T0_o7,
     gen_op_movl_T0_l0,
     gen_op_movl_T0_l1,
     gen_op_movl_T0_l2,
     gen_op_movl_T0_l3,
     gen_op_movl_T0_l4,
     gen_op_movl_T0_l5,
     gen_op_movl_T0_l6,
     gen_op_movl_T0_l7,
     gen_op_movl_T0_i0,
     gen_op_movl_T0_i1,
     gen_op_movl_T0_i2,
     gen_op_movl_T0_i3,
     gen_op_movl_T0_i4,
     gen_op_movl_T0_i5,
     gen_op_movl_T0_i6,
     gen_op_movl_T0_i7,
     },
    {
     gen_op_movl_T1_g0,
     gen_op_movl_T1_g1,
     gen_op_movl_T1_g2,
     gen_op_movl_T1_g3,
     gen_op_movl_T1_g4,
     gen_op_movl_T1_g5,
     gen_op_movl_T1_g6,
     gen_op_movl_T1_g7,
     gen_op_movl_T1_o0,
     gen_op_movl_T1_o1,
     gen_op_movl_T1_o2,
     gen_op_movl_T1_o3,
     gen_op_movl_T1_o4,
     gen_op_movl_T1_o5,
     gen_op_movl_T1_o6,
     gen_op_movl_T1_o7,
     gen_op_movl_T1_l0,
     gen_op_movl_T1_l1,
     gen_op_movl_T1_l2,
     gen_op_movl_T1_l3,
     gen_op_movl_T1_l4,
     gen_op_movl_T1_l5,
     gen_op_movl_T1_l6,
     gen_op_movl_T1_l7,
     gen_op_movl_T1_i0,
     gen_op_movl_T1_i1,
     gen_op_movl_T1_i2,
     gen_op_movl_T1_i3,
     gen_op_movl_T1_i4,
     gen_op_movl_T1_i5,
     gen_op_movl_T1_i6,
     gen_op_movl_T1_i7,
     },
    {
     gen_op_movl_T2_g0,
     gen_op_movl_T2_g1,
     gen_op_movl_T2_g2,
     gen_op_movl_T2_g3,
     gen_op_movl_T2_g4,
     gen_op_movl_T2_g5,
     gen_op_movl_T2_g6,
     gen_op_movl_T2_g7,
     gen_op_movl_T2_o0,
     gen_op_movl_T2_o1,
     gen_op_movl_T2_o2,
     gen_op_movl_T2_o3,
     gen_op_movl_T2_o4,
     gen_op_movl_T2_o5,
     gen_op_movl_T2_o6,
     gen_op_movl_T2_o7,
     gen_op_movl_T2_l0,
     gen_op_movl_T2_l1,
     gen_op_movl_T2_l2,
     gen_op_movl_T2_l3,
     gen_op_movl_T2_l4,
     gen_op_movl_T2_l5,
     gen_op_movl_T2_l6,
     gen_op_movl_T2_l7,
     gen_op_movl_T2_i0,
     gen_op_movl_T2_i1,
     gen_op_movl_T2_i2,
     gen_op_movl_T2_i3,
     gen_op_movl_T2_i4,
     gen_op_movl_T2_i5,
     gen_op_movl_T2_i6,
     gen_op_movl_T2_i7,
     }
275 276
};

B
blueswir1 已提交
277
static GenOpFunc1 * const gen_op_movl_TN_im[3] = {
278 279 280
    gen_op_movl_T0_im,
    gen_op_movl_T1_im,
    gen_op_movl_T2_im
281 282
};

B
bellard 已提交
283 284 285 286 287 288 289 290 291
// Sign extending version
static GenOpFunc1 * const gen_op_movl_TN_sim[3] = {
    gen_op_movl_T0_sim,
    gen_op_movl_T1_sim,
    gen_op_movl_T2_sim
};

#ifdef TARGET_SPARC64
#define GEN32(func, NAME) \
B
blueswir1 已提交
292
static GenOpFunc * const NAME ## _table [64] = {                              \
B
bellard 已提交
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
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
311
#define GEN32(func, NAME) \
B
blueswir1 已提交
312
static GenOpFunc *const NAME ## _table [32] = {                               \
313 314 315 316 317 318 319 320 321 322 323 324 325
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 已提交
326
#endif
327 328 329 330 331 332 333 334 335 336 337 338

/* 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 已提交
339 340 341 342 343 344 345
#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

346 347
/* moves */
#ifdef CONFIG_USER_ONLY
B
bellard 已提交
348
#define supervisor(dc) 0
349
#ifdef TARGET_SPARC64
B
blueswir1 已提交
350
#define hypervisor(dc) 0
351
#endif
B
bellard 已提交
352 353
#define gen_op_ldst(name)        gen_op_##name##_raw()
#else
B
blueswir1 已提交
354
#define supervisor(dc) (dc->mem_idx >= 1)
355 356
#ifdef TARGET_SPARC64
#define hypervisor(dc) (dc->mem_idx == 2)
B
blueswir1 已提交
357 358 359 360 361 362 363
#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 已提交
364
#define OP_LD_TABLE(width)                                              \
B
blueswir1 已提交
365
    static GenOpFunc * const gen_op_##width[] = {                       \
B
blueswir1 已提交
366 367
        &gen_op_##width##_user,                                         \
        &gen_op_##width##_kernel,                                       \
368
    };
B
bellard 已提交
369
#endif
B
blueswir1 已提交
370 371
#define gen_op_ldst(name)        (*gen_op_##name[dc->mem_idx])()
#endif
372

373
#ifndef CONFIG_USER_ONLY
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390
OP_LD_TABLE(ld);
OP_LD_TABLE(st);
OP_LD_TABLE(ldub);
OP_LD_TABLE(lduh);
OP_LD_TABLE(ldsb);
OP_LD_TABLE(ldsh);
OP_LD_TABLE(stb);
OP_LD_TABLE(sth);
OP_LD_TABLE(std);
OP_LD_TABLE(ldstub);
OP_LD_TABLE(swap);
OP_LD_TABLE(ldd);
OP_LD_TABLE(stf);
OP_LD_TABLE(stdf);
OP_LD_TABLE(ldf);
OP_LD_TABLE(lddf);

B
bellard 已提交
391
#ifdef TARGET_SPARC64
392
OP_LD_TABLE(lduw);
B
bellard 已提交
393 394 395
OP_LD_TABLE(ldsw);
OP_LD_TABLE(ldx);
OP_LD_TABLE(stx);
396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426
#endif
#endif

/* asi moves */
#ifdef TARGET_SPARC64
static inline void gen_ld_asi(int insn, int size, int sign)
{
    int asi, offset;

    if (IS_IMM) {
        offset = GET_FIELD(insn, 25, 31);
        gen_op_ld_asi_reg(offset, size, sign);
    } else {
        asi = GET_FIELD(insn, 19, 26);
        gen_op_ld_asi(asi, size, sign);
    }
}

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

    if (IS_IMM) {
        offset = GET_FIELD(insn, 25, 31);
        gen_op_st_asi_reg(offset, size);
    } else {
        asi = GET_FIELD(insn, 19, 26);
        gen_op_st_asi(asi, size);
    }
}

427
static inline void gen_ldf_asi(int insn, int size, int rd)
428
{
429
    int asi, offset;
430 431 432 433 434 435 436 437 438 439

    if (IS_IMM) {
        offset = GET_FIELD(insn, 25, 31);
        gen_op_ldf_asi_reg(offset, size, rd);
    } else {
        asi = GET_FIELD(insn, 19, 26);
        gen_op_ldf_asi(asi, size, rd);
    }
}

440
static inline void gen_stf_asi(int insn, int size, int rd)
441
{
442
    int asi, offset;
443 444 445 446 447 448 449 450 451 452

    if (IS_IMM) {
        offset = GET_FIELD(insn, 25, 31);
        gen_op_stf_asi_reg(offset, size, rd);
    } else {
        asi = GET_FIELD(insn, 19, 26);
        gen_op_stf_asi(asi, size, rd);
    }
}

453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579
static inline void gen_swap_asi(int insn)
{
    int asi, offset;

    if (IS_IMM) {
        offset = GET_FIELD(insn, 25, 31);
        gen_op_swap_asi_reg(offset);
    } else {
        asi = GET_FIELD(insn, 19, 26);
        gen_op_swap_asi(asi);
    }
}

static inline void gen_ldstub_asi(int insn)
{
    int asi, offset;

    if (IS_IMM) {
        offset = GET_FIELD(insn, 25, 31);
        gen_op_ldstub_asi_reg(offset);
    } else {
        asi = GET_FIELD(insn, 19, 26);
        gen_op_ldstub_asi(asi);
    }
}

static inline void gen_ldda_asi(int insn)
{
    int asi, offset;

    if (IS_IMM) {
        offset = GET_FIELD(insn, 25, 31);
        gen_op_ldda_asi_reg(offset);
    } else {
        asi = GET_FIELD(insn, 19, 26);
        gen_op_ldda_asi(asi);
    }
}

static inline void gen_stda_asi(int insn)
{
    int asi, offset;

    if (IS_IMM) {
        offset = GET_FIELD(insn, 25, 31);
        gen_op_stda_asi_reg(offset);
    } else {
        asi = GET_FIELD(insn, 19, 26);
        gen_op_stda_asi(asi);
    }
}

static inline void gen_cas_asi(int insn)
{
    int asi, offset;

    if (IS_IMM) {
        offset = GET_FIELD(insn, 25, 31);
        gen_op_cas_asi_reg(offset);
    } else {
        asi = GET_FIELD(insn, 19, 26);
        gen_op_cas_asi(asi);
    }
}

static inline void gen_casx_asi(int insn)
{
    int asi, offset;

    if (IS_IMM) {
        offset = GET_FIELD(insn, 25, 31);
        gen_op_casx_asi_reg(offset);
    } else {
        asi = GET_FIELD(insn, 19, 26);
        gen_op_casx_asi(asi);
    }
}

#elif !defined(CONFIG_USER_ONLY)

static inline void gen_ld_asi(int insn, int size, int sign)
{
    int asi;

    asi = GET_FIELD(insn, 19, 26);
    gen_op_ld_asi(asi, size, sign);
}

static inline void gen_st_asi(int insn, int size)
{
    int asi;

    asi = GET_FIELD(insn, 19, 26);
    gen_op_st_asi(asi, size);
}

static inline void gen_ldstub_asi(int insn)
{
    int asi;

    asi = GET_FIELD(insn, 19, 26);
    gen_op_ldstub_asi(asi);
}

static inline void gen_swap_asi(int insn)
{
    int asi;

    asi = GET_FIELD(insn, 19, 26);
    gen_op_swap_asi(asi);
}

static inline void gen_ldda_asi(int insn)
{
    int asi;

    asi = GET_FIELD(insn, 19, 26);
    gen_op_ld_asi(asi, 8, 0);
}

static inline void gen_stda_asi(int insn)
{
    int asi;

    asi = GET_FIELD(insn, 19, 26);
    gen_op_st_asi(asi, 8);
}
B
bellard 已提交
580 581 582
#endif

static inline void gen_movl_imm_TN(int reg, uint32_t imm)
583
{
B
bellard 已提交
584
    gen_op_movl_TN_im[reg](imm);
585 586
}

B
bellard 已提交
587
static inline void gen_movl_imm_T1(uint32_t val)
588
{
589
    gen_movl_imm_TN(1, val);
590 591
}

B
bellard 已提交
592
static inline void gen_movl_imm_T0(uint32_t val)
593
{
594
    gen_movl_imm_TN(0, val);
595 596
}

B
bellard 已提交
597 598 599 600 601 602 603 604 605 606 607 608 609 610 611
static inline void gen_movl_simm_TN(int reg, int32_t imm)
{
    gen_op_movl_TN_sim[reg](imm);
}

static inline void gen_movl_simm_T1(int32_t val)
{
    gen_movl_simm_TN(1, val);
}

static inline void gen_movl_simm_T0(int32_t val)
{
    gen_movl_simm_TN(0, val);
}

612
static inline void gen_movl_reg_TN(int reg, int t)
613
{
614
    if (reg)
B
blueswir1 已提交
615
        gen_op_movl_reg_TN[t][reg] ();
616
    else
B
blueswir1 已提交
617
        gen_movl_imm_TN(t, 0);
618 619
}

620
static inline void gen_movl_reg_T0(int reg)
621
{
622
    gen_movl_reg_TN(reg, 0);
623 624
}

625
static inline void gen_movl_reg_T1(int reg)
626
{
627
    gen_movl_reg_TN(reg, 1);
628 629
}

630
static inline void gen_movl_reg_T2(int reg)
631
{
632
    gen_movl_reg_TN(reg, 2);
633 634
}

635
static inline void gen_movl_TN_reg(int reg, int t)
636
{
637
    if (reg)
B
blueswir1 已提交
638
        gen_op_movl_TN_reg[t][reg] ();
639 640
}

641
static inline void gen_movl_T0_reg(int reg)
642
{
643
    gen_movl_TN_reg(reg, 0);
644 645
}

646
static inline void gen_movl_T1_reg(int reg)
647
{
648
    gen_movl_TN_reg(reg, 1);
649 650
}

B
bellard 已提交
651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676
static inline void gen_jmp_im(target_ulong pc)
{
#ifdef TARGET_SPARC64
    if (pc == (uint32_t)pc) {
        gen_op_jmp_im(pc);
    } else {
        gen_op_jmp_im64(pc >> 32, pc);
    }
#else
    gen_op_jmp_im(pc);
#endif
}

static inline void gen_movl_npc_im(target_ulong npc)
{
#ifdef TARGET_SPARC64
    if (npc == (uint32_t)npc) {
        gen_op_movl_npc_im(npc);
    } else {
        gen_op_movq_npc_im64(npc >> 32, npc);
    }
#else
    gen_op_movl_npc_im(npc);
#endif
}

677
static inline void gen_goto_tb(DisasContext *s, int tb_num,
678 679 680 681 682 683 684 685
                               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 已提交
686
        tcg_gen_goto_tb(tb_num);
687 688
        gen_jmp_im(pc);
        gen_movl_npc_im(npc);
B
bellard 已提交
689
        tcg_gen_exit_tb((long)tb + tb_num);
690 691 692 693
    } else {
        /* jump to another page: currently not optimized */
        gen_jmp_im(pc);
        gen_movl_npc_im(npc);
B
bellard 已提交
694
        tcg_gen_exit_tb(0);
695 696 697
    }
}

B
blueswir1 已提交
698 699
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
                               target_ulong pc2)
B
bellard 已提交
700 701 702 703 704 705 706
{
    int l1;

    l1 = gen_new_label();

    gen_op_jz_T2_label(l1);

707
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
B
bellard 已提交
708 709

    gen_set_label(l1);
710
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
B
bellard 已提交
711 712
}

B
blueswir1 已提交
713 714
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
                                target_ulong pc2)
B
bellard 已提交
715 716 717 718 719 720 721
{
    int l1;

    l1 = gen_new_label();

    gen_op_jz_T2_label(l1);

722
    gen_goto_tb(dc, 0, pc2, pc1);
B
bellard 已提交
723 724

    gen_set_label(l1);
725
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
B
bellard 已提交
726 727
}

B
blueswir1 已提交
728 729
static inline void gen_branch(DisasContext *dc, target_ulong pc,
                              target_ulong npc)
B
bellard 已提交
730
{
731
    gen_goto_tb(dc, 0, pc, npc);
B
bellard 已提交
732 733
}

B
blueswir1 已提交
734
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2)
B
bellard 已提交
735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753
{
    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 已提交
754
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
B
bellard 已提交
755 756 757 758
        dc->npc = DYNAMIC_PC;
    }
}

B
bellard 已提交
759 760 761
static inline void save_npc(DisasContext * dc)
{
    if (dc->npc == JUMP_PC) {
B
blueswir1 已提交
762
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
B
bellard 已提交
763 764
        dc->npc = DYNAMIC_PC;
    } else if (dc->npc != DYNAMIC_PC) {
B
bellard 已提交
765
        gen_movl_npc_im(dc->npc);
B
bellard 已提交
766 767 768 769 770
    }
}

static inline void save_state(DisasContext * dc)
{
B
bellard 已提交
771
    gen_jmp_im(dc->pc);
B
bellard 已提交
772 773 774
    save_npc(dc);
}

B
bellard 已提交
775 776 777
static inline void gen_mov_pc_npc(DisasContext * dc)
{
    if (dc->npc == JUMP_PC) {
B
blueswir1 已提交
778
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
B
bellard 已提交
779 780 781 782 783 784 785 786 787 788
        gen_op_mov_pc_npc();
        dc->pc = DYNAMIC_PC;
    } else if (dc->npc == DYNAMIC_PC) {
        gen_op_mov_pc_npc();
        dc->pc = DYNAMIC_PC;
    } else {
        dc->pc = dc->npc;
    }
}

B
bellard 已提交
789 790
static GenOpFunc * const gen_cond[2][16] = {
    {
B
blueswir1 已提交
791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806
        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 已提交
807 808 809
    },
    {
#ifdef TARGET_SPARC64
B
blueswir1 已提交
810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825
        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 已提交
826 827 828 829 830 831
#endif
    },
};

static GenOpFunc * const gen_fcond[4][16] = {
    {
B
blueswir1 已提交
832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847
        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 已提交
848 849 850
    },
#ifdef TARGET_SPARC64
    {
B
blueswir1 已提交
851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866
        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 已提交
867 868
    },
    {
B
blueswir1 已提交
869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884
        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 已提交
885 886
    },
    {
B
blueswir1 已提交
887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902
        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 已提交
903 904 905 906 907
    },
#else
    {}, {}, {},
#endif
};
908

B
bellard 已提交
909 910
#ifdef TARGET_SPARC64
static void gen_cond_reg(int cond)
911
{
B
blueswir1 已提交
912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927
        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;
928
        default:
B
blueswir1 已提交
929 930 931 932
        case 0x7:
            gen_op_eval_brgez();
            break;
        }
933
}
B
bellard 已提交
934
#endif
935

B
bellard 已提交
936
/* XXX: potentially incorrect if dynamic npc */
B
bellard 已提交
937
static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
938
{
939
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
940
    target_ulong target = dc->pc + offset;
941

942
    if (cond == 0x0) {
B
blueswir1 已提交
943 944 945 946 947 948 949 950
        /* 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;
        }
951
    } else if (cond == 0x8) {
B
blueswir1 已提交
952 953 954 955 956 957 958 959
        /* unconditional taken */
        if (a) {
            dc->pc = target;
            dc->npc = dc->pc + 4;
        } else {
            dc->pc = dc->npc;
            dc->npc = target;
        }
960
    } else {
B
bellard 已提交
961
        flush_T2(dc);
B
bellard 已提交
962
        gen_cond[cc][cond]();
B
blueswir1 已提交
963 964
        if (a) {
            gen_branch_a(dc, target, dc->npc);
965
            dc->is_br = 1;
B
blueswir1 已提交
966
        } else {
967
            dc->pc = dc->npc;
B
bellard 已提交
968 969 970
            dc->jump_pc[0] = target;
            dc->jump_pc[1] = dc->npc + 4;
            dc->npc = JUMP_PC;
B
blueswir1 已提交
971
        }
972
    }
973 974
}

B
bellard 已提交
975
/* XXX: potentially incorrect if dynamic npc */
B
bellard 已提交
976
static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
977 978
{
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
979 980
    target_ulong target = dc->pc + offset;

981
    if (cond == 0x0) {
B
blueswir1 已提交
982 983 984 985 986 987 988 989
        /* 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;
        }
990
    } else if (cond == 0x8) {
B
blueswir1 已提交
991 992 993 994 995 996 997 998
        /* unconditional taken */
        if (a) {
            dc->pc = target;
            dc->npc = dc->pc + 4;
        } else {
            dc->pc = dc->npc;
            dc->npc = target;
        }
999 1000
    } else {
        flush_T2(dc);
B
bellard 已提交
1001
        gen_fcond[cc][cond]();
B
blueswir1 已提交
1002 1003
        if (a) {
            gen_branch_a(dc, target, dc->npc);
1004
            dc->is_br = 1;
B
blueswir1 已提交
1005
        } else {
1006 1007 1008 1009
            dc->pc = dc->npc;
            dc->jump_pc[0] = target;
            dc->jump_pc[1] = dc->npc + 4;
            dc->npc = JUMP_PC;
B
blueswir1 已提交
1010
        }
1011 1012 1013
    }
}

B
bellard 已提交
1014 1015 1016
#ifdef TARGET_SPARC64
/* XXX: potentially incorrect if dynamic npc */
static void do_branch_reg(DisasContext * dc, int32_t offset, uint32_t insn)
1017
{
B
bellard 已提交
1018 1019 1020 1021 1022 1023
    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 已提交
1024 1025
        gen_branch_a(dc, target, dc->npc);
        dc->is_br = 1;
B
bellard 已提交
1026
    } else {
B
blueswir1 已提交
1027 1028 1029 1030
        dc->pc = dc->npc;
        dc->jump_pc[0] = target;
        dc->jump_pc[1] = dc->npc + 4;
        dc->npc = JUMP_PC;
B
bellard 已提交
1031
    }
1032 1033
}

B
bellard 已提交
1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046
static GenOpFunc * const gen_fcmps[4] = {
    gen_op_fcmps,
    gen_op_fcmps_fcc1,
    gen_op_fcmps_fcc2,
    gen_op_fcmps_fcc3,
};

static GenOpFunc * const gen_fcmpd[4] = {
    gen_op_fcmpd,
    gen_op_fcmpd_fcc1,
    gen_op_fcmpd_fcc2,
    gen_op_fcmpd_fcc3,
};
1047

B
blueswir1 已提交
1048 1049 1050 1051 1052 1053 1054 1055 1056
#if defined(CONFIG_USER_ONLY)
static GenOpFunc * const gen_fcmpq[4] = {
    gen_op_fcmpq,
    gen_op_fcmpq_fcc1,
    gen_op_fcmpq_fcc2,
    gen_op_fcmpq_fcc3,
};
#endif

1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070
static GenOpFunc * const gen_fcmpes[4] = {
    gen_op_fcmpes,
    gen_op_fcmpes_fcc1,
    gen_op_fcmpes_fcc2,
    gen_op_fcmpes_fcc3,
};

static GenOpFunc * const gen_fcmped[4] = {
    gen_op_fcmped,
    gen_op_fcmped_fcc1,
    gen_op_fcmped_fcc2,
    gen_op_fcmped_fcc3,
};

B
blueswir1 已提交
1071 1072 1073 1074 1075 1076 1077 1078
#if defined(CONFIG_USER_ONLY)
static GenOpFunc * const gen_fcmpeq[4] = {
    gen_op_fcmpeq,
    gen_op_fcmpeq_fcc1,
    gen_op_fcmpeq_fcc2,
    gen_op_fcmpeq_fcc3,
};
#endif
B
bellard 已提交
1079 1080
#endif

B
bellard 已提交
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093
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;
}

B
bellard 已提交
1094
/* before an instruction, dc->pc must be static */
1095 1096 1097
static void disas_sparc_insn(DisasContext * dc)
{
    unsigned int insn, opc, rs1, rs2, rd;
1098

B
bellard 已提交
1099
    insn = ldl_code(dc->pc);
1100
    opc = GET_FIELD(insn, 0, 1);
1101

1102 1103
    rd = GET_FIELD(insn, 2, 6);
    switch (opc) {
B
blueswir1 已提交
1104 1105 1106 1107 1108
    case 0:                     /* branches/sethi */
        {
            unsigned int xop = GET_FIELD(insn, 7, 9);
            int32_t target;
            switch (xop) {
B
bellard 已提交
1109
#ifdef TARGET_SPARC64
B
blueswir1 已提交
1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128
            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) |
1129
                        (GET_FIELD_SP(insn, 20, 21) << 14);
B
blueswir1 已提交
1130 1131 1132 1133 1134 1135 1136 1137 1138 1139
                    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 已提交
1140 1141
                    if (gen_trap_ifnofpu(dc))
                        goto jmp_insn;
B
blueswir1 已提交
1142 1143 1144 1145 1146 1147
                    target = GET_FIELD_SP(insn, 0, 18);
                    target = sign_extend(target, 19);
                    target <<= 2;
                    do_fbranch(dc, target, insn, cc);
                    goto jmp_insn;
                }
1148
#else
B
blueswir1 已提交
1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163
            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 已提交
1164 1165
                    if (gen_trap_ifnofpu(dc))
                        goto jmp_insn;
B
blueswir1 已提交
1166 1167 1168 1169 1170 1171 1172
                    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 已提交
1173 1174
#define OPTIM
#if defined(OPTIM)
B
blueswir1 已提交
1175
                if (rd) { // nop
B
bellard 已提交
1176
#endif
B
blueswir1 已提交
1177 1178 1179
                    uint32_t value = GET_FIELD(insn, 10, 31);
                    gen_movl_imm_T0(value << 10);
                    gen_movl_T0_reg(rd);
B
bellard 已提交
1180
#if defined(OPTIM)
B
blueswir1 已提交
1181
                }
B
bellard 已提交
1182
#endif
B
blueswir1 已提交
1183 1184 1185
                break;
            case 0x0:           /* UNIMPL */
            default:
B
bellard 已提交
1186
                goto illegal_insn;
B
blueswir1 已提交
1187 1188 1189 1190
            }
            break;
        }
        break;
1191
    case 1:
B
blueswir1 已提交
1192 1193
        /*CALL*/ {
            target_long target = GET_FIELDs(insn, 2, 31) << 2;
1194

B
bellard 已提交
1195
#ifdef TARGET_SPARC64
B
blueswir1 已提交
1196 1197 1198 1199 1200
            if (dc->pc == (uint32_t)dc->pc) {
                gen_op_movl_T0_im(dc->pc);
            } else {
                gen_op_movq_T0_im64(dc->pc >> 32, dc->pc);
            }
B
bellard 已提交
1201
#else
B
blueswir1 已提交
1202
            gen_op_movl_T0_im(dc->pc);
B
bellard 已提交
1203
#endif
B
blueswir1 已提交
1204 1205
            gen_movl_T0_reg(15);
            target += dc->pc;
B
bellard 已提交
1206
            gen_mov_pc_npc(dc);
B
blueswir1 已提交
1207 1208 1209 1210 1211 1212 1213
            dc->npc = target;
        }
        goto jmp_insn;
    case 2:                     /* FPU & Logical Operations */
        {
            unsigned int xop = GET_FIELD(insn, 7, 12);
            if (xop == 0x3a) {  /* generate trap */
1214
                int cond;
B
bellard 已提交
1215

1216 1217
                rs1 = GET_FIELD(insn, 13, 17);
                gen_movl_reg_T0(rs1);
B
blueswir1 已提交
1218 1219
                if (IS_IMM) {
                    rs2 = GET_FIELD(insn, 25, 31);
B
bellard 已提交
1220
#if defined(OPTIM)
B
blueswir1 已提交
1221
                    if (rs2 != 0) {
B
bellard 已提交
1222
#endif
B
blueswir1 已提交
1223 1224
                        gen_movl_simm_T1(rs2);
                        gen_op_add_T1_T0();
B
bellard 已提交
1225
#if defined(OPTIM)
B
blueswir1 已提交
1226
                    }
B
bellard 已提交
1227
#endif
1228 1229
                } else {
                    rs2 = GET_FIELD(insn, 27, 31);
B
bellard 已提交
1230
#if defined(OPTIM)
B
blueswir1 已提交
1231
                    if (rs2 != 0) {
B
bellard 已提交
1232
#endif
B
blueswir1 已提交
1233 1234
                        gen_movl_reg_T1(rs2);
                        gen_op_add_T1_T0();
B
bellard 已提交
1235
#if defined(OPTIM)
B
blueswir1 已提交
1236
                    }
B
bellard 已提交
1237
#endif
1238 1239 1240
                }
                cond = GET_FIELD(insn, 3, 6);
                if (cond == 0x8) {
B
bellard 已提交
1241
                    save_state(dc);
1242
                    gen_op_trap_T0();
1243
                } else if (cond != 0) {
B
bellard 已提交
1244
#ifdef TARGET_SPARC64
B
blueswir1 已提交
1245 1246 1247
                    /* V9 icc/xcc */
                    int cc = GET_FIELD_SP(insn, 11, 12);
                    flush_T2(dc);
B
bellard 已提交
1248
                    save_state(dc);
B
blueswir1 已提交
1249 1250 1251 1252 1253 1254
                    if (cc == 0)
                        gen_cond[0][cond]();
                    else if (cc == 2)
                        gen_cond[1][cond]();
                    else
                        goto illegal_insn;
B
bellard 已提交
1255
#else
B
blueswir1 已提交
1256
                    flush_T2(dc);
B
bellard 已提交
1257
                    save_state(dc);
B
blueswir1 已提交
1258
                    gen_cond[0][cond]();
B
bellard 已提交
1259
#endif
1260 1261
                    gen_op_trapcc_T0();
                }
B
bellard 已提交
1262
                gen_op_next_insn();
B
bellard 已提交
1263
                tcg_gen_exit_tb(0);
B
bellard 已提交
1264 1265
                dc->is_br = 1;
                goto jmp_insn;
1266 1267 1268 1269
            } else if (xop == 0x28) {
                rs1 = GET_FIELD(insn, 13, 17);
                switch(rs1) {
                case 0: /* rdy */
1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280
#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));
1281 1282
                    gen_movl_T0_reg(rd);
                    break;
B
bellard 已提交
1283
#ifdef TARGET_SPARC64
B
blueswir1 已提交
1284
                case 0x2: /* V9 rdccr */
B
bellard 已提交
1285 1286 1287
                    gen_op_rdccr();
                    gen_movl_T0_reg(rd);
                    break;
B
blueswir1 已提交
1288 1289
                case 0x3: /* V9 rdasi */
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, asi));
B
bellard 已提交
1290 1291
                    gen_movl_T0_reg(rd);
                    break;
B
blueswir1 已提交
1292
                case 0x4: /* V9 rdtick */
B
bellard 已提交
1293 1294 1295
                    gen_op_rdtick();
                    gen_movl_T0_reg(rd);
                    break;
B
blueswir1 已提交
1296 1297 1298 1299 1300 1301 1302 1303 1304 1305
                case 0x5: /* V9 rdpc */
                    if (dc->pc == (uint32_t)dc->pc) {
                        gen_op_movl_T0_im(dc->pc);
                    } else {
                        gen_op_movq_T0_im64(dc->pc >> 32, dc->pc);
                    }
                    gen_movl_T0_reg(rd);
                    break;
                case 0x6: /* V9 rdfprs */
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, fprs));
B
bellard 已提交
1306 1307
                    gen_movl_T0_reg(rd);
                    break;
1308 1309
                case 0xf: /* V9 membar */
                    break; /* no effect */
B
blueswir1 已提交
1310
                case 0x13: /* Graphics Status */
B
bellard 已提交
1311 1312
                    if (gen_trap_ifnofpu(dc))
                        goto jmp_insn;
B
blueswir1 已提交
1313
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, gsr));
B
bellard 已提交
1314 1315
                    gen_movl_T0_reg(rd);
                    break;
B
blueswir1 已提交
1316 1317
                case 0x17: /* Tick compare */
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, tick_cmpr));
B
bellard 已提交
1318 1319
                    gen_movl_T0_reg(rd);
                    break;
B
blueswir1 已提交
1320
                case 0x18: /* System tick */
1321
                    gen_op_rdstick();
B
bellard 已提交
1322 1323
                    gen_movl_T0_reg(rd);
                    break;
B
blueswir1 已提交
1324 1325
                case 0x19: /* System tick compare */
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, stick_cmpr));
B
bellard 已提交
1326 1327
                    gen_movl_T0_reg(rd);
                    break;
B
blueswir1 已提交
1328 1329 1330 1331 1332 1333
                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 已提交
1334 1335
#endif
                default:
1336 1337
                    goto illegal_insn;
                }
1338
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
1339
            } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
B
bellard 已提交
1340
#ifndef TARGET_SPARC64
B
blueswir1 已提交
1341 1342
                if (!supervisor(dc))
                    goto priv_insn;
1343
                gen_op_rdpsr();
B
blueswir1 已提交
1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370
#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
1371 1372
                gen_movl_T0_reg(rd);
                break;
B
bellard 已提交
1373
            } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
B
blueswir1 已提交
1374 1375
                if (!supervisor(dc))
                    goto priv_insn;
B
bellard 已提交
1376 1377
#ifdef TARGET_SPARC64
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423
                switch (rs1) {
                case 0: // tpc
                    gen_op_rdtpc();
                    break;
                case 1: // tnpc
                    gen_op_rdtnpc();
                    break;
                case 2: // tstate
                    gen_op_rdtstate();
                    break;
                case 3: // tt
                    gen_op_rdtt();
                    break;
                case 4: // tick
                    gen_op_rdtick();
                    break;
                case 5: // tba
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
                    break;
                case 6: // pstate
                    gen_op_rdpstate();
                    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 已提交
1424 1425 1426 1427 1428 1429 1430 1431
                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 已提交
1432 1433 1434 1435 1436 1437 1438
                case 31: // ver
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, version));
                    break;
                case 15: // fq
                default:
                    goto illegal_insn;
                }
B
bellard 已提交
1439
#else
B
blueswir1 已提交
1440
                gen_op_movl_T0_env(offsetof(CPUSPARCState, wim));
B
bellard 已提交
1441
#endif
1442 1443
                gen_movl_T0_reg(rd);
                break;
B
bellard 已提交
1444 1445
            } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
#ifdef TARGET_SPARC64
B
blueswir1 已提交
1446
                gen_op_flushw();
B
bellard 已提交
1447
#else
B
blueswir1 已提交
1448 1449 1450
                if (!supervisor(dc))
                    goto priv_insn;
                gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
1451
                gen_movl_T0_reg(rd);
B
bellard 已提交
1452
#endif
1453 1454
                break;
#endif
B
blueswir1 已提交
1455
            } else if (xop == 0x34) {   /* FPU Operations */
B
bellard 已提交
1456 1457
                if (gen_trap_ifnofpu(dc))
                    goto jmp_insn;
B
blueswir1 已提交
1458
                gen_op_clear_ieee_excp_and_FTT();
1459
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487
                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);
                        gen_op_fabss();
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x29: /* fsqrts */
                        gen_op_load_fpr_FT1(rs2);
                        gen_op_fsqrts();
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x2a: /* fsqrtd */
                        gen_op_load_fpr_DT1(DFPREG(rs2));
                        gen_op_fsqrtd();
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x2b: /* fsqrtq */
B
blueswir1 已提交
1488 1489 1490 1491 1492 1493
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT1(QFPREG(rs2));
                        gen_op_fsqrtq();
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
B
blueswir1 已提交
1494
                        goto nfpu_insn;
B
blueswir1 已提交
1495
#endif
B
blueswir1 已提交
1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508
                    case 0x41:
                        gen_op_load_fpr_FT0(rs1);
                        gen_op_load_fpr_FT1(rs2);
                        gen_op_fadds();
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x42:
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
                        gen_op_faddd();
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x43: /* faddq */
B
blueswir1 已提交
1509 1510 1511 1512 1513 1514 1515
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
                        gen_op_faddq();
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
B
blueswir1 已提交
1516
                        goto nfpu_insn;
B
blueswir1 已提交
1517
#endif
B
blueswir1 已提交
1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530
                    case 0x45:
                        gen_op_load_fpr_FT0(rs1);
                        gen_op_load_fpr_FT1(rs2);
                        gen_op_fsubs();
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x46:
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
                        gen_op_fsubd();
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x47: /* fsubq */
B
blueswir1 已提交
1531 1532 1533 1534 1535 1536 1537
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
                        gen_op_fsubq();
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
B
blueswir1 已提交
1538
                        goto nfpu_insn;
B
blueswir1 已提交
1539
#endif
B
blueswir1 已提交
1540 1541 1542 1543 1544 1545 1546 1547 1548 1549
                    case 0x49:
                        gen_op_load_fpr_FT0(rs1);
                        gen_op_load_fpr_FT1(rs2);
                        gen_op_fmuls();
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x4a:
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
                        gen_op_fmuld();
1550
                        gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
1551 1552
                        break;
                    case 0x4b: /* fmulq */
B
blueswir1 已提交
1553 1554 1555 1556 1557 1558 1559
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
                        gen_op_fmulq();
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
B
blueswir1 已提交
1560
                        goto nfpu_insn;
B
blueswir1 已提交
1561
#endif
B
blueswir1 已提交
1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574
                    case 0x4d:
                        gen_op_load_fpr_FT0(rs1);
                        gen_op_load_fpr_FT1(rs2);
                        gen_op_fdivs();
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x4e:
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
                        gen_op_fdivd();
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x4f: /* fdivq */
B
blueswir1 已提交
1575 1576 1577 1578 1579 1580 1581
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
                        gen_op_fdivq();
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
B
blueswir1 已提交
1582
                        goto nfpu_insn;
B
blueswir1 已提交
1583
#endif
B
blueswir1 已提交
1584 1585 1586 1587 1588 1589 1590
                    case 0x69:
                        gen_op_load_fpr_FT0(rs1);
                        gen_op_load_fpr_FT1(rs2);
                        gen_op_fsmuld();
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x6e: /* fdmulq */
B
blueswir1 已提交
1591 1592 1593 1594 1595 1596 1597
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
                        gen_op_fdmulq();
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
B
blueswir1 已提交
1598
                        goto nfpu_insn;
B
blueswir1 已提交
1599
#endif
B
blueswir1 已提交
1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610
                    case 0xc4:
                        gen_op_load_fpr_FT1(rs2);
                        gen_op_fitos();
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0xc6:
                        gen_op_load_fpr_DT1(DFPREG(rs2));
                        gen_op_fdtos();
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0xc7: /* fqtos */
B
blueswir1 已提交
1611 1612 1613 1614 1615 1616
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT1(QFPREG(rs2));
                        gen_op_fqtos();
                        gen_op_store_FT0_fpr(rd);
                        break;
#else
B
blueswir1 已提交
1617
                        goto nfpu_insn;
B
blueswir1 已提交
1618
#endif
B
blueswir1 已提交
1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629
                    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 已提交
1630 1631 1632 1633 1634 1635
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT1(QFPREG(rs2));
                        gen_op_fqtod();
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
#else
B
blueswir1 已提交
1636
                        goto nfpu_insn;
B
blueswir1 已提交
1637
#endif
B
blueswir1 已提交
1638
                    case 0xcc: /* fitoq */
B
blueswir1 已提交
1639 1640 1641 1642 1643 1644
#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 已提交
1645
                        goto nfpu_insn;
B
blueswir1 已提交
1646
#endif
B
blueswir1 已提交
1647
                    case 0xcd: /* fstoq */
B
blueswir1 已提交
1648 1649 1650 1651 1652 1653
#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 已提交
1654
                        goto nfpu_insn;
B
blueswir1 已提交
1655
#endif
B
blueswir1 已提交
1656
                    case 0xce: /* fdtoq */
B
blueswir1 已提交
1657 1658 1659 1660 1661 1662
#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 已提交
1663
                        goto nfpu_insn;
B
blueswir1 已提交
1664
#endif
B
blueswir1 已提交
1665 1666 1667 1668 1669 1670
                    case 0xd1:
                        gen_op_load_fpr_FT1(rs2);
                        gen_op_fstoi();
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0xd2:
1671
                        gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
1672 1673 1674 1675
                        gen_op_fdtoi();
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0xd3: /* fqtoi */
B
blueswir1 已提交
1676 1677 1678 1679 1680 1681
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT1(QFPREG(rs2));
                        gen_op_fqtoi();
                        gen_op_store_FT0_fpr(rd);
                        break;
#else
B
blueswir1 已提交
1682
                        goto nfpu_insn;
B
blueswir1 已提交
1683
#endif
B
bellard 已提交
1684
#ifdef TARGET_SPARC64
B
blueswir1 已提交
1685 1686 1687 1688
                    case 0x2: /* V9 fmovd */
                        gen_op_load_fpr_DT0(DFPREG(rs2));
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
B
blueswir1 已提交
1689 1690 1691 1692 1693 1694 1695 1696
                    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 已提交
1697 1698 1699 1700 1701
                    case 0x6: /* V9 fnegd */
                        gen_op_load_fpr_DT1(DFPREG(rs2));
                        gen_op_fnegd();
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
B
blueswir1 已提交
1702 1703 1704 1705 1706 1707 1708 1709 1710
                    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 已提交
1711 1712 1713 1714 1715
                    case 0xa: /* V9 fabsd */
                        gen_op_load_fpr_DT1(DFPREG(rs2));
                        gen_op_fabsd();
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
B
blueswir1 已提交
1716 1717 1718 1719 1720 1721 1722 1723 1724
                    case 0xb: /* V9 fabsq */
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT1(QFPREG(rs2));
                        gen_op_fabsq();
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
                        goto nfpu_insn;
#endif
B
blueswir1 已提交
1725 1726 1727 1728 1729 1730 1731 1732 1733 1734
                    case 0x81: /* V9 fstox */
                        gen_op_load_fpr_FT1(rs2);
                        gen_op_fstox();
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x82: /* V9 fdtox */
                        gen_op_load_fpr_DT1(DFPREG(rs2));
                        gen_op_fdtox();
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
B
blueswir1 已提交
1735 1736 1737 1738 1739 1740 1741 1742 1743
                    case 0x83: /* V9 fqtox */
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT1(QFPREG(rs2));
                        gen_op_fqtox();
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
#else
                        goto nfpu_insn;
#endif
B
blueswir1 已提交
1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754
                    case 0x84: /* V9 fxtos */
                        gen_op_load_fpr_DT1(DFPREG(rs2));
                        gen_op_fxtos();
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x88: /* V9 fxtod */
                        gen_op_load_fpr_DT1(DFPREG(rs2));
                        gen_op_fxtod();
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x8c: /* V9 fxtoq */
B
blueswir1 已提交
1755 1756 1757 1758 1759 1760
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_DT1(DFPREG(rs2));
                        gen_op_fxtoq();
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#else
B
blueswir1 已提交
1761
                        goto nfpu_insn;
B
blueswir1 已提交
1762
#endif
B
blueswir1 已提交
1763 1764 1765 1766 1767
#endif
                    default:
                        goto illegal_insn;
                }
            } else if (xop == 0x35) {   /* FPU Operations */
B
bellard 已提交
1768
#ifdef TARGET_SPARC64
B
blueswir1 已提交
1769
                int cond;
B
bellard 已提交
1770
#endif
B
bellard 已提交
1771 1772
                if (gen_trap_ifnofpu(dc))
                    goto jmp_insn;
B
blueswir1 已提交
1773
                gen_op_clear_ieee_excp_and_FTT();
1774
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
1775 1776
                rs2 = GET_FIELD(insn, 27, 31);
                xop = GET_FIELD(insn, 18, 26);
B
bellard 已提交
1777
#ifdef TARGET_SPARC64
B
blueswir1 已提交
1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790
                if ((xop & 0x11f) == 0x005) { // V9 fmovsr
                    cond = GET_FIELD_SP(insn, 14, 17);
                    gen_op_load_fpr_FT0(rd);
                    gen_op_load_fpr_FT1(rs2);
                    rs1 = GET_FIELD(insn, 13, 17);
                    gen_movl_reg_T0(rs1);
                    flush_T2(dc);
                    gen_cond_reg(cond);
                    gen_op_fmovs_cc();
                    gen_op_store_FT0_fpr(rd);
                    break;
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
                    cond = GET_FIELD_SP(insn, 14, 17);
1791 1792
                    gen_op_load_fpr_DT0(DFPREG(rd));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
1793 1794 1795 1796 1797
                    flush_T2(dc);
                    rs1 = GET_FIELD(insn, 13, 17);
                    gen_movl_reg_T0(rs1);
                    gen_cond_reg(cond);
                    gen_op_fmovs_cc();
1798
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
1799 1800
                    break;
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
B
blueswir1 已提交
1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812
#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);
                    rs1 = GET_FIELD(insn, 13, 17);
                    gen_movl_reg_T0(rs1);
                    gen_cond_reg(cond);
                    gen_op_fmovq_cc();
                    gen_op_store_QT0_fpr(QFPREG(rd));
                    break;
#else
B
blueswir1 已提交
1813
                    goto nfpu_insn;
B
blueswir1 已提交
1814
#endif
B
blueswir1 已提交
1815 1816 1817
                }
#endif
                switch (xop) {
B
bellard 已提交
1818
#ifdef TARGET_SPARC64
B
blueswir1 已提交
1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829
                    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);
1830 1831
                        gen_op_load_fpr_DT0(DFPREG(rd));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
1832 1833 1834
                        flush_T2(dc);
                        gen_fcond[0][cond]();
                        gen_op_fmovd_cc();
1835
                        gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
1836 1837
                        break;
                    case 0x003: /* V9 fmovqcc %fcc0 */
B
blueswir1 已提交
1838 1839 1840 1841 1842 1843 1844 1845 1846 1847
#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 已提交
1848
                        goto nfpu_insn;
B
blueswir1 已提交
1849
#endif
B
blueswir1 已提交
1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860
                    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);
1861 1862
                        gen_op_load_fpr_DT0(DFPREG(rd));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
1863 1864 1865
                        flush_T2(dc);
                        gen_fcond[1][cond]();
                        gen_op_fmovd_cc();
1866
                        gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
1867 1868
                        break;
                    case 0x043: /* V9 fmovqcc %fcc1 */
B
blueswir1 已提交
1869 1870 1871 1872 1873 1874 1875 1876 1877 1878
#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 已提交
1879
                        goto nfpu_insn;
B
blueswir1 已提交
1880
#endif
B
blueswir1 已提交
1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891
                    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);
1892 1893
                        gen_op_load_fpr_DT0(DFPREG(rd));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
1894 1895 1896
                        flush_T2(dc);
                        gen_fcond[2][cond]();
                        gen_op_fmovd_cc();
1897
                        gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
1898 1899
                        break;
                    case 0x083: /* V9 fmovqcc %fcc2 */
B
blueswir1 已提交
1900 1901 1902 1903 1904 1905 1906 1907 1908 1909
#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 已提交
1910
                        goto nfpu_insn;
B
blueswir1 已提交
1911
#endif
B
blueswir1 已提交
1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922
                    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);
1923 1924
                        gen_op_load_fpr_DT0(DFPREG(rd));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
1925 1926 1927
                        flush_T2(dc);
                        gen_fcond[3][cond]();
                        gen_op_fmovd_cc();
1928
                        gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
1929 1930
                        break;
                    case 0x0c3: /* V9 fmovqcc %fcc3 */
B
blueswir1 已提交
1931 1932 1933 1934 1935 1936 1937 1938 1939 1940
#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 已提交
1941
                        goto nfpu_insn;
B
blueswir1 已提交
1942
#endif
B
blueswir1 已提交
1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953
                    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);
1954 1955
                        gen_op_load_fpr_DT0(DFPREG(rd));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
1956 1957 1958
                        flush_T2(dc);
                        gen_cond[0][cond]();
                        gen_op_fmovd_cc();
1959
                        gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
1960 1961
                        break;
                    case 0x103: /* V9 fmovqcc %icc */
B
blueswir1 已提交
1962 1963 1964 1965 1966 1967 1968 1969 1970 1971
#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 已提交
1972
                        goto nfpu_insn;
B
blueswir1 已提交
1973
#endif
B
blueswir1 已提交
1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984
                    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);
1985 1986
                        gen_op_load_fpr_DT0(DFPREG(rd));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
1987 1988 1989
                        flush_T2(dc);
                        gen_cond[1][cond]();
                        gen_op_fmovd_cc();
1990
                        gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
1991 1992
                        break;
                    case 0x183: /* V9 fmovqcc %xcc */
B
blueswir1 已提交
1993 1994 1995 1996 1997 1998 1999 2000 2001 2002
#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 已提交
2003 2004
                        goto nfpu_insn;
#endif
B
blueswir1 已提交
2005 2006
#endif
                    case 0x51: /* fcmps, V9 %fcc */
B
blueswir1 已提交
2007 2008
                        gen_op_load_fpr_FT0(rs1);
                        gen_op_load_fpr_FT1(rs2);
B
bellard 已提交
2009
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2010
                        gen_fcmps[rd & 3]();
B
bellard 已提交
2011
#else
B
blueswir1 已提交
2012
                        gen_op_fcmps();
B
bellard 已提交
2013
#endif
B
blueswir1 已提交
2014
                        break;
B
blueswir1 已提交
2015
                    case 0x52: /* fcmpd, V9 %fcc */
B
blueswir1 已提交
2016 2017
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
B
bellard 已提交
2018
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2019
                        gen_fcmpd[rd & 3]();
B
bellard 已提交
2020
#else
B
blueswir1 已提交
2021 2022 2023
                        gen_op_fcmpd();
#endif
                        break;
B
blueswir1 已提交
2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034
                    case 0x53: /* fcmpq, V9 %fcc */
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
#ifdef TARGET_SPARC64
                        gen_fcmpq[rd & 3]();
#else
                        gen_op_fcmpq();
#endif
                        break;
#else /* !defined(CONFIG_USER_ONLY) */
B
blueswir1 已提交
2035
                        goto nfpu_insn;
B
blueswir1 已提交
2036
#endif
B
blueswir1 已提交
2037 2038 2039
                    case 0x55: /* fcmpes, V9 %fcc */
                        gen_op_load_fpr_FT0(rs1);
                        gen_op_load_fpr_FT1(rs2);
B
bellard 已提交
2040
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2041
                        gen_fcmpes[rd & 3]();
B
bellard 已提交
2042
#else
B
blueswir1 已提交
2043
                        gen_op_fcmpes();
B
bellard 已提交
2044
#endif
B
blueswir1 已提交
2045 2046 2047 2048
                        break;
                    case 0x56: /* fcmped, V9 %fcc */
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
B
bellard 已提交
2049
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2050
                        gen_fcmped[rd & 3]();
B
bellard 已提交
2051
#else
B
blueswir1 已提交
2052 2053 2054
                        gen_op_fcmped();
#endif
                        break;
B
blueswir1 已提交
2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065
                    case 0x57: /* fcmpeq, V9 %fcc */
#if defined(CONFIG_USER_ONLY)
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
#ifdef TARGET_SPARC64
                        gen_fcmpeq[rd & 3]();
#else
                        gen_op_fcmpeq();
#endif
                        break;
#else/* !defined(CONFIG_USER_ONLY) */
B
blueswir1 已提交
2066
                        goto nfpu_insn;
B
blueswir1 已提交
2067
#endif
B
blueswir1 已提交
2068 2069 2070
                    default:
                        goto illegal_insn;
                }
B
bellard 已提交
2071
#if defined(OPTIM)
B
blueswir1 已提交
2072 2073
            } else if (xop == 0x2) {
                // clr/mov shortcut
B
bellard 已提交
2074 2075

                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104
                if (rs1 == 0) {
                    // or %g0, x, y -> mov T1, x; mov y, T1
                    if (IS_IMM) {       /* immediate */
                        rs2 = GET_FIELDs(insn, 19, 31);
                        gen_movl_simm_T1(rs2);
                    } else {            /* register */
                        rs2 = GET_FIELD(insn, 27, 31);
                        gen_movl_reg_T1(rs2);
                    }
                    gen_movl_T1_reg(rd);
                } else {
                    gen_movl_reg_T0(rs1);
                    if (IS_IMM) {       /* immediate */
                        // or x, #0, y -> mov T1, x; mov y, T1
                        rs2 = GET_FIELDs(insn, 19, 31);
                        if (rs2 != 0) {
                            gen_movl_simm_T1(rs2);
                            gen_op_or_T1_T0();
                        }
                    } 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();
                        }
                    }
                    gen_movl_T0_reg(rd);
                }
B
bellard 已提交
2105 2106
#endif
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2107
            } else if (xop == 0x25) { /* sll, V9 sllx */
B
bellard 已提交
2108
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
2109 2110
                gen_movl_reg_T0(rs1);
                if (IS_IMM) {   /* immediate */
B
bellard 已提交
2111 2112
                    rs2 = GET_FIELDs(insn, 20, 31);
                    gen_movl_simm_T1(rs2);
B
blueswir1 已提交
2113
                } else {                /* register */
B
bellard 已提交
2114 2115 2116
                    rs2 = GET_FIELD(insn, 27, 31);
                    gen_movl_reg_T1(rs2);
                }
B
blueswir1 已提交
2117 2118 2119 2120 2121 2122
                if (insn & (1 << 12))
                    gen_op_sllx();
                else
                    gen_op_sll();
                gen_movl_T0_reg(rd);
            } else if (xop == 0x26) { /* srl, V9 srlx */
B
bellard 已提交
2123
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
2124 2125
                gen_movl_reg_T0(rs1);
                if (IS_IMM) {   /* immediate */
B
bellard 已提交
2126 2127
                    rs2 = GET_FIELDs(insn, 20, 31);
                    gen_movl_simm_T1(rs2);
B
blueswir1 已提交
2128
                } else {                /* register */
B
bellard 已提交
2129 2130 2131
                    rs2 = GET_FIELD(insn, 27, 31);
                    gen_movl_reg_T1(rs2);
                }
B
blueswir1 已提交
2132 2133 2134 2135 2136 2137
                if (insn & (1 << 12))
                    gen_op_srlx();
                else
                    gen_op_srl();
                gen_movl_T0_reg(rd);
            } else if (xop == 0x27) { /* sra, V9 srax */
B
bellard 已提交
2138
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
2139 2140
                gen_movl_reg_T0(rs1);
                if (IS_IMM) {   /* immediate */
B
bellard 已提交
2141 2142
                    rs2 = GET_FIELDs(insn, 20, 31);
                    gen_movl_simm_T1(rs2);
B
blueswir1 已提交
2143
                } else {                /* register */
B
bellard 已提交
2144 2145 2146
                    rs2 = GET_FIELD(insn, 27, 31);
                    gen_movl_reg_T1(rs2);
                }
B
blueswir1 已提交
2147 2148 2149 2150 2151
                if (insn & (1 << 12))
                    gen_op_srax();
                else
                    gen_op_sra();
                gen_movl_T0_reg(rd);
B
bellard 已提交
2152
#endif
2153
            } else if (xop < 0x36) {
B
bellard 已提交
2154
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
2155 2156
                gen_movl_reg_T0(rs1);
                if (IS_IMM) {   /* immediate */
2157
                    rs2 = GET_FIELDs(insn, 19, 31);
B
bellard 已提交
2158
                    gen_movl_simm_T1(rs2);
B
blueswir1 已提交
2159
                } else {                /* register */
2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176
                    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:
                        gen_op_and_T1_T0();
                        if (xop & 0x10)
                            gen_op_logic_T0_cc();
                        break;
                    case 0x2:
B
blueswir1 已提交
2177 2178 2179 2180
                        gen_op_or_T1_T0();
                        if (xop & 0x10)
                            gen_op_logic_T0_cc();
                        break;
2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208
                    case 0x3:
                        gen_op_xor_T1_T0();
                        if (xop & 0x10)
                            gen_op_logic_T0_cc();
                        break;
                    case 0x4:
                        if (xop & 0x10)
                            gen_op_sub_T1_T0_cc();
                        else
                            gen_op_sub_T1_T0();
                        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)
2209 2210 2211
                            gen_op_addx_T1_T0_cc();
                        else
                            gen_op_addx_T1_T0();
2212
                        break;
P
pbrook 已提交
2213
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2214
                    case 0x9: /* V9 mulx */
P
pbrook 已提交
2215 2216 2217
                        gen_op_mulx_T1_T0();
                        break;
#endif
2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229
                    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)
2230 2231 2232
                            gen_op_subx_T1_T0_cc();
                        else
                            gen_op_subx_T1_T0();
2233
                        break;
P
pbrook 已提交
2234
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2235
                    case 0xd: /* V9 udivx */
P
pbrook 已提交
2236 2237 2238
                        gen_op_udivx_T1_T0();
                        break;
#endif
2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251
                    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 已提交
2252
                    gen_movl_T0_reg(rd);
2253 2254
                } else {
                    switch (xop) {
B
blueswir1 已提交
2255 2256 2257 2258 2259 2260 2261 2262 2263
                    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 */
2264
                        save_state(dc);
B
blueswir1 已提交
2265 2266 2267 2268
                        gen_op_tadd_T1_T0_ccTV();
                        gen_movl_T0_reg(rd);
                        break;
                    case 0x23: /* tsubcctv */
2269
                        save_state(dc);
B
blueswir1 已提交
2270 2271 2272
                        gen_op_tsub_T1_T0_ccTV();
                        gen_movl_T0_reg(rd);
                        break;
2273 2274 2275 2276
                    case 0x24: /* mulscc */
                        gen_op_mulscc_T1_T0();
                        gen_movl_T0_reg(rd);
                        break;
B
bellard 已提交
2277
#ifndef TARGET_SPARC64
B
blueswir1 已提交
2278 2279
                    case 0x25:  /* sll */
                        gen_op_sll();
2280 2281
                        gen_movl_T0_reg(rd);
                        break;
B
bellard 已提交
2282
                    case 0x26:  /* srl */
B
blueswir1 已提交
2283
                        gen_op_srl();
2284 2285
                        gen_movl_T0_reg(rd);
                        break;
B
bellard 已提交
2286
                    case 0x27:  /* sra */
B
blueswir1 已提交
2287
                        gen_op_sra();
2288 2289
                        gen_movl_T0_reg(rd);
                        break;
B
bellard 已提交
2290
#endif
2291 2292 2293
                    case 0x30:
                        {
                            switch(rd) {
B
bellard 已提交
2294
                            case 0: /* wry */
B
blueswir1 已提交
2295 2296
                                gen_op_xor_T1_T0();
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, y));
2297
                                break;
2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308
#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 已提交
2309
                            case 0x2: /* V9 wrccr */
B
blueswir1 已提交
2310
                                gen_op_xor_T1_T0();
B
bellard 已提交
2311
                                gen_op_wrccr();
B
blueswir1 已提交
2312 2313
                                break;
                            case 0x3: /* V9 wrasi */
B
blueswir1 已提交
2314
                                gen_op_xor_T1_T0();
B
blueswir1 已提交
2315 2316 2317 2318 2319
                                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));
2320 2321
                                save_state(dc);
                                gen_op_next_insn();
B
bellard 已提交
2322
                                tcg_gen_exit_tb(0);
2323
                                dc->is_br = 1;
B
blueswir1 已提交
2324 2325
                                break;
                            case 0xf: /* V9 sir, nop if user */
B
bellard 已提交
2326
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
2327 2328
                                if (supervisor(dc))
                                    gen_op_sir();
B
bellard 已提交
2329
#endif
B
blueswir1 已提交
2330 2331
                                break;
                            case 0x13: /* Graphics Status */
B
bellard 已提交
2332 2333
                                if (gen_trap_ifnofpu(dc))
                                    goto jmp_insn;
B
blueswir1 已提交
2334
                                gen_op_xor_T1_T0();
B
blueswir1 已提交
2335 2336 2337
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, gsr));
                                break;
                            case 0x17: /* Tick compare */
B
bellard 已提交
2338
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
2339 2340
                                if (!supervisor(dc))
                                    goto illegal_insn;
B
bellard 已提交
2341
#endif
B
blueswir1 已提交
2342
                                gen_op_xor_T1_T0();
2343 2344
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, tick_cmpr));
                                gen_op_wrtick_cmpr();
B
blueswir1 已提交
2345 2346
                                break;
                            case 0x18: /* System tick */
B
bellard 已提交
2347
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
2348 2349
                                if (!supervisor(dc))
                                    goto illegal_insn;
B
bellard 已提交
2350
#endif
B
blueswir1 已提交
2351
                                gen_op_xor_T1_T0();
2352
                                gen_op_wrstick();
B
blueswir1 已提交
2353 2354
                                break;
                            case 0x19: /* System tick compare */
B
bellard 已提交
2355
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
2356 2357
                                if (!supervisor(dc))
                                    goto illegal_insn;
B
bellard 已提交
2358
#endif
B
blueswir1 已提交
2359
                                gen_op_xor_T1_T0();
2360 2361
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, stick_cmpr));
                                gen_op_wrstick_cmpr();
B
blueswir1 已提交
2362
                                break;
B
bellard 已提交
2363

B
blueswir1 已提交
2364 2365 2366 2367 2368 2369
                            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 已提交
2370
#endif
B
bellard 已提交
2371
                            default:
2372 2373 2374 2375
                                goto illegal_insn;
                            }
                        }
                        break;
2376
#if !defined(CONFIG_USER_ONLY)
2377
                    case 0x31: /* wrpsr, V9 saved, restored */
2378
                        {
B
blueswir1 已提交
2379 2380
                            if (!supervisor(dc))
                                goto priv_insn;
B
bellard 已提交
2381
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2382 2383 2384 2385 2386 2387 2388
                            switch (rd) {
                            case 0:
                                gen_op_saved();
                                break;
                            case 1:
                                gen_op_restored();
                                break;
B
blueswir1 已提交
2389 2390 2391 2392 2393
                            case 2: /* UA2005 allclean */
                            case 3: /* UA2005 otherw */
                            case 4: /* UA2005 normalw */
                            case 5: /* UA2005 invalw */
                                // XXX
B
blueswir1 已提交
2394
                            default:
B
bellard 已提交
2395 2396 2397
                                goto illegal_insn;
                            }
#else
2398 2399
                            gen_op_xor_T1_T0();
                            gen_op_wrpsr();
B
bellard 已提交
2400 2401
                            save_state(dc);
                            gen_op_next_insn();
B
bellard 已提交
2402
                            tcg_gen_exit_tb(0);
B
blueswir1 已提交
2403
                            dc->is_br = 1;
B
bellard 已提交
2404
#endif
2405 2406
                        }
                        break;
2407
                    case 0x32: /* wrwim, V9 wrpr */
2408
                        {
B
blueswir1 已提交
2409 2410
                            if (!supervisor(dc))
                                goto priv_insn;
2411
                            gen_op_xor_T1_T0();
B
bellard 已提交
2412
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433
                            switch (rd) {
                            case 0: // tpc
                                gen_op_wrtpc();
                                break;
                            case 1: // tnpc
                                gen_op_wrtnpc();
                                break;
                            case 2: // tstate
                                gen_op_wrtstate();
                                break;
                            case 3: // tt
                                gen_op_wrtt();
                                break;
                            case 4: // tick
                                gen_op_wrtick();
                                break;
                            case 5: // tba
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
                                break;
                            case 6: // pstate
                                gen_op_wrpstate();
P
pbrook 已提交
2434 2435
                                save_state(dc);
                                gen_op_next_insn();
B
bellard 已提交
2436
                                tcg_gen_exit_tb(0);
P
pbrook 已提交
2437
                                dc->is_br = 1;
B
blueswir1 已提交
2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462
                                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 已提交
2463 2464 2465 2466 2467 2468 2469 2470
                            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 已提交
2471 2472 2473
                            default:
                                goto illegal_insn;
                            }
B
bellard 已提交
2474
#else
B
blueswir1 已提交
2475
                            gen_op_wrwim();
B
bellard 已提交
2476
#endif
2477 2478
                        }
                        break;
B
blueswir1 已提交
2479
                    case 0x33: /* wrtbr, UA2005 wrhpr */
2480
                        {
B
blueswir1 已提交
2481
#ifndef TARGET_SPARC64
B
blueswir1 已提交
2482 2483
                            if (!supervisor(dc))
                                goto priv_insn;
2484
                            gen_op_xor_T1_T0();
B
blueswir1 已提交
2485 2486 2487 2488 2489 2490 2491 2492 2493 2494
                            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 已提交
2495
                                tcg_gen_exit_tb(0);
B
blueswir1 已提交
2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507
                                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
2508 2509
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, hstick_cmpr));
                                gen_op_wrhstick_cmpr();
B
blueswir1 已提交
2510 2511 2512 2513 2514 2515
                                break;
                            case 6: // hver readonly
                            default:
                                goto illegal_insn;
                            }
#endif
2516 2517 2518
                        }
                        break;
#endif
B
bellard 已提交
2519
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548
                    case 0x2c: /* V9 movcc */
                        {
                            int cc = GET_FIELD_SP(insn, 11, 12);
                            int cond = GET_FIELD_SP(insn, 14, 17);
                            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_reg_T0(rd);
                            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]();
                            }
                            gen_op_mov_cc();
                            gen_movl_T0_reg(rd);
                            break;
                        }
                    case 0x2d: /* V9 sdivx */
B
bellard 已提交
2549
                        gen_op_sdivx_T1_T0();
B
blueswir1 已提交
2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590
                        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);
                            }
                            gen_op_popc();
                            gen_movl_T0_reg(rd);
                        }
                    case 0x2f: /* V9 movr */
                        {
                            int cond = GET_FIELD_SP(insn, 10, 12);
                            rs1 = GET_FIELD(insn, 13, 17);
                            flush_T2(dc);
                            gen_movl_reg_T0(rs1);
                            gen_cond_reg(cond);
                            if (IS_IMM) {       /* immediate */
                                rs2 = GET_FIELD_SPs(insn, 0, 9);
                                gen_movl_simm_T1(rs2);
                            }
                            else {
                                rs2 = GET_FIELD_SP(insn, 0, 4);
                                gen_movl_reg_T1(rs2);
                            }
                            gen_movl_reg_T0(rd);
                            gen_op_mov_cc();
                            gen_movl_T0_reg(rd);
                            break;
                        }
#endif
                    default:
                        goto illegal_insn;
                    }
                }
2591 2592 2593 2594 2595
            } 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 已提交
2596 2597
                if (gen_trap_ifnofpu(dc))
                    goto jmp_insn;
2598 2599

                switch (opf) {
B
blueswir1 已提交
2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631
                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;
2632 2633 2634 2635 2636 2637
                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 已提交
2638
                case 0x019: /* VIS II bmask */
2639 2640
                case 0x01a: /* VIS I alignaddrl */
                    // XXX
B
blueswir1 已提交
2641 2642
                    goto illegal_insn;
                case 0x020: /* VIS I fcmple16 */
2643 2644
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2645
                    gen_op_fcmple16();
2646
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2647 2648
                    break;
                case 0x022: /* VIS I fcmpne16 */
2649 2650
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2651
                    gen_op_fcmpne16();
2652
                    gen_op_store_DT0_fpr(DFPREG(rd));
2653
                    break;
B
blueswir1 已提交
2654
                case 0x024: /* VIS I fcmple32 */
2655 2656
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2657
                    gen_op_fcmple32();
2658
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2659 2660
                    break;
                case 0x026: /* VIS I fcmpne32 */
2661 2662
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2663
                    gen_op_fcmpne32();
2664
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2665 2666
                    break;
                case 0x028: /* VIS I fcmpgt16 */
2667 2668
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2669
                    gen_op_fcmpgt16();
2670
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2671 2672
                    break;
                case 0x02a: /* VIS I fcmpeq16 */
2673 2674
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2675
                    gen_op_fcmpeq16();
2676
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2677 2678
                    break;
                case 0x02c: /* VIS I fcmpgt32 */
2679 2680
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2681
                    gen_op_fcmpgt32();
2682
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2683 2684
                    break;
                case 0x02e: /* VIS I fcmpeq32 */
2685 2686
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2687
                    gen_op_fcmpeq32();
2688
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2689 2690
                    break;
                case 0x031: /* VIS I fmul8x16 */
2691 2692
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2693
                    gen_op_fmul8x16();
2694
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2695 2696
                    break;
                case 0x033: /* VIS I fmul8x16au */
2697 2698
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2699
                    gen_op_fmul8x16au();
2700
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2701 2702
                    break;
                case 0x035: /* VIS I fmul8x16al */
2703 2704
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2705
                    gen_op_fmul8x16al();
2706
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2707 2708
                    break;
                case 0x036: /* VIS I fmul8sux16 */
2709 2710
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2711
                    gen_op_fmul8sux16();
2712
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2713 2714
                    break;
                case 0x037: /* VIS I fmul8ulx16 */
2715 2716
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2717
                    gen_op_fmul8ulx16();
2718
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2719 2720
                    break;
                case 0x038: /* VIS I fmuld8sux16 */
2721 2722
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2723
                    gen_op_fmuld8sux16();
2724
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2725 2726
                    break;
                case 0x039: /* VIS I fmuld8ulx16 */
2727 2728
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2729
                    gen_op_fmuld8ulx16();
2730
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2731 2732 2733 2734 2735 2736 2737
                    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;
2738
                case 0x048: /* VIS I faligndata */
2739 2740
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
2741
                    gen_op_faligndata();
2742
                    gen_op_store_DT0_fpr(DFPREG(rd));
2743
                    break;
B
blueswir1 已提交
2744
                case 0x04b: /* VIS I fpmerge */
2745 2746
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2747
                    gen_op_fpmerge();
2748
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2749 2750 2751 2752 2753
                    break;
                case 0x04c: /* VIS II bshuffle */
                    // XXX
                    goto illegal_insn;
                case 0x04d: /* VIS I fexpand */
2754 2755
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2756
                    gen_op_fexpand();
2757
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2758 2759
                    break;
                case 0x050: /* VIS I fpadd16 */
2760 2761
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2762
                    gen_op_fpadd16();
2763
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2764 2765 2766 2767 2768 2769 2770 2771
                    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 */
2772 2773
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2774
                    gen_op_fpadd32();
2775
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2776 2777 2778 2779 2780 2781 2782 2783
                    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 */
2784 2785
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2786
                    gen_op_fpsub16();
2787
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2788 2789 2790 2791 2792 2793 2794 2795
                    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 */
2796 2797
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2798
                    gen_op_fpadd32();
2799
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2800 2801 2802 2803 2804 2805 2806
                    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;
2807 2808
                case 0x060: /* VIS I fzero */
                    gen_op_movl_DT0_0();
2809
                    gen_op_store_DT0_fpr(DFPREG(rd));
2810 2811 2812 2813 2814
                    break;
                case 0x061: /* VIS I fzeros */
                    gen_op_movl_FT0_0();
                    gen_op_store_FT0_fpr(rd);
                    break;
B
blueswir1 已提交
2815
                case 0x062: /* VIS I fnor */
2816 2817
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2818
                    gen_op_fnor();
2819
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2820 2821 2822 2823 2824 2825 2826 2827
                    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 */
2828 2829
                    gen_op_load_fpr_DT1(DFPREG(rs1));
                    gen_op_load_fpr_DT0(DFPREG(rs2));
B
blueswir1 已提交
2830
                    gen_op_fandnot();
2831
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2832 2833 2834 2835 2836 2837 2838 2839
                    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 */
2840
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2841
                    gen_op_fnot();
2842
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2843 2844 2845 2846 2847 2848 2849
                    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 */
2850 2851
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2852
                    gen_op_fandnot();
2853
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2854 2855 2856 2857 2858 2859 2860 2861
                    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 */
2862
                    gen_op_load_fpr_DT1(DFPREG(rs1));
B
blueswir1 已提交
2863
                    gen_op_fnot();
2864
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2865 2866 2867 2868 2869 2870 2871
                    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 */
2872 2873
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2874
                    gen_op_fxor();
2875
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2876 2877 2878 2879 2880 2881 2882 2883
                    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 */
2884 2885
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2886
                    gen_op_fnand();
2887
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2888 2889 2890 2891 2892 2893 2894 2895
                    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 */
2896 2897
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2898
                    gen_op_fand();
2899
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2900 2901 2902 2903 2904 2905 2906 2907
                    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 */
2908 2909
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2910
                    gen_op_fxnor();
2911
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2912 2913 2914 2915 2916 2917 2918
                    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;
2919
                case 0x074: /* VIS I fsrc1 */
2920 2921
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_store_DT0_fpr(DFPREG(rd));
2922 2923 2924 2925 2926
                    break;
                case 0x075: /* VIS I fsrc1s */
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_store_FT0_fpr(rd);
                    break;
B
blueswir1 已提交
2927
                case 0x076: /* VIS I fornot2 */
2928 2929
                    gen_op_load_fpr_DT1(DFPREG(rs1));
                    gen_op_load_fpr_DT0(DFPREG(rs2));
B
blueswir1 已提交
2930
                    gen_op_fornot();
2931
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2932 2933 2934 2935 2936 2937 2938
                    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;
2939
                case 0x078: /* VIS I fsrc2 */
2940 2941
                    gen_op_load_fpr_DT0(DFPREG(rs2));
                    gen_op_store_DT0_fpr(DFPREG(rd));
2942 2943 2944 2945 2946
                    break;
                case 0x079: /* VIS I fsrc2s */
                    gen_op_load_fpr_FT0(rs2);
                    gen_op_store_FT0_fpr(rd);
                    break;
B
blueswir1 已提交
2947
                case 0x07a: /* VIS I fornot1 */
2948 2949
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2950
                    gen_op_fornot();
2951
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2952 2953 2954 2955 2956 2957 2958 2959
                    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 */
2960 2961
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
B
blueswir1 已提交
2962
                    gen_op_for();
2963
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2964 2965 2966 2967 2968 2969 2970
                    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;
2971 2972
                case 0x07e: /* VIS I fone */
                    gen_op_movl_DT0_1();
2973
                    gen_op_store_DT0_fpr(DFPREG(rd));
2974 2975 2976 2977 2978
                    break;
                case 0x07f: /* VIS I fones */
                    gen_op_movl_FT0_1();
                    gen_op_store_FT0_fpr(rd);
                    break;
B
blueswir1 已提交
2979 2980 2981 2982
                case 0x080: /* VIS I shutdown */
                case 0x081: /* VIS II siam */
                    // XXX
                    goto illegal_insn;
2983 2984 2985 2986
                default:
                    goto illegal_insn;
                }
#else
B
blueswir1 已提交
2987
                goto ncp_insn;
2988 2989
#endif
            } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
2990
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2991
                goto illegal_insn;
2992
#else
B
blueswir1 已提交
2993
                goto ncp_insn;
2994
#endif
B
bellard 已提交
2995
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2996
            } else if (xop == 0x39) { /* V9 return */
B
bellard 已提交
2997
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
2998
                save_state(dc);
B
blueswir1 已提交
2999 3000 3001
                gen_movl_reg_T0(rs1);
                if (IS_IMM) {   /* immediate */
                    rs2 = GET_FIELDs(insn, 19, 31);
B
bellard 已提交
3002
#if defined(OPTIM)
B
blueswir1 已提交
3003
                    if (rs2) {
B
bellard 已提交
3004
#endif
B
blueswir1 已提交
3005 3006
                        gen_movl_simm_T1(rs2);
                        gen_op_add_T1_T0();
B
bellard 已提交
3007
#if defined(OPTIM)
B
blueswir1 已提交
3008
                    }
B
bellard 已提交
3009
#endif
B
blueswir1 已提交
3010
                } else {                /* register */
B
bellard 已提交
3011 3012
                    rs2 = GET_FIELD(insn, 27, 31);
#if defined(OPTIM)
B
blueswir1 已提交
3013
                    if (rs2) {
B
bellard 已提交
3014
#endif
B
blueswir1 已提交
3015 3016
                        gen_movl_reg_T1(rs2);
                        gen_op_add_T1_T0();
B
bellard 已提交
3017
#if defined(OPTIM)
B
blueswir1 已提交
3018
                    }
B
bellard 已提交
3019 3020
#endif
                }
B
blueswir1 已提交
3021 3022
                gen_op_restore();
                gen_mov_pc_npc(dc);
B
blueswir1 已提交
3023
                gen_op_check_align_T0_3();
B
blueswir1 已提交
3024 3025 3026
                gen_op_movl_npc_T0();
                dc->npc = DYNAMIC_PC;
                goto jmp_insn;
B
bellard 已提交
3027
#endif
B
blueswir1 已提交
3028
            } else {
B
bellard 已提交
3029
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
3030 3031 3032
                gen_movl_reg_T0(rs1);
                if (IS_IMM) {   /* immediate */
                    rs2 = GET_FIELDs(insn, 19, 31);
B
bellard 已提交
3033
#if defined(OPTIM)
B
blueswir1 已提交
3034
                    if (rs2) {
3035
#endif
B
blueswir1 已提交
3036 3037
                        gen_movl_simm_T1(rs2);
                        gen_op_add_T1_T0();
B
bellard 已提交
3038
#if defined(OPTIM)
B
blueswir1 已提交
3039
                    }
3040
#endif
B
blueswir1 已提交
3041
                } else {                /* register */
B
bellard 已提交
3042 3043
                    rs2 = GET_FIELD(insn, 27, 31);
#if defined(OPTIM)
B
blueswir1 已提交
3044
                    if (rs2) {
B
bellard 已提交
3045
#endif
B
blueswir1 已提交
3046 3047
                        gen_movl_reg_T1(rs2);
                        gen_op_add_T1_T0();
B
bellard 已提交
3048
#if defined(OPTIM)
B
blueswir1 已提交
3049
                    }
3050
#endif
3051
                }
B
blueswir1 已提交
3052 3053 3054 3055
                switch (xop) {
                case 0x38:      /* jmpl */
                    {
                        if (rd != 0) {
P
pbrook 已提交
3056 3057 3058 3059 3060 3061 3062
#ifdef TARGET_SPARC64
                            if (dc->pc == (uint32_t)dc->pc) {
                                gen_op_movl_T1_im(dc->pc);
                            } else {
                                gen_op_movq_T1_im64(dc->pc >> 32, dc->pc);
                            }
#else
B
blueswir1 已提交
3063
                            gen_op_movl_T1_im(dc->pc);
P
pbrook 已提交
3064
#endif
B
blueswir1 已提交
3065 3066
                            gen_movl_T1_reg(rd);
                        }
B
bellard 已提交
3067
                        gen_mov_pc_npc(dc);
B
blueswir1 已提交
3068
                        gen_op_check_align_T0_3();
B
blueswir1 已提交
3069 3070 3071 3072
                        gen_op_movl_npc_T0();
                        dc->npc = DYNAMIC_PC;
                    }
                    goto jmp_insn;
B
bellard 已提交
3073
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
B
blueswir1 已提交
3074 3075 3076 3077
                case 0x39:      /* rett, V9 return */
                    {
                        if (!supervisor(dc))
                            goto priv_insn;
B
bellard 已提交
3078
                        gen_mov_pc_npc(dc);
B
blueswir1 已提交
3079
                        gen_op_check_align_T0_3();
B
blueswir1 已提交
3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098
                        gen_op_movl_npc_T0();
                        dc->npc = DYNAMIC_PC;
                        gen_op_rett();
                    }
                    goto jmp_insn;
#endif
                case 0x3b: /* flush */
                    gen_op_flush_T0();
                    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 已提交
3099
#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
B
blueswir1 已提交
3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125
                case 0x3e:      /* V9 done/retry */
                    {
                        switch (rd) {
                        case 0:
                            if (!supervisor(dc))
                                goto priv_insn;
                            dc->npc = DYNAMIC_PC;
                            dc->pc = DYNAMIC_PC;
                            gen_op_done();
                            goto jmp_insn;
                        case 1:
                            if (!supervisor(dc))
                                goto priv_insn;
                            dc->npc = DYNAMIC_PC;
                            dc->pc = DYNAMIC_PC;
                            gen_op_retry();
                            goto jmp_insn;
                        default:
                            goto illegal_insn;
                        }
                    }
                    break;
#endif
                default:
                    goto illegal_insn;
                }
3126
            }
B
blueswir1 已提交
3127 3128 3129 3130 3131 3132 3133
            break;
        }
        break;
    case 3:                     /* load/store instructions */
        {
            unsigned int xop = GET_FIELD(insn, 7, 12);
            rs1 = GET_FIELD(insn, 13, 17);
3134
            save_state(dc);
B
blueswir1 已提交
3135
            gen_movl_reg_T0(rs1);
3136 3137 3138 3139 3140 3141
            if (xop == 0x3c || xop == 0x3e)
            {
                rs2 = GET_FIELD(insn, 27, 31);
                gen_movl_reg_T1(rs2);
            }
            else if (IS_IMM) {       /* immediate */
B
blueswir1 已提交
3142
                rs2 = GET_FIELDs(insn, 19, 31);
B
bellard 已提交
3143
#if defined(OPTIM)
B
blueswir1 已提交
3144
                if (rs2 != 0) {
B
bellard 已提交
3145
#endif
B
blueswir1 已提交
3146 3147
                    gen_movl_simm_T1(rs2);
                    gen_op_add_T1_T0();
B
bellard 已提交
3148
#if defined(OPTIM)
B
blueswir1 已提交
3149
                }
B
bellard 已提交
3150
#endif
B
blueswir1 已提交
3151 3152
            } else {            /* register */
                rs2 = GET_FIELD(insn, 27, 31);
B
bellard 已提交
3153
#if defined(OPTIM)
B
blueswir1 已提交
3154
                if (rs2 != 0) {
B
bellard 已提交
3155
#endif
B
blueswir1 已提交
3156 3157
                    gen_movl_reg_T1(rs2);
                    gen_op_add_T1_T0();
B
bellard 已提交
3158
#if defined(OPTIM)
B
blueswir1 已提交
3159
                }
B
bellard 已提交
3160
#endif
B
blueswir1 已提交
3161
            }
B
blueswir1 已提交
3162 3163 3164
            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
                (xop > 0x17 && xop <= 0x1d ) ||
                (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
B
blueswir1 已提交
3165 3166
                switch (xop) {
                case 0x0:       /* load word */
B
blueswir1 已提交
3167
                    gen_op_check_align_T0_3();
3168
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3169
                    gen_op_ldst(ld);
3170 3171 3172
#else
                    gen_op_ldst(lduw);
#endif
B
blueswir1 已提交
3173 3174 3175 3176 3177
                    break;
                case 0x1:       /* load unsigned byte */
                    gen_op_ldst(ldub);
                    break;
                case 0x2:       /* load unsigned halfword */
B
blueswir1 已提交
3178
                    gen_op_check_align_T0_1();
B
blueswir1 已提交
3179 3180 3181 3182
                    gen_op_ldst(lduh);
                    break;
                case 0x3:       /* load double word */
                    if (rd & 1)
3183
                        goto illegal_insn;
B
blueswir1 已提交
3184
                    gen_op_check_align_T0_7();
B
blueswir1 已提交
3185 3186 3187 3188 3189 3190 3191
                    gen_op_ldst(ldd);
                    gen_movl_T0_reg(rd + 1);
                    break;
                case 0x9:       /* load signed byte */
                    gen_op_ldst(ldsb);
                    break;
                case 0xa:       /* load signed halfword */
B
blueswir1 已提交
3192
                    gen_op_check_align_T0_1();
B
blueswir1 已提交
3193 3194 3195 3196 3197 3198
                    gen_op_ldst(ldsh);
                    break;
                case 0xd:       /* ldstub -- XXX: should be atomically */
                    gen_op_ldst(ldstub);
                    break;
                case 0x0f:      /* swap register with memory. Also atomically */
B
blueswir1 已提交
3199
                    gen_op_check_align_T0_3();
B
blueswir1 已提交
3200 3201 3202
                    gen_movl_reg_T1(rd);
                    gen_op_ldst(swap);
                    break;
B
bellard 已提交
3203
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
B
blueswir1 已提交
3204
                case 0x10:      /* load word alternate */
B
bellard 已提交
3205
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3206 3207 3208 3209
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
blueswir1 已提交
3210
#endif
B
blueswir1 已提交
3211
                    gen_op_check_align_T0_3();
3212
                    gen_ld_asi(insn, 4, 0);
B
blueswir1 已提交
3213 3214
                    break;
                case 0x11:      /* load unsigned byte alternate */
B
bellard 已提交
3215
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3216 3217 3218 3219 3220
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
#endif
3221
                    gen_ld_asi(insn, 1, 0);
B
blueswir1 已提交
3222 3223
                    break;
                case 0x12:      /* load unsigned halfword alternate */
B
bellard 已提交
3224
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3225 3226 3227 3228
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
bellard 已提交
3229
#endif
B
blueswir1 已提交
3230
                    gen_op_check_align_T0_1();
3231
                    gen_ld_asi(insn, 2, 0);
B
blueswir1 已提交
3232 3233
                    break;
                case 0x13:      /* load double word alternate */
B
bellard 已提交
3234
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3235 3236 3237 3238
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
bellard 已提交
3239
#endif
B
blueswir1 已提交
3240
                    if (rd & 1)
3241
                        goto illegal_insn;
B
blueswir1 已提交
3242
                    gen_op_check_align_T0_7();
3243
                    gen_ldda_asi(insn);
B
blueswir1 已提交
3244 3245 3246
                    gen_movl_T0_reg(rd + 1);
                    break;
                case 0x19:      /* load signed byte alternate */
B
bellard 已提交
3247
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3248 3249 3250 3251 3252
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
#endif
3253
                    gen_ld_asi(insn, 1, 1);
B
blueswir1 已提交
3254 3255
                    break;
                case 0x1a:      /* load signed halfword alternate */
B
bellard 已提交
3256
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3257 3258 3259 3260
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
bellard 已提交
3261
#endif
B
blueswir1 已提交
3262
                    gen_op_check_align_T0_1();
3263
                    gen_ld_asi(insn, 2, 1);
B
blueswir1 已提交
3264 3265
                    break;
                case 0x1d:      /* ldstuba -- XXX: should be atomically */
B
bellard 已提交
3266
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3267 3268 3269 3270 3271
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
#endif
3272
                    gen_ldstub_asi(insn);
B
blueswir1 已提交
3273 3274
                    break;
                case 0x1f:      /* swap reg with alt. memory. Also atomically */
B
bellard 已提交
3275
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3276 3277 3278 3279
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
blueswir1 已提交
3280
#endif
B
blueswir1 已提交
3281
                    gen_op_check_align_T0_3();
3282 3283
                    gen_movl_reg_T1(rd);
                    gen_swap_asi(insn);
B
blueswir1 已提交
3284
                    break;
B
bellard 已提交
3285 3286

#ifndef TARGET_SPARC64
B
blueswir1 已提交
3287 3288 3289 3290
                case 0x30: /* ldc */
                case 0x31: /* ldcsr */
                case 0x33: /* lddc */
                    goto ncp_insn;
B
bellard 已提交
3291 3292 3293
#endif
#endif
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3294
                case 0x08: /* V9 ldsw */
B
blueswir1 已提交
3295
                    gen_op_check_align_T0_3();
B
blueswir1 已提交
3296 3297 3298
                    gen_op_ldst(ldsw);
                    break;
                case 0x0b: /* V9 ldx */
B
blueswir1 已提交
3299
                    gen_op_check_align_T0_7();
B
blueswir1 已提交
3300 3301 3302
                    gen_op_ldst(ldx);
                    break;
                case 0x18: /* V9 ldswa */
B
blueswir1 已提交
3303
                    gen_op_check_align_T0_3();
3304
                    gen_ld_asi(insn, 4, 1);
B
blueswir1 已提交
3305 3306
                    break;
                case 0x1b: /* V9 ldxa */
B
blueswir1 已提交
3307
                    gen_op_check_align_T0_7();
3308
                    gen_ld_asi(insn, 8, 0);
B
blueswir1 已提交
3309 3310 3311 3312
                    break;
                case 0x2d: /* V9 prefetch, no effect */
                    goto skip_move;
                case 0x30: /* V9 ldfa */
B
blueswir1 已提交
3313
                    gen_op_check_align_T0_3();
3314
                    gen_ldf_asi(insn, 4, rd);
3315
                    goto skip_move;
B
blueswir1 已提交
3316
                case 0x33: /* V9 lddfa */
3317
                    gen_op_check_align_T0_3();
3318
                    gen_ldf_asi(insn, 8, DFPREG(rd));
3319
                    goto skip_move;
B
blueswir1 已提交
3320 3321 3322
                case 0x3d: /* V9 prefetcha, no effect */
                    goto skip_move;
                case 0x32: /* V9 ldqfa */
B
blueswir1 已提交
3323 3324
#if defined(CONFIG_USER_ONLY)
                    gen_op_check_align_T0_3();
3325
                    gen_ldf_asi(insn, 16, QFPREG(rd));
B
blueswir1 已提交
3326 3327
                    goto skip_move;
#else
B
blueswir1 已提交
3328
                    goto nfpu_insn;
B
blueswir1 已提交
3329
#endif
B
blueswir1 已提交
3330 3331 3332 3333 3334
#endif
                default:
                    goto illegal_insn;
                }
                gen_movl_T1_reg(rd);
B
bellard 已提交
3335
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3336
            skip_move: ;
B
bellard 已提交
3337
#endif
B
blueswir1 已提交
3338
            } else if (xop >= 0x20 && xop < 0x24) {
B
bellard 已提交
3339 3340
                if (gen_trap_ifnofpu(dc))
                    goto jmp_insn;
B
blueswir1 已提交
3341 3342
                switch (xop) {
                case 0x20:      /* load fpreg */
B
blueswir1 已提交
3343
                    gen_op_check_align_T0_3();
B
blueswir1 已提交
3344 3345 3346 3347
                    gen_op_ldst(ldf);
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x21:      /* load fsr */
B
blueswir1 已提交
3348
                    gen_op_check_align_T0_3();
B
blueswir1 已提交
3349 3350 3351 3352
                    gen_op_ldst(ldf);
                    gen_op_ldfsr();
                    break;
                case 0x22:      /* load quad fpreg */
B
blueswir1 已提交
3353 3354 3355 3356 3357 3358
#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 已提交
3359
                    goto nfpu_insn;
B
blueswir1 已提交
3360
#endif
B
blueswir1 已提交
3361
                case 0x23:      /* load double fpreg */
B
blueswir1 已提交
3362
                    gen_op_check_align_T0_7();
B
blueswir1 已提交
3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373
                    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) {
                case 0x4:
B
blueswir1 已提交
3374
                    gen_op_check_align_T0_3();
B
blueswir1 已提交
3375 3376 3377 3378 3379 3380
                    gen_op_ldst(st);
                    break;
                case 0x5:
                    gen_op_ldst(stb);
                    break;
                case 0x6:
B
blueswir1 已提交
3381
                    gen_op_check_align_T0_1();
B
blueswir1 已提交
3382 3383 3384 3385
                    gen_op_ldst(sth);
                    break;
                case 0x7:
                    if (rd & 1)
3386
                        goto illegal_insn;
B
blueswir1 已提交
3387
                    gen_op_check_align_T0_7();
B
bellard 已提交
3388
                    flush_T2(dc);
B
blueswir1 已提交
3389 3390 3391
                    gen_movl_reg_T2(rd + 1);
                    gen_op_ldst(std);
                    break;
B
bellard 已提交
3392
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
B
blueswir1 已提交
3393
                case 0x14:
B
bellard 已提交
3394
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3395 3396 3397 3398
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
blueswir1 已提交
3399 3400
#endif
                    gen_op_check_align_T0_3();
3401
                    gen_st_asi(insn, 4);
B
bellard 已提交
3402
                    break;
B
blueswir1 已提交
3403
                case 0x15:
B
bellard 已提交
3404
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3405 3406 3407 3408
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
bellard 已提交
3409
#endif
3410
                    gen_st_asi(insn, 1);
B
bellard 已提交
3411
                    break;
B
blueswir1 已提交
3412
                case 0x16:
B
bellard 已提交
3413
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3414 3415 3416 3417
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
blueswir1 已提交
3418 3419
#endif
                    gen_op_check_align_T0_1();
3420
                    gen_st_asi(insn, 2);
B
bellard 已提交
3421
                    break;
B
blueswir1 已提交
3422
                case 0x17:
B
bellard 已提交
3423
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3424 3425 3426 3427
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
bellard 已提交
3428
#endif
B
blueswir1 已提交
3429
                    if (rd & 1)
3430
                        goto illegal_insn;
B
blueswir1 已提交
3431
                    gen_op_check_align_T0_7();
3432
                    flush_T2(dc);
B
blueswir1 已提交
3433
                    gen_movl_reg_T2(rd + 1);
3434
                    gen_stda_asi(insn);
B
bellard 已提交
3435
                    break;
B
bellard 已提交
3436
#endif
B
bellard 已提交
3437
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3438
                case 0x0e: /* V9 stx */
B
blueswir1 已提交
3439
                    gen_op_check_align_T0_7();
B
blueswir1 已提交
3440 3441 3442
                    gen_op_ldst(stx);
                    break;
                case 0x1e: /* V9 stxa */
B
blueswir1 已提交
3443
                    gen_op_check_align_T0_7();
3444
                    gen_st_asi(insn, 8);
B
blueswir1 已提交
3445
                    break;
B
bellard 已提交
3446
#endif
B
blueswir1 已提交
3447 3448 3449 3450
                default:
                    goto illegal_insn;
                }
            } else if (xop > 0x23 && xop < 0x28) {
B
bellard 已提交
3451 3452
                if (gen_trap_ifnofpu(dc))
                    goto jmp_insn;
B
blueswir1 已提交
3453 3454
                switch (xop) {
                case 0x24:
B
blueswir1 已提交
3455
                    gen_op_check_align_T0_3();
3456
                    gen_op_load_fpr_FT0(rd);
B
blueswir1 已提交
3457 3458 3459
                    gen_op_ldst(stf);
                    break;
                case 0x25: /* stfsr, V9 stxfsr */
B
blueswir1 已提交
3460 3461 3462
#ifdef CONFIG_USER_ONLY
                    gen_op_check_align_T0_3();
#endif
B
blueswir1 已提交
3463 3464 3465
                    gen_op_stfsr();
                    gen_op_ldst(stf);
                    break;
B
blueswir1 已提交
3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481
                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 已提交
3482 3483 3484 3485 3486
                    if (!supervisor(dc))
                        goto priv_insn;
                    if (gen_trap_ifnofpu(dc))
                        goto jmp_insn;
                    goto nfq_insn;
B
blueswir1 已提交
3487
#endif
B
blueswir1 已提交
3488 3489
#endif
                case 0x27:
B
blueswir1 已提交
3490
                    gen_op_check_align_T0_7();
B
bellard 已提交
3491
                    gen_op_load_fpr_DT0(DFPREG(rd));
B
blueswir1 已提交
3492 3493 3494 3495 3496 3497 3498
                    gen_op_ldst(stdf);
                    break;
                default:
                    goto illegal_insn;
                }
            } else if (xop > 0x33 && xop < 0x3f) {
                switch (xop) {
3499
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3500
                case 0x34: /* V9 stfa */
B
blueswir1 已提交
3501
                    gen_op_check_align_T0_3();
3502
                    gen_op_load_fpr_FT0(rd);
3503
                    gen_stf_asi(insn, 4, rd);
B
blueswir1 已提交
3504
                    break;
B
blueswir1 已提交
3505 3506 3507 3508
                case 0x36: /* V9 stqfa */
#if defined(CONFIG_USER_ONLY)
                    gen_op_check_align_T0_7();
                    gen_op_load_fpr_QT0(QFPREG(rd));
3509
                    gen_stf_asi(insn, 16, QFPREG(rd));
B
blueswir1 已提交
3510 3511 3512 3513
                    break;
#else
                    goto nfpu_insn;
#endif
B
blueswir1 已提交
3514
                case 0x37: /* V9 stdfa */
3515 3516
                    gen_op_check_align_T0_3();
                    gen_op_load_fpr_DT0(DFPREG(rd));
3517
                    gen_stf_asi(insn, 8, DFPREG(rd));
B
blueswir1 已提交
3518 3519
                    break;
                case 0x3c: /* V9 casa */
B
blueswir1 已提交
3520
                    gen_op_check_align_T0_3();
3521 3522 3523 3524
                    flush_T2(dc);
                    gen_movl_reg_T2(rd);
                    gen_cas_asi(insn);
                    gen_movl_T1_reg(rd);
B
blueswir1 已提交
3525 3526
                    break;
                case 0x3e: /* V9 casxa */
B
blueswir1 已提交
3527
                    gen_op_check_align_T0_7();
3528 3529 3530 3531
                    flush_T2(dc);
                    gen_movl_reg_T2(rd);
                    gen_casx_asi(insn);
                    gen_movl_T1_reg(rd);
B
blueswir1 已提交
3532
                    break;
3533
#else
B
blueswir1 已提交
3534 3535 3536 3537 3538 3539 3540 3541 3542
                case 0x34: /* stc */
                case 0x35: /* stcsr */
                case 0x36: /* stdcq */
                case 0x37: /* stdc */
                    goto ncp_insn;
#endif
                default:
                    goto illegal_insn;
                }
3543
            }
B
blueswir1 已提交
3544 3545 3546 3547
            else
                goto illegal_insn;
        }
        break;
3548 3549
    }
    /* default case for non jump instructions */
B
bellard 已提交
3550
    if (dc->npc == DYNAMIC_PC) {
B
blueswir1 已提交
3551 3552
        dc->pc = DYNAMIC_PC;
        gen_op_next_insn();
B
bellard 已提交
3553 3554
    } else if (dc->npc == JUMP_PC) {
        /* we can do a static jump */
B
blueswir1 已提交
3555
        gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1]);
B
bellard 已提交
3556 3557
        dc->is_br = 1;
    } else {
B
blueswir1 已提交
3558 3559
        dc->pc = dc->npc;
        dc->npc = dc->npc + 4;
3560
    }
B
bellard 已提交
3561
 jmp_insn:
3562 3563
    return;
 illegal_insn:
B
bellard 已提交
3564
    save_state(dc);
3565 3566
    gen_op_exception(TT_ILL_INSN);
    dc->is_br = 1;
3567
    return;
B
bellard 已提交
3568
#if !defined(CONFIG_USER_ONLY)
3569 3570 3571 3572
 priv_insn:
    save_state(dc);
    gen_op_exception(TT_PRIV_INSN);
    dc->is_br = 1;
B
bellard 已提交
3573 3574 3575 3576 3577
    return;
 nfpu_insn:
    save_state(dc);
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
    dc->is_br = 1;
3578
    return;
B
blueswir1 已提交
3579
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3580 3581 3582 3583 3584 3585
 nfq_insn:
    save_state(dc);
    gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
    dc->is_br = 1;
    return;
#endif
B
blueswir1 已提交
3586
#endif
3587 3588 3589 3590 3591 3592 3593
#ifndef TARGET_SPARC64
 ncp_insn:
    save_state(dc);
    gen_op_exception(TT_NCP_INSN);
    dc->is_br = 1;
    return;
#endif
3594 3595
}

3596
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
B
blueswir1 已提交
3597
                                                 int spc, CPUSPARCState *env)
3598
{
B
bellard 已提交
3599
    target_ulong pc_start, last_pc;
3600 3601
    uint16_t *gen_opc_end;
    DisasContext dc1, *dc = &dc1;
3602
    int j, lj = -1;
3603 3604 3605

    memset(dc, 0, sizeof(DisasContext));
    dc->tb = tb;
B
bellard 已提交
3606
    pc_start = tb->pc;
3607
    dc->pc = pc_start;
B
bellard 已提交
3608
    last_pc = dc->pc;
B
bellard 已提交
3609
    dc->npc = (target_ulong) tb->cs_base;
B
blueswir1 已提交
3610 3611
    dc->mem_idx = cpu_mmu_index(env);
    dc->fpu_enabled = cpu_fpu_enabled(env);
3612 3613 3614
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;

    do {
3615 3616 3617
        if (env->nb_breakpoints > 0) {
            for(j = 0; j < env->nb_breakpoints; j++) {
                if (env->breakpoints[j] == dc->pc) {
B
blueswir1 已提交
3618 3619
                    if (dc->pc != pc_start)
                        save_state(dc);
B
bellard 已提交
3620
                    gen_op_debug();
B
bellard 已提交
3621
                    tcg_gen_exit_tb(0);
B
blueswir1 已提交
3622
                    dc->is_br = 1;
B
bellard 已提交
3623
                    goto exit_gen_loop;
3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639
                }
            }
        }
        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 已提交
3640 3641 3642 3643 3644 3645 3646 3647
        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 已提交
3648 3649 3650 3651
        /* 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 已提交
3652 3653 3654
        /* if single step mode, we generate only one instruction and
           generate an exception */
        if (env->singlestep_enabled) {
B
bellard 已提交
3655
            gen_jmp_im(dc->pc);
B
bellard 已提交
3656
            tcg_gen_exit_tb(0);
B
bellard 已提交
3657 3658
            break;
        }
3659
    } while ((gen_opc_ptr < gen_opc_end) &&
B
blueswir1 已提交
3660
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
B
bellard 已提交
3661 3662

 exit_gen_loop:
B
bellard 已提交
3663
    if (!dc->is_br) {
3664
        if (dc->pc != DYNAMIC_PC &&
B
bellard 已提交
3665 3666
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
            /* static PC and NPC: we can use direct chaining */
B
blueswir1 已提交
3667
            gen_branch(dc, dc->pc, dc->npc);
B
bellard 已提交
3668 3669
        } else {
            if (dc->pc != DYNAMIC_PC)
B
bellard 已提交
3670
                gen_jmp_im(dc->pc);
B
bellard 已提交
3671
            save_npc(dc);
B
bellard 已提交
3672
            tcg_gen_exit_tb(0);
B
bellard 已提交
3673 3674
        }
    }
3675
    *gen_opc_ptr = INDEX_op_end;
3676 3677 3678 3679 3680 3681 3682 3683 3684 3685
    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
3686 3687
        gen_opc_jump_pc[0] = dc->jump_pc[0];
        gen_opc_jump_pc[1] = dc->jump_pc[1];
3688
    } else {
B
bellard 已提交
3689
        tb->size = last_pc + 4 - pc_start;
3690
    }
3691
#ifdef DEBUG_DISAS
B
bellard 已提交
3692
    if (loglevel & CPU_LOG_TB_IN_ASM) {
B
blueswir1 已提交
3693 3694 3695 3696
        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");
3697
    }
3698
#endif
3699
    return 0;
3700 3701
}

3702
int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
3703
{
3704
    return gen_intermediate_code_internal(tb, 0, env);
3705 3706
}

3707
int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
3708
{
3709
    return gen_intermediate_code_internal(tb, 1, env);
3710 3711
}

B
bellard 已提交
3712 3713
void cpu_reset(CPUSPARCState *env)
{
B
bellard 已提交
3714
    tlb_flush(env, 1);
3715 3716 3717
    env->cwp = 0;
    env->wim = 1;
    env->regwptr = env->regbase + (env->cwp * 16);
3718
#if defined(CONFIG_USER_ONLY)
3719
    env->user_mode_only = 1;
3720
#ifdef TARGET_SPARC64
3721 3722 3723 3724
    env->cleanwin = NWINDOWS - 2;
    env->cansave = NWINDOWS - 2;
    env->pstate = PS_RMO | PS_PEF | PS_IE;
    env->asi = 0x82; // Primary no-fault
3725
#endif
3726
#else
B
blueswir1 已提交
3727
    env->psret = 0;
3728
    env->psrs = 1;
B
bellard 已提交
3729
    env->psrps = 1;
B
bellard 已提交
3730
#ifdef TARGET_SPARC64
B
bellard 已提交
3731
    env->pstate = PS_PRIV;
B
blueswir1 已提交
3732
    env->hpstate = HS_PRIV;
B
bellard 已提交
3733
    env->pc = 0x1fff0000000ULL;
B
bellard 已提交
3734
#else
B
blueswir1 已提交
3735
    env->pc = 0;
B
blueswir1 已提交
3736
    env->mmuregs[0] &= ~(MMU_E | MMU_NF);
3737
    env->mmuregs[0] |= env->mmu_bm;
B
bellard 已提交
3738
#endif
B
bellard 已提交
3739
    env->npc = env->pc + 4;
3740
#endif
B
bellard 已提交
3741 3742
}

B
bellard 已提交
3743
CPUSPARCState *cpu_sparc_init(const char *cpu_model)
B
bellard 已提交
3744 3745
{
    CPUSPARCState *env;
B
bellard 已提交
3746 3747 3748 3749 3750
    const sparc_def_t *def;

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

B
bellard 已提交
3752 3753
    env = qemu_mallocz(sizeof(CPUSPARCState));
    if (!env)
B
blueswir1 已提交
3754
        return NULL;
B
bellard 已提交
3755
    cpu_exec_init(env);
3756
    env->cpu_model_str = cpu_model;
B
bellard 已提交
3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773
    env->version = def->iu_version;
    env->fsr = def->fpu_version;
#if !defined(TARGET_SPARC64)
    env->mmu_bm = def->mmu_bm;
    env->mmuregs[0] |= def->mmu_version;
    cpu_sparc_set_id(env, 0);
#endif
    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
3774 3775
}

B
blueswir1 已提交
3776 3777
static const sparc_def_t sparc_defs[] = {
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812
    {
        .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 已提交
3813 3814
    {
        .name = "TI UltraSparc II",
B
blueswir1 已提交
3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878
        .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 已提交
3879 3880 3881 3882 3883
                       | (MAXTL << 8) | (NWINDOWS - 1)),
        .fpu_version = 0x00000000,
        .mmu_version = 0,
    },
#else
B
blueswir1 已提交
3884 3885 3886 3887 3888 3889 3890
    {
        .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,
    },
B
blueswir1 已提交
3891 3892 3893 3894 3895
    {
        .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 */
3896
        .mmu_bm = 0x00004000,
B
blueswir1 已提交
3897
    },
B
blueswir1 已提交
3898
    {
B
blueswir1 已提交
3899 3900 3901 3902
        .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 */
3903
        .mmu_bm = 0x00004000,
B
blueswir1 已提交
3904
    },
B
blueswir1 已提交
3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932
    {
        .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,
    },
    {
        .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,
    },
    {
        .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,
    },
    {
        .name = "TI SuperSparc II",
        .iu_version = 0x40000000,
        .fpu_version = 0 << 17,
        .mmu_version = 0x04000000,
        .mmu_bm = 0x00002000,
    },
B
blueswir1 已提交
3933 3934 3935 3936 3937
    {
        .name = "TI MicroSparc I",
        .iu_version = 0x41000000,
        .fpu_version = 4 << 17,
        .mmu_version = 0x41000000,
3938
        .mmu_bm = 0x00004000,
B
blueswir1 已提交
3939 3940
    },
    {
B
blueswir1 已提交
3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956
        .name = "TI MicroSparc II",
        .iu_version = 0x42000000,
        .fpu_version = 4 << 17,
        .mmu_version = 0x02000000,
        .mmu_bm = 0x00004000,
    },
    {
        .name = "TI MicroSparc IIep",
        .iu_version = 0x42000000,
        .fpu_version = 4 << 17,
        .mmu_version = 0x04000000,
        .mmu_bm = 0x00004000,
    },
    {
        .name = "TI SuperSparc 51",
        .iu_version = 0x43000000,
B
blueswir1 已提交
3957 3958
        .fpu_version = 0 << 17,
        .mmu_version = 0x04000000,
3959
        .mmu_bm = 0x00002000,
B
blueswir1 已提交
3960 3961
    },
    {
B
blueswir1 已提交
3962 3963 3964 3965 3966 3967 3968 3969
        .name = "TI SuperSparc 61",
        .iu_version = 0x44000000,
        .fpu_version = 0 << 17,
        .mmu_version = 0x04000000,
        .mmu_bm = 0x00002000,
    },
    {
        .name = "Ross RT625",
B
blueswir1 已提交
3970 3971
        .iu_version = 0x1e000000,
        .fpu_version = 1 << 17,
B
blueswir1 已提交
3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014
        .mmu_version = 0x1e000000,
        .mmu_bm = 0x00004000,
    },
    {
        .name = "Ross RT620",
        .iu_version = 0x1f000000,
        .fpu_version = 1 << 17,
        .mmu_version = 0x1f000000,
        .mmu_bm = 0x00004000,
    },
    {
        .name = "BIT B5010",
        .iu_version = 0x20000000,
        .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
        .mmu_version = 0x20000000,
        .mmu_bm = 0x00004000,
    },
    {
        .name = "Matsushita MN10501",
        .iu_version = 0x50000000,
        .fpu_version = 0 << 17,
        .mmu_version = 0x50000000,
        .mmu_bm = 0x00004000,
    },
    {
        .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,
    },
    {
        .name = "LEON2",
        .iu_version = 0xf2000000,
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
        .mmu_version = 0xf2000000,
        .mmu_bm = 0x00004000,
    },
    {
        .name = "LEON3",
        .iu_version = 0xf3000000,
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
        .mmu_version = 0xf3000000,
4015
        .mmu_bm = 0x00004000,
B
blueswir1 已提交
4016
    },
B
blueswir1 已提交
4017 4018 4019
#endif
};

B
bellard 已提交
4020
static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name)
B
blueswir1 已提交
4021 4022 4023 4024 4025
{
    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 已提交
4026
            return &sparc_defs[i];
B
blueswir1 已提交
4027 4028
        }
    }
B
bellard 已提交
4029
    return NULL;
B
blueswir1 已提交
4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044
}

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);
    }
}

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

4047
void cpu_dump_state(CPUState *env, FILE *f,
B
bellard 已提交
4048 4049
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                    int flags)
4050
{
4051 4052
    int i, x;

4053
    cpu_fprintf(f, "pc: " TARGET_FMT_lx "  npc: " TARGET_FMT_lx "\n", env->pc, env->npc);
B
bellard 已提交
4054
    cpu_fprintf(f, "General Registers:\n");
4055
    for (i = 0; i < 4; i++)
B
blueswir1 已提交
4056
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
B
bellard 已提交
4057
    cpu_fprintf(f, "\n");
4058
    for (; i < 8; i++)
B
blueswir1 已提交
4059
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
B
bellard 已提交
4060
    cpu_fprintf(f, "\nCurrent Register Window:\n");
4061
    for (x = 0; x < 3; x++) {
B
blueswir1 已提交
4062 4063 4064 4065 4066 4067 4068 4069 4070 4071
        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");
4072
    }
B
bellard 已提交
4073
    cpu_fprintf(f, "\nFloating Point Registers:\n");
4074 4075
    for (i = 0; i < 32; i++) {
        if ((i & 3) == 0)
B
bellard 已提交
4076 4077
            cpu_fprintf(f, "%%f%02d:", i);
        cpu_fprintf(f, " %016lf", env->fpr[i]);
4078
        if ((i & 3) == 3)
B
bellard 已提交
4079
            cpu_fprintf(f, "\n");
4080
    }
P
pbrook 已提交
4081
#ifdef TARGET_SPARC64
4082
    cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d fprs: %d\n",
B
blueswir1 已提交
4083
                env->pstate, GET_CCR(env), env->asi, env->tl, env->fprs);
P
pbrook 已提交
4084
    cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d cleanwin %d cwp %d\n",
B
blueswir1 已提交
4085 4086
                env->cansave, env->canrestore, env->otherwin, env->wstate,
                env->cleanwin, NWINDOWS - 1 - env->cwp);
P
pbrook 已提交
4087
#else
B
bellard 已提交
4088
    cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n", GET_PSR(env),
B
blueswir1 已提交
4089 4090 4091 4092
            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 已提交
4093
#endif
B
bellard 已提交
4094
    cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env));
4095
}
B
bellard 已提交
4096

B
bellard 已提交
4097
#if defined(CONFIG_USER_ONLY)
4098
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
B
bellard 已提交
4099 4100 4101
{
    return addr;
}
B
bellard 已提交
4102

B
bellard 已提交
4103
#else
4104 4105
extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
                                 int *access_index, target_ulong address, int rw,
4106
                                 int mmu_idx);
B
bellard 已提交
4107

4108
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
B
bellard 已提交
4109
{
4110
    target_phys_addr_t phys_addr;
B
bellard 已提交
4111 4112 4113
    int prot, access_index;

    if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2, 0) != 0)
4114 4115
        if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 0, 0) != 0)
            return -1;
4116 4117
    if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED)
        return -1;
B
bellard 已提交
4118 4119 4120 4121
    return phys_addr;
}
#endif

B
bellard 已提交
4122 4123 4124 4125 4126
void helper_flush(target_ulong addr)
{
    addr &= ~7;
    tb_invalidate_page_range(addr, addr + 8);
}