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

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

   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
18
   License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 20 21 22 23 24 25 26 27 28
 */

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

#include "cpu.h"
#include "disas.h"
B
blueswir1 已提交
29
#include "helper.h"
B
bellard 已提交
30
#include "tcg-op.h"
31

P
pbrook 已提交
32 33 34
#define GEN_HELPER 1
#include "helper.h"

35 36
#define DEBUG_DISAS

B
bellard 已提交
37 38 39 40
#define DYNAMIC_PC  1 /* dynamic pc value */
#define JUMP_PC     2 /* dynamic pc value which takes only two values
                         according to jump_pc[T2] */

B
blueswir1 已提交
41
/* global register indexes */
P
pbrook 已提交
42
static TCGv_ptr cpu_env, cpu_regwptr;
43 44
static TCGv cpu_cc_src, cpu_cc_src2, cpu_cc_dst;
static TCGv_i32 cpu_cc_op;
P
pbrook 已提交
45 46
static TCGv_i32 cpu_psr;
static TCGv cpu_fsr, cpu_pc, cpu_npc, cpu_gregs[8];
47 48 49 50
static TCGv cpu_y;
#ifndef CONFIG_USER_ONLY
static TCGv cpu_tbr;
#endif
51
static TCGv cpu_cond, cpu_dst, cpu_addr, cpu_val;
52
#ifdef TARGET_SPARC64
P
pbrook 已提交
53 54
static TCGv_i32 cpu_xcc, cpu_asi, cpu_fprs;
static TCGv cpu_gsr;
55
static TCGv cpu_tick_cmpr, cpu_stick_cmpr, cpu_hstick_cmpr;
P
pbrook 已提交
56 57
static TCGv cpu_hintp, cpu_htba, cpu_hver, cpu_ssr, cpu_ver;
static TCGv_i32 cpu_softint;
58 59
#else
static TCGv cpu_wim;
60
#endif
B
blueswir1 已提交
61
/* local register indexes (only used inside old micro ops) */
P
pbrook 已提交
62 63 64
static TCGv cpu_tmp0;
static TCGv_i32 cpu_tmp32;
static TCGv_i64 cpu_tmp64;
B
blueswir1 已提交
65
/* Floating point registers */
P
pbrook 已提交
66
static TCGv_i32 cpu_fpr[TARGET_FPREGS];
B
blueswir1 已提交
67

68 69 70
static target_ulong gen_opc_npc[OPC_BUF_SIZE];
static target_ulong gen_opc_jump_pc[2];

P
pbrook 已提交
71 72
#include "gen-icount.h"

73
typedef struct DisasContext {
B
blueswir1 已提交
74 75
    target_ulong pc;    /* current Program Counter: integer or DYNAMIC_PC */
    target_ulong npc;   /* next PC: integer or DYNAMIC_PC or JUMP_PC */
B
bellard 已提交
76
    target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
77
    int is_br;
78
    int mem_idx;
B
bellard 已提交
79
    int fpu_enabled;
B
blueswir1 已提交
80
    int address_mask_32bit;
81
    int singlestep;
82
    uint32_t cc_op;  /* current CC operation */
83
    struct TranslationBlock *tb;
84
    sparc_def_t *def;
85 86
} DisasContext;

B
bellard 已提交
87
// This function uses non-native bit order
B
Blue Swirl 已提交
88 89
#define GET_FIELD(X, FROM, TO)                                  \
    ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
90

B
bellard 已提交
91
// This function uses the order in the manuals, i.e. bit 0 is 2^0
B
Blue Swirl 已提交
92
#define GET_FIELD_SP(X, FROM, TO)               \
B
bellard 已提交
93 94 95
    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 已提交
96
#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
B
bellard 已提交
97 98

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

B
blueswir1 已提交
106 107 108
#define UA2005_HTRAP_MASK 0xff
#define V8_TRAP_MASK 0x7f

B
bellard 已提交
109 110 111 112 113 114
static int sign_extend(int x, int len)
{
    len = 32 - len;
    return (x << len) >> len;
}

115 116
#define IS_IMM (insn & (1<<13))

B
blueswir1 已提交
117 118 119
/* floating point registers moves */
static void gen_op_load_fpr_DT0(unsigned int src)
{
B
blueswir1 已提交
120
    tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, dt0) +
B
blueswir1 已提交
121
                   offsetof(CPU_DoubleU, l.upper));
B
blueswir1 已提交
122
    tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, dt0) +
B
blueswir1 已提交
123
                   offsetof(CPU_DoubleU, l.lower));
B
blueswir1 已提交
124 125 126 127
}

static void gen_op_load_fpr_DT1(unsigned int src)
{
B
blueswir1 已提交
128
    tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, dt1) +
B
blueswir1 已提交
129
                   offsetof(CPU_DoubleU, l.upper));
B
blueswir1 已提交
130
    tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, dt1) +
B
blueswir1 已提交
131
                   offsetof(CPU_DoubleU, l.lower));
B
blueswir1 已提交
132 133 134 135
}

static void gen_op_store_DT0_fpr(unsigned int dst)
{
B
blueswir1 已提交
136
    tcg_gen_ld_i32(cpu_fpr[dst], cpu_env, offsetof(CPUSPARCState, dt0) +
B
blueswir1 已提交
137
                   offsetof(CPU_DoubleU, l.upper));
B
blueswir1 已提交
138
    tcg_gen_ld_i32(cpu_fpr[dst + 1], cpu_env, offsetof(CPUSPARCState, dt0) +
B
blueswir1 已提交
139
                   offsetof(CPU_DoubleU, l.lower));
B
blueswir1 已提交
140 141 142 143
}

static void gen_op_load_fpr_QT0(unsigned int src)
{
B
blueswir1 已提交
144
    tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, qt0) +
B
blueswir1 已提交
145
                   offsetof(CPU_QuadU, l.upmost));
B
blueswir1 已提交
146
    tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, qt0) +
B
blueswir1 已提交
147
                   offsetof(CPU_QuadU, l.upper));
B
blueswir1 已提交
148
    tcg_gen_st_i32(cpu_fpr[src + 2], cpu_env, offsetof(CPUSPARCState, qt0) +
B
blueswir1 已提交
149
                   offsetof(CPU_QuadU, l.lower));
B
blueswir1 已提交
150
    tcg_gen_st_i32(cpu_fpr[src + 3], cpu_env, offsetof(CPUSPARCState, qt0) +
B
blueswir1 已提交
151
                   offsetof(CPU_QuadU, l.lowest));
B
blueswir1 已提交
152 153 154 155
}

static void gen_op_load_fpr_QT1(unsigned int src)
{
B
blueswir1 已提交
156
    tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, qt1) +
B
blueswir1 已提交
157
                   offsetof(CPU_QuadU, l.upmost));
B
blueswir1 已提交
158
    tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, qt1) +
B
blueswir1 已提交
159
                   offsetof(CPU_QuadU, l.upper));
B
blueswir1 已提交
160
    tcg_gen_st_i32(cpu_fpr[src + 2], cpu_env, offsetof(CPUSPARCState, qt1) +
B
blueswir1 已提交
161
                   offsetof(CPU_QuadU, l.lower));
B
blueswir1 已提交
162
    tcg_gen_st_i32(cpu_fpr[src + 3], cpu_env, offsetof(CPUSPARCState, qt1) +
B
blueswir1 已提交
163
                   offsetof(CPU_QuadU, l.lowest));
B
blueswir1 已提交
164 165 166 167
}

static void gen_op_store_QT0_fpr(unsigned int dst)
{
B
blueswir1 已提交
168
    tcg_gen_ld_i32(cpu_fpr[dst], cpu_env, offsetof(CPUSPARCState, qt0) +
B
blueswir1 已提交
169
                   offsetof(CPU_QuadU, l.upmost));
B
blueswir1 已提交
170
    tcg_gen_ld_i32(cpu_fpr[dst + 1], cpu_env, offsetof(CPUSPARCState, qt0) +
B
blueswir1 已提交
171
                   offsetof(CPU_QuadU, l.upper));
B
blueswir1 已提交
172
    tcg_gen_ld_i32(cpu_fpr[dst + 2], cpu_env, offsetof(CPUSPARCState, qt0) +
B
blueswir1 已提交
173
                   offsetof(CPU_QuadU, l.lower));
B
blueswir1 已提交
174
    tcg_gen_ld_i32(cpu_fpr[dst + 3], cpu_env, offsetof(CPUSPARCState, qt0) +
B
blueswir1 已提交
175
                   offsetof(CPU_QuadU, l.lowest));
B
blueswir1 已提交
176
}
B
blueswir1 已提交
177

178 179
/* moves */
#ifdef CONFIG_USER_ONLY
B
bellard 已提交
180
#define supervisor(dc) 0
181
#ifdef TARGET_SPARC64
B
blueswir1 已提交
182
#define hypervisor(dc) 0
183
#endif
B
bellard 已提交
184
#else
185
#define supervisor(dc) (dc->mem_idx >= MMU_KERNEL_IDX)
186
#ifdef TARGET_SPARC64
187
#define hypervisor(dc) (dc->mem_idx == MMU_HYPV_IDX)
B
blueswir1 已提交
188
#else
B
bellard 已提交
189
#endif
190 191
#endif

B
blueswir1 已提交
192 193 194
#ifdef TARGET_SPARC64
#ifndef TARGET_ABI32
#define AM_CHECK(dc) ((dc)->address_mask_32bit)
B
blueswir1 已提交
195
#else
B
blueswir1 已提交
196 197
#define AM_CHECK(dc) (1)
#endif
B
blueswir1 已提交
198
#endif
199

B
blueswir1 已提交
200 201 202 203 204 205 206 207
static inline void gen_address_mask(DisasContext *dc, TCGv addr)
{
#ifdef TARGET_SPARC64
    if (AM_CHECK(dc))
        tcg_gen_andi_tl(addr, addr, 0xffffffffULL);
#endif
}

B
blueswir1 已提交
208
static inline void gen_movl_reg_TN(int reg, TCGv tn)
209
{
B
blueswir1 已提交
210 211 212
    if (reg == 0)
        tcg_gen_movi_tl(tn, 0);
    else if (reg < 8)
B
blueswir1 已提交
213
        tcg_gen_mov_tl(tn, cpu_gregs[reg]);
B
blueswir1 已提交
214 215
    else {
        tcg_gen_ld_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
216 217 218
    }
}

B
blueswir1 已提交
219
static inline void gen_movl_TN_reg(int reg, TCGv tn)
220
{
B
blueswir1 已提交
221 222 223
    if (reg == 0)
        return;
    else if (reg < 8)
B
blueswir1 已提交
224
        tcg_gen_mov_tl(cpu_gregs[reg], tn);
B
blueswir1 已提交
225 226
    else {
        tcg_gen_st_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
227 228 229
    }
}

230
static inline void gen_goto_tb(DisasContext *s, int tb_num,
231 232 233 234 235 236
                               target_ulong pc, target_ulong npc)
{
    TranslationBlock *tb;

    tb = s->tb;
    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
237 238
        (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
        !s->singlestep)  {
239
        /* jump to same page: we can use a direct jump */
B
bellard 已提交
240
        tcg_gen_goto_tb(tb_num);
B
blueswir1 已提交
241 242
        tcg_gen_movi_tl(cpu_pc, pc);
        tcg_gen_movi_tl(cpu_npc, npc);
243
        tcg_gen_exit_tb((tcg_target_long)tb + tb_num);
244 245
    } else {
        /* jump to another page: currently not optimized */
B
blueswir1 已提交
246 247
        tcg_gen_movi_tl(cpu_pc, pc);
        tcg_gen_movi_tl(cpu_npc, npc);
B
bellard 已提交
248
        tcg_gen_exit_tb(0);
249 250 251
    }
}

252
// XXX suboptimal
P
pbrook 已提交
253
static inline void gen_mov_reg_N(TCGv reg, TCGv_i32 src)
254
{
B
blueswir1 已提交
255
    tcg_gen_extu_i32_tl(reg, src);
B
blueswir1 已提交
256
    tcg_gen_shri_tl(reg, reg, PSR_NEG_SHIFT);
257 258 259
    tcg_gen_andi_tl(reg, reg, 0x1);
}

P
pbrook 已提交
260
static inline void gen_mov_reg_Z(TCGv reg, TCGv_i32 src)
261
{
B
blueswir1 已提交
262
    tcg_gen_extu_i32_tl(reg, src);
B
blueswir1 已提交
263
    tcg_gen_shri_tl(reg, reg, PSR_ZERO_SHIFT);
264 265 266
    tcg_gen_andi_tl(reg, reg, 0x1);
}

P
pbrook 已提交
267
static inline void gen_mov_reg_V(TCGv reg, TCGv_i32 src)
268
{
B
blueswir1 已提交
269
    tcg_gen_extu_i32_tl(reg, src);
B
blueswir1 已提交
270
    tcg_gen_shri_tl(reg, reg, PSR_OVF_SHIFT);
271 272 273
    tcg_gen_andi_tl(reg, reg, 0x1);
}

P
pbrook 已提交
274
static inline void gen_mov_reg_C(TCGv reg, TCGv_i32 src)
275
{
B
blueswir1 已提交
276
    tcg_gen_extu_i32_tl(reg, src);
B
blueswir1 已提交
277
    tcg_gen_shri_tl(reg, reg, PSR_CARRY_SHIFT);
278 279 280
    tcg_gen_andi_tl(reg, reg, 0x1);
}

281 282
static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
{
P
pbrook 已提交
283 284
    TCGv r_temp;
    TCGv_i32 r_const;
285 286 287 288
    int l1;

    l1 = gen_new_label();

P
pbrook 已提交
289
    r_temp = tcg_temp_new();
290
    tcg_gen_xor_tl(r_temp, src1, src2);
B
blueswir1 已提交
291
    tcg_gen_not_tl(r_temp, r_temp);
292 293
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
294
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
P
pbrook 已提交
295
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
B
blueswir1 已提交
296
    r_const = tcg_const_i32(TT_TOVF);
P
pbrook 已提交
297 298
    gen_helper_raise_exception(r_const);
    tcg_temp_free_i32(r_const);
299
    gen_set_label(l1);
B
blueswir1 已提交
300
    tcg_temp_free(r_temp);
301 302 303 304 305
}

static inline void gen_tag_tv(TCGv src1, TCGv src2)
{
    int l1;
P
pbrook 已提交
306
    TCGv_i32 r_const;
307 308

    l1 = gen_new_label();
309 310
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
P
pbrook 已提交
311
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
B
blueswir1 已提交
312
    r_const = tcg_const_i32(TT_TOVF);
P
pbrook 已提交
313 314
    gen_helper_raise_exception(r_const);
    tcg_temp_free_i32(r_const);
315 316 317
    gen_set_label(l1);
}

318 319 320 321 322
static inline void gen_op_addi_cc(TCGv dst, TCGv src1, target_long src2)
{
    tcg_gen_mov_tl(cpu_cc_src, src1);
    tcg_gen_movi_tl(cpu_cc_src2, src2);
    tcg_gen_addi_tl(cpu_cc_dst, cpu_cc_src, src2);
B
Blue Swirl 已提交
323
    tcg_gen_mov_tl(dst, cpu_cc_dst);
324 325
}

326
static inline void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2)
327
{
328
    tcg_gen_mov_tl(cpu_cc_src, src1);
329
    tcg_gen_mov_tl(cpu_cc_src2, src2);
330
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
B
Blue Swirl 已提交
331
    tcg_gen_mov_tl(dst, cpu_cc_dst);
332 333
}

334
static TCGv_i32 gen_add32_carry32(void)
335
{
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
    TCGv_i32 carry_32, cc_src1_32, cc_src2_32;

    /* Carry is computed from a previous add: (dst < src)  */
#if TARGET_LONG_BITS == 64
    cc_src1_32 = tcg_temp_new_i32();
    cc_src2_32 = tcg_temp_new_i32();
    tcg_gen_trunc_i64_i32(cc_src1_32, cpu_cc_dst);
    tcg_gen_trunc_i64_i32(cc_src2_32, cpu_cc_src);
#else
    cc_src1_32 = cpu_cc_dst;
    cc_src2_32 = cpu_cc_src;
#endif

    carry_32 = tcg_temp_new_i32();
    tcg_gen_setcond_i32(TCG_COND_LTU, carry_32, cc_src1_32, cc_src2_32);

#if TARGET_LONG_BITS == 64
    tcg_temp_free_i32(cc_src1_32);
    tcg_temp_free_i32(cc_src2_32);
#endif

    return carry_32;
358 359
}

360
static TCGv_i32 gen_sub32_carry32(void)
361
{
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 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 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459
    TCGv_i32 carry_32, cc_src1_32, cc_src2_32;

    /* Carry is computed from a previous borrow: (src1 < src2)  */
#if TARGET_LONG_BITS == 64
    cc_src1_32 = tcg_temp_new_i32();
    cc_src2_32 = tcg_temp_new_i32();
    tcg_gen_trunc_i64_i32(cc_src1_32, cpu_cc_src);
    tcg_gen_trunc_i64_i32(cc_src2_32, cpu_cc_src2);
#else
    cc_src1_32 = cpu_cc_src;
    cc_src2_32 = cpu_cc_src2;
#endif

    carry_32 = tcg_temp_new_i32();
    tcg_gen_setcond_i32(TCG_COND_LTU, carry_32, cc_src1_32, cc_src2_32);

#if TARGET_LONG_BITS == 64
    tcg_temp_free_i32(cc_src1_32);
    tcg_temp_free_i32(cc_src2_32);
#endif

    return carry_32;
}

static void gen_op_addx_int(DisasContext *dc, TCGv dst, TCGv src1,
                            TCGv src2, int update_cc)
{
    TCGv_i32 carry_32;
    TCGv carry;

    switch (dc->cc_op) {
    case CC_OP_DIV:
    case CC_OP_LOGIC:
        /* Carry is known to be zero.  Fall back to plain ADD.  */
        if (update_cc) {
            gen_op_add_cc(dst, src1, src2);
        } else {
            tcg_gen_add_tl(dst, src1, src2);
        }
        return;

    case CC_OP_ADD:
    case CC_OP_TADD:
    case CC_OP_TADDTV:
#if TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 32
        {
            /* For 32-bit hosts, we can re-use the host's hardware carry
               generation by using an ADD2 opcode.  We discard the low
               part of the output.  Ideally we'd combine this operation
               with the add that generated the carry in the first place.  */
            TCGv dst_low = tcg_temp_new();
            tcg_gen_op6_i32(INDEX_op_add2_i32, dst_low, dst,
                            cpu_cc_src, src1, cpu_cc_src2, src2);
            tcg_temp_free(dst_low);
            goto add_done;
        }
#endif
        carry_32 = gen_add32_carry32();
        break;

    case CC_OP_SUB:
    case CC_OP_TSUB:
    case CC_OP_TSUBTV:
        carry_32 = gen_sub32_carry32();
        break;

    default:
        /* We need external help to produce the carry.  */
        carry_32 = tcg_temp_new_i32();
        gen_helper_compute_C_icc(carry_32);
        break;
    }

#if TARGET_LONG_BITS == 64
    carry = tcg_temp_new();
    tcg_gen_extu_i32_i64(carry, carry_32);
#else
    carry = carry_32;
#endif

    tcg_gen_add_tl(dst, src1, src2);
    tcg_gen_add_tl(dst, dst, carry);

    tcg_temp_free_i32(carry_32);
#if TARGET_LONG_BITS == 64
    tcg_temp_free(carry);
#endif

#if TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 32
 add_done:
#endif
    if (update_cc) {
        tcg_gen_mov_tl(cpu_cc_src, src1);
        tcg_gen_mov_tl(cpu_cc_src2, src2);
        tcg_gen_mov_tl(cpu_cc_dst, dst);
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADDX);
        dc->cc_op = CC_OP_ADDX;
    }
460 461
}

462
static inline void gen_op_tadd_cc(TCGv dst, TCGv src1, TCGv src2)
463
{
464
    tcg_gen_mov_tl(cpu_cc_src, src1);
465
    tcg_gen_mov_tl(cpu_cc_src2, src2);
466 467
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
    tcg_gen_mov_tl(dst, cpu_cc_dst);
468 469
}

470
static inline void gen_op_tadd_ccTV(TCGv dst, TCGv src1, TCGv src2)
471
{
472
    tcg_gen_mov_tl(cpu_cc_src, src1);
473 474
    tcg_gen_mov_tl(cpu_cc_src2, src2);
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
475 476 477
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
    gen_add_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
    tcg_gen_mov_tl(dst, cpu_cc_dst);
478 479 480 481
}

static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
{
P
pbrook 已提交
482 483
    TCGv r_temp;
    TCGv_i32 r_const;
484 485 486 487
    int l1;

    l1 = gen_new_label();

P
pbrook 已提交
488
    r_temp = tcg_temp_new();
489
    tcg_gen_xor_tl(r_temp, src1, src2);
490 491
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
492
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
P
pbrook 已提交
493
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
B
blueswir1 已提交
494
    r_const = tcg_const_i32(TT_TOVF);
P
pbrook 已提交
495 496
    gen_helper_raise_exception(r_const);
    tcg_temp_free_i32(r_const);
497
    gen_set_label(l1);
B
blueswir1 已提交
498
    tcg_temp_free(r_temp);
499 500
}

B
Blue Swirl 已提交
501
static inline void gen_op_subi_cc(TCGv dst, TCGv src1, target_long src2, DisasContext *dc)
502 503 504
{
    tcg_gen_mov_tl(cpu_cc_src, src1);
    tcg_gen_movi_tl(cpu_cc_src2, src2);
B
Blue Swirl 已提交
505
    if (src2 == 0) {
B
Blue Swirl 已提交
506 507 508
        tcg_gen_mov_tl(cpu_cc_dst, src1);
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
        dc->cc_op = CC_OP_LOGIC;
B
Blue Swirl 已提交
509 510
    } else {
        tcg_gen_subi_tl(cpu_cc_dst, cpu_cc_src, src2);
B
Blue Swirl 已提交
511 512
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUB);
        dc->cc_op = CC_OP_SUB;
B
Blue Swirl 已提交
513
    }
B
Blue Swirl 已提交
514
    tcg_gen_mov_tl(dst, cpu_cc_dst);
515 516 517
}

static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2)
518
{
519
    tcg_gen_mov_tl(cpu_cc_src, src1);
520
    tcg_gen_mov_tl(cpu_cc_src2, src2);
521
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
B
Blue Swirl 已提交
522
    tcg_gen_mov_tl(dst, cpu_cc_dst);
523 524
}

525 526
static void gen_op_subx_int(DisasContext *dc, TCGv dst, TCGv src1,
                            TCGv src2, int update_cc)
527
{
528 529
    TCGv_i32 carry_32;
    TCGv carry;
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 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598
    switch (dc->cc_op) {
    case CC_OP_DIV:
    case CC_OP_LOGIC:
        /* Carry is known to be zero.  Fall back to plain SUB.  */
        if (update_cc) {
            gen_op_sub_cc(dst, src1, src2);
        } else {
            tcg_gen_sub_tl(dst, src1, src2);
        }
        return;

    case CC_OP_ADD:
    case CC_OP_TADD:
    case CC_OP_TADDTV:
        carry_32 = gen_add32_carry32();
        break;

    case CC_OP_SUB:
    case CC_OP_TSUB:
    case CC_OP_TSUBTV:
#if TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 32
        {
            /* For 32-bit hosts, we can re-use the host's hardware carry
               generation by using a SUB2 opcode.  We discard the low
               part of the output.  Ideally we'd combine this operation
               with the add that generated the carry in the first place.  */
            TCGv dst_low = tcg_temp_new();
            tcg_gen_op6_i32(INDEX_op_sub2_i32, dst_low, dst,
                            cpu_cc_src, src1, cpu_cc_src2, src2);
            tcg_temp_free(dst_low);
            goto sub_done;
        }
#endif
        carry_32 = gen_sub32_carry32();
        break;

    default:
        /* We need external help to produce the carry.  */
        carry_32 = tcg_temp_new_i32();
        gen_helper_compute_C_icc(carry_32);
        break;
    }

#if TARGET_LONG_BITS == 64
    carry = tcg_temp_new();
    tcg_gen_extu_i32_i64(carry, carry_32);
#else
    carry = carry_32;
#endif

    tcg_gen_sub_tl(dst, src1, src2);
    tcg_gen_sub_tl(dst, dst, carry);

    tcg_temp_free_i32(carry_32);
#if TARGET_LONG_BITS == 64
    tcg_temp_free(carry);
#endif

#if TCG_TARGET_REG_BITS == 32 && TARGET_LONG_BITS == 32
 sub_done:
#endif
    if (update_cc) {
        tcg_gen_mov_tl(cpu_cc_src, src1);
        tcg_gen_mov_tl(cpu_cc_src2, src2);
        tcg_gen_mov_tl(cpu_cc_dst, dst);
        tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUBX);
        dc->cc_op = CC_OP_SUBX;
    }
599 600
}

601
static inline void gen_op_tsub_cc(TCGv dst, TCGv src1, TCGv src2)
602
{
603
    tcg_gen_mov_tl(cpu_cc_src, src1);
604
    tcg_gen_mov_tl(cpu_cc_src2, src2);
605 606
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
    tcg_gen_mov_tl(dst, cpu_cc_dst);
607 608
}

609
static inline void gen_op_tsub_ccTV(TCGv dst, TCGv src1, TCGv src2)
610
{
611
    tcg_gen_mov_tl(cpu_cc_src, src1);
612 613
    tcg_gen_mov_tl(cpu_cc_src2, src2);
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
614 615 616
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
    gen_sub_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
    tcg_gen_mov_tl(dst, cpu_cc_dst);
617 618
}

619
static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
B
blueswir1 已提交
620
{
B
blueswir1 已提交
621
    TCGv r_temp;
622
    int l1;
B
blueswir1 已提交
623 624

    l1 = gen_new_label();
P
pbrook 已提交
625
    r_temp = tcg_temp_new();
B
blueswir1 已提交
626 627 628 629 630

    /* old op:
    if (!(env->y & 1))
        T1 = 0;
    */
631
    tcg_gen_andi_tl(cpu_cc_src, src1, 0xffffffff);
632
    tcg_gen_andi_tl(r_temp, cpu_y, 0x1);
633
    tcg_gen_andi_tl(cpu_cc_src2, src2, 0xffffffff);
B
blueswir1 已提交
634
    tcg_gen_brcondi_tl(TCG_COND_NE, r_temp, 0, l1);
B
blueswir1 已提交
635
    tcg_gen_movi_tl(cpu_cc_src2, 0);
636
    gen_set_label(l1);
B
blueswir1 已提交
637 638 639

    // b2 = T0 & 1;
    // env->y = (b2 << 31) | (env->y >> 1);
B
blueswir1 已提交
640 641
    tcg_gen_andi_tl(r_temp, cpu_cc_src, 0x1);
    tcg_gen_shli_tl(r_temp, r_temp, 31);
642
    tcg_gen_shri_tl(cpu_tmp0, cpu_y, 1);
643
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x7fffffff);
644 645
    tcg_gen_or_tl(cpu_tmp0, cpu_tmp0, r_temp);
    tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
B
blueswir1 已提交
646 647 648 649 650

    // b1 = N ^ V;
    gen_mov_reg_N(cpu_tmp0, cpu_psr);
    gen_mov_reg_V(r_temp, cpu_psr);
    tcg_gen_xor_tl(cpu_tmp0, cpu_tmp0, r_temp);
B
blueswir1 已提交
651
    tcg_temp_free(r_temp);
B
blueswir1 已提交
652 653 654 655

    // T0 = (b1 << 31) | (T0 >> 1);
    // src1 = T0;
    tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
656
    tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
B
blueswir1 已提交
657 658
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);

659
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
B
blueswir1 已提交
660

661
    tcg_gen_mov_tl(dst, cpu_cc_dst);
B
blueswir1 已提交
662 663
}

664
static inline void gen_op_multiply(TCGv dst, TCGv src1, TCGv src2, int sign_ext)
B
blueswir1 已提交
665
{
666
    TCGv_i32 r_src1, r_src2;
P
pbrook 已提交
667
    TCGv_i64 r_temp, r_temp2;
B
blueswir1 已提交
668

669 670 671 672 673 674
    r_src1 = tcg_temp_new_i32();
    r_src2 = tcg_temp_new_i32();

    tcg_gen_trunc_tl_i32(r_src1, src1);
    tcg_gen_trunc_tl_i32(r_src2, src2);

P
pbrook 已提交
675 676
    r_temp = tcg_temp_new_i64();
    r_temp2 = tcg_temp_new_i64();
B
blueswir1 已提交
677

678 679 680 681 682 683 684 685
    if (sign_ext) {
        tcg_gen_ext_i32_i64(r_temp, r_src2);
        tcg_gen_ext_i32_i64(r_temp2, r_src1);
    } else {
        tcg_gen_extu_i32_i64(r_temp, r_src2);
        tcg_gen_extu_i32_i64(r_temp2, r_src1);
    }

B
blueswir1 已提交
686 687 688
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);

    tcg_gen_shri_i64(r_temp, r_temp2, 32);
B
blueswir1 已提交
689
    tcg_gen_trunc_i64_tl(cpu_tmp0, r_temp);
P
pbrook 已提交
690
    tcg_temp_free_i64(r_temp);
691
    tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
692

693
    tcg_gen_trunc_i64_tl(dst, r_temp2);
694

P
pbrook 已提交
695
    tcg_temp_free_i64(r_temp2);
696 697 698

    tcg_temp_free_i32(r_src1);
    tcg_temp_free_i32(r_src2);
B
blueswir1 已提交
699 700
}

701
static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
B
blueswir1 已提交
702
{
703 704 705
    /* zero-extend truncated operands before multiplication */
    gen_op_multiply(dst, src1, src2, 0);
}
B
blueswir1 已提交
706

707 708 709 710
static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
{
    /* sign-extend truncated operands before multiplication */
    gen_op_multiply(dst, src1, src2, 1);
B
blueswir1 已提交
711 712
}

B
blueswir1 已提交
713
#ifdef TARGET_SPARC64
B
blueswir1 已提交
714
static inline void gen_trap_ifdivzero_tl(TCGv divisor)
B
blueswir1 已提交
715
{
P
pbrook 已提交
716
    TCGv_i32 r_const;
B
blueswir1 已提交
717 718 719
    int l1;

    l1 = gen_new_label();
P
pbrook 已提交
720
    tcg_gen_brcondi_tl(TCG_COND_NE, divisor, 0, l1);
B
blueswir1 已提交
721
    r_const = tcg_const_i32(TT_DIV_ZERO);
P
pbrook 已提交
722 723
    gen_helper_raise_exception(r_const);
    tcg_temp_free_i32(r_const);
B
blueswir1 已提交
724 725 726
    gen_set_label(l1);
}

727
static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
B
blueswir1 已提交
728 729
{
    int l1, l2;
730
    TCGv r_temp1, r_temp2;
B
blueswir1 已提交
731 732 733

    l1 = gen_new_label();
    l2 = gen_new_label();
734 735 736 737 738 739 740
    r_temp1 = tcg_temp_local_new();
    r_temp2 = tcg_temp_local_new();
    tcg_gen_mov_tl(r_temp1, src1);
    tcg_gen_mov_tl(r_temp2, src2);
    gen_trap_ifdivzero_tl(r_temp2);
    tcg_gen_brcondi_tl(TCG_COND_NE, r_temp1, INT64_MIN, l1);
    tcg_gen_brcondi_tl(TCG_COND_NE, r_temp2, -1, l1);
741
    tcg_gen_movi_i64(dst, INT64_MIN);
B
blueswir1 已提交
742
    tcg_gen_br(l2);
B
blueswir1 已提交
743
    gen_set_label(l1);
744
    tcg_gen_div_i64(dst, r_temp1, r_temp2);
B
blueswir1 已提交
745
    gen_set_label(l2);
746 747
    tcg_temp_free(r_temp1);
    tcg_temp_free(r_temp2);
B
blueswir1 已提交
748 749 750
}
#endif

751 752 753 754 755 756 757
// 1
static inline void gen_op_eval_ba(TCGv dst)
{
    tcg_gen_movi_tl(dst, 1);
}

// Z
P
pbrook 已提交
758
static inline void gen_op_eval_be(TCGv dst, TCGv_i32 src)
759 760 761 762 763
{
    gen_mov_reg_Z(dst, src);
}

// Z | (N ^ V)
P
pbrook 已提交
764
static inline void gen_op_eval_ble(TCGv dst, TCGv_i32 src)
765
{
766
    gen_mov_reg_N(cpu_tmp0, src);
767
    gen_mov_reg_V(dst, src);
768 769 770
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
    gen_mov_reg_Z(cpu_tmp0, src);
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
771 772 773
}

// N ^ V
P
pbrook 已提交
774
static inline void gen_op_eval_bl(TCGv dst, TCGv_i32 src)
775
{
776
    gen_mov_reg_V(cpu_tmp0, src);
777
    gen_mov_reg_N(dst, src);
778
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
779 780 781
}

// C | Z
P
pbrook 已提交
782
static inline void gen_op_eval_bleu(TCGv dst, TCGv_i32 src)
783
{
784
    gen_mov_reg_Z(cpu_tmp0, src);
785
    gen_mov_reg_C(dst, src);
786
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
787 788 789
}

// C
P
pbrook 已提交
790
static inline void gen_op_eval_bcs(TCGv dst, TCGv_i32 src)
791 792 793 794 795
{
    gen_mov_reg_C(dst, src);
}

// V
P
pbrook 已提交
796
static inline void gen_op_eval_bvs(TCGv dst, TCGv_i32 src)
797 798 799 800 801 802 803 804 805 806 807
{
    gen_mov_reg_V(dst, src);
}

// 0
static inline void gen_op_eval_bn(TCGv dst)
{
    tcg_gen_movi_tl(dst, 0);
}

// N
P
pbrook 已提交
808
static inline void gen_op_eval_bneg(TCGv dst, TCGv_i32 src)
809 810 811 812 813
{
    gen_mov_reg_N(dst, src);
}

// !Z
P
pbrook 已提交
814
static inline void gen_op_eval_bne(TCGv dst, TCGv_i32 src)
815 816 817 818 819 820
{
    gen_mov_reg_Z(dst, src);
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !(Z | (N ^ V))
P
pbrook 已提交
821
static inline void gen_op_eval_bg(TCGv dst, TCGv_i32 src)
822
{
823
    gen_mov_reg_N(cpu_tmp0, src);
824
    gen_mov_reg_V(dst, src);
825 826 827
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
    gen_mov_reg_Z(cpu_tmp0, src);
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
828 829 830 831
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !(N ^ V)
P
pbrook 已提交
832
static inline void gen_op_eval_bge(TCGv dst, TCGv_i32 src)
833
{
834
    gen_mov_reg_V(cpu_tmp0, src);
835
    gen_mov_reg_N(dst, src);
836
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
837 838 839 840
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !(C | Z)
P
pbrook 已提交
841
static inline void gen_op_eval_bgu(TCGv dst, TCGv_i32 src)
842
{
843
    gen_mov_reg_Z(cpu_tmp0, src);
844
    gen_mov_reg_C(dst, src);
845
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
846 847 848 849
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !C
P
pbrook 已提交
850
static inline void gen_op_eval_bcc(TCGv dst, TCGv_i32 src)
851 852 853 854 855 856
{
    gen_mov_reg_C(dst, src);
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !N
P
pbrook 已提交
857
static inline void gen_op_eval_bpos(TCGv dst, TCGv_i32 src)
858 859 860 861 862 863
{
    gen_mov_reg_N(dst, src);
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !V
P
pbrook 已提交
864
static inline void gen_op_eval_bvc(TCGv dst, TCGv_i32 src)
865 866 867 868 869 870 871 872 873 874 875 876 877 878 879
{
    gen_mov_reg_V(dst, src);
    tcg_gen_xori_tl(dst, dst, 0x1);
}

/*
  FPSR bit field FCC1 | FCC0:
   0 =
   1 <
   2 >
   3 unordered
*/
static inline void gen_mov_reg_FCC0(TCGv reg, TCGv src,
                                    unsigned int fcc_offset)
{
880
    tcg_gen_shri_tl(reg, src, FSR_FCC0_SHIFT + fcc_offset);
881 882 883 884 885 886
    tcg_gen_andi_tl(reg, reg, 0x1);
}

static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
                                    unsigned int fcc_offset)
{
887
    tcg_gen_shri_tl(reg, src, FSR_FCC1_SHIFT + fcc_offset);
888 889 890 891 892 893 894 895
    tcg_gen_andi_tl(reg, reg, 0x1);
}

// !0: FCC0 | FCC1
static inline void gen_op_eval_fbne(TCGv dst, TCGv src,
                                    unsigned int fcc_offset)
{
    gen_mov_reg_FCC0(dst, src, fcc_offset);
896 897
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
898 899 900 901 902 903 904
}

// 1 or 2: FCC0 ^ FCC1
static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
                                    unsigned int fcc_offset)
{
    gen_mov_reg_FCC0(dst, src, fcc_offset);
905 906
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
907 908 909 910 911 912 913 914 915 916 917 918 919 920
}

// 1 or 3: FCC0
static inline void gen_op_eval_fbul(TCGv dst, TCGv src,
                                    unsigned int fcc_offset)
{
    gen_mov_reg_FCC0(dst, src, fcc_offset);
}

// 1: FCC0 & !FCC1
static inline void gen_op_eval_fbl(TCGv dst, TCGv src,
                                    unsigned int fcc_offset)
{
    gen_mov_reg_FCC0(dst, src, fcc_offset);
921 922 923
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
924 925 926 927 928 929 930 931 932 933 934 935 936 937 938
}

// 2 or 3: FCC1
static inline void gen_op_eval_fbug(TCGv dst, TCGv src,
                                    unsigned int fcc_offset)
{
    gen_mov_reg_FCC1(dst, src, fcc_offset);
}

// 2: !FCC0 & FCC1
static inline void gen_op_eval_fbg(TCGv dst, TCGv src,
                                    unsigned int fcc_offset)
{
    gen_mov_reg_FCC0(dst, src, fcc_offset);
    tcg_gen_xori_tl(dst, dst, 0x1);
939 940
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
941 942 943 944 945 946 947
}

// 3: FCC0 & FCC1
static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
                                    unsigned int fcc_offset)
{
    gen_mov_reg_FCC0(dst, src, fcc_offset);
948 949
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
950 951 952 953 954 955 956
}

// 0: !(FCC0 | FCC1)
static inline void gen_op_eval_fbe(TCGv dst, TCGv src,
                                    unsigned int fcc_offset)
{
    gen_mov_reg_FCC0(dst, src, fcc_offset);
957 958
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
959 960 961 962 963 964 965 966
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// 0 or 3: !(FCC0 ^ FCC1)
static inline void gen_op_eval_fbue(TCGv dst, TCGv src,
                                    unsigned int fcc_offset)
{
    gen_mov_reg_FCC0(dst, src, fcc_offset);
967 968
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// 0 or 2: !FCC0
static inline void gen_op_eval_fbge(TCGv dst, TCGv src,
                                    unsigned int fcc_offset)
{
    gen_mov_reg_FCC0(dst, src, fcc_offset);
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !1: !(FCC0 & !FCC1)
static inline void gen_op_eval_fbuge(TCGv dst, TCGv src,
                                    unsigned int fcc_offset)
{
    gen_mov_reg_FCC0(dst, src, fcc_offset);
985 986 987
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_xori_tl(cpu_tmp0, cpu_tmp0, 0x1);
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// 0 or 1: !FCC1
static inline void gen_op_eval_fble(TCGv dst, TCGv src,
                                    unsigned int fcc_offset)
{
    gen_mov_reg_FCC1(dst, src, fcc_offset);
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !2: !(!FCC0 & FCC1)
static inline void gen_op_eval_fbule(TCGv dst, TCGv src,
                                    unsigned int fcc_offset)
{
    gen_mov_reg_FCC0(dst, src, fcc_offset);
    tcg_gen_xori_tl(dst, dst, 0x1);
1005 1006
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1007 1008 1009 1010 1011 1012 1013 1014
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !3: !(FCC0 & FCC1)
static inline void gen_op_eval_fbo(TCGv dst, TCGv src,
                                    unsigned int fcc_offset)
{
    gen_mov_reg_FCC0(dst, src, fcc_offset);
1015 1016
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1017 1018 1019
    tcg_gen_xori_tl(dst, dst, 0x1);
}

B
blueswir1 已提交
1020
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
1021
                               target_ulong pc2, TCGv r_cond)
B
bellard 已提交
1022 1023 1024 1025 1026
{
    int l1;

    l1 = gen_new_label();

P
pbrook 已提交
1027
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
B
bellard 已提交
1028

1029
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
B
bellard 已提交
1030 1031

    gen_set_label(l1);
1032
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
B
bellard 已提交
1033 1034
}

B
blueswir1 已提交
1035
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
1036
                                target_ulong pc2, TCGv r_cond)
B
bellard 已提交
1037 1038 1039 1040 1041
{
    int l1;

    l1 = gen_new_label();

P
pbrook 已提交
1042
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
B
bellard 已提交
1043

1044
    gen_goto_tb(dc, 0, pc2, pc1);
B
bellard 已提交
1045 1046

    gen_set_label(l1);
1047
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
B
bellard 已提交
1048 1049
}

1050 1051
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
                                      TCGv r_cond)
B
bellard 已提交
1052 1053 1054 1055 1056
{
    int l1, l2;

    l1 = gen_new_label();
    l2 = gen_new_label();
1057

P
pbrook 已提交
1058
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
B
bellard 已提交
1059

B
blueswir1 已提交
1060
    tcg_gen_movi_tl(cpu_npc, npc1);
B
blueswir1 已提交
1061
    tcg_gen_br(l2);
B
bellard 已提交
1062 1063

    gen_set_label(l1);
B
blueswir1 已提交
1064
    tcg_gen_movi_tl(cpu_npc, npc2);
B
bellard 已提交
1065 1066 1067
    gen_set_label(l2);
}

1068 1069 1070
/* call this function before using the condition register as it may
   have been set for a jump */
static inline void flush_cond(DisasContext *dc, TCGv cond)
B
bellard 已提交
1071 1072
{
    if (dc->npc == JUMP_PC) {
1073
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
B
bellard 已提交
1074 1075 1076 1077
        dc->npc = DYNAMIC_PC;
    }
}

1078
static inline void save_npc(DisasContext *dc, TCGv cond)
B
bellard 已提交
1079 1080
{
    if (dc->npc == JUMP_PC) {
1081
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
B
bellard 已提交
1082 1083
        dc->npc = DYNAMIC_PC;
    } else if (dc->npc != DYNAMIC_PC) {
B
blueswir1 已提交
1084
        tcg_gen_movi_tl(cpu_npc, dc->npc);
B
bellard 已提交
1085 1086 1087
    }
}

1088
static inline void save_state(DisasContext *dc, TCGv cond)
B
bellard 已提交
1089
{
B
blueswir1 已提交
1090
    tcg_gen_movi_tl(cpu_pc, dc->pc);
1091 1092 1093 1094 1095
    /* flush pending conditional evaluations before exposing cpu state */
    if (dc->cc_op != CC_OP_FLAGS) {
        dc->cc_op = CC_OP_FLAGS;
        gen_helper_compute_psr();
    }
1096
    save_npc(dc, cond);
B
bellard 已提交
1097 1098
}

1099
static inline void gen_mov_pc_npc(DisasContext *dc, TCGv cond)
B
bellard 已提交
1100 1101
{
    if (dc->npc == JUMP_PC) {
1102
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
B
blueswir1 已提交
1103
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
B
bellard 已提交
1104 1105
        dc->pc = DYNAMIC_PC;
    } else if (dc->npc == DYNAMIC_PC) {
B
blueswir1 已提交
1106
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
B
bellard 已提交
1107 1108 1109 1110 1111 1112
        dc->pc = DYNAMIC_PC;
    } else {
        dc->pc = dc->npc;
    }
}

1113 1114
static inline void gen_op_next_insn(void)
{
B
blueswir1 已提交
1115 1116
    tcg_gen_mov_tl(cpu_pc, cpu_npc);
    tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
1117 1118
}

1119 1120
static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond,
                            DisasContext *dc)
1121
{
P
pbrook 已提交
1122
    TCGv_i32 r_src;
B
bellard 已提交
1123 1124

#ifdef TARGET_SPARC64
1125
    if (cc)
1126
        r_src = cpu_xcc;
1127
    else
1128
        r_src = cpu_psr;
B
bellard 已提交
1129
#else
1130
    r_src = cpu_psr;
B
bellard 已提交
1131
#endif
1132 1133 1134 1135 1136 1137 1138 1139
    switch (dc->cc_op) {
    case CC_OP_FLAGS:
        break;
    default:
        gen_helper_compute_psr();
        dc->cc_op = CC_OP_FLAGS;
        break;
    }
1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190
    switch (cond) {
    case 0x0:
        gen_op_eval_bn(r_dst);
        break;
    case 0x1:
        gen_op_eval_be(r_dst, r_src);
        break;
    case 0x2:
        gen_op_eval_ble(r_dst, r_src);
        break;
    case 0x3:
        gen_op_eval_bl(r_dst, r_src);
        break;
    case 0x4:
        gen_op_eval_bleu(r_dst, r_src);
        break;
    case 0x5:
        gen_op_eval_bcs(r_dst, r_src);
        break;
    case 0x6:
        gen_op_eval_bneg(r_dst, r_src);
        break;
    case 0x7:
        gen_op_eval_bvs(r_dst, r_src);
        break;
    case 0x8:
        gen_op_eval_ba(r_dst);
        break;
    case 0x9:
        gen_op_eval_bne(r_dst, r_src);
        break;
    case 0xa:
        gen_op_eval_bg(r_dst, r_src);
        break;
    case 0xb:
        gen_op_eval_bge(r_dst, r_src);
        break;
    case 0xc:
        gen_op_eval_bgu(r_dst, r_src);
        break;
    case 0xd:
        gen_op_eval_bcc(r_dst, r_src);
        break;
    case 0xe:
        gen_op_eval_bpos(r_dst, r_src);
        break;
    case 0xf:
        gen_op_eval_bvc(r_dst, r_src);
        break;
    }
}
1191

1192
static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
1193
{
1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216
    unsigned int offset;

    switch (cc) {
    default:
    case 0x0:
        offset = 0;
        break;
    case 0x1:
        offset = 32 - 10;
        break;
    case 0x2:
        offset = 34 - 10;
        break;
    case 0x3:
        offset = 36 - 10;
        break;
    }

    switch (cond) {
    case 0x0:
        gen_op_eval_bn(r_dst);
        break;
    case 0x1:
B
blueswir1 已提交
1217
        gen_op_eval_fbne(r_dst, cpu_fsr, offset);
1218 1219
        break;
    case 0x2:
B
blueswir1 已提交
1220
        gen_op_eval_fblg(r_dst, cpu_fsr, offset);
1221 1222
        break;
    case 0x3:
B
blueswir1 已提交
1223
        gen_op_eval_fbul(r_dst, cpu_fsr, offset);
1224 1225
        break;
    case 0x4:
B
blueswir1 已提交
1226
        gen_op_eval_fbl(r_dst, cpu_fsr, offset);
1227 1228
        break;
    case 0x5:
B
blueswir1 已提交
1229
        gen_op_eval_fbug(r_dst, cpu_fsr, offset);
1230 1231
        break;
    case 0x6:
B
blueswir1 已提交
1232
        gen_op_eval_fbg(r_dst, cpu_fsr, offset);
1233 1234
        break;
    case 0x7:
B
blueswir1 已提交
1235
        gen_op_eval_fbu(r_dst, cpu_fsr, offset);
1236 1237 1238 1239 1240
        break;
    case 0x8:
        gen_op_eval_ba(r_dst);
        break;
    case 0x9:
B
blueswir1 已提交
1241
        gen_op_eval_fbe(r_dst, cpu_fsr, offset);
1242 1243
        break;
    case 0xa:
B
blueswir1 已提交
1244
        gen_op_eval_fbue(r_dst, cpu_fsr, offset);
1245 1246
        break;
    case 0xb:
B
blueswir1 已提交
1247
        gen_op_eval_fbge(r_dst, cpu_fsr, offset);
1248 1249
        break;
    case 0xc:
B
blueswir1 已提交
1250
        gen_op_eval_fbuge(r_dst, cpu_fsr, offset);
1251 1252
        break;
    case 0xd:
B
blueswir1 已提交
1253
        gen_op_eval_fble(r_dst, cpu_fsr, offset);
1254 1255
        break;
    case 0xe:
B
blueswir1 已提交
1256
        gen_op_eval_fbule(r_dst, cpu_fsr, offset);
1257 1258
        break;
    case 0xf:
B
blueswir1 已提交
1259
        gen_op_eval_fbo(r_dst, cpu_fsr, offset);
1260 1261
        break;
    }
1262
}
1263

1264
#ifdef TARGET_SPARC64
1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275
// Inverted logic
static const int gen_tcg_cond_reg[8] = {
    -1,
    TCG_COND_NE,
    TCG_COND_GT,
    TCG_COND_GE,
    -1,
    TCG_COND_EQ,
    TCG_COND_LE,
    TCG_COND_LT,
};
1276

1277
static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
1278 1279 1280 1281
{
    int l1;

    l1 = gen_new_label();
1282
    tcg_gen_movi_tl(r_dst, 0);
P
pbrook 已提交
1283
    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], r_src, 0, l1);
1284 1285 1286
    tcg_gen_movi_tl(r_dst, 1);
    gen_set_label(l1);
}
B
bellard 已提交
1287
#endif
1288

B
bellard 已提交
1289
/* XXX: potentially incorrect if dynamic npc */
1290 1291
static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
                      TCGv r_cond)
1292
{
1293
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1294
    target_ulong target = dc->pc + offset;
1295

1296
    if (cond == 0x0) {
B
blueswir1 已提交
1297 1298 1299 1300 1301 1302 1303 1304
        /* 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;
        }
1305
    } else if (cond == 0x8) {
B
blueswir1 已提交
1306 1307 1308 1309 1310 1311 1312
        /* unconditional taken */
        if (a) {
            dc->pc = target;
            dc->npc = dc->pc + 4;
        } else {
            dc->pc = dc->npc;
            dc->npc = target;
1313
            tcg_gen_mov_tl(cpu_pc, cpu_npc);
B
blueswir1 已提交
1314
        }
1315
    } else {
1316
        flush_cond(dc, r_cond);
1317
        gen_cond(r_cond, cc, cond, dc);
B
blueswir1 已提交
1318
        if (a) {
1319
            gen_branch_a(dc, target, dc->npc, r_cond);
1320
            dc->is_br = 1;
B
blueswir1 已提交
1321
        } else {
1322
            dc->pc = dc->npc;
B
bellard 已提交
1323 1324 1325
            dc->jump_pc[0] = target;
            dc->jump_pc[1] = dc->npc + 4;
            dc->npc = JUMP_PC;
B
blueswir1 已提交
1326
        }
1327
    }
1328 1329
}

B
bellard 已提交
1330
/* XXX: potentially incorrect if dynamic npc */
1331 1332
static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
                      TCGv r_cond)
1333 1334
{
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1335 1336
    target_ulong target = dc->pc + offset;

1337
    if (cond == 0x0) {
B
blueswir1 已提交
1338 1339 1340 1341 1342 1343 1344 1345
        /* 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;
        }
1346
    } else if (cond == 0x8) {
B
blueswir1 已提交
1347 1348 1349 1350 1351 1352 1353
        /* unconditional taken */
        if (a) {
            dc->pc = target;
            dc->npc = dc->pc + 4;
        } else {
            dc->pc = dc->npc;
            dc->npc = target;
1354
            tcg_gen_mov_tl(cpu_pc, cpu_npc);
B
blueswir1 已提交
1355
        }
1356
    } else {
1357 1358
        flush_cond(dc, r_cond);
        gen_fcond(r_cond, cc, cond);
B
blueswir1 已提交
1359
        if (a) {
1360
            gen_branch_a(dc, target, dc->npc, r_cond);
1361
            dc->is_br = 1;
B
blueswir1 已提交
1362
        } else {
1363 1364 1365 1366
            dc->pc = dc->npc;
            dc->jump_pc[0] = target;
            dc->jump_pc[1] = dc->npc + 4;
            dc->npc = JUMP_PC;
B
blueswir1 已提交
1367
        }
1368 1369 1370
    }
}

B
bellard 已提交
1371 1372
#ifdef TARGET_SPARC64
/* XXX: potentially incorrect if dynamic npc */
1373 1374
static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
                          TCGv r_cond, TCGv r_reg)
1375
{
B
bellard 已提交
1376 1377 1378
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
    target_ulong target = dc->pc + offset;

1379 1380
    flush_cond(dc, r_cond);
    gen_cond_reg(r_cond, cond, r_reg);
B
bellard 已提交
1381
    if (a) {
1382
        gen_branch_a(dc, target, dc->npc, r_cond);
B
blueswir1 已提交
1383
        dc->is_br = 1;
B
bellard 已提交
1384
    } else {
B
blueswir1 已提交
1385 1386 1387 1388
        dc->pc = dc->npc;
        dc->jump_pc[0] = target;
        dc->jump_pc[1] = dc->npc + 4;
        dc->npc = JUMP_PC;
B
bellard 已提交
1389
    }
1390 1391
}

P
pbrook 已提交
1392
static inline void gen_op_fcmps(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
1393
{
B
blueswir1 已提交
1394 1395
    switch (fccno) {
    case 0:
P
pbrook 已提交
1396
        gen_helper_fcmps(r_rs1, r_rs2);
B
blueswir1 已提交
1397 1398
        break;
    case 1:
P
pbrook 已提交
1399
        gen_helper_fcmps_fcc1(r_rs1, r_rs2);
B
blueswir1 已提交
1400 1401
        break;
    case 2:
P
pbrook 已提交
1402
        gen_helper_fcmps_fcc2(r_rs1, r_rs2);
B
blueswir1 已提交
1403 1404
        break;
    case 3:
P
pbrook 已提交
1405
        gen_helper_fcmps_fcc3(r_rs1, r_rs2);
B
blueswir1 已提交
1406 1407
        break;
    }
1408 1409 1410 1411
}

static inline void gen_op_fcmpd(int fccno)
{
P
pbrook 已提交
1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425
    switch (fccno) {
    case 0:
        gen_helper_fcmpd();
        break;
    case 1:
        gen_helper_fcmpd_fcc1();
        break;
    case 2:
        gen_helper_fcmpd_fcc2();
        break;
    case 3:
        gen_helper_fcmpd_fcc3();
        break;
    }
1426 1427 1428 1429
}

static inline void gen_op_fcmpq(int fccno)
{
P
pbrook 已提交
1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443
    switch (fccno) {
    case 0:
        gen_helper_fcmpq();
        break;
    case 1:
        gen_helper_fcmpq_fcc1();
        break;
    case 2:
        gen_helper_fcmpq_fcc2();
        break;
    case 3:
        gen_helper_fcmpq_fcc3();
        break;
    }
1444 1445
}

P
pbrook 已提交
1446
static inline void gen_op_fcmpes(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
1447
{
B
blueswir1 已提交
1448 1449
    switch (fccno) {
    case 0:
P
pbrook 已提交
1450
        gen_helper_fcmpes(r_rs1, r_rs2);
B
blueswir1 已提交
1451 1452
        break;
    case 1:
P
pbrook 已提交
1453
        gen_helper_fcmpes_fcc1(r_rs1, r_rs2);
B
blueswir1 已提交
1454 1455
        break;
    case 2:
P
pbrook 已提交
1456
        gen_helper_fcmpes_fcc2(r_rs1, r_rs2);
B
blueswir1 已提交
1457 1458
        break;
    case 3:
P
pbrook 已提交
1459
        gen_helper_fcmpes_fcc3(r_rs1, r_rs2);
B
blueswir1 已提交
1460 1461
        break;
    }
1462 1463 1464 1465
}

static inline void gen_op_fcmped(int fccno)
{
P
pbrook 已提交
1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479
    switch (fccno) {
    case 0:
        gen_helper_fcmped();
        break;
    case 1:
        gen_helper_fcmped_fcc1();
        break;
    case 2:
        gen_helper_fcmped_fcc2();
        break;
    case 3:
        gen_helper_fcmped_fcc3();
        break;
    }
1480 1481 1482 1483
}

static inline void gen_op_fcmpeq(int fccno)
{
P
pbrook 已提交
1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497
    switch (fccno) {
    case 0:
        gen_helper_fcmpeq();
        break;
    case 1:
        gen_helper_fcmpeq_fcc1();
        break;
    case 2:
        gen_helper_fcmpeq_fcc2();
        break;
    case 3:
        gen_helper_fcmpeq_fcc3();
        break;
    }
1498 1499 1500 1501
}

#else

B
blueswir1 已提交
1502
static inline void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2)
1503
{
P
pbrook 已提交
1504
    gen_helper_fcmps(r_rs1, r_rs2);
1505 1506 1507 1508
}

static inline void gen_op_fcmpd(int fccno)
{
P
pbrook 已提交
1509
    gen_helper_fcmpd();
1510 1511 1512 1513
}

static inline void gen_op_fcmpq(int fccno)
{
P
pbrook 已提交
1514
    gen_helper_fcmpq();
1515 1516
}

B
blueswir1 已提交
1517
static inline void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2)
1518
{
P
pbrook 已提交
1519
    gen_helper_fcmpes(r_rs1, r_rs2);
1520 1521 1522 1523
}

static inline void gen_op_fcmped(int fccno)
{
P
pbrook 已提交
1524
    gen_helper_fcmped();
1525 1526 1527 1528
}

static inline void gen_op_fcmpeq(int fccno)
{
P
pbrook 已提交
1529
    gen_helper_fcmpeq();
1530 1531 1532
}
#endif

B
blueswir1 已提交
1533 1534
static inline void gen_op_fpexception_im(int fsr_flags)
{
P
pbrook 已提交
1535
    TCGv_i32 r_const;
B
blueswir1 已提交
1536

1537
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_NMASK);
B
blueswir1 已提交
1538
    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
B
blueswir1 已提交
1539
    r_const = tcg_const_i32(TT_FP_EXCP);
P
pbrook 已提交
1540 1541
    gen_helper_raise_exception(r_const);
    tcg_temp_free_i32(r_const);
B
blueswir1 已提交
1542 1543
}

1544
static int gen_trap_ifnofpu(DisasContext *dc, TCGv r_cond)
B
bellard 已提交
1545 1546 1547
{
#if !defined(CONFIG_USER_ONLY)
    if (!dc->fpu_enabled) {
P
pbrook 已提交
1548
        TCGv_i32 r_const;
B
blueswir1 已提交
1549

1550
        save_state(dc, r_cond);
B
blueswir1 已提交
1551
        r_const = tcg_const_i32(TT_NFPU_INSN);
P
pbrook 已提交
1552 1553
        gen_helper_raise_exception(r_const);
        tcg_temp_free_i32(r_const);
B
bellard 已提交
1554 1555 1556 1557 1558 1559 1560
        dc->is_br = 1;
        return 1;
    }
#endif
    return 0;
}

1561 1562 1563 1564 1565 1566 1567
static inline void gen_update_fprs_dirty(int rd)
{
#if defined(TARGET_SPARC64)
    tcg_gen_ori_i32(cpu_fprs, cpu_fprs, (rd < 32) ? 1 : 2);
#endif
}

1568 1569
static inline void gen_op_clear_ieee_excp_and_FTT(void)
{
1570
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_CEXC_NMASK);
1571 1572 1573 1574
}

static inline void gen_clear_float_exceptions(void)
{
P
pbrook 已提交
1575
    gen_helper_clear_float_exceptions();
1576 1577
}

B
blueswir1 已提交
1578 1579
/* asi moves */
#ifdef TARGET_SPARC64
P
pbrook 已提交
1580
static inline TCGv_i32 gen_get_asi(int insn, TCGv r_addr)
B
blueswir1 已提交
1581
{
1582
    int asi;
P
pbrook 已提交
1583
    TCGv_i32 r_asi;
B
blueswir1 已提交
1584 1585

    if (IS_IMM) {
P
pbrook 已提交
1586
        r_asi = tcg_temp_new_i32();
1587
        tcg_gen_mov_i32(r_asi, cpu_asi);
B
blueswir1 已提交
1588 1589
    } else {
        asi = GET_FIELD(insn, 19, 26);
1590
        r_asi = tcg_const_i32(asi);
B
blueswir1 已提交
1591
    }
1592 1593 1594
    return r_asi;
}

B
blueswir1 已提交
1595 1596
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
                              int sign)
1597
{
P
pbrook 已提交
1598
    TCGv_i32 r_asi, r_size, r_sign;
1599

1600
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1601 1602
    r_size = tcg_const_i32(size);
    r_sign = tcg_const_i32(sign);
P
pbrook 已提交
1603 1604 1605 1606
    gen_helper_ld_asi(dst, addr, r_asi, r_size, r_sign);
    tcg_temp_free_i32(r_sign);
    tcg_temp_free_i32(r_size);
    tcg_temp_free_i32(r_asi);
B
blueswir1 已提交
1607 1608
}

1609
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
B
blueswir1 已提交
1610
{
P
pbrook 已提交
1611
    TCGv_i32 r_asi, r_size;
B
blueswir1 已提交
1612

1613
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1614
    r_size = tcg_const_i32(size);
P
pbrook 已提交
1615 1616 1617
    gen_helper_st_asi(addr, src, r_asi, r_size);
    tcg_temp_free_i32(r_size);
    tcg_temp_free_i32(r_asi);
B
blueswir1 已提交
1618 1619
}

1620
static inline void gen_ldf_asi(TCGv addr, int insn, int size, int rd)
B
blueswir1 已提交
1621
{
P
pbrook 已提交
1622
    TCGv_i32 r_asi, r_size, r_rd;
B
blueswir1 已提交
1623

1624
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1625 1626
    r_size = tcg_const_i32(size);
    r_rd = tcg_const_i32(rd);
P
pbrook 已提交
1627 1628 1629 1630
    gen_helper_ldf_asi(addr, r_asi, r_size, r_rd);
    tcg_temp_free_i32(r_rd);
    tcg_temp_free_i32(r_size);
    tcg_temp_free_i32(r_asi);
B
blueswir1 已提交
1631 1632
}

1633
static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
B
blueswir1 已提交
1634
{
P
pbrook 已提交
1635
    TCGv_i32 r_asi, r_size, r_rd;
B
blueswir1 已提交
1636

1637
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1638 1639
    r_size = tcg_const_i32(size);
    r_rd = tcg_const_i32(rd);
P
pbrook 已提交
1640 1641 1642 1643
    gen_helper_stf_asi(addr, r_asi, r_size, r_rd);
    tcg_temp_free_i32(r_rd);
    tcg_temp_free_i32(r_size);
    tcg_temp_free_i32(r_asi);
B
blueswir1 已提交
1644 1645
}

1646
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
B
blueswir1 已提交
1647
{
P
pbrook 已提交
1648
    TCGv_i32 r_asi, r_size, r_sign;
B
blueswir1 已提交
1649

1650
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1651 1652
    r_size = tcg_const_i32(4);
    r_sign = tcg_const_i32(0);
P
pbrook 已提交
1653 1654 1655 1656 1657
    gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
    tcg_temp_free_i32(r_sign);
    gen_helper_st_asi(addr, dst, r_asi, r_size);
    tcg_temp_free_i32(r_size);
    tcg_temp_free_i32(r_asi);
B
blueswir1 已提交
1658
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
B
blueswir1 已提交
1659 1660
}

B
blueswir1 已提交
1661
static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
B
blueswir1 已提交
1662
{
P
pbrook 已提交
1663
    TCGv_i32 r_asi, r_rd;
B
blueswir1 已提交
1664

1665
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1666
    r_rd = tcg_const_i32(rd);
P
pbrook 已提交
1667 1668 1669
    gen_helper_ldda_asi(addr, r_asi, r_rd);
    tcg_temp_free_i32(r_rd);
    tcg_temp_free_i32(r_asi);
1670 1671
}

1672
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1673
{
P
pbrook 已提交
1674
    TCGv_i32 r_asi, r_size;
1675 1676

    gen_movl_reg_TN(rd + 1, cpu_tmp0);
1677
    tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, hi);
1678
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1679
    r_size = tcg_const_i32(8);
P
pbrook 已提交
1680 1681 1682
    gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
    tcg_temp_free_i32(r_size);
    tcg_temp_free_i32(r_asi);
B
blueswir1 已提交
1683 1684
}

B
blueswir1 已提交
1685 1686
static inline void gen_cas_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
                               int rd)
B
blueswir1 已提交
1687
{
P
pbrook 已提交
1688 1689
    TCGv r_val1;
    TCGv_i32 r_asi;
B
blueswir1 已提交
1690

P
pbrook 已提交
1691
    r_val1 = tcg_temp_new();
B
blueswir1 已提交
1692
    gen_movl_reg_TN(rd, r_val1);
1693
    r_asi = gen_get_asi(insn, addr);
P
pbrook 已提交
1694 1695
    gen_helper_cas_asi(dst, addr, r_val1, val2, r_asi);
    tcg_temp_free_i32(r_asi);
B
blueswir1 已提交
1696
    tcg_temp_free(r_val1);
B
blueswir1 已提交
1697 1698
}

B
blueswir1 已提交
1699 1700
static inline void gen_casx_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
                                int rd)
B
blueswir1 已提交
1701
{
P
pbrook 已提交
1702
    TCGv_i32 r_asi;
B
blueswir1 已提交
1703

B
blueswir1 已提交
1704
    gen_movl_reg_TN(rd, cpu_tmp64);
1705
    r_asi = gen_get_asi(insn, addr);
P
pbrook 已提交
1706 1707
    gen_helper_casx_asi(dst, addr, cpu_tmp64, val2, r_asi);
    tcg_temp_free_i32(r_asi);
B
blueswir1 已提交
1708 1709 1710 1711
}

#elif !defined(CONFIG_USER_ONLY)

B
blueswir1 已提交
1712 1713
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
                              int sign)
B
blueswir1 已提交
1714
{
P
pbrook 已提交
1715
    TCGv_i32 r_asi, r_size, r_sign;
B
blueswir1 已提交
1716

B
blueswir1 已提交
1717 1718 1719
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(size);
    r_sign = tcg_const_i32(sign);
P
pbrook 已提交
1720
    gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
B
blueswir1 已提交
1721 1722 1723
    tcg_temp_free(r_sign);
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
1724
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
B
blueswir1 已提交
1725 1726
}

1727
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
B
blueswir1 已提交
1728
{
P
pbrook 已提交
1729
    TCGv_i32 r_asi, r_size;
B
blueswir1 已提交
1730

1731
    tcg_gen_extu_tl_i64(cpu_tmp64, src);
B
blueswir1 已提交
1732 1733
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(size);
P
pbrook 已提交
1734
    gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
B
blueswir1 已提交
1735 1736
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
B
blueswir1 已提交
1737 1738
}

1739
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
B
blueswir1 已提交
1740
{
P
pbrook 已提交
1741 1742
    TCGv_i32 r_asi, r_size, r_sign;
    TCGv_i64 r_val;
B
blueswir1 已提交
1743

B
blueswir1 已提交
1744 1745 1746
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(4);
    r_sign = tcg_const_i32(0);
P
pbrook 已提交
1747
    gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
B
blueswir1 已提交
1748
    tcg_temp_free(r_sign);
P
pbrook 已提交
1749 1750 1751 1752
    r_val = tcg_temp_new_i64();
    tcg_gen_extu_tl_i64(r_val, dst);
    gen_helper_st_asi(addr, r_val, r_asi, r_size);
    tcg_temp_free_i64(r_val);
B
blueswir1 已提交
1753 1754
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
B
blueswir1 已提交
1755
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
B
blueswir1 已提交
1756 1757
}

B
blueswir1 已提交
1758
static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
B
blueswir1 已提交
1759
{
P
pbrook 已提交
1760
    TCGv_i32 r_asi, r_size, r_sign;
B
blueswir1 已提交
1761

B
blueswir1 已提交
1762 1763 1764
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(8);
    r_sign = tcg_const_i32(0);
P
pbrook 已提交
1765
    gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
B
blueswir1 已提交
1766 1767 1768
    tcg_temp_free(r_sign);
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
B
blueswir1 已提交
1769 1770
    tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
    gen_movl_TN_reg(rd + 1, cpu_tmp0);
B
blueswir1 已提交
1771
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1772
    tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
B
blueswir1 已提交
1773
    gen_movl_TN_reg(rd, hi);
1774 1775
}

1776
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1777
{
P
pbrook 已提交
1778
    TCGv_i32 r_asi, r_size;
1779 1780

    gen_movl_reg_TN(rd + 1, cpu_tmp0);
1781
    tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, hi);
B
blueswir1 已提交
1782 1783
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(8);
P
pbrook 已提交
1784
    gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
B
blueswir1 已提交
1785 1786
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
B
blueswir1 已提交
1787 1788 1789 1790
}
#endif

#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1791
static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
B
blueswir1 已提交
1792
{
P
pbrook 已提交
1793 1794
    TCGv_i64 r_val;
    TCGv_i32 r_asi, r_size;
B
blueswir1 已提交
1795

1796
    gen_ld_asi(dst, addr, insn, 1, 0);
B
blueswir1 已提交
1797

B
blueswir1 已提交
1798 1799 1800
    r_val = tcg_const_i64(0xffULL);
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(1);
P
pbrook 已提交
1801 1802 1803 1804
    gen_helper_st_asi(addr, r_val, r_asi, r_size);
    tcg_temp_free_i32(r_size);
    tcg_temp_free_i32(r_asi);
    tcg_temp_free_i64(r_val);
B
blueswir1 已提交
1805 1806 1807
}
#endif

1808 1809 1810 1811 1812 1813
static inline TCGv get_src1(unsigned int insn, TCGv def)
{
    TCGv r_rs1 = def;
    unsigned int rs1;

    rs1 = GET_FIELD(insn, 13, 17);
1814 1815 1816
    if (rs1 == 0) {
        tcg_gen_movi_tl(def, 0);
    } else if (rs1 < 8) {
1817
        r_rs1 = cpu_gregs[rs1];
1818
    } else {
1819
        tcg_gen_ld_tl(def, cpu_regwptr, (rs1 - 8) * sizeof(target_ulong));
1820
    }
1821 1822 1823
    return r_rs1;
}

B
blueswir1 已提交
1824 1825 1826 1827 1828
static inline TCGv get_src2(unsigned int insn, TCGv def)
{
    TCGv r_rs2 = def;

    if (IS_IMM) { /* immediate */
1829 1830
        target_long simm = GET_FIELDs(insn, 19, 31);
        tcg_gen_movi_tl(def, simm);
B
blueswir1 已提交
1831
    } else { /* register */
1832 1833 1834 1835
        unsigned int rs2 = GET_FIELD(insn, 27, 31);
        if (rs2 == 0) {
            tcg_gen_movi_tl(def, 0);
        } else if (rs2 < 8) {
B
blueswir1 已提交
1836
            r_rs2 = cpu_gregs[rs2];
1837
        } else {
B
blueswir1 已提交
1838
            tcg_gen_ld_tl(def, cpu_regwptr, (rs2 - 8) * sizeof(target_ulong));
1839
        }
B
blueswir1 已提交
1840 1841 1842 1843
    }
    return r_rs2;
}

1844 1845 1846
#ifdef TARGET_SPARC64
static inline void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_ptr cpu_env)
{
1847
    TCGv_i32 r_tl = tcg_temp_new_i32();
1848 1849

    /* load env->tl into r_tl */
1850
    tcg_gen_ld_i32(r_tl, cpu_env, offsetof(CPUSPARCState, tl));
1851 1852

    /* tl = [0 ... MAXTL_MASK] where MAXTL_MASK must be power of 2 */
1853
    tcg_gen_andi_i32(r_tl, r_tl, MAXTL_MASK);
1854 1855

    /* calculate offset to current trap state from env->ts, reuse r_tl */
1856
    tcg_gen_muli_i32(r_tl, r_tl, sizeof (trap_state));
1857 1858 1859
    tcg_gen_addi_ptr(r_tsptr, cpu_env, offsetof(CPUState, ts));

    /* tsptr = env->ts[env->tl & MAXTL_MASK] */
1860 1861 1862 1863
    {
        TCGv_ptr r_tl_tmp = tcg_temp_new_ptr();
        tcg_gen_ext_i32_ptr(r_tl_tmp, r_tl);
        tcg_gen_add_ptr(r_tsptr, r_tsptr, r_tl_tmp);
1864
        tcg_temp_free_ptr(r_tl_tmp);
1865
    }
1866

1867
    tcg_temp_free_i32(r_tl);
1868 1869 1870
}
#endif

B
blueswir1 已提交
1871
#define CHECK_IU_FEATURE(dc, FEATURE)                      \
1872
    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
B
blueswir1 已提交
1873 1874
        goto illegal_insn;
#define CHECK_FPU_FEATURE(dc, FEATURE)                     \
1875
    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
B
blueswir1 已提交
1876 1877
        goto nfpu_insn;

B
bellard 已提交
1878
/* before an instruction, dc->pc must be static */
1879 1880 1881
static void disas_sparc_insn(DisasContext * dc)
{
    unsigned int insn, opc, rs1, rs2, rd;
1882
    TCGv cpu_src1, cpu_src2, cpu_tmp1, cpu_tmp2;
B
Blue Swirl 已提交
1883
    target_long simm;
1884

1885
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
B
blueswir1 已提交
1886
        tcg_gen_debug_insn_start(dc->pc);
B
bellard 已提交
1887
    insn = ldl_code(dc->pc);
1888
    opc = GET_FIELD(insn, 0, 1);
1889

1890
    rd = GET_FIELD(insn, 2, 6);
1891

1892 1893
    cpu_tmp1 = cpu_src1 = tcg_temp_new();
    cpu_tmp2 = cpu_src2 = tcg_temp_new();
1894

1895
    switch (opc) {
B
blueswir1 已提交
1896 1897 1898 1899 1900
    case 0:                     /* branches/sethi */
        {
            unsigned int xop = GET_FIELD(insn, 7, 9);
            int32_t target;
            switch (xop) {
B
bellard 已提交
1901
#ifdef TARGET_SPARC64
B
blueswir1 已提交
1902 1903 1904 1905 1906
            case 0x1:           /* V9 BPcc */
                {
                    int cc;

                    target = GET_FIELD_SP(insn, 0, 18);
1907
                    target = sign_extend(target, 19);
B
blueswir1 已提交
1908 1909 1910
                    target <<= 2;
                    cc = GET_FIELD_SP(insn, 20, 21);
                    if (cc == 0)
1911
                        do_branch(dc, target, insn, 0, cpu_cond);
B
blueswir1 已提交
1912
                    else if (cc == 2)
1913
                        do_branch(dc, target, insn, 1, cpu_cond);
B
blueswir1 已提交
1914 1915 1916 1917 1918 1919 1920
                    else
                        goto illegal_insn;
                    goto jmp_insn;
                }
            case 0x3:           /* V9 BPr */
                {
                    target = GET_FIELD_SP(insn, 0, 13) |
1921
                        (GET_FIELD_SP(insn, 20, 21) << 14);
B
blueswir1 已提交
1922 1923
                    target = sign_extend(target, 16);
                    target <<= 2;
1924
                    cpu_src1 = get_src1(insn, cpu_src1);
1925
                    do_branch_reg(dc, target, insn, cpu_cond, cpu_src1);
B
blueswir1 已提交
1926 1927 1928 1929 1930
                    goto jmp_insn;
                }
            case 0x5:           /* V9 FBPcc */
                {
                    int cc = GET_FIELD_SP(insn, 20, 21);
1931
                    if (gen_trap_ifnofpu(dc, cpu_cond))
B
bellard 已提交
1932
                        goto jmp_insn;
B
blueswir1 已提交
1933 1934 1935
                    target = GET_FIELD_SP(insn, 0, 18);
                    target = sign_extend(target, 19);
                    target <<= 2;
1936
                    do_fbranch(dc, target, insn, cc, cpu_cond);
B
blueswir1 已提交
1937 1938
                    goto jmp_insn;
                }
1939
#else
B
blueswir1 已提交
1940 1941 1942 1943 1944 1945 1946 1947 1948 1949
            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;
1950
                    do_branch(dc, target, insn, 0, cpu_cond);
B
blueswir1 已提交
1951 1952 1953 1954
                    goto jmp_insn;
                }
            case 0x6:           /* FBN+x */
                {
1955
                    if (gen_trap_ifnofpu(dc, cpu_cond))
B
bellard 已提交
1956
                        goto jmp_insn;
B
blueswir1 已提交
1957 1958 1959
                    target = GET_FIELD(insn, 10, 31);
                    target = sign_extend(target, 22);
                    target <<= 2;
1960
                    do_fbranch(dc, target, insn, 0, cpu_cond);
B
blueswir1 已提交
1961 1962 1963 1964 1965
                    goto jmp_insn;
                }
            case 0x4:           /* SETHI */
                if (rd) { // nop
                    uint32_t value = GET_FIELD(insn, 10, 31);
B
blueswir1 已提交
1966 1967 1968 1969 1970
                    TCGv r_const;

                    r_const = tcg_const_tl(value << 10);
                    gen_movl_TN_reg(rd, r_const);
                    tcg_temp_free(r_const);
B
blueswir1 已提交
1971 1972 1973 1974
                }
                break;
            case 0x0:           /* UNIMPL */
            default:
B
bellard 已提交
1975
                goto illegal_insn;
B
blueswir1 已提交
1976 1977 1978 1979
            }
            break;
        }
        break;
B
Blue Swirl 已提交
1980 1981
    case 1:                     /*CALL*/
        {
B
blueswir1 已提交
1982
            target_long target = GET_FIELDs(insn, 2, 31) << 2;
B
blueswir1 已提交
1983
            TCGv r_const;
1984

B
blueswir1 已提交
1985 1986 1987
            r_const = tcg_const_tl(dc->pc);
            gen_movl_TN_reg(15, r_const);
            tcg_temp_free(r_const);
B
blueswir1 已提交
1988
            target += dc->pc;
1989
            gen_mov_pc_npc(dc, cpu_cond);
B
blueswir1 已提交
1990 1991 1992 1993 1994 1995 1996
            dc->npc = target;
        }
        goto jmp_insn;
    case 2:                     /* FPU & Logical Operations */
        {
            unsigned int xop = GET_FIELD(insn, 7, 12);
            if (xop == 0x3a) {  /* generate trap */
1997
                int cond;
B
bellard 已提交
1998

1999
                cpu_src1 = get_src1(insn, cpu_src1);
B
blueswir1 已提交
2000 2001
                if (IS_IMM) {
                    rs2 = GET_FIELD(insn, 25, 31);
2002
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, rs2);
2003 2004
                } else {
                    rs2 = GET_FIELD(insn, 27, 31);
B
blueswir1 已提交
2005
                    if (rs2 != 0) {
2006 2007
                        gen_movl_reg_TN(rs2, cpu_src2);
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
2008 2009
                    } else
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
2010
                }
F
Fabien Chouteau 已提交
2011

2012
                cond = GET_FIELD(insn, 3, 6);
F
Fabien Chouteau 已提交
2013
                if (cond == 0x8) { /* Trap Always */
2014
                    save_state(dc, cpu_cond);
B
blueswir1 已提交
2015 2016 2017 2018 2019 2020
                    if ((dc->def->features & CPU_FEATURE_HYPV) &&
                        supervisor(dc))
                        tcg_gen_andi_tl(cpu_dst, cpu_dst, UA2005_HTRAP_MASK);
                    else
                        tcg_gen_andi_tl(cpu_dst, cpu_dst, V8_TRAP_MASK);
                    tcg_gen_addi_tl(cpu_dst, cpu_dst, TT_TRAP);
P
pbrook 已提交
2021
                    tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
F
Fabien Chouteau 已提交
2022 2023 2024 2025 2026 2027 2028 2029 2030

                    if (rs2 == 0 &&
                        dc->def->features & CPU_FEATURE_TA0_SHUTDOWN) {

                        gen_helper_shutdown();

                    } else {
                        gen_helper_raise_exception(cpu_tmp32);
                    }
2031
                } else if (cond != 0) {
P
pbrook 已提交
2032
                    TCGv r_cond = tcg_temp_new();
B
blueswir1 已提交
2033
                    int l1;
B
bellard 已提交
2034
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2035 2036
                    /* V9 icc/xcc */
                    int cc = GET_FIELD_SP(insn, 11, 12);
B
blueswir1 已提交
2037

2038
                    save_state(dc, cpu_cond);
B
blueswir1 已提交
2039
                    if (cc == 0)
2040
                        gen_cond(r_cond, 0, cond, dc);
B
blueswir1 已提交
2041
                    else if (cc == 2)
2042
                        gen_cond(r_cond, 1, cond, dc);
B
blueswir1 已提交
2043 2044
                    else
                        goto illegal_insn;
B
bellard 已提交
2045
#else
2046
                    save_state(dc, cpu_cond);
2047
                    gen_cond(r_cond, 0, cond, dc);
B
bellard 已提交
2048
#endif
B
blueswir1 已提交
2049 2050 2051 2052 2053 2054 2055 2056 2057
                    l1 = gen_new_label();
                    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);

                    if ((dc->def->features & CPU_FEATURE_HYPV) &&
                        supervisor(dc))
                        tcg_gen_andi_tl(cpu_dst, cpu_dst, UA2005_HTRAP_MASK);
                    else
                        tcg_gen_andi_tl(cpu_dst, cpu_dst, V8_TRAP_MASK);
                    tcg_gen_addi_tl(cpu_dst, cpu_dst, TT_TRAP);
P
pbrook 已提交
2058 2059
                    tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
                    gen_helper_raise_exception(cpu_tmp32);
B
blueswir1 已提交
2060 2061

                    gen_set_label(l1);
B
blueswir1 已提交
2062
                    tcg_temp_free(r_cond);
2063
                }
B
bellard 已提交
2064
                gen_op_next_insn();
B
bellard 已提交
2065
                tcg_gen_exit_tb(0);
B
bellard 已提交
2066 2067
                dc->is_br = 1;
                goto jmp_insn;
2068 2069 2070 2071
            } else if (xop == 0x28) {
                rs1 = GET_FIELD(insn, 13, 17);
                switch(rs1) {
                case 0: /* rdy */
2072 2073 2074 2075 2076 2077 2078 2079 2080
#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 */
2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091
                    /* Read Asr17 */
                    if (rs1 == 0x11 && dc->def->features & CPU_FEATURE_ASR17) {
                        TCGv r_const;

                        /* Read Asr17 for a Leon3 monoprocessor */
                        r_const = tcg_const_tl((1 << 8)
                                               | (dc->def->nwindows - 1));
                        gen_movl_TN_reg(rd, r_const);
                        tcg_temp_free(r_const);
                        break;
                    }
2092
#endif
2093
                    gen_movl_TN_reg(rd, cpu_y);
2094
                    break;
B
bellard 已提交
2095
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2096
                case 0x2: /* V9 rdccr */
2097
                    gen_helper_compute_psr();
P
pbrook 已提交
2098
                    gen_helper_rdccr(cpu_dst);
2099
                    gen_movl_TN_reg(rd, cpu_dst);
B
bellard 已提交
2100
                    break;
B
blueswir1 已提交
2101
                case 0x3: /* V9 rdasi */
2102
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_asi);
2103
                    gen_movl_TN_reg(rd, cpu_dst);
B
bellard 已提交
2104
                    break;
B
blueswir1 已提交
2105
                case 0x4: /* V9 rdtick */
B
blueswir1 已提交
2106
                    {
P
pbrook 已提交
2107
                        TCGv_ptr r_tickptr;
B
blueswir1 已提交
2108

P
pbrook 已提交
2109
                        r_tickptr = tcg_temp_new_ptr();
B
blueswir1 已提交
2110 2111
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                       offsetof(CPUState, tick));
P
pbrook 已提交
2112 2113
                        gen_helper_tick_get_count(cpu_dst, r_tickptr);
                        tcg_temp_free_ptr(r_tickptr);
2114
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
2115
                    }
B
bellard 已提交
2116
                    break;
B
blueswir1 已提交
2117
                case 0x5: /* V9 rdpc */
B
blueswir1 已提交
2118 2119 2120 2121 2122 2123 2124
                    {
                        TCGv r_const;

                        r_const = tcg_const_tl(dc->pc);
                        gen_movl_TN_reg(rd, r_const);
                        tcg_temp_free(r_const);
                    }
B
blueswir1 已提交
2125 2126
                    break;
                case 0x6: /* V9 rdfprs */
2127
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_fprs);
2128
                    gen_movl_TN_reg(rd, cpu_dst);
B
bellard 已提交
2129
                    break;
2130 2131
                case 0xf: /* V9 membar */
                    break; /* no effect */
B
blueswir1 已提交
2132
                case 0x13: /* Graphics Status */
2133
                    if (gen_trap_ifnofpu(dc, cpu_cond))
B
bellard 已提交
2134
                        goto jmp_insn;
2135
                    gen_movl_TN_reg(rd, cpu_gsr);
B
bellard 已提交
2136
                    break;
2137 2138 2139 2140
                case 0x16: /* Softint */
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_softint);
                    gen_movl_TN_reg(rd, cpu_dst);
                    break;
B
blueswir1 已提交
2141
                case 0x17: /* Tick compare */
2142
                    gen_movl_TN_reg(rd, cpu_tick_cmpr);
B
bellard 已提交
2143
                    break;
B
blueswir1 已提交
2144
                case 0x18: /* System tick */
B
blueswir1 已提交
2145
                    {
P
pbrook 已提交
2146
                        TCGv_ptr r_tickptr;
B
blueswir1 已提交
2147

P
pbrook 已提交
2148
                        r_tickptr = tcg_temp_new_ptr();
B
blueswir1 已提交
2149 2150
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                       offsetof(CPUState, stick));
P
pbrook 已提交
2151 2152
                        gen_helper_tick_get_count(cpu_dst, r_tickptr);
                        tcg_temp_free_ptr(r_tickptr);
2153
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
2154
                    }
B
bellard 已提交
2155
                    break;
B
blueswir1 已提交
2156
                case 0x19: /* System tick compare */
2157
                    gen_movl_TN_reg(rd, cpu_stick_cmpr);
B
bellard 已提交
2158
                    break;
B
blueswir1 已提交
2159 2160 2161 2162 2163
                case 0x10: /* Performance Control */
                case 0x11: /* Performance Instrumentation Counter */
                case 0x12: /* Dispatch Control */
                case 0x14: /* Softint set, WO */
                case 0x15: /* Softint clear, WO */
B
bellard 已提交
2164 2165
#endif
                default:
2166 2167
                    goto illegal_insn;
                }
2168
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
2169
            } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
B
bellard 已提交
2170
#ifndef TARGET_SPARC64
B
blueswir1 已提交
2171 2172
                if (!supervisor(dc))
                    goto priv_insn;
2173 2174
                gen_helper_compute_psr();
                dc->cc_op = CC_OP_FLAGS;
P
pbrook 已提交
2175
                gen_helper_rdpsr(cpu_dst);
B
blueswir1 已提交
2176
#else
2177
                CHECK_IU_FEATURE(dc, HYPV);
B
blueswir1 已提交
2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188
                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
2189
                    tcg_gen_mov_tl(cpu_dst, cpu_hintp);
B
blueswir1 已提交
2190 2191
                    break;
                case 5: // htba
2192
                    tcg_gen_mov_tl(cpu_dst, cpu_htba);
B
blueswir1 已提交
2193 2194
                    break;
                case 6: // hver
2195
                    tcg_gen_mov_tl(cpu_dst, cpu_hver);
B
blueswir1 已提交
2196 2197
                    break;
                case 31: // hstick_cmpr
2198
                    tcg_gen_mov_tl(cpu_dst, cpu_hstick_cmpr);
B
blueswir1 已提交
2199 2200 2201 2202 2203
                    break;
                default:
                    goto illegal_insn;
                }
#endif
2204
                gen_movl_TN_reg(rd, cpu_dst);
2205
                break;
B
bellard 已提交
2206
            } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
B
blueswir1 已提交
2207 2208
                if (!supervisor(dc))
                    goto priv_insn;
B
bellard 已提交
2209 2210
#ifdef TARGET_SPARC64
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
2211 2212
                switch (rs1) {
                case 0: // tpc
2213
                    {
P
pbrook 已提交
2214
                        TCGv_ptr r_tsptr;
2215

P
pbrook 已提交
2216
                        r_tsptr = tcg_temp_new_ptr();
2217
                        gen_load_trap_state_at_tl(r_tsptr, cpu_env);
P
pbrook 已提交
2218
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2219
                                      offsetof(trap_state, tpc));
P
pbrook 已提交
2220
                        tcg_temp_free_ptr(r_tsptr);
2221
                    }
B
blueswir1 已提交
2222 2223
                    break;
                case 1: // tnpc
2224
                    {
P
pbrook 已提交
2225
                        TCGv_ptr r_tsptr;
2226

P
pbrook 已提交
2227
                        r_tsptr = tcg_temp_new_ptr();
2228
                        gen_load_trap_state_at_tl(r_tsptr, cpu_env);
2229
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2230
                                      offsetof(trap_state, tnpc));
P
pbrook 已提交
2231
                        tcg_temp_free_ptr(r_tsptr);
2232
                    }
B
blueswir1 已提交
2233 2234
                    break;
                case 2: // tstate
2235
                    {
P
pbrook 已提交
2236
                        TCGv_ptr r_tsptr;
2237

P
pbrook 已提交
2238
                        r_tsptr = tcg_temp_new_ptr();
2239
                        gen_load_trap_state_at_tl(r_tsptr, cpu_env);
2240
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2241
                                      offsetof(trap_state, tstate));
P
pbrook 已提交
2242
                        tcg_temp_free_ptr(r_tsptr);
2243
                    }
B
blueswir1 已提交
2244 2245
                    break;
                case 3: // tt
2246
                    {
P
pbrook 已提交
2247
                        TCGv_ptr r_tsptr;
2248

P
pbrook 已提交
2249
                        r_tsptr = tcg_temp_new_ptr();
2250
                        gen_load_trap_state_at_tl(r_tsptr, cpu_env);
P
pbrook 已提交
2251
                        tcg_gen_ld_i32(cpu_tmp32, r_tsptr,
2252
                                       offsetof(trap_state, tt));
P
pbrook 已提交
2253 2254
                        tcg_temp_free_ptr(r_tsptr);
                        tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2255
                    }
B
blueswir1 已提交
2256 2257
                    break;
                case 4: // tick
B
blueswir1 已提交
2258
                    {
P
pbrook 已提交
2259
                        TCGv_ptr r_tickptr;
B
blueswir1 已提交
2260

P
pbrook 已提交
2261
                        r_tickptr = tcg_temp_new_ptr();
B
blueswir1 已提交
2262 2263
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                       offsetof(CPUState, tick));
P
pbrook 已提交
2264
                        gen_helper_tick_get_count(cpu_tmp0, r_tickptr);
2265
                        gen_movl_TN_reg(rd, cpu_tmp0);
P
pbrook 已提交
2266
                        tcg_temp_free_ptr(r_tickptr);
B
blueswir1 已提交
2267
                    }
B
blueswir1 已提交
2268 2269
                    break;
                case 5: // tba
2270
                    tcg_gen_mov_tl(cpu_tmp0, cpu_tbr);
B
blueswir1 已提交
2271 2272
                    break;
                case 6: // pstate
B
blueswir1 已提交
2273 2274
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, pstate));
2275
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
B
blueswir1 已提交
2276 2277
                    break;
                case 7: // tl
B
blueswir1 已提交
2278 2279
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, tl));
2280
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
B
blueswir1 已提交
2281 2282
                    break;
                case 8: // pil
B
blueswir1 已提交
2283 2284
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, psrpil));
2285
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
B
blueswir1 已提交
2286 2287
                    break;
                case 9: // cwp
P
pbrook 已提交
2288
                    gen_helper_rdcwp(cpu_tmp0);
B
blueswir1 已提交
2289 2290
                    break;
                case 10: // cansave
B
blueswir1 已提交
2291 2292
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, cansave));
2293
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
B
blueswir1 已提交
2294 2295
                    break;
                case 11: // canrestore
B
blueswir1 已提交
2296 2297
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, canrestore));
2298
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
B
blueswir1 已提交
2299 2300
                    break;
                case 12: // cleanwin
B
blueswir1 已提交
2301 2302
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, cleanwin));
2303
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
B
blueswir1 已提交
2304 2305
                    break;
                case 13: // otherwin
B
blueswir1 已提交
2306 2307
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, otherwin));
2308
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
B
blueswir1 已提交
2309 2310
                    break;
                case 14: // wstate
B
blueswir1 已提交
2311 2312
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, wstate));
2313
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
B
blueswir1 已提交
2314
                    break;
B
blueswir1 已提交
2315
                case 16: // UA2005 gl
2316
                    CHECK_IU_FEATURE(dc, GL);
B
blueswir1 已提交
2317 2318
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, gl));
2319
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
B
blueswir1 已提交
2320 2321
                    break;
                case 26: // UA2005 strand status
2322
                    CHECK_IU_FEATURE(dc, HYPV);
B
blueswir1 已提交
2323 2324
                    if (!hypervisor(dc))
                        goto priv_insn;
B
blueswir1 已提交
2325
                    tcg_gen_mov_tl(cpu_tmp0, cpu_ssr);
B
blueswir1 已提交
2326
                    break;
B
blueswir1 已提交
2327
                case 31: // ver
2328
                    tcg_gen_mov_tl(cpu_tmp0, cpu_ver);
B
blueswir1 已提交
2329 2330 2331 2332 2333
                    break;
                case 15: // fq
                default:
                    goto illegal_insn;
                }
B
bellard 已提交
2334
#else
2335
                tcg_gen_ext_i32_tl(cpu_tmp0, cpu_wim);
B
bellard 已提交
2336
#endif
2337
                gen_movl_TN_reg(rd, cpu_tmp0);
2338
                break;
B
bellard 已提交
2339 2340
            } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
#ifdef TARGET_SPARC64
2341
                save_state(dc, cpu_cond);
P
pbrook 已提交
2342
                gen_helper_flushw();
B
bellard 已提交
2343
#else
B
blueswir1 已提交
2344 2345
                if (!supervisor(dc))
                    goto priv_insn;
2346
                gen_movl_TN_reg(rd, cpu_tbr);
B
bellard 已提交
2347
#endif
2348 2349
                break;
#endif
B
blueswir1 已提交
2350
            } else if (xop == 0x34) {   /* FPU Operations */
2351
                if (gen_trap_ifnofpu(dc, cpu_cond))
B
bellard 已提交
2352
                    goto jmp_insn;
B
blueswir1 已提交
2353
                gen_op_clear_ieee_excp_and_FTT();
2354
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
2355 2356
                rs2 = GET_FIELD(insn, 27, 31);
                xop = GET_FIELD(insn, 18, 26);
B
Blue Swirl 已提交
2357
                save_state(dc, cpu_cond);
B
blueswir1 已提交
2358
                switch (xop) {
B
Blue Swirl 已提交
2359 2360
                case 0x1: /* fmovs */
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);
2361
                    gen_update_fprs_dirty(rd);
B
Blue Swirl 已提交
2362 2363 2364
                    break;
                case 0x5: /* fnegs */
                    gen_helper_fnegs(cpu_fpr[rd], cpu_fpr[rs2]);
2365
                    gen_update_fprs_dirty(rd);
B
Blue Swirl 已提交
2366 2367 2368
                    break;
                case 0x9: /* fabss */
                    gen_helper_fabss(cpu_fpr[rd], cpu_fpr[rs2]);
2369
                    gen_update_fprs_dirty(rd);
B
Blue Swirl 已提交
2370 2371 2372 2373 2374 2375 2376
                    break;
                case 0x29: /* fsqrts */
                    CHECK_FPU_FEATURE(dc, FSQRT);
                    gen_clear_float_exceptions();
                    gen_helper_fsqrts(cpu_tmp32, cpu_fpr[rs2]);
                    gen_helper_check_ieee_exceptions();
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2377
                    gen_update_fprs_dirty(rd);
B
Blue Swirl 已提交
2378 2379 2380 2381 2382 2383 2384 2385
                    break;
                case 0x2a: /* fsqrtd */
                    CHECK_FPU_FEATURE(dc, FSQRT);
                    gen_op_load_fpr_DT1(DFPREG(rs2));
                    gen_clear_float_exceptions();
                    gen_helper_fsqrtd();
                    gen_helper_check_ieee_exceptions();
                    gen_op_store_DT0_fpr(DFPREG(rd));
2386
                    gen_update_fprs_dirty(DFPREG(rd));
B
Blue Swirl 已提交
2387 2388 2389 2390 2391 2392 2393 2394
                    break;
                case 0x2b: /* fsqrtq */
                    CHECK_FPU_FEATURE(dc, FLOAT128);
                    gen_op_load_fpr_QT1(QFPREG(rs2));
                    gen_clear_float_exceptions();
                    gen_helper_fsqrtq();
                    gen_helper_check_ieee_exceptions();
                    gen_op_store_QT0_fpr(QFPREG(rd));
2395
                    gen_update_fprs_dirty(QFPREG(rd));
B
Blue Swirl 已提交
2396 2397 2398 2399 2400 2401
                    break;
                case 0x41: /* fadds */
                    gen_clear_float_exceptions();
                    gen_helper_fadds(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
                    gen_helper_check_ieee_exceptions();
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2402
                    gen_update_fprs_dirty(rd);
B
Blue Swirl 已提交
2403 2404 2405 2406 2407 2408 2409 2410
                    break;
                case 0x42: /* faddd */
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
                    gen_clear_float_exceptions();
                    gen_helper_faddd();
                    gen_helper_check_ieee_exceptions();
                    gen_op_store_DT0_fpr(DFPREG(rd));
2411
                    gen_update_fprs_dirty(DFPREG(rd));
B
Blue Swirl 已提交
2412 2413 2414 2415 2416 2417 2418 2419 2420
                    break;
                case 0x43: /* faddq */
                    CHECK_FPU_FEATURE(dc, FLOAT128);
                    gen_op_load_fpr_QT0(QFPREG(rs1));
                    gen_op_load_fpr_QT1(QFPREG(rs2));
                    gen_clear_float_exceptions();
                    gen_helper_faddq();
                    gen_helper_check_ieee_exceptions();
                    gen_op_store_QT0_fpr(QFPREG(rd));
2421
                    gen_update_fprs_dirty(QFPREG(rd));
B
Blue Swirl 已提交
2422 2423 2424 2425 2426 2427
                    break;
                case 0x45: /* fsubs */
                    gen_clear_float_exceptions();
                    gen_helper_fsubs(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
                    gen_helper_check_ieee_exceptions();
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2428
                    gen_update_fprs_dirty(rd);
B
Blue Swirl 已提交
2429 2430 2431 2432 2433 2434 2435 2436
                    break;
                case 0x46: /* fsubd */
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
                    gen_clear_float_exceptions();
                    gen_helper_fsubd();
                    gen_helper_check_ieee_exceptions();
                    gen_op_store_DT0_fpr(DFPREG(rd));
2437
                    gen_update_fprs_dirty(DFPREG(rd));
B
Blue Swirl 已提交
2438 2439 2440 2441 2442 2443 2444 2445 2446
                    break;
                case 0x47: /* fsubq */
                    CHECK_FPU_FEATURE(dc, FLOAT128);
                    gen_op_load_fpr_QT0(QFPREG(rs1));
                    gen_op_load_fpr_QT1(QFPREG(rs2));
                    gen_clear_float_exceptions();
                    gen_helper_fsubq();
                    gen_helper_check_ieee_exceptions();
                    gen_op_store_QT0_fpr(QFPREG(rd));
2447
                    gen_update_fprs_dirty(QFPREG(rd));
B
Blue Swirl 已提交
2448 2449 2450 2451 2452 2453 2454
                    break;
                case 0x49: /* fmuls */
                    CHECK_FPU_FEATURE(dc, FMUL);
                    gen_clear_float_exceptions();
                    gen_helper_fmuls(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
                    gen_helper_check_ieee_exceptions();
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2455
                    gen_update_fprs_dirty(rd);
B
Blue Swirl 已提交
2456 2457 2458 2459 2460 2461 2462 2463 2464
                    break;
                case 0x4a: /* fmuld */
                    CHECK_FPU_FEATURE(dc, FMUL);
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
                    gen_clear_float_exceptions();
                    gen_helper_fmuld();
                    gen_helper_check_ieee_exceptions();
                    gen_op_store_DT0_fpr(DFPREG(rd));
2465
                    gen_update_fprs_dirty(DFPREG(rd));
B
Blue Swirl 已提交
2466 2467 2468 2469 2470 2471 2472 2473 2474 2475
                    break;
                case 0x4b: /* fmulq */
                    CHECK_FPU_FEATURE(dc, FLOAT128);
                    CHECK_FPU_FEATURE(dc, FMUL);
                    gen_op_load_fpr_QT0(QFPREG(rs1));
                    gen_op_load_fpr_QT1(QFPREG(rs2));
                    gen_clear_float_exceptions();
                    gen_helper_fmulq();
                    gen_helper_check_ieee_exceptions();
                    gen_op_store_QT0_fpr(QFPREG(rd));
2476
                    gen_update_fprs_dirty(QFPREG(rd));
B
Blue Swirl 已提交
2477 2478 2479 2480 2481 2482
                    break;
                case 0x4d: /* fdivs */
                    gen_clear_float_exceptions();
                    gen_helper_fdivs(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
                    gen_helper_check_ieee_exceptions();
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2483
                    gen_update_fprs_dirty(rd);
B
Blue Swirl 已提交
2484 2485 2486 2487 2488 2489 2490 2491
                    break;
                case 0x4e: /* fdivd */
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
                    gen_clear_float_exceptions();
                    gen_helper_fdivd();
                    gen_helper_check_ieee_exceptions();
                    gen_op_store_DT0_fpr(DFPREG(rd));
2492
                    gen_update_fprs_dirty(DFPREG(rd));
B
Blue Swirl 已提交
2493 2494 2495 2496 2497 2498 2499 2500 2501
                    break;
                case 0x4f: /* fdivq */
                    CHECK_FPU_FEATURE(dc, FLOAT128);
                    gen_op_load_fpr_QT0(QFPREG(rs1));
                    gen_op_load_fpr_QT1(QFPREG(rs2));
                    gen_clear_float_exceptions();
                    gen_helper_fdivq();
                    gen_helper_check_ieee_exceptions();
                    gen_op_store_QT0_fpr(QFPREG(rd));
2502
                    gen_update_fprs_dirty(QFPREG(rd));
B
Blue Swirl 已提交
2503 2504 2505 2506 2507 2508 2509
                    break;
                case 0x69: /* fsmuld */
                    CHECK_FPU_FEATURE(dc, FSMULD);
                    gen_clear_float_exceptions();
                    gen_helper_fsmuld(cpu_fpr[rs1], cpu_fpr[rs2]);
                    gen_helper_check_ieee_exceptions();
                    gen_op_store_DT0_fpr(DFPREG(rd));
2510
                    gen_update_fprs_dirty(DFPREG(rd));
B
Blue Swirl 已提交
2511 2512 2513 2514 2515 2516 2517 2518 2519
                    break;
                case 0x6e: /* fdmulq */
                    CHECK_FPU_FEATURE(dc, FLOAT128);
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
                    gen_clear_float_exceptions();
                    gen_helper_fdmulq();
                    gen_helper_check_ieee_exceptions();
                    gen_op_store_QT0_fpr(QFPREG(rd));
2520
                    gen_update_fprs_dirty(QFPREG(rd));
B
Blue Swirl 已提交
2521 2522 2523 2524 2525 2526
                    break;
                case 0xc4: /* fitos */
                    gen_clear_float_exceptions();
                    gen_helper_fitos(cpu_tmp32, cpu_fpr[rs2]);
                    gen_helper_check_ieee_exceptions();
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2527
                    gen_update_fprs_dirty(rd);
B
Blue Swirl 已提交
2528 2529 2530 2531 2532 2533 2534
                    break;
                case 0xc6: /* fdtos */
                    gen_op_load_fpr_DT1(DFPREG(rs2));
                    gen_clear_float_exceptions();
                    gen_helper_fdtos(cpu_tmp32);
                    gen_helper_check_ieee_exceptions();
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2535
                    gen_update_fprs_dirty(rd);
B
Blue Swirl 已提交
2536 2537 2538 2539 2540 2541 2542 2543
                    break;
                case 0xc7: /* fqtos */
                    CHECK_FPU_FEATURE(dc, FLOAT128);
                    gen_op_load_fpr_QT1(QFPREG(rs2));
                    gen_clear_float_exceptions();
                    gen_helper_fqtos(cpu_tmp32);
                    gen_helper_check_ieee_exceptions();
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2544
                    gen_update_fprs_dirty(rd);
B
Blue Swirl 已提交
2545 2546 2547 2548
                    break;
                case 0xc8: /* fitod */
                    gen_helper_fitod(cpu_fpr[rs2]);
                    gen_op_store_DT0_fpr(DFPREG(rd));
2549
                    gen_update_fprs_dirty(DFPREG(rd));
B
Blue Swirl 已提交
2550 2551 2552 2553
                    break;
                case 0xc9: /* fstod */
                    gen_helper_fstod(cpu_fpr[rs2]);
                    gen_op_store_DT0_fpr(DFPREG(rd));
2554
                    gen_update_fprs_dirty(DFPREG(rd));
B
Blue Swirl 已提交
2555 2556 2557 2558 2559 2560 2561 2562
                    break;
                case 0xcb: /* fqtod */
                    CHECK_FPU_FEATURE(dc, FLOAT128);
                    gen_op_load_fpr_QT1(QFPREG(rs2));
                    gen_clear_float_exceptions();
                    gen_helper_fqtod();
                    gen_helper_check_ieee_exceptions();
                    gen_op_store_DT0_fpr(DFPREG(rd));
2563
                    gen_update_fprs_dirty(DFPREG(rd));
B
Blue Swirl 已提交
2564 2565 2566 2567 2568
                    break;
                case 0xcc: /* fitoq */
                    CHECK_FPU_FEATURE(dc, FLOAT128);
                    gen_helper_fitoq(cpu_fpr[rs2]);
                    gen_op_store_QT0_fpr(QFPREG(rd));
2569
                    gen_update_fprs_dirty(QFPREG(rd));
B
Blue Swirl 已提交
2570 2571 2572 2573 2574
                    break;
                case 0xcd: /* fstoq */
                    CHECK_FPU_FEATURE(dc, FLOAT128);
                    gen_helper_fstoq(cpu_fpr[rs2]);
                    gen_op_store_QT0_fpr(QFPREG(rd));
2575
                    gen_update_fprs_dirty(QFPREG(rd));
B
Blue Swirl 已提交
2576 2577 2578 2579 2580 2581
                    break;
                case 0xce: /* fdtoq */
                    CHECK_FPU_FEATURE(dc, FLOAT128);
                    gen_op_load_fpr_DT1(DFPREG(rs2));
                    gen_helper_fdtoq();
                    gen_op_store_QT0_fpr(QFPREG(rd));
2582
                    gen_update_fprs_dirty(QFPREG(rd));
B
Blue Swirl 已提交
2583 2584 2585 2586 2587 2588
                    break;
                case 0xd1: /* fstoi */
                    gen_clear_float_exceptions();
                    gen_helper_fstoi(cpu_tmp32, cpu_fpr[rs2]);
                    gen_helper_check_ieee_exceptions();
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2589
                    gen_update_fprs_dirty(rd);
B
Blue Swirl 已提交
2590 2591 2592 2593 2594 2595 2596
                    break;
                case 0xd2: /* fdtoi */
                    gen_op_load_fpr_DT1(DFPREG(rs2));
                    gen_clear_float_exceptions();
                    gen_helper_fdtoi(cpu_tmp32);
                    gen_helper_check_ieee_exceptions();
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2597
                    gen_update_fprs_dirty(rd);
B
Blue Swirl 已提交
2598 2599 2600 2601 2602 2603 2604 2605
                    break;
                case 0xd3: /* fqtoi */
                    CHECK_FPU_FEATURE(dc, FLOAT128);
                    gen_op_load_fpr_QT1(QFPREG(rs2));
                    gen_clear_float_exceptions();
                    gen_helper_fqtoi(cpu_tmp32);
                    gen_helper_check_ieee_exceptions();
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2606
                    gen_update_fprs_dirty(rd);
B
Blue Swirl 已提交
2607
                    break;
B
bellard 已提交
2608
#ifdef TARGET_SPARC64
B
Blue Swirl 已提交
2609 2610 2611 2612
                case 0x2: /* V9 fmovd */
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)]);
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1],
                                    cpu_fpr[DFPREG(rs2) + 1]);
2613
                    gen_update_fprs_dirty(DFPREG(rd));
B
Blue Swirl 已提交
2614 2615 2616 2617 2618 2619 2620 2621 2622 2623
                    break;
                case 0x3: /* V9 fmovq */
                    CHECK_FPU_FEATURE(dc, FLOAT128);
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], cpu_fpr[QFPREG(rs2)]);
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1],
                                    cpu_fpr[QFPREG(rs2) + 1]);
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2],
                                    cpu_fpr[QFPREG(rs2) + 2]);
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3],
                                    cpu_fpr[QFPREG(rs2) + 3]);
2624
                    gen_update_fprs_dirty(QFPREG(rd));
B
Blue Swirl 已提交
2625 2626 2627 2628 2629
                    break;
                case 0x6: /* V9 fnegd */
                    gen_op_load_fpr_DT1(DFPREG(rs2));
                    gen_helper_fnegd();
                    gen_op_store_DT0_fpr(DFPREG(rd));
2630
                    gen_update_fprs_dirty(DFPREG(rd));
B
Blue Swirl 已提交
2631 2632 2633 2634 2635 2636
                    break;
                case 0x7: /* V9 fnegq */
                    CHECK_FPU_FEATURE(dc, FLOAT128);
                    gen_op_load_fpr_QT1(QFPREG(rs2));
                    gen_helper_fnegq();
                    gen_op_store_QT0_fpr(QFPREG(rd));
2637
                    gen_update_fprs_dirty(QFPREG(rd));
B
Blue Swirl 已提交
2638 2639 2640 2641 2642
                    break;
                case 0xa: /* V9 fabsd */
                    gen_op_load_fpr_DT1(DFPREG(rs2));
                    gen_helper_fabsd();
                    gen_op_store_DT0_fpr(DFPREG(rd));
2643
                    gen_update_fprs_dirty(DFPREG(rd));
B
Blue Swirl 已提交
2644 2645 2646 2647 2648 2649
                    break;
                case 0xb: /* V9 fabsq */
                    CHECK_FPU_FEATURE(dc, FLOAT128);
                    gen_op_load_fpr_QT1(QFPREG(rs2));
                    gen_helper_fabsq();
                    gen_op_store_QT0_fpr(QFPREG(rd));
2650
                    gen_update_fprs_dirty(QFPREG(rd));
B
Blue Swirl 已提交
2651 2652 2653 2654 2655 2656
                    break;
                case 0x81: /* V9 fstox */
                    gen_clear_float_exceptions();
                    gen_helper_fstox(cpu_fpr[rs2]);
                    gen_helper_check_ieee_exceptions();
                    gen_op_store_DT0_fpr(DFPREG(rd));
2657
                    gen_update_fprs_dirty(DFPREG(rd));
B
Blue Swirl 已提交
2658 2659 2660 2661 2662 2663 2664
                    break;
                case 0x82: /* V9 fdtox */
                    gen_op_load_fpr_DT1(DFPREG(rs2));
                    gen_clear_float_exceptions();
                    gen_helper_fdtox();
                    gen_helper_check_ieee_exceptions();
                    gen_op_store_DT0_fpr(DFPREG(rd));
2665
                    gen_update_fprs_dirty(DFPREG(rd));
B
Blue Swirl 已提交
2666 2667 2668 2669 2670 2671 2672 2673
                    break;
                case 0x83: /* V9 fqtox */
                    CHECK_FPU_FEATURE(dc, FLOAT128);
                    gen_op_load_fpr_QT1(QFPREG(rs2));
                    gen_clear_float_exceptions();
                    gen_helper_fqtox();
                    gen_helper_check_ieee_exceptions();
                    gen_op_store_DT0_fpr(DFPREG(rd));
2674
                    gen_update_fprs_dirty(DFPREG(rd));
B
Blue Swirl 已提交
2675 2676 2677 2678 2679 2680 2681
                    break;
                case 0x84: /* V9 fxtos */
                    gen_op_load_fpr_DT1(DFPREG(rs2));
                    gen_clear_float_exceptions();
                    gen_helper_fxtos(cpu_tmp32);
                    gen_helper_check_ieee_exceptions();
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2682
                    gen_update_fprs_dirty(rd);
B
Blue Swirl 已提交
2683 2684 2685 2686 2687 2688 2689
                    break;
                case 0x88: /* V9 fxtod */
                    gen_op_load_fpr_DT1(DFPREG(rs2));
                    gen_clear_float_exceptions();
                    gen_helper_fxtod();
                    gen_helper_check_ieee_exceptions();
                    gen_op_store_DT0_fpr(DFPREG(rd));
2690
                    gen_update_fprs_dirty(DFPREG(rd));
B
Blue Swirl 已提交
2691 2692 2693 2694 2695 2696 2697 2698
                    break;
                case 0x8c: /* V9 fxtoq */
                    CHECK_FPU_FEATURE(dc, FLOAT128);
                    gen_op_load_fpr_DT1(DFPREG(rs2));
                    gen_clear_float_exceptions();
                    gen_helper_fxtoq();
                    gen_helper_check_ieee_exceptions();
                    gen_op_store_QT0_fpr(QFPREG(rd));
2699
                    gen_update_fprs_dirty(QFPREG(rd));
B
Blue Swirl 已提交
2700
                    break;
B
blueswir1 已提交
2701
#endif
B
Blue Swirl 已提交
2702 2703
                default:
                    goto illegal_insn;
B
blueswir1 已提交
2704 2705
                }
            } else if (xop == 0x35) {   /* FPU Operations */
B
bellard 已提交
2706
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2707
                int cond;
B
bellard 已提交
2708
#endif
2709
                if (gen_trap_ifnofpu(dc, cpu_cond))
B
bellard 已提交
2710
                    goto jmp_insn;
B
blueswir1 已提交
2711
                gen_op_clear_ieee_excp_and_FTT();
2712
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
2713 2714
                rs2 = GET_FIELD(insn, 27, 31);
                xop = GET_FIELD(insn, 18, 26);
B
Blue Swirl 已提交
2715
                save_state(dc, cpu_cond);
B
bellard 已提交
2716
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2717
                if ((xop & 0x11f) == 0x005) { // V9 fmovsr
B
blueswir1 已提交
2718 2719 2720
                    int l1;

                    l1 = gen_new_label();
B
blueswir1 已提交
2721
                    cond = GET_FIELD_SP(insn, 14, 17);
2722
                    cpu_src1 = get_src1(insn, cpu_src1);
P
pbrook 已提交
2723 2724
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
                                       0, l1);
B
blueswir1 已提交
2725
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);
2726
                    gen_update_fprs_dirty(rd);
B
blueswir1 已提交
2727
                    gen_set_label(l1);
B
blueswir1 已提交
2728 2729
                    break;
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
B
blueswir1 已提交
2730 2731 2732
                    int l1;

                    l1 = gen_new_label();
B
blueswir1 已提交
2733
                    cond = GET_FIELD_SP(insn, 14, 17);
2734
                    cpu_src1 = get_src1(insn, cpu_src1);
P
pbrook 已提交
2735 2736
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
                                       0, l1);
B
blueswir1 已提交
2737 2738
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)]);
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], cpu_fpr[DFPREG(rs2) + 1]);
2739
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
2740
                    gen_set_label(l1);
B
blueswir1 已提交
2741 2742
                    break;
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
B
blueswir1 已提交
2743 2744
                    int l1;

B
blueswir1 已提交
2745
                    CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2746
                    l1 = gen_new_label();
B
blueswir1 已提交
2747
                    cond = GET_FIELD_SP(insn, 14, 17);
2748
                    cpu_src1 = get_src1(insn, cpu_src1);
P
pbrook 已提交
2749 2750
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
                                       0, l1);
B
blueswir1 已提交
2751 2752 2753 2754
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], cpu_fpr[QFPREG(rs2)]);
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], cpu_fpr[QFPREG(rs2) + 1]);
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], cpu_fpr[QFPREG(rs2) + 2]);
                    tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], cpu_fpr[QFPREG(rs2) + 3]);
2755
                    gen_update_fprs_dirty(QFPREG(rd));
B
blueswir1 已提交
2756
                    gen_set_label(l1);
B
blueswir1 已提交
2757
                    break;
B
blueswir1 已提交
2758 2759 2760
                }
#endif
                switch (xop) {
B
bellard 已提交
2761
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2762
#define FMOVSCC(fcc)                                                    \
2763
                    {                                                   \
2764
                        TCGv r_cond;                                    \
2765 2766 2767
                        int l1;                                         \
                                                                        \
                        l1 = gen_new_label();                           \
B
Blue Swirl 已提交
2768
                        r_cond = tcg_temp_new();                        \
2769 2770
                        cond = GET_FIELD_SP(insn, 14, 17);              \
                        gen_fcond(r_cond, fcc, cond);                   \
P
pbrook 已提交
2771 2772
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
                                           0, l1);                      \
B
blueswir1 已提交
2773
                        tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);     \
2774
                        gen_update_fprs_dirty(rd);                      \
B
blueswir1 已提交
2775 2776 2777 2778 2779 2780 2781 2782 2783
                        gen_set_label(l1);                              \
                        tcg_temp_free(r_cond);                          \
                    }
#define FMOVDCC(fcc)                                                    \
                    {                                                   \
                        TCGv r_cond;                                    \
                        int l1;                                         \
                                                                        \
                        l1 = gen_new_label();                           \
B
Blue Swirl 已提交
2784
                        r_cond = tcg_temp_new();                        \
B
blueswir1 已提交
2785 2786 2787 2788 2789 2790 2791 2792
                        cond = GET_FIELD_SP(insn, 14, 17);              \
                        gen_fcond(r_cond, fcc, cond);                   \
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
                                           0, l1);                      \
                        tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)],            \
                                        cpu_fpr[DFPREG(rs2)]);          \
                        tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1],        \
                                        cpu_fpr[DFPREG(rs2) + 1]);      \
2793
                        gen_update_fprs_dirty(DFPREG(rd));              \
B
blueswir1 已提交
2794 2795 2796 2797 2798 2799 2800 2801 2802
                        gen_set_label(l1);                              \
                        tcg_temp_free(r_cond);                          \
                    }
#define FMOVQCC(fcc)                                                    \
                    {                                                   \
                        TCGv r_cond;                                    \
                        int l1;                                         \
                                                                        \
                        l1 = gen_new_label();                           \
B
Blue Swirl 已提交
2803
                        r_cond = tcg_temp_new();                        \
B
blueswir1 已提交
2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815
                        cond = GET_FIELD_SP(insn, 14, 17);              \
                        gen_fcond(r_cond, fcc, cond);                   \
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
                                           0, l1);                      \
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)],            \
                                        cpu_fpr[QFPREG(rs2)]);          \
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1],        \
                                        cpu_fpr[QFPREG(rs2) + 1]);      \
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2],        \
                                        cpu_fpr[QFPREG(rs2) + 2]);      \
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3],        \
                                        cpu_fpr[QFPREG(rs2) + 3]);      \
2816
                        gen_update_fprs_dirty(QFPREG(rd));              \
2817
                        gen_set_label(l1);                              \
B
blueswir1 已提交
2818
                        tcg_temp_free(r_cond);                          \
2819
                    }
B
blueswir1 已提交
2820
                    case 0x001: /* V9 fmovscc %fcc0 */
B
blueswir1 已提交
2821
                        FMOVSCC(0);
B
blueswir1 已提交
2822 2823
                        break;
                    case 0x002: /* V9 fmovdcc %fcc0 */
B
blueswir1 已提交
2824
                        FMOVDCC(0);
B
blueswir1 已提交
2825 2826
                        break;
                    case 0x003: /* V9 fmovqcc %fcc0 */
B
blueswir1 已提交
2827
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2828
                        FMOVQCC(0);
B
blueswir1 已提交
2829
                        break;
B
blueswir1 已提交
2830
                    case 0x041: /* V9 fmovscc %fcc1 */
B
blueswir1 已提交
2831
                        FMOVSCC(1);
B
blueswir1 已提交
2832 2833
                        break;
                    case 0x042: /* V9 fmovdcc %fcc1 */
B
blueswir1 已提交
2834
                        FMOVDCC(1);
B
blueswir1 已提交
2835 2836
                        break;
                    case 0x043: /* V9 fmovqcc %fcc1 */
B
blueswir1 已提交
2837
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2838
                        FMOVQCC(1);
B
blueswir1 已提交
2839
                        break;
B
blueswir1 已提交
2840
                    case 0x081: /* V9 fmovscc %fcc2 */
B
blueswir1 已提交
2841
                        FMOVSCC(2);
B
blueswir1 已提交
2842 2843
                        break;
                    case 0x082: /* V9 fmovdcc %fcc2 */
B
blueswir1 已提交
2844
                        FMOVDCC(2);
B
blueswir1 已提交
2845 2846
                        break;
                    case 0x083: /* V9 fmovqcc %fcc2 */
B
blueswir1 已提交
2847
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2848
                        FMOVQCC(2);
B
blueswir1 已提交
2849
                        break;
B
blueswir1 已提交
2850
                    case 0x0c1: /* V9 fmovscc %fcc3 */
B
blueswir1 已提交
2851
                        FMOVSCC(3);
B
blueswir1 已提交
2852 2853
                        break;
                    case 0x0c2: /* V9 fmovdcc %fcc3 */
B
blueswir1 已提交
2854
                        FMOVDCC(3);
B
blueswir1 已提交
2855 2856
                        break;
                    case 0x0c3: /* V9 fmovqcc %fcc3 */
B
blueswir1 已提交
2857
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2858
                        FMOVQCC(3);
B
blueswir1 已提交
2859
                        break;
B
blueswir1 已提交
2860 2861 2862 2863 2864 2865 2866 2867 2868
#undef FMOVSCC
#undef FMOVDCC
#undef FMOVQCC
#define FMOVSCC(icc)                                                    \
                    {                                                   \
                        TCGv r_cond;                                    \
                        int l1;                                         \
                                                                        \
                        l1 = gen_new_label();                           \
B
Blue Swirl 已提交
2869
                        r_cond = tcg_temp_new();                        \
B
blueswir1 已提交
2870
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2871
                        gen_cond(r_cond, icc, cond, dc);                \
B
blueswir1 已提交
2872 2873 2874
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
                                           0, l1);                      \
                        tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);     \
2875
                        gen_update_fprs_dirty(rd);                      \
B
blueswir1 已提交
2876 2877 2878 2879 2880 2881 2882 2883 2884
                        gen_set_label(l1);                              \
                        tcg_temp_free(r_cond);                          \
                    }
#define FMOVDCC(icc)                                                    \
                    {                                                   \
                        TCGv r_cond;                                    \
                        int l1;                                         \
                                                                        \
                        l1 = gen_new_label();                           \
B
Blue Swirl 已提交
2885
                        r_cond = tcg_temp_new();                        \
B
blueswir1 已提交
2886
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2887
                        gen_cond(r_cond, icc, cond, dc);                \
B
blueswir1 已提交
2888 2889 2890 2891 2892 2893
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
                                           0, l1);                      \
                        tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)],            \
                                        cpu_fpr[DFPREG(rs2)]);          \
                        tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1],        \
                                        cpu_fpr[DFPREG(rs2) + 1]);      \
2894
                        gen_update_fprs_dirty(DFPREG(rd));              \
B
blueswir1 已提交
2895 2896 2897 2898 2899 2900 2901 2902 2903
                        gen_set_label(l1);                              \
                        tcg_temp_free(r_cond);                          \
                    }
#define FMOVQCC(icc)                                                    \
                    {                                                   \
                        TCGv r_cond;                                    \
                        int l1;                                         \
                                                                        \
                        l1 = gen_new_label();                           \
B
Blue Swirl 已提交
2904
                        r_cond = tcg_temp_new();                        \
B
blueswir1 已提交
2905
                        cond = GET_FIELD_SP(insn, 14, 17);              \
2906
                        gen_cond(r_cond, icc, cond, dc);                \
B
blueswir1 已提交
2907 2908 2909 2910 2911 2912 2913 2914 2915 2916
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
                                           0, l1);                      \
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)],            \
                                        cpu_fpr[QFPREG(rs2)]);          \
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1],        \
                                        cpu_fpr[QFPREG(rs2) + 1]);      \
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2],        \
                                        cpu_fpr[QFPREG(rs2) + 2]);      \
                        tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3],        \
                                        cpu_fpr[QFPREG(rs2) + 3]);      \
2917
                        gen_update_fprs_dirty(QFPREG(rd));              \
B
blueswir1 已提交
2918 2919 2920
                        gen_set_label(l1);                              \
                        tcg_temp_free(r_cond);                          \
                    }
2921

B
blueswir1 已提交
2922
                    case 0x101: /* V9 fmovscc %icc */
B
blueswir1 已提交
2923
                        FMOVSCC(0);
B
blueswir1 已提交
2924 2925
                        break;
                    case 0x102: /* V9 fmovdcc %icc */
B
blueswir1 已提交
2926
                        FMOVDCC(0);
2927
                        break;
B
blueswir1 已提交
2928
                    case 0x103: /* V9 fmovqcc %icc */
B
blueswir1 已提交
2929
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2930
                        FMOVQCC(0);
B
blueswir1 已提交
2931
                        break;
B
blueswir1 已提交
2932
                    case 0x181: /* V9 fmovscc %xcc */
B
blueswir1 已提交
2933
                        FMOVSCC(1);
B
blueswir1 已提交
2934 2935
                        break;
                    case 0x182: /* V9 fmovdcc %xcc */
B
blueswir1 已提交
2936
                        FMOVDCC(1);
B
blueswir1 已提交
2937 2938
                        break;
                    case 0x183: /* V9 fmovqcc %xcc */
B
blueswir1 已提交
2939
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2940
                        FMOVQCC(1);
B
blueswir1 已提交
2941
                        break;
B
blueswir1 已提交
2942 2943 2944
#undef FMOVSCC
#undef FMOVDCC
#undef FMOVQCC
B
blueswir1 已提交
2945 2946
#endif
                    case 0x51: /* fcmps, V9 %fcc */
B
blueswir1 已提交
2947
                        gen_op_fcmps(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]);
B
blueswir1 已提交
2948
                        break;
B
blueswir1 已提交
2949
                    case 0x52: /* fcmpd, V9 %fcc */
B
blueswir1 已提交
2950 2951
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2952
                        gen_op_fcmpd(rd & 3);
B
blueswir1 已提交
2953
                        break;
B
blueswir1 已提交
2954
                    case 0x53: /* fcmpq, V9 %fcc */
B
blueswir1 已提交
2955
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2956 2957
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2958
                        gen_op_fcmpq(rd & 3);
B
blueswir1 已提交
2959
                        break;
B
blueswir1 已提交
2960
                    case 0x55: /* fcmpes, V9 %fcc */
B
blueswir1 已提交
2961
                        gen_op_fcmpes(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]);
B
blueswir1 已提交
2962 2963 2964 2965
                        break;
                    case 0x56: /* fcmped, V9 %fcc */
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2966
                        gen_op_fcmped(rd & 3);
B
blueswir1 已提交
2967
                        break;
B
blueswir1 已提交
2968
                    case 0x57: /* fcmpeq, V9 %fcc */
B
blueswir1 已提交
2969
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2970 2971
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2972
                        gen_op_fcmpeq(rd & 3);
B
blueswir1 已提交
2973
                        break;
B
blueswir1 已提交
2974 2975 2976 2977 2978
                    default:
                        goto illegal_insn;
                }
            } else if (xop == 0x2) {
                // clr/mov shortcut
B
bellard 已提交
2979 2980

                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
2981
                if (rs1 == 0) {
B
blueswir1 已提交
2982
                    // or %g0, x, y -> mov T0, x; mov y, T0
B
blueswir1 已提交
2983
                    if (IS_IMM) {       /* immediate */
B
blueswir1 已提交
2984 2985
                        TCGv r_const;

B
Blue Swirl 已提交
2986 2987
                        simm = GET_FIELDs(insn, 19, 31);
                        r_const = tcg_const_tl(simm);
B
blueswir1 已提交
2988 2989
                        gen_movl_TN_reg(rd, r_const);
                        tcg_temp_free(r_const);
B
blueswir1 已提交
2990 2991
                    } else {            /* register */
                        rs2 = GET_FIELD(insn, 27, 31);
2992
                        gen_movl_reg_TN(rs2, cpu_dst);
B
blueswir1 已提交
2993
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
2994 2995
                    }
                } else {
2996
                    cpu_src1 = get_src1(insn, cpu_src1);
B
blueswir1 已提交
2997
                    if (IS_IMM) {       /* immediate */
B
Blue Swirl 已提交
2998 2999
                        simm = GET_FIELDs(insn, 19, 31);
                        tcg_gen_ori_tl(cpu_dst, cpu_src1, simm);
B
blueswir1 已提交
3000
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3001 3002 3003 3004
                    } else {            /* register */
                        // or x, %g0, y -> mov T1, x; mov y, T1
                        rs2 = GET_FIELD(insn, 27, 31);
                        if (rs2 != 0) {
3005 3006
                            gen_movl_reg_TN(rs2, cpu_src2);
                            tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
B
blueswir1 已提交
3007
                            gen_movl_TN_reg(rd, cpu_dst);
3008
                        } else
B
blueswir1 已提交
3009
                            gen_movl_TN_reg(rd, cpu_src1);
B
blueswir1 已提交
3010 3011
                    }
                }
B
bellard 已提交
3012
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3013
            } else if (xop == 0x25) { /* sll, V9 sllx */
3014
                cpu_src1 = get_src1(insn, cpu_src1);
B
blueswir1 已提交
3015
                if (IS_IMM) {   /* immediate */
B
Blue Swirl 已提交
3016
                    simm = GET_FIELDs(insn, 20, 31);
B
blueswir1 已提交
3017
                    if (insn & (1 << 12)) {
B
Blue Swirl 已提交
3018
                        tcg_gen_shli_i64(cpu_dst, cpu_src1, simm & 0x3f);
B
blueswir1 已提交
3019
                    } else {
B
Blue Swirl 已提交
3020
                        tcg_gen_shli_i64(cpu_dst, cpu_src1, simm & 0x1f);
B
blueswir1 已提交
3021
                    }
B
blueswir1 已提交
3022
                } else {                /* register */
B
bellard 已提交
3023
                    rs2 = GET_FIELD(insn, 27, 31);
3024
                    gen_movl_reg_TN(rs2, cpu_src2);
B
blueswir1 已提交
3025
                    if (insn & (1 << 12)) {
3026
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
B
blueswir1 已提交
3027
                    } else {
3028
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
B
blueswir1 已提交
3029
                    }
B
blueswir1 已提交
3030
                    tcg_gen_shl_i64(cpu_dst, cpu_src1, cpu_tmp0);
B
bellard 已提交
3031
                }
3032
                gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3033
            } else if (xop == 0x26) { /* srl, V9 srlx */
3034
                cpu_src1 = get_src1(insn, cpu_src1);
B
blueswir1 已提交
3035
                if (IS_IMM) {   /* immediate */
B
Blue Swirl 已提交
3036
                    simm = GET_FIELDs(insn, 20, 31);
B
blueswir1 已提交
3037
                    if (insn & (1 << 12)) {
B
Blue Swirl 已提交
3038
                        tcg_gen_shri_i64(cpu_dst, cpu_src1, simm & 0x3f);
B
blueswir1 已提交
3039
                    } else {
3040
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
B
Blue Swirl 已提交
3041
                        tcg_gen_shri_i64(cpu_dst, cpu_dst, simm & 0x1f);
B
blueswir1 已提交
3042
                    }
B
blueswir1 已提交
3043
                } else {                /* register */
B
bellard 已提交
3044
                    rs2 = GET_FIELD(insn, 27, 31);
3045
                    gen_movl_reg_TN(rs2, cpu_src2);
B
blueswir1 已提交
3046
                    if (insn & (1 << 12)) {
3047 3048
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
                        tcg_gen_shr_i64(cpu_dst, cpu_src1, cpu_tmp0);
B
blueswir1 已提交
3049
                    } else {
3050 3051 3052
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
                        tcg_gen_shr_i64(cpu_dst, cpu_dst, cpu_tmp0);
B
blueswir1 已提交
3053
                    }
B
bellard 已提交
3054
                }
3055
                gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3056
            } else if (xop == 0x27) { /* sra, V9 srax */
3057
                cpu_src1 = get_src1(insn, cpu_src1);
B
blueswir1 已提交
3058
                if (IS_IMM) {   /* immediate */
B
Blue Swirl 已提交
3059
                    simm = GET_FIELDs(insn, 20, 31);
B
blueswir1 已提交
3060
                    if (insn & (1 << 12)) {
B
Blue Swirl 已提交
3061
                        tcg_gen_sari_i64(cpu_dst, cpu_src1, simm & 0x3f);
B
blueswir1 已提交
3062
                    } else {
3063
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
B
blueswir1 已提交
3064
                        tcg_gen_ext32s_i64(cpu_dst, cpu_dst);
B
Blue Swirl 已提交
3065
                        tcg_gen_sari_i64(cpu_dst, cpu_dst, simm & 0x1f);
B
blueswir1 已提交
3066
                    }
B
blueswir1 已提交
3067
                } else {                /* register */
B
bellard 已提交
3068
                    rs2 = GET_FIELD(insn, 27, 31);
3069
                    gen_movl_reg_TN(rs2, cpu_src2);
B
blueswir1 已提交
3070
                    if (insn & (1 << 12)) {
3071 3072
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
                        tcg_gen_sar_i64(cpu_dst, cpu_src1, cpu_tmp0);
B
blueswir1 已提交
3073
                    } else {
3074 3075
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
B
blueswir1 已提交
3076
                        tcg_gen_ext32s_i64(cpu_dst, cpu_dst);
3077
                        tcg_gen_sar_i64(cpu_dst, cpu_dst, cpu_tmp0);
B
blueswir1 已提交
3078
                    }
B
bellard 已提交
3079
                }
3080
                gen_movl_TN_reg(rd, cpu_dst);
B
bellard 已提交
3081
#endif
3082
            } else if (xop < 0x36) {
3083
                if (xop < 0x20) {
3084 3085
                    cpu_src1 = get_src1(insn, cpu_src1);
                    cpu_src2 = get_src2(insn, cpu_src2);
3086
                    switch (xop & ~0x10) {
3087
                    case 0x0: /* add */
3088 3089 3090 3091
                        if (IS_IMM) {
                            simm = GET_FIELDs(insn, 19, 31);
                            if (xop & 0x10) {
                                gen_op_addi_cc(cpu_dst, cpu_src1, simm);
B
Blue Swirl 已提交
3092 3093
                                tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADD);
                                dc->cc_op = CC_OP_ADD;
3094 3095 3096 3097 3098 3099
                            } else {
                                tcg_gen_addi_tl(cpu_dst, cpu_src1, simm);
                            }
                        } else {
                            if (xop & 0x10) {
                                gen_op_add_cc(cpu_dst, cpu_src1, cpu_src2);
B
Blue Swirl 已提交
3100 3101
                                tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADD);
                                dc->cc_op = CC_OP_ADD;
3102 3103 3104 3105
                            } else {
                                tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
                            }
                        }
3106
                        break;
3107
                    case 0x1: /* and */
3108 3109 3110 3111 3112 3113 3114
                        if (IS_IMM) {
                            simm = GET_FIELDs(insn, 19, 31);
                            tcg_gen_andi_tl(cpu_dst, cpu_src1, simm);
                        } else {
                            tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_src2);
                        }
                        if (xop & 0x10) {
3115 3116 3117
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
                            dc->cc_op = CC_OP_LOGIC;
3118
                        }
3119
                        break;
3120
                    case 0x2: /* or */
3121 3122 3123 3124 3125 3126
                        if (IS_IMM) {
                            simm = GET_FIELDs(insn, 19, 31);
                            tcg_gen_ori_tl(cpu_dst, cpu_src1, simm);
                        } else {
                            tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
                        }
3127
                        if (xop & 0x10) {
3128 3129 3130
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
                            dc->cc_op = CC_OP_LOGIC;
3131
                        }
B
blueswir1 已提交
3132
                        break;
3133
                    case 0x3: /* xor */
3134 3135 3136 3137 3138 3139
                        if (IS_IMM) {
                            simm = GET_FIELDs(insn, 19, 31);
                            tcg_gen_xori_tl(cpu_dst, cpu_src1, simm);
                        } else {
                            tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
                        }
3140
                        if (xop & 0x10) {
3141 3142 3143
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
                            dc->cc_op = CC_OP_LOGIC;
3144
                        }
3145
                        break;
3146
                    case 0x4: /* sub */
3147 3148 3149
                        if (IS_IMM) {
                            simm = GET_FIELDs(insn, 19, 31);
                            if (xop & 0x10) {
B
Blue Swirl 已提交
3150
                                gen_op_subi_cc(cpu_dst, cpu_src1, simm, dc);
3151 3152 3153 3154 3155 3156
                            } else {
                                tcg_gen_subi_tl(cpu_dst, cpu_src1, simm);
                            }
                        } else {
                            if (xop & 0x10) {
                                gen_op_sub_cc(cpu_dst, cpu_src1, cpu_src2);
B
Blue Swirl 已提交
3157 3158
                                tcg_gen_movi_i32(cpu_cc_op, CC_OP_SUB);
                                dc->cc_op = CC_OP_SUB;
3159 3160 3161 3162
                            } else {
                                tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_src2);
                            }
                        }
3163
                        break;
3164
                    case 0x5: /* andn */
3165 3166 3167 3168 3169 3170
                        if (IS_IMM) {
                            simm = GET_FIELDs(insn, 19, 31);
                            tcg_gen_andi_tl(cpu_dst, cpu_src1, ~simm);
                        } else {
                            tcg_gen_andc_tl(cpu_dst, cpu_src1, cpu_src2);
                        }
3171
                        if (xop & 0x10) {
3172 3173 3174
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
                            dc->cc_op = CC_OP_LOGIC;
3175
                        }
3176
                        break;
3177
                    case 0x6: /* orn */
3178 3179 3180 3181 3182 3183
                        if (IS_IMM) {
                            simm = GET_FIELDs(insn, 19, 31);
                            tcg_gen_ori_tl(cpu_dst, cpu_src1, ~simm);
                        } else {
                            tcg_gen_orc_tl(cpu_dst, cpu_src1, cpu_src2);
                        }
3184
                        if (xop & 0x10) {
3185 3186 3187
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
                            dc->cc_op = CC_OP_LOGIC;
3188
                        }
3189
                        break;
3190
                    case 0x7: /* xorn */
3191 3192 3193 3194 3195 3196 3197
                        if (IS_IMM) {
                            simm = GET_FIELDs(insn, 19, 31);
                            tcg_gen_xori_tl(cpu_dst, cpu_src1, ~simm);
                        } else {
                            tcg_gen_not_tl(cpu_tmp0, cpu_src2);
                            tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_tmp0);
                        }
3198
                        if (xop & 0x10) {
3199 3200 3201
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
                            dc->cc_op = CC_OP_LOGIC;
3202
                        }
3203
                        break;
3204
                    case 0x8: /* addx, V9 addc */
3205 3206
                        gen_op_addx_int(dc, cpu_dst, cpu_src1, cpu_src2,
                                        (xop & 0x10));
3207
                        break;
P
pbrook 已提交
3208
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3209
                    case 0x9: /* V9 mulx */
3210 3211 3212 3213 3214 3215
                        if (IS_IMM) {
                            simm = GET_FIELDs(insn, 19, 31);
                            tcg_gen_muli_i64(cpu_dst, cpu_src1, simm);
                        } else {
                            tcg_gen_mul_i64(cpu_dst, cpu_src1, cpu_src2);
                        }
P
pbrook 已提交
3216 3217
                        break;
#endif
3218
                    case 0xa: /* umul */
B
blueswir1 已提交
3219
                        CHECK_IU_FEATURE(dc, MUL);
3220
                        gen_op_umul(cpu_dst, cpu_src1, cpu_src2);
3221
                        if (xop & 0x10) {
3222 3223 3224
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
                            dc->cc_op = CC_OP_LOGIC;
3225
                        }
3226
                        break;
3227
                    case 0xb: /* smul */
B
blueswir1 已提交
3228
                        CHECK_IU_FEATURE(dc, MUL);
3229
                        gen_op_smul(cpu_dst, cpu_src1, cpu_src2);
3230
                        if (xop & 0x10) {
3231 3232 3233
                            tcg_gen_mov_tl(cpu_cc_dst, cpu_dst);
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_LOGIC);
                            dc->cc_op = CC_OP_LOGIC;
3234
                        }
3235
                        break;
3236
                    case 0xc: /* subx, V9 subc */
3237 3238
                        gen_op_subx_int(dc, cpu_dst, cpu_src1, cpu_src2,
                                        (xop & 0x10));
3239
                        break;
P
pbrook 已提交
3240
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3241
                    case 0xd: /* V9 udivx */
3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252
                        {
                            TCGv r_temp1, r_temp2;
                            r_temp1 = tcg_temp_local_new();
                            r_temp2 = tcg_temp_local_new();
                            tcg_gen_mov_tl(r_temp1, cpu_src1);
                            tcg_gen_mov_tl(r_temp2, cpu_src2);
                            gen_trap_ifdivzero_tl(r_temp2);
                            tcg_gen_divu_i64(cpu_dst, r_temp1, r_temp2);
                            tcg_temp_free(r_temp1);
                            tcg_temp_free(r_temp2);
                        }
P
pbrook 已提交
3253 3254
                        break;
#endif
3255
                    case 0xe: /* udiv */
B
blueswir1 已提交
3256
                        CHECK_IU_FEATURE(dc, DIV);
3257
                        if (xop & 0x10) {
3258
                            gen_helper_udiv_cc(cpu_dst, cpu_src1, cpu_src2);
B
Blue Swirl 已提交
3259
                            dc->cc_op = CC_OP_DIV;
3260 3261
                        } else {
                            gen_helper_udiv(cpu_dst, cpu_src1, cpu_src2);
3262
                        }
3263
                        break;
3264
                    case 0xf: /* sdiv */
B
blueswir1 已提交
3265
                        CHECK_IU_FEATURE(dc, DIV);
3266
                        if (xop & 0x10) {
3267
                            gen_helper_sdiv_cc(cpu_dst, cpu_src1, cpu_src2);
B
Blue Swirl 已提交
3268
                            dc->cc_op = CC_OP_DIV;
3269 3270
                        } else {
                            gen_helper_sdiv(cpu_dst, cpu_src1, cpu_src2);
3271
                        }
3272 3273 3274 3275
                        break;
                    default:
                        goto illegal_insn;
                    }
3276
                    gen_movl_TN_reg(rd, cpu_dst);
3277
                } else {
3278 3279
                    cpu_src1 = get_src1(insn, cpu_src1);
                    cpu_src2 = get_src2(insn, cpu_src2);
3280
                    switch (xop) {
B
blueswir1 已提交
3281
                    case 0x20: /* taddcc */
3282 3283
                        gen_op_tadd_cc(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
B
Blue Swirl 已提交
3284 3285
                        tcg_gen_movi_i32(cpu_cc_op, CC_OP_TADD);
                        dc->cc_op = CC_OP_TADD;
B
blueswir1 已提交
3286 3287
                        break;
                    case 0x21: /* tsubcc */
3288 3289
                        gen_op_tsub_cc(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
B
Blue Swirl 已提交
3290 3291
                        tcg_gen_movi_i32(cpu_cc_op, CC_OP_TSUB);
                        dc->cc_op = CC_OP_TSUB;
B
blueswir1 已提交
3292 3293
                        break;
                    case 0x22: /* taddcctv */
3294 3295 3296
                        save_state(dc, cpu_cond);
                        gen_op_tadd_ccTV(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
B
Blue Swirl 已提交
3297 3298
                        tcg_gen_movi_i32(cpu_cc_op, CC_OP_TADDTV);
                        dc->cc_op = CC_OP_TADDTV;
B
blueswir1 已提交
3299 3300
                        break;
                    case 0x23: /* tsubcctv */
3301 3302 3303
                        save_state(dc, cpu_cond);
                        gen_op_tsub_ccTV(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
B
Blue Swirl 已提交
3304 3305
                        tcg_gen_movi_i32(cpu_cc_op, CC_OP_TSUBTV);
                        dc->cc_op = CC_OP_TSUBTV;
B
blueswir1 已提交
3306
                        break;
3307
                    case 0x24: /* mulscc */
3308
                        gen_helper_compute_psr();
3309 3310
                        gen_op_mulscc(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
B
Blue Swirl 已提交
3311 3312
                        tcg_gen_movi_i32(cpu_cc_op, CC_OP_ADD);
                        dc->cc_op = CC_OP_ADD;
3313
                        break;
B
bellard 已提交
3314
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3315
                    case 0x25:  /* sll */
3316
                        if (IS_IMM) { /* immediate */
B
Blue Swirl 已提交
3317 3318
                            simm = GET_FIELDs(insn, 20, 31);
                            tcg_gen_shli_tl(cpu_dst, cpu_src1, simm & 0x1f);
3319 3320 3321 3322
                        } else { /* register */
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
                            tcg_gen_shl_tl(cpu_dst, cpu_src1, cpu_tmp0);
                        }
3323
                        gen_movl_TN_reg(rd, cpu_dst);
3324
                        break;
B
bellard 已提交
3325
                    case 0x26:  /* srl */
3326
                        if (IS_IMM) { /* immediate */
B
Blue Swirl 已提交
3327 3328
                            simm = GET_FIELDs(insn, 20, 31);
                            tcg_gen_shri_tl(cpu_dst, cpu_src1, simm & 0x1f);
3329 3330 3331 3332
                        } else { /* register */
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
                            tcg_gen_shr_tl(cpu_dst, cpu_src1, cpu_tmp0);
                        }
3333
                        gen_movl_TN_reg(rd, cpu_dst);
3334
                        break;
B
bellard 已提交
3335
                    case 0x27:  /* sra */
3336
                        if (IS_IMM) { /* immediate */
B
Blue Swirl 已提交
3337 3338
                            simm = GET_FIELDs(insn, 20, 31);
                            tcg_gen_sari_tl(cpu_dst, cpu_src1, simm & 0x1f);
3339 3340 3341 3342
                        } else { /* register */
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
                            tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0);
                        }
3343
                        gen_movl_TN_reg(rd, cpu_dst);
3344
                        break;
B
bellard 已提交
3345
#endif
3346 3347 3348
                    case 0x30:
                        {
                            switch(rd) {
B
bellard 已提交
3349
                            case 0: /* wry */
3350 3351
                                tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
                                tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
3352
                                break;
3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363
#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 已提交
3364
                            case 0x2: /* V9 wrccr */
3365
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
P
pbrook 已提交
3366
                                gen_helper_wrccr(cpu_dst);
3367 3368
                                tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS);
                                dc->cc_op = CC_OP_FLAGS;
B
blueswir1 已提交
3369 3370
                                break;
                            case 0x3: /* V9 wrasi */
3371
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
I
Igor V. Kovalenko 已提交
3372
                                tcg_gen_andi_tl(cpu_dst, cpu_dst, 0xff);
3373
                                tcg_gen_trunc_tl_i32(cpu_asi, cpu_dst);
B
blueswir1 已提交
3374 3375
                                break;
                            case 0x6: /* V9 wrfprs */
3376
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3377
                                tcg_gen_trunc_tl_i32(cpu_fprs, cpu_dst);
3378
                                save_state(dc, cpu_cond);
3379
                                gen_op_next_insn();
B
bellard 已提交
3380
                                tcg_gen_exit_tb(0);
3381
                                dc->is_br = 1;
B
blueswir1 已提交
3382 3383
                                break;
                            case 0xf: /* V9 sir, nop if user */
B
bellard 已提交
3384
#if !defined(CONFIG_USER_ONLY)
3385
                                if (supervisor(dc)) {
B
blueswir1 已提交
3386
                                    ; // XXX
3387
                                }
B
bellard 已提交
3388
#endif
B
blueswir1 已提交
3389 3390
                                break;
                            case 0x13: /* Graphics Status */
3391
                                if (gen_trap_ifnofpu(dc, cpu_cond))
B
bellard 已提交
3392
                                    goto jmp_insn;
3393
                                tcg_gen_xor_tl(cpu_gsr, cpu_src1, cpu_src2);
B
blueswir1 已提交
3394
                                break;
3395 3396 3397 3398
                            case 0x14: /* Softint set */
                                if (!supervisor(dc))
                                    goto illegal_insn;
                                tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2);
P
pbrook 已提交
3399
                                gen_helper_set_softint(cpu_tmp64);
3400 3401 3402 3403 3404
                                break;
                            case 0x15: /* Softint clear */
                                if (!supervisor(dc))
                                    goto illegal_insn;
                                tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2);
P
pbrook 已提交
3405
                                gen_helper_clear_softint(cpu_tmp64);
3406 3407 3408 3409 3410
                                break;
                            case 0x16: /* Softint write */
                                if (!supervisor(dc))
                                    goto illegal_insn;
                                tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2);
P
pbrook 已提交
3411
                                gen_helper_write_softint(cpu_tmp64);
3412
                                break;
B
blueswir1 已提交
3413
                            case 0x17: /* Tick compare */
B
bellard 已提交
3414
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
3415 3416
                                if (!supervisor(dc))
                                    goto illegal_insn;
B
bellard 已提交
3417
#endif
B
blueswir1 已提交
3418
                                {
P
pbrook 已提交
3419
                                    TCGv_ptr r_tickptr;
B
blueswir1 已提交
3420

3421
                                    tcg_gen_xor_tl(cpu_tick_cmpr, cpu_src1,
3422
                                                   cpu_src2);
P
pbrook 已提交
3423
                                    r_tickptr = tcg_temp_new_ptr();
B
blueswir1 已提交
3424 3425
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, tick));
P
pbrook 已提交
3426 3427 3428
                                    gen_helper_tick_set_limit(r_tickptr,
                                                              cpu_tick_cmpr);
                                    tcg_temp_free_ptr(r_tickptr);
B
blueswir1 已提交
3429
                                }
B
blueswir1 已提交
3430 3431
                                break;
                            case 0x18: /* System tick */
B
bellard 已提交
3432
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
3433 3434
                                if (!supervisor(dc))
                                    goto illegal_insn;
B
bellard 已提交
3435
#endif
B
blueswir1 已提交
3436
                                {
P
pbrook 已提交
3437
                                    TCGv_ptr r_tickptr;
B
blueswir1 已提交
3438

3439 3440
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
                                                   cpu_src2);
P
pbrook 已提交
3441
                                    r_tickptr = tcg_temp_new_ptr();
B
blueswir1 已提交
3442 3443
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, stick));
P
pbrook 已提交
3444 3445 3446
                                    gen_helper_tick_set_count(r_tickptr,
                                                              cpu_dst);
                                    tcg_temp_free_ptr(r_tickptr);
B
blueswir1 已提交
3447
                                }
B
blueswir1 已提交
3448 3449
                                break;
                            case 0x19: /* System tick compare */
B
bellard 已提交
3450
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
3451 3452
                                if (!supervisor(dc))
                                    goto illegal_insn;
B
bellard 已提交
3453
#endif
B
blueswir1 已提交
3454
                                {
P
pbrook 已提交
3455
                                    TCGv_ptr r_tickptr;
B
blueswir1 已提交
3456

3457
                                    tcg_gen_xor_tl(cpu_stick_cmpr, cpu_src1,
3458
                                                   cpu_src2);
P
pbrook 已提交
3459
                                    r_tickptr = tcg_temp_new_ptr();
B
blueswir1 已提交
3460 3461
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, stick));
P
pbrook 已提交
3462 3463 3464
                                    gen_helper_tick_set_limit(r_tickptr,
                                                              cpu_stick_cmpr);
                                    tcg_temp_free_ptr(r_tickptr);
B
blueswir1 已提交
3465
                                }
B
blueswir1 已提交
3466
                                break;
B
bellard 已提交
3467

B
blueswir1 已提交
3468
                            case 0x10: /* Performance Control */
B
blueswir1 已提交
3469 3470
                            case 0x11: /* Performance Instrumentation
                                          Counter */
B
blueswir1 已提交
3471
                            case 0x12: /* Dispatch Control */
B
bellard 已提交
3472
#endif
B
bellard 已提交
3473
                            default:
3474 3475 3476 3477
                                goto illegal_insn;
                            }
                        }
                        break;
3478
#if !defined(CONFIG_USER_ONLY)
3479
                    case 0x31: /* wrpsr, V9 saved, restored */
3480
                        {
B
blueswir1 已提交
3481 3482
                            if (!supervisor(dc))
                                goto priv_insn;
B
bellard 已提交
3483
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3484 3485
                            switch (rd) {
                            case 0:
P
pbrook 已提交
3486
                                gen_helper_saved();
B
blueswir1 已提交
3487 3488
                                break;
                            case 1:
P
pbrook 已提交
3489
                                gen_helper_restored();
B
blueswir1 已提交
3490
                                break;
B
blueswir1 已提交
3491 3492 3493 3494 3495
                            case 2: /* UA2005 allclean */
                            case 3: /* UA2005 otherw */
                            case 4: /* UA2005 normalw */
                            case 5: /* UA2005 invalw */
                                // XXX
B
blueswir1 已提交
3496
                            default:
B
bellard 已提交
3497 3498 3499
                                goto illegal_insn;
                            }
#else
3500
                            tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
P
pbrook 已提交
3501
                            gen_helper_wrpsr(cpu_dst);
3502 3503
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS);
                            dc->cc_op = CC_OP_FLAGS;
3504
                            save_state(dc, cpu_cond);
B
bellard 已提交
3505
                            gen_op_next_insn();
B
bellard 已提交
3506
                            tcg_gen_exit_tb(0);
B
blueswir1 已提交
3507
                            dc->is_br = 1;
B
bellard 已提交
3508
#endif
3509 3510
                        }
                        break;
3511
                    case 0x32: /* wrwim, V9 wrpr */
3512
                        {
B
blueswir1 已提交
3513 3514
                            if (!supervisor(dc))
                                goto priv_insn;
3515
                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
B
bellard 已提交
3516
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3517 3518
                            switch (rd) {
                            case 0: // tpc
3519
                                {
P
pbrook 已提交
3520
                                    TCGv_ptr r_tsptr;
3521

P
pbrook 已提交
3522
                                    r_tsptr = tcg_temp_new_ptr();
3523
                                    gen_load_trap_state_at_tl(r_tsptr, cpu_env);
3524
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3525
                                                  offsetof(trap_state, tpc));
P
pbrook 已提交
3526
                                    tcg_temp_free_ptr(r_tsptr);
3527
                                }
B
blueswir1 已提交
3528 3529
                                break;
                            case 1: // tnpc
3530
                                {
P
pbrook 已提交
3531
                                    TCGv_ptr r_tsptr;
3532

P
pbrook 已提交
3533
                                    r_tsptr = tcg_temp_new_ptr();
3534
                                    gen_load_trap_state_at_tl(r_tsptr, cpu_env);
3535
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3536
                                                  offsetof(trap_state, tnpc));
P
pbrook 已提交
3537
                                    tcg_temp_free_ptr(r_tsptr);
3538
                                }
B
blueswir1 已提交
3539 3540
                                break;
                            case 2: // tstate
3541
                                {
P
pbrook 已提交
3542
                                    TCGv_ptr r_tsptr;
3543

P
pbrook 已提交
3544
                                    r_tsptr = tcg_temp_new_ptr();
3545
                                    gen_load_trap_state_at_tl(r_tsptr, cpu_env);
3546
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
B
blueswir1 已提交
3547 3548
                                                  offsetof(trap_state,
                                                           tstate));
P
pbrook 已提交
3549
                                    tcg_temp_free_ptr(r_tsptr);
3550
                                }
B
blueswir1 已提交
3551 3552
                                break;
                            case 3: // tt
3553
                                {
P
pbrook 已提交
3554
                                    TCGv_ptr r_tsptr;
3555

P
pbrook 已提交
3556
                                    r_tsptr = tcg_temp_new_ptr();
3557
                                    gen_load_trap_state_at_tl(r_tsptr, cpu_env);
B
blueswir1 已提交
3558 3559
                                    tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
                                    tcg_gen_st_i32(cpu_tmp32, r_tsptr,
3560
                                                   offsetof(trap_state, tt));
P
pbrook 已提交
3561
                                    tcg_temp_free_ptr(r_tsptr);
3562
                                }
B
blueswir1 已提交
3563 3564
                                break;
                            case 4: // tick
B
blueswir1 已提交
3565
                                {
P
pbrook 已提交
3566
                                    TCGv_ptr r_tickptr;
B
blueswir1 已提交
3567

P
pbrook 已提交
3568
                                    r_tickptr = tcg_temp_new_ptr();
B
blueswir1 已提交
3569 3570
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, tick));
P
pbrook 已提交
3571 3572 3573
                                    gen_helper_tick_set_count(r_tickptr,
                                                              cpu_tmp0);
                                    tcg_temp_free_ptr(r_tickptr);
B
blueswir1 已提交
3574
                                }
B
blueswir1 已提交
3575 3576
                                break;
                            case 5: // tba
3577
                                tcg_gen_mov_tl(cpu_tbr, cpu_tmp0);
B
blueswir1 已提交
3578 3579
                                break;
                            case 6: // pstate
3580 3581 3582 3583 3584 3585 3586 3587 3588
                                {
                                    TCGv r_tmp = tcg_temp_local_new();

                                    tcg_gen_mov_tl(r_tmp, cpu_tmp0);
                                    save_state(dc, cpu_cond);
                                    gen_helper_wrpstate(r_tmp);
                                    tcg_temp_free(r_tmp);
                                    dc->npc = DYNAMIC_PC;
                                }
B
blueswir1 已提交
3589 3590
                                break;
                            case 7: // tl
3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601
                                {
                                    TCGv r_tmp = tcg_temp_local_new();

                                    tcg_gen_mov_tl(r_tmp, cpu_tmp0);
                                    save_state(dc, cpu_cond);
                                    tcg_gen_trunc_tl_i32(cpu_tmp32, r_tmp);
                                    tcg_temp_free(r_tmp);
                                    tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                                   offsetof(CPUSPARCState, tl));
                                    dc->npc = DYNAMIC_PC;
                                }
B
blueswir1 已提交
3602 3603
                                break;
                            case 8: // pil
3604
                                gen_helper_wrpil(cpu_tmp0);
B
blueswir1 已提交
3605 3606
                                break;
                            case 9: // cwp
P
pbrook 已提交
3607
                                gen_helper_wrcwp(cpu_tmp0);
B
blueswir1 已提交
3608 3609
                                break;
                            case 10: // cansave
3610
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3611 3612 3613
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState,
                                                        cansave));
B
blueswir1 已提交
3614 3615
                                break;
                            case 11: // canrestore
3616
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3617 3618 3619
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState,
                                                        canrestore));
B
blueswir1 已提交
3620 3621
                                break;
                            case 12: // cleanwin
3622
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3623 3624 3625
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState,
                                                        cleanwin));
B
blueswir1 已提交
3626 3627
                                break;
                            case 13: // otherwin
3628
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3629 3630 3631
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState,
                                                        otherwin));
B
blueswir1 已提交
3632 3633
                                break;
                            case 14: // wstate
3634
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3635 3636 3637
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState,
                                                        wstate));
B
blueswir1 已提交
3638
                                break;
B
blueswir1 已提交
3639
                            case 16: // UA2005 gl
3640
                                CHECK_IU_FEATURE(dc, GL);
3641
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3642 3643
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState, gl));
B
blueswir1 已提交
3644 3645
                                break;
                            case 26: // UA2005 strand status
3646
                                CHECK_IU_FEATURE(dc, HYPV);
B
blueswir1 已提交
3647 3648
                                if (!hypervisor(dc))
                                    goto priv_insn;
B
blueswir1 已提交
3649
                                tcg_gen_mov_tl(cpu_ssr, cpu_tmp0);
B
blueswir1 已提交
3650
                                break;
B
blueswir1 已提交
3651 3652 3653
                            default:
                                goto illegal_insn;
                            }
B
bellard 已提交
3654
#else
3655
                            tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3656 3657 3658
                            if (dc->def->nwindows != 32)
                                tcg_gen_andi_tl(cpu_tmp32, cpu_tmp32,
                                                (1 << dc->def->nwindows) - 1);
3659
                            tcg_gen_mov_i32(cpu_wim, cpu_tmp32);
B
bellard 已提交
3660
#endif
3661 3662
                        }
                        break;
B
blueswir1 已提交
3663
                    case 0x33: /* wrtbr, UA2005 wrhpr */
3664
                        {
B
blueswir1 已提交
3665
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3666 3667
                            if (!supervisor(dc))
                                goto priv_insn;
3668
                            tcg_gen_xor_tl(cpu_tbr, cpu_src1, cpu_src2);
B
blueswir1 已提交
3669
#else
3670
                            CHECK_IU_FEATURE(dc, HYPV);
B
blueswir1 已提交
3671 3672
                            if (!hypervisor(dc))
                                goto priv_insn;
3673
                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
B
blueswir1 已提交
3674 3675 3676
                            switch (rd) {
                            case 0: // hpstate
                                // XXX gen_op_wrhpstate();
3677
                                save_state(dc, cpu_cond);
B
blueswir1 已提交
3678
                                gen_op_next_insn();
B
bellard 已提交
3679
                                tcg_gen_exit_tb(0);
B
blueswir1 已提交
3680 3681 3682 3683 3684 3685
                                dc->is_br = 1;
                                break;
                            case 1: // htstate
                                // XXX gen_op_wrhtstate();
                                break;
                            case 3: // hintp
3686
                                tcg_gen_mov_tl(cpu_hintp, cpu_tmp0);
B
blueswir1 已提交
3687 3688
                                break;
                            case 5: // htba
3689
                                tcg_gen_mov_tl(cpu_htba, cpu_tmp0);
B
blueswir1 已提交
3690 3691
                                break;
                            case 31: // hstick_cmpr
B
blueswir1 已提交
3692
                                {
P
pbrook 已提交
3693
                                    TCGv_ptr r_tickptr;
B
blueswir1 已提交
3694

3695
                                    tcg_gen_mov_tl(cpu_hstick_cmpr, cpu_tmp0);
P
pbrook 已提交
3696
                                    r_tickptr = tcg_temp_new_ptr();
B
blueswir1 已提交
3697 3698
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, hstick));
P
pbrook 已提交
3699 3700 3701
                                    gen_helper_tick_set_limit(r_tickptr,
                                                              cpu_hstick_cmpr);
                                    tcg_temp_free_ptr(r_tickptr);
B
blueswir1 已提交
3702
                                }
B
blueswir1 已提交
3703 3704 3705 3706 3707 3708
                                break;
                            case 6: // hver readonly
                            default:
                                goto illegal_insn;
                            }
#endif
3709 3710 3711
                        }
                        break;
#endif
B
bellard 已提交
3712
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3713 3714 3715 3716
                    case 0x2c: /* V9 movcc */
                        {
                            int cc = GET_FIELD_SP(insn, 11, 12);
                            int cond = GET_FIELD_SP(insn, 14, 17);
B
blueswir1 已提交
3717
                            TCGv r_cond;
3718 3719
                            int l1;

P
pbrook 已提交
3720
                            r_cond = tcg_temp_new();
B
blueswir1 已提交
3721 3722
                            if (insn & (1 << 18)) {
                                if (cc == 0)
3723
                                    gen_cond(r_cond, 0, cond, dc);
B
blueswir1 已提交
3724
                                else if (cc == 2)
3725
                                    gen_cond(r_cond, 1, cond, dc);
B
blueswir1 已提交
3726 3727 3728
                                else
                                    goto illegal_insn;
                            } else {
B
blueswir1 已提交
3729
                                gen_fcond(r_cond, cc, cond);
B
blueswir1 已提交
3730
                            }
3731 3732 3733

                            l1 = gen_new_label();

P
pbrook 已提交
3734
                            tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
3735
                            if (IS_IMM) {       /* immediate */
B
blueswir1 已提交
3736 3737
                                TCGv r_const;

B
Blue Swirl 已提交
3738 3739
                                simm = GET_FIELD_SPs(insn, 0, 10);
                                r_const = tcg_const_tl(simm);
B
blueswir1 已提交
3740 3741
                                gen_movl_TN_reg(rd, r_const);
                                tcg_temp_free(r_const);
3742 3743
                            } else {
                                rs2 = GET_FIELD_SP(insn, 0, 4);
B
blueswir1 已提交
3744 3745
                                gen_movl_reg_TN(rs2, cpu_tmp0);
                                gen_movl_TN_reg(rd, cpu_tmp0);
3746 3747
                            }
                            gen_set_label(l1);
B
blueswir1 已提交
3748
                            tcg_temp_free(r_cond);
B
blueswir1 已提交
3749 3750 3751
                            break;
                        }
                    case 0x2d: /* V9 sdivx */
3752 3753
                        gen_op_sdivx(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3754 3755 3756
                        break;
                    case 0x2e: /* V9 popc */
                        {
B
blueswir1 已提交
3757
                            cpu_src2 = get_src2(insn, cpu_src2);
P
pbrook 已提交
3758
                            gen_helper_popc(cpu_dst, cpu_src2);
3759
                            gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3760 3761 3762 3763
                        }
                    case 0x2f: /* V9 movr */
                        {
                            int cond = GET_FIELD_SP(insn, 10, 12);
3764 3765
                            int l1;

3766
                            cpu_src1 = get_src1(insn, cpu_src1);
3767 3768 3769

                            l1 = gen_new_label();

P
pbrook 已提交
3770 3771
                            tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond],
                                              cpu_src1, 0, l1);
B
blueswir1 已提交
3772
                            if (IS_IMM) {       /* immediate */
B
blueswir1 已提交
3773 3774
                                TCGv r_const;

B
Blue Swirl 已提交
3775 3776
                                simm = GET_FIELD_SPs(insn, 0, 9);
                                r_const = tcg_const_tl(simm);
B
blueswir1 已提交
3777 3778
                                gen_movl_TN_reg(rd, r_const);
                                tcg_temp_free(r_const);
3779
                            } else {
B
blueswir1 已提交
3780
                                rs2 = GET_FIELD_SP(insn, 0, 4);
B
blueswir1 已提交
3781 3782
                                gen_movl_reg_TN(rs2, cpu_tmp0);
                                gen_movl_TN_reg(rd, cpu_tmp0);
B
blueswir1 已提交
3783
                            }
3784
                            gen_set_label(l1);
B
blueswir1 已提交
3785 3786 3787 3788 3789 3790 3791
                            break;
                        }
#endif
                    default:
                        goto illegal_insn;
                    }
                }
3792 3793 3794 3795 3796
            } 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);
3797
                if (gen_trap_ifnofpu(dc, cpu_cond))
B
blueswir1 已提交
3798
                    goto jmp_insn;
3799 3800

                switch (opf) {
B
blueswir1 已提交
3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815
                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 */
B
blueswir1 已提交
3816
                    CHECK_FPU_FEATURE(dc, VIS1);
3817
                    cpu_src1 = get_src1(insn, cpu_src1);
3818
                    gen_movl_reg_TN(rs2, cpu_src2);
P
pbrook 已提交
3819
                    gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
3820
                    gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3821 3822
                    break;
                case 0x012: /* VIS I array16 */
B
blueswir1 已提交
3823
                    CHECK_FPU_FEATURE(dc, VIS1);
3824
                    cpu_src1 = get_src1(insn, cpu_src1);
3825
                    gen_movl_reg_TN(rs2, cpu_src2);
P
pbrook 已提交
3826
                    gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
3827 3828
                    tcg_gen_shli_i64(cpu_dst, cpu_dst, 1);
                    gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3829 3830
                    break;
                case 0x014: /* VIS I array32 */
B
blueswir1 已提交
3831
                    CHECK_FPU_FEATURE(dc, VIS1);
3832
                    cpu_src1 = get_src1(insn, cpu_src1);
3833
                    gen_movl_reg_TN(rs2, cpu_src2);
P
pbrook 已提交
3834
                    gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
3835 3836
                    tcg_gen_shli_i64(cpu_dst, cpu_dst, 2);
                    gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3837
                    break;
3838
                case 0x018: /* VIS I alignaddr */
B
blueswir1 已提交
3839
                    CHECK_FPU_FEATURE(dc, VIS1);
3840
                    cpu_src1 = get_src1(insn, cpu_src1);
3841
                    gen_movl_reg_TN(rs2, cpu_src2);
P
pbrook 已提交
3842
                    gen_helper_alignaddr(cpu_dst, cpu_src1, cpu_src2);
3843
                    gen_movl_TN_reg(rd, cpu_dst);
3844
                    break;
B
blueswir1 已提交
3845
                case 0x019: /* VIS II bmask */
3846 3847
                case 0x01a: /* VIS I alignaddrl */
                    // XXX
B
blueswir1 已提交
3848 3849
                    goto illegal_insn;
                case 0x020: /* VIS I fcmple16 */
B
blueswir1 已提交
3850
                    CHECK_FPU_FEATURE(dc, VIS1);
3851 3852
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3853 3854
                    gen_helper_fcmple16(cpu_dst);
                    gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3855 3856
                    break;
                case 0x022: /* VIS I fcmpne16 */
B
blueswir1 已提交
3857
                    CHECK_FPU_FEATURE(dc, VIS1);
3858 3859
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3860 3861
                    gen_helper_fcmpne16(cpu_dst);
                    gen_movl_TN_reg(rd, cpu_dst);
3862
                    break;
B
blueswir1 已提交
3863
                case 0x024: /* VIS I fcmple32 */
B
blueswir1 已提交
3864
                    CHECK_FPU_FEATURE(dc, VIS1);
3865 3866
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3867 3868
                    gen_helper_fcmple32(cpu_dst);
                    gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3869 3870
                    break;
                case 0x026: /* VIS I fcmpne32 */
B
blueswir1 已提交
3871
                    CHECK_FPU_FEATURE(dc, VIS1);
3872 3873
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3874 3875
                    gen_helper_fcmpne32(cpu_dst);
                    gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3876 3877
                    break;
                case 0x028: /* VIS I fcmpgt16 */
B
blueswir1 已提交
3878
                    CHECK_FPU_FEATURE(dc, VIS1);
3879 3880
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3881 3882
                    gen_helper_fcmpgt16(cpu_dst);
                    gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3883 3884
                    break;
                case 0x02a: /* VIS I fcmpeq16 */
B
blueswir1 已提交
3885
                    CHECK_FPU_FEATURE(dc, VIS1);
3886 3887
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3888 3889
                    gen_helper_fcmpeq16(cpu_dst);
                    gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3890 3891
                    break;
                case 0x02c: /* VIS I fcmpgt32 */
B
blueswir1 已提交
3892
                    CHECK_FPU_FEATURE(dc, VIS1);
3893 3894
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3895 3896
                    gen_helper_fcmpgt32(cpu_dst);
                    gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3897 3898
                    break;
                case 0x02e: /* VIS I fcmpeq32 */
B
blueswir1 已提交
3899
                    CHECK_FPU_FEATURE(dc, VIS1);
3900 3901
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3902 3903
                    gen_helper_fcmpeq32(cpu_dst);
                    gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3904 3905
                    break;
                case 0x031: /* VIS I fmul8x16 */
B
blueswir1 已提交
3906
                    CHECK_FPU_FEATURE(dc, VIS1);
3907 3908
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
P
pbrook 已提交
3909
                    gen_helper_fmul8x16();
3910
                    gen_op_store_DT0_fpr(DFPREG(rd));
3911
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
3912 3913
                    break;
                case 0x033: /* VIS I fmul8x16au */
B
blueswir1 已提交
3914
                    CHECK_FPU_FEATURE(dc, VIS1);
3915 3916
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
P
pbrook 已提交
3917
                    gen_helper_fmul8x16au();
3918
                    gen_op_store_DT0_fpr(DFPREG(rd));
3919
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
3920 3921
                    break;
                case 0x035: /* VIS I fmul8x16al */
B
blueswir1 已提交
3922
                    CHECK_FPU_FEATURE(dc, VIS1);
3923 3924
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
P
pbrook 已提交
3925
                    gen_helper_fmul8x16al();
3926
                    gen_op_store_DT0_fpr(DFPREG(rd));
3927
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
3928 3929
                    break;
                case 0x036: /* VIS I fmul8sux16 */
B
blueswir1 已提交
3930
                    CHECK_FPU_FEATURE(dc, VIS1);
3931 3932
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
P
pbrook 已提交
3933
                    gen_helper_fmul8sux16();
3934
                    gen_op_store_DT0_fpr(DFPREG(rd));
3935
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
3936 3937
                    break;
                case 0x037: /* VIS I fmul8ulx16 */
B
blueswir1 已提交
3938
                    CHECK_FPU_FEATURE(dc, VIS1);
3939 3940
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
P
pbrook 已提交
3941
                    gen_helper_fmul8ulx16();
3942
                    gen_op_store_DT0_fpr(DFPREG(rd));
3943
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
3944 3945
                    break;
                case 0x038: /* VIS I fmuld8sux16 */
B
blueswir1 已提交
3946
                    CHECK_FPU_FEATURE(dc, VIS1);
3947 3948
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
P
pbrook 已提交
3949
                    gen_helper_fmuld8sux16();
3950
                    gen_op_store_DT0_fpr(DFPREG(rd));
3951
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
3952 3953
                    break;
                case 0x039: /* VIS I fmuld8ulx16 */
B
blueswir1 已提交
3954
                    CHECK_FPU_FEATURE(dc, VIS1);
3955 3956
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
P
pbrook 已提交
3957
                    gen_helper_fmuld8ulx16();
3958
                    gen_op_store_DT0_fpr(DFPREG(rd));
3959
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
3960 3961 3962 3963 3964 3965 3966
                    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;
3967
                case 0x048: /* VIS I faligndata */
B
blueswir1 已提交
3968
                    CHECK_FPU_FEATURE(dc, VIS1);
3969 3970
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
P
pbrook 已提交
3971
                    gen_helper_faligndata();
3972
                    gen_op_store_DT0_fpr(DFPREG(rd));
3973
                    gen_update_fprs_dirty(DFPREG(rd));
3974
                    break;
B
blueswir1 已提交
3975
                case 0x04b: /* VIS I fpmerge */
B
blueswir1 已提交
3976
                    CHECK_FPU_FEATURE(dc, VIS1);
3977 3978
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
P
pbrook 已提交
3979
                    gen_helper_fpmerge();
3980
                    gen_op_store_DT0_fpr(DFPREG(rd));
3981
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
3982 3983 3984 3985 3986
                    break;
                case 0x04c: /* VIS II bshuffle */
                    // XXX
                    goto illegal_insn;
                case 0x04d: /* VIS I fexpand */
B
blueswir1 已提交
3987
                    CHECK_FPU_FEATURE(dc, VIS1);
3988 3989
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
P
pbrook 已提交
3990
                    gen_helper_fexpand();
3991
                    gen_op_store_DT0_fpr(DFPREG(rd));
3992
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
3993 3994
                    break;
                case 0x050: /* VIS I fpadd16 */
B
blueswir1 已提交
3995
                    CHECK_FPU_FEATURE(dc, VIS1);
3996 3997
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
P
pbrook 已提交
3998
                    gen_helper_fpadd16();
3999
                    gen_op_store_DT0_fpr(DFPREG(rd));
4000
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
4001 4002
                    break;
                case 0x051: /* VIS I fpadd16s */
B
blueswir1 已提交
4003
                    CHECK_FPU_FEATURE(dc, VIS1);
P
pbrook 已提交
4004 4005
                    gen_helper_fpadd16s(cpu_fpr[rd],
                                        cpu_fpr[rs1], cpu_fpr[rs2]);
4006
                    gen_update_fprs_dirty(rd);
B
blueswir1 已提交
4007 4008
                    break;
                case 0x052: /* VIS I fpadd32 */
B
blueswir1 已提交
4009
                    CHECK_FPU_FEATURE(dc, VIS1);
4010 4011
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
P
pbrook 已提交
4012
                    gen_helper_fpadd32();
4013
                    gen_op_store_DT0_fpr(DFPREG(rd));
4014
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
4015 4016
                    break;
                case 0x053: /* VIS I fpadd32s */
B
blueswir1 已提交
4017
                    CHECK_FPU_FEATURE(dc, VIS1);
P
pbrook 已提交
4018 4019
                    gen_helper_fpadd32s(cpu_fpr[rd],
                                        cpu_fpr[rs1], cpu_fpr[rs2]);
4020
                    gen_update_fprs_dirty(rd);
B
blueswir1 已提交
4021 4022
                    break;
                case 0x054: /* VIS I fpsub16 */
B
blueswir1 已提交
4023
                    CHECK_FPU_FEATURE(dc, VIS1);
4024 4025
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
P
pbrook 已提交
4026
                    gen_helper_fpsub16();
4027
                    gen_op_store_DT0_fpr(DFPREG(rd));
4028
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
4029 4030
                    break;
                case 0x055: /* VIS I fpsub16s */
B
blueswir1 已提交
4031
                    CHECK_FPU_FEATURE(dc, VIS1);
P
pbrook 已提交
4032 4033
                    gen_helper_fpsub16s(cpu_fpr[rd],
                                        cpu_fpr[rs1], cpu_fpr[rs2]);
4034
                    gen_update_fprs_dirty(rd);
B
blueswir1 已提交
4035 4036
                    break;
                case 0x056: /* VIS I fpsub32 */
B
blueswir1 已提交
4037
                    CHECK_FPU_FEATURE(dc, VIS1);
4038 4039
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
P
pbrook 已提交
4040
                    gen_helper_fpsub32();
4041
                    gen_op_store_DT0_fpr(DFPREG(rd));
4042
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
4043 4044
                    break;
                case 0x057: /* VIS I fpsub32s */
B
blueswir1 已提交
4045
                    CHECK_FPU_FEATURE(dc, VIS1);
P
pbrook 已提交
4046 4047
                    gen_helper_fpsub32s(cpu_fpr[rd],
                                        cpu_fpr[rs1], cpu_fpr[rs2]);
4048
                    gen_update_fprs_dirty(rd);
B
blueswir1 已提交
4049
                    break;
4050
                case 0x060: /* VIS I fzero */
B
blueswir1 已提交
4051
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4052 4053
                    tcg_gen_movi_i32(cpu_fpr[DFPREG(rd)], 0);
                    tcg_gen_movi_i32(cpu_fpr[DFPREG(rd) + 1], 0);
4054
                    gen_update_fprs_dirty(DFPREG(rd));
4055 4056
                    break;
                case 0x061: /* VIS I fzeros */
B
blueswir1 已提交
4057
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4058
                    tcg_gen_movi_i32(cpu_fpr[rd], 0);
4059
                    gen_update_fprs_dirty(rd);
4060
                    break;
B
blueswir1 已提交
4061
                case 0x062: /* VIS I fnor */
B
blueswir1 已提交
4062
                    CHECK_FPU_FEATURE(dc, VIS1);
T
Tsuneo Saito 已提交
4063
                    tcg_gen_nor_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
B
blueswir1 已提交
4064
                                    cpu_fpr[DFPREG(rs2)]);
T
Tsuneo Saito 已提交
4065 4066
                    tcg_gen_nor_i32(cpu_fpr[DFPREG(rd) + 1],
                                    cpu_fpr[DFPREG(rs1) + 1],
B
blueswir1 已提交
4067
                                    cpu_fpr[DFPREG(rs2) + 1]);
4068
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
4069 4070
                    break;
                case 0x063: /* VIS I fnors */
B
blueswir1 已提交
4071
                    CHECK_FPU_FEATURE(dc, VIS1);
T
Tsuneo Saito 已提交
4072
                    tcg_gen_nor_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
4073
                    gen_update_fprs_dirty(rd);
B
blueswir1 已提交
4074 4075
                    break;
                case 0x064: /* VIS I fandnot2 */
B
blueswir1 已提交
4076
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4077 4078 4079 4080 4081
                    tcg_gen_andc_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
                                     cpu_fpr[DFPREG(rs2)]);
                    tcg_gen_andc_i32(cpu_fpr[DFPREG(rd) + 1],
                                     cpu_fpr[DFPREG(rs1) + 1],
                                     cpu_fpr[DFPREG(rs2) + 1]);
4082
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
4083 4084
                    break;
                case 0x065: /* VIS I fandnot2s */
B
blueswir1 已提交
4085
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4086
                    tcg_gen_andc_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
4087
                    gen_update_fprs_dirty(rd);
B
blueswir1 已提交
4088 4089
                    break;
                case 0x066: /* VIS I fnot2 */
B
blueswir1 已提交
4090
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4091 4092 4093
                    tcg_gen_not_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)]);
                    tcg_gen_not_i32(cpu_fpr[DFPREG(rd) + 1],
                                    cpu_fpr[DFPREG(rs2) + 1]);
4094
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
4095 4096
                    break;
                case 0x067: /* VIS I fnot2s */
B
blueswir1 已提交
4097
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4098
                    tcg_gen_not_i32(cpu_fpr[rd], cpu_fpr[rs2]);
4099
                    gen_update_fprs_dirty(rd);
B
blueswir1 已提交
4100 4101
                    break;
                case 0x068: /* VIS I fandnot1 */
B
blueswir1 已提交
4102
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4103 4104 4105 4106 4107
                    tcg_gen_andc_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)],
                                     cpu_fpr[DFPREG(rs1)]);
                    tcg_gen_andc_i32(cpu_fpr[DFPREG(rd) + 1],
                                     cpu_fpr[DFPREG(rs2) + 1],
                                     cpu_fpr[DFPREG(rs1) + 1]);
4108
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
4109 4110
                    break;
                case 0x069: /* VIS I fandnot1s */
B
blueswir1 已提交
4111
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4112
                    tcg_gen_andc_i32(cpu_fpr[rd], cpu_fpr[rs2], cpu_fpr[rs1]);
4113
                    gen_update_fprs_dirty(rd);
B
blueswir1 已提交
4114 4115
                    break;
                case 0x06a: /* VIS I fnot1 */
B
blueswir1 已提交
4116
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4117 4118 4119
                    tcg_gen_not_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)]);
                    tcg_gen_not_i32(cpu_fpr[DFPREG(rd) + 1],
                                    cpu_fpr[DFPREG(rs1) + 1]);
4120
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
4121 4122
                    break;
                case 0x06b: /* VIS I fnot1s */
B
blueswir1 已提交
4123
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4124
                    tcg_gen_not_i32(cpu_fpr[rd], cpu_fpr[rs1]);
4125
                    gen_update_fprs_dirty(rd);
B
blueswir1 已提交
4126 4127
                    break;
                case 0x06c: /* VIS I fxor */
B
blueswir1 已提交
4128
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4129 4130 4131 4132 4133
                    tcg_gen_xor_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
                                    cpu_fpr[DFPREG(rs2)]);
                    tcg_gen_xor_i32(cpu_fpr[DFPREG(rd) + 1],
                                    cpu_fpr[DFPREG(rs1) + 1],
                                    cpu_fpr[DFPREG(rs2) + 1]);
4134
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
4135 4136
                    break;
                case 0x06d: /* VIS I fxors */
B
blueswir1 已提交
4137
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4138
                    tcg_gen_xor_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
4139
                    gen_update_fprs_dirty(rd);
B
blueswir1 已提交
4140 4141
                    break;
                case 0x06e: /* VIS I fnand */
B
blueswir1 已提交
4142
                    CHECK_FPU_FEATURE(dc, VIS1);
T
Tsuneo Saito 已提交
4143
                    tcg_gen_nand_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
B
blueswir1 已提交
4144
                                     cpu_fpr[DFPREG(rs2)]);
T
Tsuneo Saito 已提交
4145 4146
                    tcg_gen_nand_i32(cpu_fpr[DFPREG(rd) + 1],
                                     cpu_fpr[DFPREG(rs1) + 1],
B
blueswir1 已提交
4147
                                     cpu_fpr[DFPREG(rs2) + 1]);
4148
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
4149 4150
                    break;
                case 0x06f: /* VIS I fnands */
B
blueswir1 已提交
4151
                    CHECK_FPU_FEATURE(dc, VIS1);
T
Tsuneo Saito 已提交
4152
                    tcg_gen_nand_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
4153
                    gen_update_fprs_dirty(rd);
B
blueswir1 已提交
4154 4155
                    break;
                case 0x070: /* VIS I fand */
B
blueswir1 已提交
4156
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4157 4158 4159 4160 4161
                    tcg_gen_and_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
                                    cpu_fpr[DFPREG(rs2)]);
                    tcg_gen_and_i32(cpu_fpr[DFPREG(rd) + 1],
                                    cpu_fpr[DFPREG(rs1) + 1],
                                    cpu_fpr[DFPREG(rs2) + 1]);
4162
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
4163 4164
                    break;
                case 0x071: /* VIS I fands */
B
blueswir1 已提交
4165
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4166
                    tcg_gen_and_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
4167
                    gen_update_fprs_dirty(rd);
B
blueswir1 已提交
4168 4169
                    break;
                case 0x072: /* VIS I fxnor */
B
blueswir1 已提交
4170
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4171 4172 4173 4174 4175 4176
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs2)], -1);
                    tcg_gen_xor_i32(cpu_fpr[DFPREG(rd)], cpu_tmp32,
                                    cpu_fpr[DFPREG(rs1)]);
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[DFPREG(rs2) + 1], -1);
                    tcg_gen_xor_i32(cpu_fpr[DFPREG(rd) + 1], cpu_tmp32,
                                    cpu_fpr[DFPREG(rs1) + 1]);
4177
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
4178 4179
                    break;
                case 0x073: /* VIS I fxnors */
B
blueswir1 已提交
4180
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4181 4182
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[rs2], -1);
                    tcg_gen_xor_i32(cpu_fpr[rd], cpu_tmp32, cpu_fpr[rs1]);
4183
                    gen_update_fprs_dirty(rd);
B
blueswir1 已提交
4184
                    break;
4185
                case 0x074: /* VIS I fsrc1 */
B
blueswir1 已提交
4186
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4187 4188 4189
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)]);
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1],
                                    cpu_fpr[DFPREG(rs1) + 1]);
4190
                    gen_update_fprs_dirty(DFPREG(rd));
4191 4192
                    break;
                case 0x075: /* VIS I fsrc1s */
B
blueswir1 已提交
4193
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4194
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs1]);
4195
                    gen_update_fprs_dirty(rd);
4196
                    break;
B
blueswir1 已提交
4197
                case 0x076: /* VIS I fornot2 */
B
blueswir1 已提交
4198
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4199 4200 4201 4202 4203
                    tcg_gen_orc_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
                                    cpu_fpr[DFPREG(rs2)]);
                    tcg_gen_orc_i32(cpu_fpr[DFPREG(rd) + 1],
                                    cpu_fpr[DFPREG(rs1) + 1],
                                    cpu_fpr[DFPREG(rs2) + 1]);
4204
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
4205 4206
                    break;
                case 0x077: /* VIS I fornot2s */
B
blueswir1 已提交
4207
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4208
                    tcg_gen_orc_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
4209
                    gen_update_fprs_dirty(rd);
B
blueswir1 已提交
4210
                    break;
4211
                case 0x078: /* VIS I fsrc2 */
B
blueswir1 已提交
4212
                    CHECK_FPU_FEATURE(dc, VIS1);
4213 4214
                    gen_op_load_fpr_DT0(DFPREG(rs2));
                    gen_op_store_DT0_fpr(DFPREG(rd));
4215
                    gen_update_fprs_dirty(DFPREG(rd));
4216 4217
                    break;
                case 0x079: /* VIS I fsrc2s */
B
blueswir1 已提交
4218
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4219
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);
4220
                    gen_update_fprs_dirty(rd);
4221
                    break;
B
blueswir1 已提交
4222
                case 0x07a: /* VIS I fornot1 */
B
blueswir1 已提交
4223
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4224 4225 4226 4227 4228
                    tcg_gen_orc_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)],
                                    cpu_fpr[DFPREG(rs1)]);
                    tcg_gen_orc_i32(cpu_fpr[DFPREG(rd) + 1],
                                    cpu_fpr[DFPREG(rs2) + 1],
                                    cpu_fpr[DFPREG(rs1) + 1]);
4229
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
4230 4231
                    break;
                case 0x07b: /* VIS I fornot1s */
B
blueswir1 已提交
4232
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4233
                    tcg_gen_orc_i32(cpu_fpr[rd], cpu_fpr[rs2], cpu_fpr[rs1]);
4234
                    gen_update_fprs_dirty(rd);
B
blueswir1 已提交
4235 4236
                    break;
                case 0x07c: /* VIS I for */
B
blueswir1 已提交
4237
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4238 4239 4240 4241 4242
                    tcg_gen_or_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs1)],
                                   cpu_fpr[DFPREG(rs2)]);
                    tcg_gen_or_i32(cpu_fpr[DFPREG(rd) + 1],
                                   cpu_fpr[DFPREG(rs1) + 1],
                                   cpu_fpr[DFPREG(rs2) + 1]);
4243
                    gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
4244 4245
                    break;
                case 0x07d: /* VIS I fors */
B
blueswir1 已提交
4246
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4247
                    tcg_gen_or_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
4248
                    gen_update_fprs_dirty(rd);
B
blueswir1 已提交
4249
                    break;
4250
                case 0x07e: /* VIS I fone */
B
blueswir1 已提交
4251
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4252 4253
                    tcg_gen_movi_i32(cpu_fpr[DFPREG(rd)], -1);
                    tcg_gen_movi_i32(cpu_fpr[DFPREG(rd) + 1], -1);
4254
                    gen_update_fprs_dirty(DFPREG(rd));
4255 4256
                    break;
                case 0x07f: /* VIS I fones */
B
blueswir1 已提交
4257
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4258
                    tcg_gen_movi_i32(cpu_fpr[rd], -1);
4259
                    gen_update_fprs_dirty(rd);
4260
                    break;
B
blueswir1 已提交
4261 4262 4263 4264
                case 0x080: /* VIS I shutdown */
                case 0x081: /* VIS II siam */
                    // XXX
                    goto illegal_insn;
4265 4266 4267 4268
                default:
                    goto illegal_insn;
                }
#else
B
blueswir1 已提交
4269
                goto ncp_insn;
4270 4271
#endif
            } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
4272
#ifdef TARGET_SPARC64
B
blueswir1 已提交
4273
                goto illegal_insn;
4274
#else
B
blueswir1 已提交
4275
                goto ncp_insn;
4276
#endif
B
bellard 已提交
4277
#ifdef TARGET_SPARC64
B
blueswir1 已提交
4278
            } else if (xop == 0x39) { /* V9 return */
P
pbrook 已提交
4279
                TCGv_i32 r_const;
B
blueswir1 已提交
4280

4281
                save_state(dc, cpu_cond);
4282
                cpu_src1 = get_src1(insn, cpu_src1);
B
blueswir1 已提交
4283
                if (IS_IMM) {   /* immediate */
B
Blue Swirl 已提交
4284 4285
                    simm = GET_FIELDs(insn, 19, 31);
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, simm);
B
blueswir1 已提交
4286
                } else {                /* register */
B
bellard 已提交
4287
                    rs2 = GET_FIELD(insn, 27, 31);
B
blueswir1 已提交
4288
                    if (rs2) {
4289 4290
                        gen_movl_reg_TN(rs2, cpu_src2);
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
4291 4292
                    } else
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
B
bellard 已提交
4293
                }
P
pbrook 已提交
4294
                gen_helper_restore();
4295
                gen_mov_pc_npc(dc, cpu_cond);
B
blueswir1 已提交
4296
                r_const = tcg_const_i32(3);
P
pbrook 已提交
4297 4298
                gen_helper_check_align(cpu_dst, r_const);
                tcg_temp_free_i32(r_const);
4299
                tcg_gen_mov_tl(cpu_npc, cpu_dst);
B
blueswir1 已提交
4300 4301
                dc->npc = DYNAMIC_PC;
                goto jmp_insn;
B
bellard 已提交
4302
#endif
B
blueswir1 已提交
4303
            } else {
4304
                cpu_src1 = get_src1(insn, cpu_src1);
B
blueswir1 已提交
4305
                if (IS_IMM) {   /* immediate */
B
Blue Swirl 已提交
4306 4307
                    simm = GET_FIELDs(insn, 19, 31);
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, simm);
B
blueswir1 已提交
4308
                } else {                /* register */
B
bellard 已提交
4309
                    rs2 = GET_FIELD(insn, 27, 31);
B
blueswir1 已提交
4310
                    if (rs2) {
4311 4312
                        gen_movl_reg_TN(rs2, cpu_src2);
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
4313 4314
                    } else
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
4315
                }
B
blueswir1 已提交
4316 4317 4318
                switch (xop) {
                case 0x38:      /* jmpl */
                    {
P
pbrook 已提交
4319 4320
                        TCGv r_pc;
                        TCGv_i32 r_const;
B
blueswir1 已提交
4321

P
pbrook 已提交
4322 4323 4324
                        r_pc = tcg_const_tl(dc->pc);
                        gen_movl_TN_reg(rd, r_pc);
                        tcg_temp_free(r_pc);
4325
                        gen_mov_pc_npc(dc, cpu_cond);
B
blueswir1 已提交
4326
                        r_const = tcg_const_i32(3);
P
pbrook 已提交
4327 4328
                        gen_helper_check_align(cpu_dst, r_const);
                        tcg_temp_free_i32(r_const);
4329
                        tcg_gen_mov_tl(cpu_npc, cpu_dst);
B
blueswir1 已提交
4330 4331 4332
                        dc->npc = DYNAMIC_PC;
                    }
                    goto jmp_insn;
B
bellard 已提交
4333
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
B
blueswir1 已提交
4334 4335
                case 0x39:      /* rett, V9 return */
                    {
P
pbrook 已提交
4336
                        TCGv_i32 r_const;
B
blueswir1 已提交
4337

B
blueswir1 已提交
4338 4339
                        if (!supervisor(dc))
                            goto priv_insn;
4340
                        gen_mov_pc_npc(dc, cpu_cond);
B
blueswir1 已提交
4341
                        r_const = tcg_const_i32(3);
P
pbrook 已提交
4342 4343
                        gen_helper_check_align(cpu_dst, r_const);
                        tcg_temp_free_i32(r_const);
4344
                        tcg_gen_mov_tl(cpu_npc, cpu_dst);
B
blueswir1 已提交
4345
                        dc->npc = DYNAMIC_PC;
P
pbrook 已提交
4346
                        gen_helper_rett();
B
blueswir1 已提交
4347 4348 4349 4350
                    }
                    goto jmp_insn;
#endif
                case 0x3b: /* flush */
4351
                    if (!((dc)->def->features & CPU_FEATURE_FLUSH))
B
blueswir1 已提交
4352
                        goto unimp_flush;
4353
                    /* nop */
B
blueswir1 已提交
4354 4355
                    break;
                case 0x3c:      /* save */
4356
                    save_state(dc, cpu_cond);
P
pbrook 已提交
4357
                    gen_helper_save();
4358
                    gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
4359 4360
                    break;
                case 0x3d:      /* restore */
4361
                    save_state(dc, cpu_cond);
P
pbrook 已提交
4362
                    gen_helper_restore();
4363
                    gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
4364
                    break;
B
bellard 已提交
4365
#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
B
blueswir1 已提交
4366 4367 4368 4369 4370 4371 4372 4373
                case 0x3e:      /* V9 done/retry */
                    {
                        switch (rd) {
                        case 0:
                            if (!supervisor(dc))
                                goto priv_insn;
                            dc->npc = DYNAMIC_PC;
                            dc->pc = DYNAMIC_PC;
P
pbrook 已提交
4374
                            gen_helper_done();
B
blueswir1 已提交
4375 4376 4377 4378 4379 4380
                            goto jmp_insn;
                        case 1:
                            if (!supervisor(dc))
                                goto priv_insn;
                            dc->npc = DYNAMIC_PC;
                            dc->pc = DYNAMIC_PC;
P
pbrook 已提交
4381
                            gen_helper_retry();
B
blueswir1 已提交
4382 4383 4384 4385 4386 4387 4388 4389 4390 4391
                            goto jmp_insn;
                        default:
                            goto illegal_insn;
                        }
                    }
                    break;
#endif
                default:
                    goto illegal_insn;
                }
4392
            }
B
blueswir1 已提交
4393 4394 4395 4396 4397 4398
            break;
        }
        break;
    case 3:                     /* load/store instructions */
        {
            unsigned int xop = GET_FIELD(insn, 7, 12);
4399

4400 4401 4402 4403 4404 4405
            /* flush pending conditional evaluations before exposing
               cpu state */
            if (dc->cc_op != CC_OP_FLAGS) {
                dc->cc_op = CC_OP_FLAGS;
                gen_helper_compute_psr();
            }
4406
            cpu_src1 = get_src1(insn, cpu_src1);
B
blueswir1 已提交
4407
            if (xop == 0x3c || xop == 0x3e) { // V9 casa/casxa
4408
                rs2 = GET_FIELD(insn, 27, 31);
4409
                gen_movl_reg_TN(rs2, cpu_src2);
B
blueswir1 已提交
4410 4411
                tcg_gen_mov_tl(cpu_addr, cpu_src1);
            } else if (IS_IMM) {     /* immediate */
B
Blue Swirl 已提交
4412 4413
                simm = GET_FIELDs(insn, 19, 31);
                tcg_gen_addi_tl(cpu_addr, cpu_src1, simm);
B
blueswir1 已提交
4414 4415 4416
            } else {            /* register */
                rs2 = GET_FIELD(insn, 27, 31);
                if (rs2 != 0) {
4417 4418
                    gen_movl_reg_TN(rs2, cpu_src2);
                    tcg_gen_add_tl(cpu_addr, cpu_src1, cpu_src2);
4419 4420
                } else
                    tcg_gen_mov_tl(cpu_addr, cpu_src1);
B
blueswir1 已提交
4421
            }
B
blueswir1 已提交
4422 4423 4424
            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
                (xop > 0x17 && xop <= 0x1d ) ||
                (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
B
blueswir1 已提交
4425
                switch (xop) {
4426
                case 0x0:       /* ld, V9 lduw, load unsigned word */
B
blueswir1 已提交
4427
                    gen_address_mask(dc, cpu_addr);
4428
                    tcg_gen_qemu_ld32u(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4429
                    break;
4430
                case 0x1:       /* ldub, load unsigned byte */
B
blueswir1 已提交
4431
                    gen_address_mask(dc, cpu_addr);
4432
                    tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4433
                    break;
4434
                case 0x2:       /* lduh, load unsigned halfword */
B
blueswir1 已提交
4435
                    gen_address_mask(dc, cpu_addr);
4436
                    tcg_gen_qemu_ld16u(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4437
                    break;
4438
                case 0x3:       /* ldd, load double word */
B
blueswir1 已提交
4439
                    if (rd & 1)
4440
                        goto illegal_insn;
B
blueswir1 已提交
4441
                    else {
P
pbrook 已提交
4442
                        TCGv_i32 r_const;
B
blueswir1 已提交
4443

4444
                        save_state(dc, cpu_cond);
B
blueswir1 已提交
4445
                        r_const = tcg_const_i32(7);
P
pbrook 已提交
4446 4447
                        gen_helper_check_align(cpu_addr, r_const); // XXX remove
                        tcg_temp_free_i32(r_const);
B
blueswir1 已提交
4448
                        gen_address_mask(dc, cpu_addr);
4449
                        tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
4450 4451 4452
                        tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
                        tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffffULL);
                        gen_movl_TN_reg(rd + 1, cpu_tmp0);
B
blueswir1 已提交
4453
                        tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
4454 4455
                        tcg_gen_trunc_i64_tl(cpu_val, cpu_tmp64);
                        tcg_gen_andi_tl(cpu_val, cpu_val, 0xffffffffULL);
B
blueswir1 已提交
4456
                    }
B
blueswir1 已提交
4457
                    break;
4458
                case 0x9:       /* ldsb, load signed byte */
B
blueswir1 已提交
4459
                    gen_address_mask(dc, cpu_addr);
4460
                    tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4461
                    break;
4462
                case 0xa:       /* ldsh, load signed halfword */
B
blueswir1 已提交
4463
                    gen_address_mask(dc, cpu_addr);
4464
                    tcg_gen_qemu_ld16s(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4465 4466
                    break;
                case 0xd:       /* ldstub -- XXX: should be atomically */
B
blueswir1 已提交
4467 4468 4469
                    {
                        TCGv r_const;

B
blueswir1 已提交
4470
                        gen_address_mask(dc, cpu_addr);
B
blueswir1 已提交
4471 4472 4473 4474 4475
                        tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
                        r_const = tcg_const_tl(0xff);
                        tcg_gen_qemu_st8(r_const, cpu_addr, dc->mem_idx);
                        tcg_temp_free(r_const);
                    }
B
blueswir1 已提交
4476
                    break;
4477
                case 0x0f:      /* swap, swap register with memory. Also
B
blueswir1 已提交
4478
                                   atomically */
B
blueswir1 已提交
4479
                    CHECK_IU_FEATURE(dc, SWAP);
4480
                    gen_movl_reg_TN(rd, cpu_val);
B
blueswir1 已提交
4481
                    gen_address_mask(dc, cpu_addr);
B
blueswir1 已提交
4482
                    tcg_gen_qemu_ld32u(cpu_tmp0, cpu_addr, dc->mem_idx);
4483
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4484
                    tcg_gen_mov_tl(cpu_val, cpu_tmp0);
B
blueswir1 已提交
4485
                    break;
B
bellard 已提交
4486
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4487
                case 0x10:      /* lda, V9 lduwa, load word alternate */
B
bellard 已提交
4488
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4489 4490 4491 4492
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
blueswir1 已提交
4493
#endif
4494
                    save_state(dc, cpu_cond);
4495
                    gen_ld_asi(cpu_val, cpu_addr, insn, 4, 0);
B
blueswir1 已提交
4496
                    break;
4497
                case 0x11:      /* lduba, load unsigned byte alternate */
B
bellard 已提交
4498
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4499 4500 4501 4502 4503
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
#endif
4504
                    save_state(dc, cpu_cond);
4505
                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 0);
B
blueswir1 已提交
4506
                    break;
4507
                case 0x12:      /* lduha, load unsigned halfword alternate */
B
bellard 已提交
4508
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4509 4510 4511 4512
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
bellard 已提交
4513
#endif
4514
                    save_state(dc, cpu_cond);
4515
                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 0);
B
blueswir1 已提交
4516
                    break;
4517
                case 0x13:      /* ldda, load double word alternate */
B
bellard 已提交
4518
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4519 4520 4521 4522
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
bellard 已提交
4523
#endif
B
blueswir1 已提交
4524
                    if (rd & 1)
4525
                        goto illegal_insn;
4526
                    save_state(dc, cpu_cond);
B
blueswir1 已提交
4527 4528
                    gen_ldda_asi(cpu_val, cpu_addr, insn, rd);
                    goto skip_move;
4529
                case 0x19:      /* ldsba, load signed byte alternate */
B
bellard 已提交
4530
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4531 4532 4533 4534 4535
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
#endif
4536
                    save_state(dc, cpu_cond);
4537
                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 1);
B
blueswir1 已提交
4538
                    break;
4539
                case 0x1a:      /* ldsha, load signed halfword alternate */
B
bellard 已提交
4540
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4541 4542 4543 4544
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
bellard 已提交
4545
#endif
4546
                    save_state(dc, cpu_cond);
4547
                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 1);
B
blueswir1 已提交
4548 4549
                    break;
                case 0x1d:      /* ldstuba -- XXX: should be atomically */
B
bellard 已提交
4550
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4551 4552 4553 4554 4555
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
#endif
4556
                    save_state(dc, cpu_cond);
4557
                    gen_ldstub_asi(cpu_val, cpu_addr, insn);
B
blueswir1 已提交
4558
                    break;
4559
                case 0x1f:      /* swapa, swap reg with alt. memory. Also
B
blueswir1 已提交
4560
                                   atomically */
B
blueswir1 已提交
4561
                    CHECK_IU_FEATURE(dc, SWAP);
B
bellard 已提交
4562
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4563 4564 4565 4566
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
blueswir1 已提交
4567
#endif
4568
                    save_state(dc, cpu_cond);
4569 4570
                    gen_movl_reg_TN(rd, cpu_val);
                    gen_swap_asi(cpu_val, cpu_addr, insn);
B
blueswir1 已提交
4571
                    break;
B
bellard 已提交
4572 4573

#ifndef TARGET_SPARC64
B
blueswir1 已提交
4574 4575 4576 4577
                case 0x30: /* ldc */
                case 0x31: /* ldcsr */
                case 0x33: /* lddc */
                    goto ncp_insn;
B
bellard 已提交
4578 4579 4580
#endif
#endif
#ifdef TARGET_SPARC64
B
blueswir1 已提交
4581
                case 0x08: /* V9 ldsw */
B
blueswir1 已提交
4582
                    gen_address_mask(dc, cpu_addr);
4583
                    tcg_gen_qemu_ld32s(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4584 4585
                    break;
                case 0x0b: /* V9 ldx */
B
blueswir1 已提交
4586
                    gen_address_mask(dc, cpu_addr);
4587
                    tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4588 4589
                    break;
                case 0x18: /* V9 ldswa */
4590
                    save_state(dc, cpu_cond);
4591
                    gen_ld_asi(cpu_val, cpu_addr, insn, 4, 1);
B
blueswir1 已提交
4592 4593
                    break;
                case 0x1b: /* V9 ldxa */
4594
                    save_state(dc, cpu_cond);
4595
                    gen_ld_asi(cpu_val, cpu_addr, insn, 8, 0);
B
blueswir1 已提交
4596 4597 4598 4599
                    break;
                case 0x2d: /* V9 prefetch, no effect */
                    goto skip_move;
                case 0x30: /* V9 ldfa */
4600 4601 4602
                    if (gen_trap_ifnofpu(dc, cpu_cond)) {
                        goto jmp_insn;
                    }
4603
                    save_state(dc, cpu_cond);
4604
                    gen_ldf_asi(cpu_addr, insn, 4, rd);
4605
                    gen_update_fprs_dirty(rd);
4606
                    goto skip_move;
B
blueswir1 已提交
4607
                case 0x33: /* V9 lddfa */
4608 4609 4610
                    if (gen_trap_ifnofpu(dc, cpu_cond)) {
                        goto jmp_insn;
                    }
4611
                    save_state(dc, cpu_cond);
4612
                    gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd));
4613
                    gen_update_fprs_dirty(DFPREG(rd));
4614
                    goto skip_move;
B
blueswir1 已提交
4615 4616 4617
                case 0x3d: /* V9 prefetcha, no effect */
                    goto skip_move;
                case 0x32: /* V9 ldqfa */
B
blueswir1 已提交
4618
                    CHECK_FPU_FEATURE(dc, FLOAT128);
4619 4620 4621
                    if (gen_trap_ifnofpu(dc, cpu_cond)) {
                        goto jmp_insn;
                    }
4622
                    save_state(dc, cpu_cond);
4623
                    gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd));
4624
                    gen_update_fprs_dirty(QFPREG(rd));
B
blueswir1 已提交
4625
                    goto skip_move;
B
blueswir1 已提交
4626 4627 4628 4629
#endif
                default:
                    goto illegal_insn;
                }
4630
                gen_movl_TN_reg(rd, cpu_val);
B
blueswir1 已提交
4631
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
B
blueswir1 已提交
4632
            skip_move: ;
B
bellard 已提交
4633
#endif
B
blueswir1 已提交
4634
            } else if (xop >= 0x20 && xop < 0x24) {
4635
                if (gen_trap_ifnofpu(dc, cpu_cond))
B
bellard 已提交
4636
                    goto jmp_insn;
4637
                save_state(dc, cpu_cond);
B
blueswir1 已提交
4638
                switch (xop) {
4639
                case 0x20:      /* ldf, load fpreg */
B
blueswir1 已提交
4640
                    gen_address_mask(dc, cpu_addr);
B
blueswir1 已提交
4641 4642
                    tcg_gen_qemu_ld32u(cpu_tmp0, cpu_addr, dc->mem_idx);
                    tcg_gen_trunc_tl_i32(cpu_fpr[rd], cpu_tmp0);
4643
                    gen_update_fprs_dirty(rd);
B
blueswir1 已提交
4644
                    break;
4645 4646
                case 0x21:      /* ldfsr, V9 ldxfsr */
#ifdef TARGET_SPARC64
B
blueswir1 已提交
4647
                    gen_address_mask(dc, cpu_addr);
4648 4649
                    if (rd == 1) {
                        tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
P
pbrook 已提交
4650
                        gen_helper_ldxfsr(cpu_tmp64);
I
Igor V. Kovalenko 已提交
4651 4652 4653 4654 4655
                    } else {
                        tcg_gen_qemu_ld32u(cpu_tmp0, cpu_addr, dc->mem_idx);
                        tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
                        gen_helper_ldfsr(cpu_tmp32);
                    }
4656 4657 4658
#else
                    {
                        tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
P
pbrook 已提交
4659
                        gen_helper_ldfsr(cpu_tmp32);
4660 4661
                    }
#endif
B
blueswir1 已提交
4662
                    break;
4663
                case 0x22:      /* ldqf, load quad fpreg */
B
blueswir1 已提交
4664
                    {
P
pbrook 已提交
4665
                        TCGv_i32 r_const;
B
blueswir1 已提交
4666 4667 4668

                        CHECK_FPU_FEATURE(dc, FLOAT128);
                        r_const = tcg_const_i32(dc->mem_idx);
4669
                        gen_address_mask(dc, cpu_addr);
P
pbrook 已提交
4670 4671
                        gen_helper_ldqf(cpu_addr, r_const);
                        tcg_temp_free_i32(r_const);
B
blueswir1 已提交
4672
                        gen_op_store_QT0_fpr(QFPREG(rd));
4673
                        gen_update_fprs_dirty(QFPREG(rd));
B
blueswir1 已提交
4674
                    }
B
blueswir1 已提交
4675
                    break;
4676
                case 0x23:      /* lddf, load double fpreg */
B
blueswir1 已提交
4677
                    {
P
pbrook 已提交
4678
                        TCGv_i32 r_const;
B
blueswir1 已提交
4679 4680

                        r_const = tcg_const_i32(dc->mem_idx);
4681
                        gen_address_mask(dc, cpu_addr);
P
pbrook 已提交
4682 4683
                        gen_helper_lddf(cpu_addr, r_const);
                        tcg_temp_free_i32(r_const);
B
blueswir1 已提交
4684
                        gen_op_store_DT0_fpr(DFPREG(rd));
4685
                        gen_update_fprs_dirty(DFPREG(rd));
B
blueswir1 已提交
4686
                    }
B
blueswir1 已提交
4687 4688 4689 4690
                    break;
                default:
                    goto illegal_insn;
                }
B
Blue Swirl 已提交
4691
            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) ||
B
blueswir1 已提交
4692
                       xop == 0xe || xop == 0x1e) {
4693
                gen_movl_reg_TN(rd, cpu_val);
B
blueswir1 已提交
4694
                switch (xop) {
4695
                case 0x4: /* st, store word */
B
blueswir1 已提交
4696
                    gen_address_mask(dc, cpu_addr);
4697
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4698
                    break;
4699
                case 0x5: /* stb, store byte */
B
blueswir1 已提交
4700
                    gen_address_mask(dc, cpu_addr);
4701
                    tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4702
                    break;
4703
                case 0x6: /* sth, store halfword */
B
blueswir1 已提交
4704
                    gen_address_mask(dc, cpu_addr);
4705
                    tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4706
                    break;
4707
                case 0x7: /* std, store double word */
B
blueswir1 已提交
4708
                    if (rd & 1)
4709
                        goto illegal_insn;
B
blueswir1 已提交
4710
                    else {
P
pbrook 已提交
4711
                        TCGv_i32 r_const;
B
blueswir1 已提交
4712

4713
                        save_state(dc, cpu_cond);
B
blueswir1 已提交
4714
                        gen_address_mask(dc, cpu_addr);
B
blueswir1 已提交
4715
                        r_const = tcg_const_i32(7);
P
pbrook 已提交
4716 4717
                        gen_helper_check_align(cpu_addr, r_const); // XXX remove
                        tcg_temp_free_i32(r_const);
4718
                        gen_movl_reg_TN(rd + 1, cpu_tmp0);
4719
                        tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, cpu_val);
4720
                        tcg_gen_qemu_st64(cpu_tmp64, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4721
                    }
B
blueswir1 已提交
4722
                    break;
B
bellard 已提交
4723
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4724
                case 0x14: /* sta, V9 stwa, store word alternate */
B
bellard 已提交
4725
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4726 4727 4728 4729
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
blueswir1 已提交
4730
#endif
4731
                    save_state(dc, cpu_cond);
4732
                    gen_st_asi(cpu_val, cpu_addr, insn, 4);
4733
                    dc->npc = DYNAMIC_PC;
B
bellard 已提交
4734
                    break;
4735
                case 0x15: /* stba, store byte alternate */
B
bellard 已提交
4736
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4737 4738 4739 4740
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
bellard 已提交
4741
#endif
4742
                    save_state(dc, cpu_cond);
4743
                    gen_st_asi(cpu_val, cpu_addr, insn, 1);
4744
                    dc->npc = DYNAMIC_PC;
B
bellard 已提交
4745
                    break;
4746
                case 0x16: /* stha, store halfword alternate */
B
bellard 已提交
4747
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4748 4749 4750 4751
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
blueswir1 已提交
4752
#endif
4753
                    save_state(dc, cpu_cond);
4754
                    gen_st_asi(cpu_val, cpu_addr, insn, 2);
4755
                    dc->npc = DYNAMIC_PC;
B
bellard 已提交
4756
                    break;
4757
                case 0x17: /* stda, store double word alternate */
B
bellard 已提交
4758
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4759 4760 4761 4762
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
bellard 已提交
4763
#endif
B
blueswir1 已提交
4764
                    if (rd & 1)
4765
                        goto illegal_insn;
B
blueswir1 已提交
4766
                    else {
4767
                        save_state(dc, cpu_cond);
4768
                        gen_stda_asi(cpu_val, cpu_addr, insn, rd);
B
blueswir1 已提交
4769
                    }
B
bellard 已提交
4770
                    break;
B
bellard 已提交
4771
#endif
B
bellard 已提交
4772
#ifdef TARGET_SPARC64
B
blueswir1 已提交
4773
                case 0x0e: /* V9 stx */
B
blueswir1 已提交
4774
                    gen_address_mask(dc, cpu_addr);
4775
                    tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4776 4777
                    break;
                case 0x1e: /* V9 stxa */
4778
                    save_state(dc, cpu_cond);
4779
                    gen_st_asi(cpu_val, cpu_addr, insn, 8);
4780
                    dc->npc = DYNAMIC_PC;
B
blueswir1 已提交
4781
                    break;
B
bellard 已提交
4782
#endif
B
blueswir1 已提交
4783 4784 4785 4786
                default:
                    goto illegal_insn;
                }
            } else if (xop > 0x23 && xop < 0x28) {
4787
                if (gen_trap_ifnofpu(dc, cpu_cond))
B
bellard 已提交
4788
                    goto jmp_insn;
4789
                save_state(dc, cpu_cond);
B
blueswir1 已提交
4790
                switch (xop) {
4791
                case 0x24: /* stf, store fpreg */
B
blueswir1 已提交
4792
                    gen_address_mask(dc, cpu_addr);
B
blueswir1 已提交
4793 4794
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_fpr[rd]);
                    tcg_gen_qemu_st32(cpu_tmp0, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4795 4796
                    break;
                case 0x25: /* stfsr, V9 stxfsr */
4797
#ifdef TARGET_SPARC64
B
blueswir1 已提交
4798
                    gen_address_mask(dc, cpu_addr);
4799 4800 4801
                    tcg_gen_ld_i64(cpu_tmp64, cpu_env, offsetof(CPUState, fsr));
                    if (rd == 1)
                        tcg_gen_qemu_st64(cpu_tmp64, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4802 4803
                    else
                        tcg_gen_qemu_st32(cpu_tmp64, cpu_addr, dc->mem_idx);
4804 4805
#else
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUState, fsr));
4806
                    tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx);
4807
#endif
B
blueswir1 已提交
4808
                    break;
B
blueswir1 已提交
4809 4810 4811
                case 0x26:
#ifdef TARGET_SPARC64
                    /* V9 stqf, store quad fpreg */
B
blueswir1 已提交
4812
                    {
P
pbrook 已提交
4813
                        TCGv_i32 r_const;
B
blueswir1 已提交
4814 4815 4816 4817

                        CHECK_FPU_FEATURE(dc, FLOAT128);
                        gen_op_load_fpr_QT0(QFPREG(rd));
                        r_const = tcg_const_i32(dc->mem_idx);
4818
                        gen_address_mask(dc, cpu_addr);
P
pbrook 已提交
4819 4820
                        gen_helper_stqf(cpu_addr, r_const);
                        tcg_temp_free_i32(r_const);
B
blueswir1 已提交
4821
                    }
B
blueswir1 已提交
4822 4823 4824 4825 4826 4827
                    break;
#else /* !TARGET_SPARC64 */
                    /* stdfq, store floating point queue */
#if defined(CONFIG_USER_ONLY)
                    goto illegal_insn;
#else
B
blueswir1 已提交
4828 4829
                    if (!supervisor(dc))
                        goto priv_insn;
4830
                    if (gen_trap_ifnofpu(dc, cpu_cond))
B
blueswir1 已提交
4831 4832
                        goto jmp_insn;
                    goto nfq_insn;
B
blueswir1 已提交
4833
#endif
B
blueswir1 已提交
4834
#endif
4835
                case 0x27: /* stdf, store double fpreg */
B
blueswir1 已提交
4836
                    {
P
pbrook 已提交
4837
                        TCGv_i32 r_const;
B
blueswir1 已提交
4838 4839 4840

                        gen_op_load_fpr_DT0(DFPREG(rd));
                        r_const = tcg_const_i32(dc->mem_idx);
4841
                        gen_address_mask(dc, cpu_addr);
P
pbrook 已提交
4842 4843
                        gen_helper_stdf(cpu_addr, r_const);
                        tcg_temp_free_i32(r_const);
B
blueswir1 已提交
4844
                    }
B
blueswir1 已提交
4845 4846 4847 4848 4849
                    break;
                default:
                    goto illegal_insn;
                }
            } else if (xop > 0x33 && xop < 0x3f) {
4850
                save_state(dc, cpu_cond);
B
blueswir1 已提交
4851
                switch (xop) {
4852
#ifdef TARGET_SPARC64
B
blueswir1 已提交
4853
                case 0x34: /* V9 stfa */
4854 4855 4856
                    if (gen_trap_ifnofpu(dc, cpu_cond)) {
                        goto jmp_insn;
                    }
4857
                    gen_stf_asi(cpu_addr, insn, 4, rd);
B
blueswir1 已提交
4858
                    break;
B
blueswir1 已提交
4859
                case 0x36: /* V9 stqfa */
B
blueswir1 已提交
4860
                    {
P
pbrook 已提交
4861
                        TCGv_i32 r_const;
B
blueswir1 已提交
4862 4863

                        CHECK_FPU_FEATURE(dc, FLOAT128);
4864 4865 4866
                        if (gen_trap_ifnofpu(dc, cpu_cond)) {
                            goto jmp_insn;
                        }
B
blueswir1 已提交
4867
                        r_const = tcg_const_i32(7);
P
pbrook 已提交
4868 4869
                        gen_helper_check_align(cpu_addr, r_const);
                        tcg_temp_free_i32(r_const);
B
blueswir1 已提交
4870 4871
                        gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd));
                    }
B
blueswir1 已提交
4872
                    break;
B
blueswir1 已提交
4873
                case 0x37: /* V9 stdfa */
4874 4875 4876
                    if (gen_trap_ifnofpu(dc, cpu_cond)) {
                        goto jmp_insn;
                    }
4877
                    gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
B
blueswir1 已提交
4878 4879
                    break;
                case 0x3c: /* V9 casa */
B
blueswir1 已提交
4880
                    gen_cas_asi(cpu_val, cpu_addr, cpu_src2, insn, rd);
4881
                    gen_movl_TN_reg(rd, cpu_val);
B
blueswir1 已提交
4882 4883
                    break;
                case 0x3e: /* V9 casxa */
B
blueswir1 已提交
4884
                    gen_casx_asi(cpu_val, cpu_addr, cpu_src2, insn, rd);
4885
                    gen_movl_TN_reg(rd, cpu_val);
B
blueswir1 已提交
4886
                    break;
4887
#else
B
blueswir1 已提交
4888 4889 4890 4891 4892 4893 4894 4895 4896
                case 0x34: /* stc */
                case 0x35: /* stcsr */
                case 0x36: /* stdcq */
                case 0x37: /* stdc */
                    goto ncp_insn;
#endif
                default:
                    goto illegal_insn;
                }
B
Blue Swirl 已提交
4897
            } else
B
blueswir1 已提交
4898 4899 4900
                goto illegal_insn;
        }
        break;
4901 4902
    }
    /* default case for non jump instructions */
B
bellard 已提交
4903
    if (dc->npc == DYNAMIC_PC) {
B
blueswir1 已提交
4904 4905
        dc->pc = DYNAMIC_PC;
        gen_op_next_insn();
B
bellard 已提交
4906 4907
    } else if (dc->npc == JUMP_PC) {
        /* we can do a static jump */
4908
        gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
B
bellard 已提交
4909 4910
        dc->is_br = 1;
    } else {
B
blueswir1 已提交
4911 4912
        dc->pc = dc->npc;
        dc->npc = dc->npc + 4;
4913
    }
B
bellard 已提交
4914
 jmp_insn:
4915
    goto egress;
4916
 illegal_insn:
B
blueswir1 已提交
4917
    {
P
pbrook 已提交
4918
        TCGv_i32 r_const;
B
blueswir1 已提交
4919 4920 4921

        save_state(dc, cpu_cond);
        r_const = tcg_const_i32(TT_ILL_INSN);
P
pbrook 已提交
4922 4923
        gen_helper_raise_exception(r_const);
        tcg_temp_free_i32(r_const);
B
blueswir1 已提交
4924 4925
        dc->is_br = 1;
    }
4926
    goto egress;
B
blueswir1 已提交
4927
 unimp_flush:
B
blueswir1 已提交
4928
    {
P
pbrook 已提交
4929
        TCGv_i32 r_const;
B
blueswir1 已提交
4930 4931 4932

        save_state(dc, cpu_cond);
        r_const = tcg_const_i32(TT_UNIMP_FLUSH);
P
pbrook 已提交
4933 4934
        gen_helper_raise_exception(r_const);
        tcg_temp_free_i32(r_const);
B
blueswir1 已提交
4935 4936
        dc->is_br = 1;
    }
4937
    goto egress;
B
bellard 已提交
4938
#if !defined(CONFIG_USER_ONLY)
4939
 priv_insn:
B
blueswir1 已提交
4940
    {
P
pbrook 已提交
4941
        TCGv_i32 r_const;
B
blueswir1 已提交
4942 4943 4944

        save_state(dc, cpu_cond);
        r_const = tcg_const_i32(TT_PRIV_INSN);
P
pbrook 已提交
4945 4946
        gen_helper_raise_exception(r_const);
        tcg_temp_free_i32(r_const);
B
blueswir1 已提交
4947 4948
        dc->is_br = 1;
    }
4949
    goto egress;
B
blueswir1 已提交
4950
#endif
B
bellard 已提交
4951
 nfpu_insn:
4952
    save_state(dc, cpu_cond);
B
bellard 已提交
4953 4954
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
    dc->is_br = 1;
4955
    goto egress;
B
blueswir1 已提交
4956
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
B
blueswir1 已提交
4957
 nfq_insn:
4958
    save_state(dc, cpu_cond);
B
blueswir1 已提交
4959 4960
    gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
    dc->is_br = 1;
4961
    goto egress;
B
blueswir1 已提交
4962
#endif
4963 4964
#ifndef TARGET_SPARC64
 ncp_insn:
B
blueswir1 已提交
4965 4966 4967 4968 4969
    {
        TCGv r_const;

        save_state(dc, cpu_cond);
        r_const = tcg_const_i32(TT_NCP_INSN);
P
pbrook 已提交
4970
        gen_helper_raise_exception(r_const);
B
blueswir1 已提交
4971 4972 4973
        tcg_temp_free(r_const);
        dc->is_br = 1;
    }
4974
    goto egress;
4975
#endif
4976 4977 4978
 egress:
    tcg_temp_free(cpu_tmp1);
    tcg_temp_free(cpu_tmp2);
4979 4980
}

4981 4982
static inline void gen_intermediate_code_internal(TranslationBlock * tb,
                                                  int spc, CPUSPARCState *env)
4983
{
B
bellard 已提交
4984
    target_ulong pc_start, last_pc;
4985 4986
    uint16_t *gen_opc_end;
    DisasContext dc1, *dc = &dc1;
4987
    CPUBreakpoint *bp;
4988
    int j, lj = -1;
P
pbrook 已提交
4989 4990
    int num_insns;
    int max_insns;
4991 4992 4993

    memset(dc, 0, sizeof(DisasContext));
    dc->tb = tb;
B
bellard 已提交
4994
    pc_start = tb->pc;
4995
    dc->pc = pc_start;
B
bellard 已提交
4996
    last_pc = dc->pc;
B
bellard 已提交
4997
    dc->npc = (target_ulong) tb->cs_base;
4998
    dc->cc_op = CC_OP_DYNAMIC;
B
blueswir1 已提交
4999
    dc->mem_idx = cpu_mmu_index(env);
5000
    dc->def = env->def;
5001 5002
    dc->fpu_enabled = tb_fpu_enabled(tb->flags);
    dc->address_mask_32bit = tb_am_enabled(tb->flags);
5003
    dc->singlestep = (env->singlestep_enabled || singlestep);
5004 5005
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;

P
pbrook 已提交
5006 5007 5008
    cpu_tmp0 = tcg_temp_new();
    cpu_tmp32 = tcg_temp_new_i32();
    cpu_tmp64 = tcg_temp_new_i64();
B
blueswir1 已提交
5009

P
pbrook 已提交
5010
    cpu_dst = tcg_temp_local_new();
B
blueswir1 已提交
5011 5012

    // loads and stores
P
pbrook 已提交
5013 5014
    cpu_val = tcg_temp_local_new();
    cpu_addr = tcg_temp_local_new();
B
blueswir1 已提交
5015

P
pbrook 已提交
5016 5017 5018 5019 5020
    num_insns = 0;
    max_insns = tb->cflags & CF_COUNT_MASK;
    if (max_insns == 0)
        max_insns = CF_COUNT_MASK;
    gen_icount_start();
5021
    do {
B
Blue Swirl 已提交
5022 5023
        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
5024
                if (bp->pc == dc->pc) {
B
blueswir1 已提交
5025
                    if (dc->pc != pc_start)
5026
                        save_state(dc, cpu_cond);
P
pbrook 已提交
5027
                    gen_helper_debug();
B
bellard 已提交
5028
                    tcg_gen_exit_tb(0);
B
blueswir1 已提交
5029
                    dc->is_br = 1;
B
bellard 已提交
5030
                    goto exit_gen_loop;
5031 5032 5033 5034
                }
            }
        }
        if (spc) {
5035
            qemu_log("Search PC...\n");
5036 5037 5038 5039 5040 5041 5042 5043
            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;
P
pbrook 已提交
5044
                gen_opc_icount[lj] = num_insns;
5045 5046
            }
        }
P
pbrook 已提交
5047 5048
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
            gen_io_start();
B
blueswir1 已提交
5049 5050
        last_pc = dc->pc;
        disas_sparc_insn(dc);
P
pbrook 已提交
5051
        num_insns++;
B
blueswir1 已提交
5052 5053 5054 5055 5056 5057

        if (dc->is_br)
            break;
        /* if the next PC is different, we abort now */
        if (dc->pc != (last_pc + 4))
            break;
B
bellard 已提交
5058 5059 5060 5061
        /* 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 已提交
5062 5063
        /* if single step mode, we generate only one instruction and
           generate an exception */
5064
        if (dc->singlestep) {
B
bellard 已提交
5065 5066
            break;
        }
5067
    } while ((gen_opc_ptr < gen_opc_end) &&
P
pbrook 已提交
5068 5069
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32) &&
             num_insns < max_insns);
B
bellard 已提交
5070 5071

 exit_gen_loop:
B
blueswir1 已提交
5072
    tcg_temp_free(cpu_addr);
B
blueswir1 已提交
5073
    tcg_temp_free(cpu_val);
B
blueswir1 已提交
5074
    tcg_temp_free(cpu_dst);
P
pbrook 已提交
5075 5076
    tcg_temp_free_i64(cpu_tmp64);
    tcg_temp_free_i32(cpu_tmp32);
B
blueswir1 已提交
5077
    tcg_temp_free(cpu_tmp0);
P
pbrook 已提交
5078 5079
    if (tb->cflags & CF_LAST_IO)
        gen_io_end();
B
bellard 已提交
5080
    if (!dc->is_br) {
5081
        if (dc->pc != DYNAMIC_PC &&
B
bellard 已提交
5082 5083
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
            /* static PC and NPC: we can use direct chaining */
B
blueswir1 已提交
5084
            gen_goto_tb(dc, 0, dc->pc, dc->npc);
B
bellard 已提交
5085 5086
        } else {
            if (dc->pc != DYNAMIC_PC)
B
blueswir1 已提交
5087
                tcg_gen_movi_tl(cpu_pc, dc->pc);
5088
            save_npc(dc, cpu_cond);
B
bellard 已提交
5089
            tcg_gen_exit_tb(0);
B
bellard 已提交
5090 5091
        }
    }
P
pbrook 已提交
5092
    gen_icount_end(tb, num_insns);
5093
    *gen_opc_ptr = INDEX_op_end;
5094 5095 5096 5097 5098 5099
    if (spc) {
        j = gen_opc_ptr - gen_opc_buf;
        lj++;
        while (lj <= j)
            gen_opc_instr_start[lj++] = 0;
#if 0
5100
        log_page_dump();
5101
#endif
5102 5103
        gen_opc_jump_pc[0] = dc->jump_pc[0];
        gen_opc_jump_pc[1] = dc->jump_pc[1];
5104
    } else {
B
bellard 已提交
5105
        tb->size = last_pc + 4 - pc_start;
P
pbrook 已提交
5106
        tb->icount = num_insns;
5107
    }
5108
#ifdef DEBUG_DISAS
5109
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
5110 5111 5112 5113
        qemu_log("--------------\n");
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
        log_target_disas(pc_start, last_pc + 4 - pc_start, 0);
        qemu_log("\n");
5114
    }
5115 5116 5117
#endif
}

5118
void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
5119
{
5120
    gen_intermediate_code_internal(tb, 0, env);
5121 5122
}

5123
void gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
5124
{
5125
    gen_intermediate_code_internal(tb, 1, env);
5126 5127
}

5128
void gen_intermediate_code_init(CPUSPARCState *env)
B
bellard 已提交
5129
{
B
blueswir1 已提交
5130
    unsigned int i;
5131
    static int inited;
B
blueswir1 已提交
5132 5133 5134 5135 5136 5137 5138 5139 5140 5141
    static const char * const gregnames[8] = {
        NULL, // g0 not used
        "g1",
        "g2",
        "g3",
        "g4",
        "g5",
        "g6",
        "g7",
    };
B
blueswir1 已提交
5142 5143 5144 5145 5146 5147 5148 5149 5150 5151
    static const char * const fregnames[64] = {
        "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
        "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
        "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
        "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
        "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
        "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
        "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
        "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
    };
B
bellard 已提交
5152

B
blueswir1 已提交
5153 5154 5155 5156
    /* init various static tables */
    if (!inited) {
        inited = 1;

P
pbrook 已提交
5157 5158 5159 5160
        cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
        cpu_regwptr = tcg_global_mem_new_ptr(TCG_AREG0,
                                             offsetof(CPUState, regwptr),
                                             "regwptr");
B
blueswir1 已提交
5161
#ifdef TARGET_SPARC64
P
pbrook 已提交
5162 5163 5164 5165 5166 5167 5168
        cpu_xcc = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, xcc),
                                         "xcc");
        cpu_asi = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, asi),
                                         "asi");
        cpu_fprs = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, fprs),
                                          "fprs");
        cpu_gsr = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, gsr),
5169
                                     "gsr");
P
pbrook 已提交
5170
        cpu_tick_cmpr = tcg_global_mem_new(TCG_AREG0,
5171 5172
                                           offsetof(CPUState, tick_cmpr),
                                           "tick_cmpr");
P
pbrook 已提交
5173
        cpu_stick_cmpr = tcg_global_mem_new(TCG_AREG0,
5174 5175
                                            offsetof(CPUState, stick_cmpr),
                                            "stick_cmpr");
P
pbrook 已提交
5176
        cpu_hstick_cmpr = tcg_global_mem_new(TCG_AREG0,
5177 5178
                                             offsetof(CPUState, hstick_cmpr),
                                             "hstick_cmpr");
P
pbrook 已提交
5179
        cpu_hintp = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, hintp),
5180
                                       "hintp");
P
pbrook 已提交
5181 5182 5183 5184 5185
        cpu_htba = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, htba),
                                      "htba");
        cpu_hver = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, hver),
                                      "hver");
        cpu_ssr = tcg_global_mem_new(TCG_AREG0,
5186
                                     offsetof(CPUState, ssr), "ssr");
P
pbrook 已提交
5187
        cpu_ver = tcg_global_mem_new(TCG_AREG0,
5188
                                     offsetof(CPUState, version), "ver");
P
pbrook 已提交
5189 5190 5191
        cpu_softint = tcg_global_mem_new_i32(TCG_AREG0,
                                             offsetof(CPUState, softint),
                                             "softint");
5192
#else
P
pbrook 已提交
5193
        cpu_wim = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, wim),
5194
                                     "wim");
B
blueswir1 已提交
5195
#endif
P
pbrook 已提交
5196
        cpu_cond = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cond),
B
blueswir1 已提交
5197
                                      "cond");
P
pbrook 已提交
5198
        cpu_cc_src = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_src),
5199
                                        "cc_src");
P
pbrook 已提交
5200
        cpu_cc_src2 = tcg_global_mem_new(TCG_AREG0,
B
blueswir1 已提交
5201 5202
                                         offsetof(CPUState, cc_src2),
                                         "cc_src2");
P
pbrook 已提交
5203
        cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_dst),
5204
                                        "cc_dst");
5205 5206
        cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, cc_op),
                                           "cc_op");
P
pbrook 已提交
5207 5208 5209
        cpu_psr = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, psr),
                                         "psr");
        cpu_fsr = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, fsr),
B
blueswir1 已提交
5210
                                     "fsr");
P
pbrook 已提交
5211
        cpu_pc = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, pc),
B
blueswir1 已提交
5212
                                    "pc");
P
pbrook 已提交
5213 5214 5215
        cpu_npc = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, npc),
                                     "npc");
        cpu_y = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, y), "y");
5216
#ifndef CONFIG_USER_ONLY
P
pbrook 已提交
5217
        cpu_tbr = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, tbr),
5218 5219
                                     "tbr");
#endif
B
blueswir1 已提交
5220
        for (i = 1; i < 8; i++)
P
pbrook 已提交
5221
            cpu_gregs[i] = tcg_global_mem_new(TCG_AREG0,
B
blueswir1 已提交
5222 5223
                                              offsetof(CPUState, gregs[i]),
                                              gregnames[i]);
B
blueswir1 已提交
5224
        for (i = 0; i < TARGET_FPREGS; i++)
P
pbrook 已提交
5225 5226 5227
            cpu_fpr[i] = tcg_global_mem_new_i32(TCG_AREG0,
                                                offsetof(CPUState, fpr[i]),
                                                fregnames[i]);
B
blueswir1 已提交
5228

B
blueswir1 已提交
5229 5230
        /* register helpers */

P
pbrook 已提交
5231
#define GEN_HELPER 2
B
blueswir1 已提交
5232
#include "helper.h"
B
blueswir1 已提交
5233
    }
B
bellard 已提交
5234
}
A
aurel32 已提交
5235

5236
void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
A
aurel32 已提交
5237 5238 5239 5240 5241 5242 5243
{
    target_ulong npc;
    env->pc = gen_opc_pc[pc_pos];
    npc = gen_opc_npc[pc_pos];
    if (npc == 1) {
        /* dynamic NPC: already stored */
    } else if (npc == 2) {
B
Blue Swirl 已提交
5244 5245
        /* jump PC: use 'cond' and the jump targets of the translation */
        if (env->cond) {
A
aurel32 已提交
5246
            env->npc = gen_opc_jump_pc[0];
B
Blue Swirl 已提交
5247
        } else {
A
aurel32 已提交
5248
            env->npc = gen_opc_jump_pc[1];
B
Blue Swirl 已提交
5249
        }
A
aurel32 已提交
5250 5251 5252
    } else {
        env->npc = npc;
    }
5253 5254 5255 5256 5257

    /* flush pending conditional evaluations before exposing cpu state */
    if (CC_OP != CC_OP_FLAGS) {
        helper_compute_psr();
    }
A
aurel32 已提交
5258
}