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

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

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

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

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

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

#include "cpu.h"
#include "exec-all.h"
#include "disas.h"
B
blueswir1 已提交
31
#include "helper.h"
B
bellard 已提交
32
#include "tcg-op.h"
33 34 35

#define DEBUG_DISAS

B
bellard 已提交
36 37 38 39
#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 已提交
40
/* global register indexes */
B
blueswir1 已提交
41
static TCGv cpu_env, cpu_regwptr;
B
blueswir1 已提交
42
static TCGv cpu_cc_src, cpu_cc_src2, cpu_cc_dst;
B
blueswir1 已提交
43
static TCGv cpu_psr, cpu_fsr, cpu_pc, cpu_npc, cpu_gregs[8];
44
static TCGv cpu_cond, cpu_src1, cpu_src2, cpu_dst, cpu_addr, cpu_val;
45 46 47
#ifdef TARGET_SPARC64
static TCGv cpu_xcc;
#endif
B
blueswir1 已提交
48
/* local register indexes (only used inside old micro ops) */
B
blueswir1 已提交
49
static TCGv cpu_tmp0, cpu_tmp32, cpu_tmp64;
B
blueswir1 已提交
50

P
pbrook 已提交
51 52
#include "gen-icount.h"

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

B
bellard 已提交
65
// This function uses non-native bit order
66 67 68
#define GET_FIELD(X, FROM, TO) \
  ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))

B
bellard 已提交
69 70 71 72 73
// This function uses the order in the manuals, i.e. bit 0 is 2^0
#define GET_FIELD_SP(X, FROM, TO) \
    GET_FIELD(X, 31 - (TO), 31 - (FROM))

#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
B
blueswir1 已提交
74
#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
B
bellard 已提交
75 76

#ifdef TARGET_SPARC64
77
#define FFPREG(r) (r)
78
#define DFPREG(r) (((r & 1) << 5) | (r & 0x1e))
B
blueswir1 已提交
79
#define QFPREG(r) (((r & 1) << 5) | (r & 0x1c))
B
bellard 已提交
80
#else
81
#define FFPREG(r) (r)
82
#define DFPREG(r) (r & 0x1e)
B
blueswir1 已提交
83
#define QFPREG(r) (r & 0x1c)
B
bellard 已提交
84 85 86 87 88 89 90 91
#endif

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

92 93
#define IS_IMM (insn & (1<<13))

B
blueswir1 已提交
94 95 96
/* floating point registers moves */
static void gen_op_load_fpr_FT0(unsigned int src)
{
B
blueswir1 已提交
97 98
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft0));
B
bellard 已提交
99
}
B
blueswir1 已提交
100 101 102

static void gen_op_load_fpr_FT1(unsigned int src)
{
B
blueswir1 已提交
103 104
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft1));
105 106
}

B
blueswir1 已提交
107 108
static void gen_op_store_FT0_fpr(unsigned int dst)
{
B
blueswir1 已提交
109 110
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft0));
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst]));
B
blueswir1 已提交
111 112 113 114
}

static void gen_op_load_fpr_DT0(unsigned int src)
{
B
blueswir1 已提交
115
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
B
blueswir1 已提交
116 117
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) +
                   offsetof(CPU_DoubleU, l.upper));
B
blueswir1 已提交
118
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
B
blueswir1 已提交
119 120
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) +
                   offsetof(CPU_DoubleU, l.lower));
B
blueswir1 已提交
121 122 123 124
}

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

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

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

static void gen_op_load_fpr_QT1(unsigned int src)
{
B
blueswir1 已提交
161
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
B
blueswir1 已提交
162 163
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) +
                   offsetof(CPU_QuadU, l.upmost));
B
blueswir1 已提交
164
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1]));
B
blueswir1 已提交
165 166
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) +
                   offsetof(CPU_QuadU, l.upper));
B
blueswir1 已提交
167
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 2]));
B
blueswir1 已提交
168 169
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) +
                   offsetof(CPU_QuadU, l.lower));
B
blueswir1 已提交
170
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 3]));
B
blueswir1 已提交
171 172
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) +
                   offsetof(CPU_QuadU, l.lowest));
B
blueswir1 已提交
173 174 175 176
}

static void gen_op_store_QT0_fpr(unsigned int dst)
{
B
blueswir1 已提交
177 178
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) +
                   offsetof(CPU_QuadU, l.upmost));
B
blueswir1 已提交
179
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst]));
B
blueswir1 已提交
180 181
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) +
                   offsetof(CPU_QuadU, l.upper));
B
blueswir1 已提交
182
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 1]));
B
blueswir1 已提交
183 184
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) +
                   offsetof(CPU_QuadU, l.lower));
B
blueswir1 已提交
185
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 2]));
B
blueswir1 已提交
186 187
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) +
                   offsetof(CPU_QuadU, l.lowest));
B
blueswir1 已提交
188
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 3]));
B
blueswir1 已提交
189
}
B
blueswir1 已提交
190

191 192
/* moves */
#ifdef CONFIG_USER_ONLY
B
bellard 已提交
193
#define supervisor(dc) 0
194
#ifdef TARGET_SPARC64
B
blueswir1 已提交
195
#define hypervisor(dc) 0
196
#endif
B
bellard 已提交
197
#else
B
blueswir1 已提交
198
#define supervisor(dc) (dc->mem_idx >= 1)
199 200
#ifdef TARGET_SPARC64
#define hypervisor(dc) (dc->mem_idx == 2)
B
blueswir1 已提交
201
#else
B
bellard 已提交
202
#endif
203 204
#endif

B
blueswir1 已提交
205 206 207
#ifdef TARGET_SPARC64
#ifndef TARGET_ABI32
#define AM_CHECK(dc) ((dc)->address_mask_32bit)
B
blueswir1 已提交
208
#else
B
blueswir1 已提交
209 210
#define AM_CHECK(dc) (1)
#endif
B
blueswir1 已提交
211
#endif
212

B
blueswir1 已提交
213 214 215 216 217 218 219 220
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 已提交
221
static inline void gen_movl_reg_TN(int reg, TCGv tn)
222
{
B
blueswir1 已提交
223 224 225
    if (reg == 0)
        tcg_gen_movi_tl(tn, 0);
    else if (reg < 8)
B
blueswir1 已提交
226
        tcg_gen_mov_tl(tn, cpu_gregs[reg]);
B
blueswir1 已提交
227 228
    else {
        tcg_gen_ld_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
229 230 231
    }
}

B
blueswir1 已提交
232
static inline void gen_movl_TN_reg(int reg, TCGv tn)
233
{
B
blueswir1 已提交
234 235 236
    if (reg == 0)
        return;
    else if (reg < 8)
B
blueswir1 已提交
237
        tcg_gen_mov_tl(cpu_gregs[reg], tn);
B
blueswir1 已提交
238 239
    else {
        tcg_gen_st_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
240 241 242
    }
}

243
static inline void gen_goto_tb(DisasContext *s, int tb_num,
244 245 246 247 248 249 250 251
                               target_ulong pc, target_ulong npc)
{
    TranslationBlock *tb;

    tb = s->tb;
    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
        (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK))  {
        /* jump to same page: we can use a direct jump */
B
bellard 已提交
252
        tcg_gen_goto_tb(tb_num);
B
blueswir1 已提交
253 254
        tcg_gen_movi_tl(cpu_pc, pc);
        tcg_gen_movi_tl(cpu_npc, npc);
B
bellard 已提交
255
        tcg_gen_exit_tb((long)tb + tb_num);
256 257
    } else {
        /* jump to another page: currently not optimized */
B
blueswir1 已提交
258 259
        tcg_gen_movi_tl(cpu_pc, pc);
        tcg_gen_movi_tl(cpu_npc, npc);
B
bellard 已提交
260
        tcg_gen_exit_tb(0);
261 262 263
    }
}

264 265 266
// XXX suboptimal
static inline void gen_mov_reg_N(TCGv reg, TCGv src)
{
B
blueswir1 已提交
267
    tcg_gen_extu_i32_tl(reg, src);
B
blueswir1 已提交
268
    tcg_gen_shri_tl(reg, reg, PSR_NEG_SHIFT);
269 270 271 272 273
    tcg_gen_andi_tl(reg, reg, 0x1);
}

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

static inline void gen_mov_reg_V(TCGv reg, TCGv src)
{
B
blueswir1 已提交
281
    tcg_gen_extu_i32_tl(reg, src);
B
blueswir1 已提交
282
    tcg_gen_shri_tl(reg, reg, PSR_OVF_SHIFT);
283 284 285 286 287
    tcg_gen_andi_tl(reg, reg, 0x1);
}

static inline void gen_mov_reg_C(TCGv reg, TCGv src)
{
B
blueswir1 已提交
288
    tcg_gen_extu_i32_tl(reg, src);
B
blueswir1 已提交
289
    tcg_gen_shri_tl(reg, reg, PSR_CARRY_SHIFT);
290 291 292
    tcg_gen_andi_tl(reg, reg, 0x1);
}

293
static inline void gen_cc_clear_icc(void)
294 295
{
    tcg_gen_movi_i32(cpu_psr, 0);
296 297
}

298
#ifdef TARGET_SPARC64
299 300
static inline void gen_cc_clear_xcc(void)
{
301 302
    tcg_gen_movi_i32(cpu_xcc, 0);
}
303
#endif
304 305 306 307 308 309 310

/* old op:
    if (!T0)
        env->psr |= PSR_ZERO;
    if ((int32_t) T0 < 0)
        env->psr |= PSR_NEG;
*/
311
static inline void gen_cc_NZ_icc(TCGv dst)
312
{
B
blueswir1 已提交
313
    TCGv r_temp;
314 315 316 317
    int l1, l2;

    l1 = gen_new_label();
    l2 = gen_new_label();
B
blueswir1 已提交
318 319
    r_temp = tcg_temp_new(TCG_TYPE_TL);
    tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
P
pbrook 已提交
320
    tcg_gen_brcondi_tl(TCG_COND_NE, r_temp, 0, l1);
321 322
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_ZERO);
    gen_set_label(l1);
B
blueswir1 已提交
323
    tcg_gen_ext_i32_tl(r_temp, dst);
P
pbrook 已提交
324
    tcg_gen_brcondi_tl(TCG_COND_GE, r_temp, 0, l2);
325 326
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_NEG);
    gen_set_label(l2);
B
blueswir1 已提交
327
    tcg_temp_free(r_temp);
328 329
}

330
#ifdef TARGET_SPARC64
331 332 333 334 335 336
static inline void gen_cc_NZ_xcc(TCGv dst)
{
    int l1, l2;

    l1 = gen_new_label();
    l2 = gen_new_label();
P
pbrook 已提交
337
    tcg_gen_brcondi_tl(TCG_COND_NE, dst, 0, l1);
338 339
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_ZERO);
    gen_set_label(l1);
P
pbrook 已提交
340
    tcg_gen_brcondi_tl(TCG_COND_GE, dst, 0, l2);
341 342
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_NEG);
    gen_set_label(l2);
343
}
344
#endif
345 346 347 348 349

/* old op:
    if (T0 < src1)
        env->psr |= PSR_CARRY;
*/
350
static inline void gen_cc_C_add_icc(TCGv dst, TCGv src1)
351
{
352
    TCGv r_temp1, r_temp2;
353 354 355
    int l1;

    l1 = gen_new_label();
356 357 358 359 360
    r_temp1 = tcg_temp_new(TCG_TYPE_TL);
    r_temp2 = tcg_temp_new(TCG_TYPE_TL);
    tcg_gen_andi_tl(r_temp1, dst, 0xffffffffULL);
    tcg_gen_andi_tl(r_temp2, src1, 0xffffffffULL);
    tcg_gen_brcond_tl(TCG_COND_GEU, r_temp1, r_temp2, l1);
361 362
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
    gen_set_label(l1);
363 364
    tcg_temp_free(r_temp1);
    tcg_temp_free(r_temp2);
365 366
}

367
#ifdef TARGET_SPARC64
368 369 370
static inline void gen_cc_C_add_xcc(TCGv dst, TCGv src1)
{
    int l1;
371

372 373 374 375
    l1 = gen_new_label();
    tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l1);
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
    gen_set_label(l1);
376
}
377
#endif
378 379 380 381 382

/* old op:
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
        env->psr |= PSR_OVF;
*/
383
static inline void gen_cc_V_add_icc(TCGv dst, TCGv src1, TCGv src2)
384
{
385
    TCGv r_temp;
386 387 388 389

    r_temp = tcg_temp_new(TCG_TYPE_TL);
    tcg_gen_xor_tl(r_temp, src1, src2);
    tcg_gen_xori_tl(r_temp, r_temp, -1);
390 391
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
392
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
B
blueswir1 已提交
393 394
    tcg_gen_shri_tl(r_temp, r_temp, 31 - PSR_OVF_SHIFT);
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
B
blueswir1 已提交
395
    tcg_temp_free(r_temp);
B
blueswir1 已提交
396
    tcg_gen_or_i32(cpu_psr, cpu_psr, cpu_tmp32);
397 398
}

399
#ifdef TARGET_SPARC64
400 401 402 403 404 405 406 407 408 409
static inline void gen_cc_V_add_xcc(TCGv dst, TCGv src1, TCGv src2)
{
    TCGv r_temp;

    r_temp = tcg_temp_new(TCG_TYPE_TL);
    tcg_gen_xor_tl(r_temp, src1, src2);
    tcg_gen_xori_tl(r_temp, r_temp, -1);
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
B
blueswir1 已提交
410 411
    tcg_gen_shri_tl(r_temp, r_temp, 63 - PSR_OVF_SHIFT);
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
B
blueswir1 已提交
412
    tcg_temp_free(r_temp);
B
blueswir1 已提交
413
    tcg_gen_or_i32(cpu_xcc, cpu_xcc, cpu_tmp32);
414
}
415
#endif
416 417 418

static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
{
B
blueswir1 已提交
419
    TCGv r_temp, r_const;
420 421 422 423 424 425 426
    int l1;

    l1 = gen_new_label();

    r_temp = tcg_temp_new(TCG_TYPE_TL);
    tcg_gen_xor_tl(r_temp, src1, src2);
    tcg_gen_xori_tl(r_temp, r_temp, -1);
427 428
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
429
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
P
pbrook 已提交
430
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
B
blueswir1 已提交
431 432 433
    r_const = tcg_const_i32(TT_TOVF);
    tcg_gen_helper_0_1(raise_exception, r_const);
    tcg_temp_free(r_const);
434
    gen_set_label(l1);
B
blueswir1 已提交
435
    tcg_temp_free(r_temp);
436 437 438 439 440 441 442
}

static inline void gen_cc_V_tag(TCGv src1, TCGv src2)
{
    int l1;

    l1 = gen_new_label();
443 444
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
P
pbrook 已提交
445
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
446 447 448 449 450 451 452
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
    gen_set_label(l1);
}

static inline void gen_tag_tv(TCGv src1, TCGv src2)
{
    int l1;
B
blueswir1 已提交
453
    TCGv r_const;
454 455

    l1 = gen_new_label();
456 457
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
P
pbrook 已提交
458
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
B
blueswir1 已提交
459 460 461
    r_const = tcg_const_i32(TT_TOVF);
    tcg_gen_helper_0_1(raise_exception, r_const);
    tcg_temp_free(r_const);
462 463 464
    gen_set_label(l1);
}

465
static inline void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2)
466
{
467
    tcg_gen_mov_tl(cpu_cc_src, src1);
468
    tcg_gen_mov_tl(cpu_cc_src2, src2);
469
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
470
    gen_cc_clear_icc();
471 472 473
    gen_cc_NZ_icc(cpu_cc_dst);
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
474 475
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
476 477 478
    gen_cc_NZ_xcc(cpu_cc_dst);
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
479
#endif
480
    tcg_gen_mov_tl(dst, cpu_cc_dst);
481 482
}

483
static inline void gen_op_addx_cc(TCGv dst, TCGv src1, TCGv src2)
484
{
485
    tcg_gen_mov_tl(cpu_cc_src, src1);
486
    tcg_gen_mov_tl(cpu_cc_src2, src2);
487
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
488
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_tmp0);
489
    gen_cc_clear_icc();
490
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
491 492
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
493
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
494
#endif
495
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_dst, cpu_cc_src2);
496 497 498
    gen_cc_NZ_icc(cpu_cc_dst);
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
499
#ifdef TARGET_SPARC64
500 501 502
    gen_cc_NZ_xcc(cpu_cc_dst);
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
503
#endif
504
    tcg_gen_mov_tl(dst, cpu_cc_dst);
505 506
}

507
static inline void gen_op_tadd_cc(TCGv dst, TCGv src1, TCGv src2)
508
{
509
    tcg_gen_mov_tl(cpu_cc_src, src1);
510
    tcg_gen_mov_tl(cpu_cc_src2, src2);
511
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
512
    gen_cc_clear_icc();
513 514 515
    gen_cc_NZ_icc(cpu_cc_dst);
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
516
    gen_cc_V_tag(cpu_cc_src, cpu_cc_src2);
517 518
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
519 520 521
    gen_cc_NZ_xcc(cpu_cc_dst);
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
522
#endif
523
    tcg_gen_mov_tl(dst, cpu_cc_dst);
524 525
}

526
static inline void gen_op_tadd_ccTV(TCGv dst, TCGv src1, TCGv src2)
527
{
528
    tcg_gen_mov_tl(cpu_cc_src, src1);
529 530
    tcg_gen_mov_tl(cpu_cc_src2, src2);
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
531 532
    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);
533
    gen_cc_clear_icc();
534 535
    gen_cc_NZ_icc(cpu_cc_dst);
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
536 537
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
538 539 540
    gen_cc_NZ_xcc(cpu_cc_dst);
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
    gen_cc_V_add_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
541
#endif
542
    tcg_gen_mov_tl(dst, cpu_cc_dst);
543 544 545 546 547 548
}

/* old op:
    if (src1 < T1)
        env->psr |= PSR_CARRY;
*/
549
static inline void gen_cc_C_sub_icc(TCGv src1, TCGv src2)
550
{
B
blueswir1 已提交
551
    TCGv r_temp1, r_temp2;
552 553 554
    int l1;

    l1 = gen_new_label();
B
blueswir1 已提交
555 556 557 558 559
    r_temp1 = tcg_temp_new(TCG_TYPE_TL);
    r_temp2 = tcg_temp_new(TCG_TYPE_TL);
    tcg_gen_andi_tl(r_temp1, src1, 0xffffffffULL);
    tcg_gen_andi_tl(r_temp2, src2, 0xffffffffULL);
    tcg_gen_brcond_tl(TCG_COND_GEU, r_temp1, r_temp2, l1);
560 561
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
    gen_set_label(l1);
B
blueswir1 已提交
562 563
    tcg_temp_free(r_temp1);
    tcg_temp_free(r_temp2);
564 565
}

566
#ifdef TARGET_SPARC64
567 568 569
static inline void gen_cc_C_sub_xcc(TCGv src1, TCGv src2)
{
    int l1;
570

571 572 573 574
    l1 = gen_new_label();
    tcg_gen_brcond_tl(TCG_COND_GEU, src1, src2, l1);
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_CARRY);
    gen_set_label(l1);
575
}
576
#endif
577 578 579 580 581

/* old op:
    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
        env->psr |= PSR_OVF;
*/
582
static inline void gen_cc_V_sub_icc(TCGv dst, TCGv src1, TCGv src2)
583
{
584
    TCGv r_temp;
585 586 587

    r_temp = tcg_temp_new(TCG_TYPE_TL);
    tcg_gen_xor_tl(r_temp, src1, src2);
588 589
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
590
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
B
blueswir1 已提交
591 592 593
    tcg_gen_shri_tl(r_temp, r_temp, 31 - PSR_OVF_SHIFT);
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
    tcg_gen_or_i32(cpu_psr, cpu_psr, cpu_tmp32);
B
blueswir1 已提交
594
    tcg_temp_free(r_temp);
595 596
}

597
#ifdef TARGET_SPARC64
598 599 600 601 602 603 604 605 606
static inline void gen_cc_V_sub_xcc(TCGv dst, TCGv src1, TCGv src2)
{
    TCGv r_temp;

    r_temp = tcg_temp_new(TCG_TYPE_TL);
    tcg_gen_xor_tl(r_temp, src1, src2);
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
B
blueswir1 已提交
607 608 609
    tcg_gen_shri_tl(r_temp, r_temp, 63 - PSR_OVF_SHIFT);
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
    tcg_gen_or_i32(cpu_xcc, cpu_xcc, cpu_tmp32);
B
blueswir1 已提交
610
    tcg_temp_free(r_temp);
611
}
612
#endif
613 614 615

static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
{
B
blueswir1 已提交
616
    TCGv r_temp, r_const;
617 618 619 620 621 622
    int l1;

    l1 = gen_new_label();

    r_temp = tcg_temp_new(TCG_TYPE_TL);
    tcg_gen_xor_tl(r_temp, src1, src2);
623 624
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
625
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
P
pbrook 已提交
626
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
B
blueswir1 已提交
627 628 629
    r_const = tcg_const_i32(TT_TOVF);
    tcg_gen_helper_0_1(raise_exception, r_const);
    tcg_temp_free(r_const);
630
    gen_set_label(l1);
B
blueswir1 已提交
631
    tcg_temp_free(r_temp);
632 633
}

634
static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2)
635
{
636
    tcg_gen_mov_tl(cpu_cc_src, src1);
637
    tcg_gen_mov_tl(cpu_cc_src2, src2);
638
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
639
    gen_cc_clear_icc();
640
    gen_cc_NZ_icc(cpu_cc_dst);
641
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
642
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
643 644
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
645
    gen_cc_NZ_xcc(cpu_cc_dst);
646
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
647
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
648
#endif
649
    tcg_gen_mov_tl(dst, cpu_cc_dst);
650 651
}

652
static inline void gen_op_subx_cc(TCGv dst, TCGv src1, TCGv src2)
653
{
654
    tcg_gen_mov_tl(cpu_cc_src, src1);
655
    tcg_gen_mov_tl(cpu_cc_src2, src2);
656
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
657
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_tmp0);
658
    gen_cc_clear_icc();
659
    gen_cc_C_sub_icc(cpu_cc_dst, cpu_cc_src);
660 661
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
662
    gen_cc_C_sub_xcc(cpu_cc_dst, cpu_cc_src);
663
#endif
664
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_dst, cpu_cc_src2);
665 666 667
    gen_cc_NZ_icc(cpu_cc_dst);
    gen_cc_C_sub_icc(cpu_cc_dst, cpu_cc_src);
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
668
#ifdef TARGET_SPARC64
669 670 671
    gen_cc_NZ_xcc(cpu_cc_dst);
    gen_cc_C_sub_xcc(cpu_cc_dst, cpu_cc_src);
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
672
#endif
673
    tcg_gen_mov_tl(dst, cpu_cc_dst);
674 675
}

676
static inline void gen_op_tsub_cc(TCGv dst, TCGv src1, TCGv src2)
677
{
678
    tcg_gen_mov_tl(cpu_cc_src, src1);
679
    tcg_gen_mov_tl(cpu_cc_src2, src2);
680
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
681
    gen_cc_clear_icc();
682
    gen_cc_NZ_icc(cpu_cc_dst);
683
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
684
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
685
    gen_cc_V_tag(cpu_cc_src, cpu_cc_src2);
686 687
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
688
    gen_cc_NZ_xcc(cpu_cc_dst);
689
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
690
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
691
#endif
692
    tcg_gen_mov_tl(dst, cpu_cc_dst);
693 694
}

695
static inline void gen_op_tsub_ccTV(TCGv dst, TCGv src1, TCGv src2)
696
{
697
    tcg_gen_mov_tl(cpu_cc_src, src1);
698 699
    tcg_gen_mov_tl(cpu_cc_src2, src2);
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
700 701
    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);
702
    gen_cc_clear_icc();
703
    gen_cc_NZ_icc(cpu_cc_dst);
704
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
705 706
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
707
    gen_cc_NZ_xcc(cpu_cc_dst);
708
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
709
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
710
#endif
711
    tcg_gen_mov_tl(dst, cpu_cc_dst);
712 713
}

714
static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
B
blueswir1 已提交
715
{
B
blueswir1 已提交
716
    TCGv r_temp;
717
    int l1;
B
blueswir1 已提交
718 719 720 721 722 723 724 725

    l1 = gen_new_label();
    r_temp = tcg_temp_new(TCG_TYPE_TL);

    /* old op:
    if (!(env->y & 1))
        T1 = 0;
    */
726
    tcg_gen_mov_tl(cpu_cc_src, src1);
B
blueswir1 已提交
727 728
    tcg_gen_ld_tl(r_temp, cpu_env, offsetof(CPUSPARCState, y));
    tcg_gen_andi_tl(r_temp, r_temp, 0x1);
729
    tcg_gen_mov_tl(cpu_cc_src2, src2);
B
blueswir1 已提交
730
    tcg_gen_brcondi_tl(TCG_COND_NE, r_temp, 0, l1);
B
blueswir1 已提交
731
    tcg_gen_movi_tl(cpu_cc_src2, 0);
732
    gen_set_label(l1);
B
blueswir1 已提交
733 734 735

    // b2 = T0 & 1;
    // env->y = (b2 << 31) | (env->y >> 1);
B
blueswir1 已提交
736 737 738 739 740 741
    tcg_gen_andi_tl(r_temp, cpu_cc_src, 0x1);
    tcg_gen_shli_tl(r_temp, r_temp, 31);
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, y));
    tcg_gen_shri_tl(cpu_tmp0, cpu_tmp0, 1);
    tcg_gen_or_tl(cpu_tmp0, cpu_tmp0, r_temp);
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, y));
B
blueswir1 已提交
742 743 744 745 746

    // 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 已提交
747
    tcg_temp_free(r_temp);
B
blueswir1 已提交
748 749 750 751

    // T0 = (b1 << 31) | (T0 >> 1);
    // src1 = T0;
    tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
752
    tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
B
blueswir1 已提交
753 754 755
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);

    /* do addition and update flags */
756
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
B
blueswir1 已提交
757

758
    gen_cc_clear_icc();
759 760 761
    gen_cc_NZ_icc(cpu_cc_dst);
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
762
    tcg_gen_mov_tl(dst, cpu_cc_dst);
B
blueswir1 已提交
763 764
}

765
static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
B
blueswir1 已提交
766 767 768 769 770 771
{
    TCGv r_temp, r_temp2;

    r_temp = tcg_temp_new(TCG_TYPE_I64);
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);

772 773
    tcg_gen_extu_i32_i64(r_temp, src2);
    tcg_gen_extu_i32_i64(r_temp2, src1);
B
blueswir1 已提交
774 775 776
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);

    tcg_gen_shri_i64(r_temp, r_temp2, 32);
B
blueswir1 已提交
777
    tcg_gen_trunc_i64_tl(cpu_tmp0, r_temp);
B
blueswir1 已提交
778
    tcg_temp_free(r_temp);
B
blueswir1 已提交
779 780
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffff);
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, y));
B
blueswir1 已提交
781
#ifdef TARGET_SPARC64
782
    tcg_gen_mov_i64(dst, r_temp2);
B
blueswir1 已提交
783
#else
784
    tcg_gen_trunc_i64_tl(dst, r_temp2);
B
blueswir1 已提交
785
#endif
B
blueswir1 已提交
786
    tcg_temp_free(r_temp2);
B
blueswir1 已提交
787 788
}

789
static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
B
blueswir1 已提交
790 791 792 793 794 795
{
    TCGv r_temp, r_temp2;

    r_temp = tcg_temp_new(TCG_TYPE_I64);
    r_temp2 = tcg_temp_new(TCG_TYPE_I64);

796 797
    tcg_gen_ext_i32_i64(r_temp, src2);
    tcg_gen_ext_i32_i64(r_temp2, src1);
B
blueswir1 已提交
798 799 800
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);

    tcg_gen_shri_i64(r_temp, r_temp2, 32);
B
blueswir1 已提交
801
    tcg_gen_trunc_i64_tl(cpu_tmp0, r_temp);
B
blueswir1 已提交
802
    tcg_temp_free(r_temp);
B
blueswir1 已提交
803 804
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0xffffffff);
    tcg_gen_st_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, y));
B
blueswir1 已提交
805
#ifdef TARGET_SPARC64
806
    tcg_gen_mov_i64(dst, r_temp2);
B
blueswir1 已提交
807
#else
808
    tcg_gen_trunc_i64_tl(dst, r_temp2);
B
blueswir1 已提交
809
#endif
B
blueswir1 已提交
810
    tcg_temp_free(r_temp2);
B
blueswir1 已提交
811 812
}

B
blueswir1 已提交
813
#ifdef TARGET_SPARC64
B
blueswir1 已提交
814
static inline void gen_trap_ifdivzero_tl(TCGv divisor)
B
blueswir1 已提交
815
{
B
blueswir1 已提交
816
    TCGv r_const;
B
blueswir1 已提交
817 818 819
    int l1;

    l1 = gen_new_label();
P
pbrook 已提交
820
    tcg_gen_brcondi_tl(TCG_COND_NE, divisor, 0, l1);
B
blueswir1 已提交
821 822 823
    r_const = tcg_const_i32(TT_DIV_ZERO);
    tcg_gen_helper_0_1(raise_exception, r_const);
    tcg_temp_free(r_const);
B
blueswir1 已提交
824 825 826
    gen_set_label(l1);
}

827
static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
B
blueswir1 已提交
828 829 830 831 832
{
    int l1, l2;

    l1 = gen_new_label();
    l2 = gen_new_label();
833 834
    tcg_gen_mov_tl(cpu_cc_src, src1);
    tcg_gen_mov_tl(cpu_cc_src2, src2);
835
    gen_trap_ifdivzero_tl(cpu_cc_src2);
P
pbrook 已提交
836 837
    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc_src, INT64_MIN, l1);
    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_cc_src2, -1, l1);
838
    tcg_gen_movi_i64(dst, INT64_MIN);
B
blueswir1 已提交
839
    tcg_gen_br(l2);
B
blueswir1 已提交
840
    gen_set_label(l1);
841
    tcg_gen_div_i64(dst, cpu_cc_src, cpu_cc_src2);
B
blueswir1 已提交
842 843 844 845
    gen_set_label(l2);
}
#endif

846
static inline void gen_op_div_cc(TCGv dst)
847 848 849
{
    int l1;

850
    tcg_gen_mov_tl(cpu_cc_dst, dst);
851
    gen_cc_clear_icc();
852
    gen_cc_NZ_icc(cpu_cc_dst);
853
    l1 = gen_new_label();
854
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cc_src2, 0, l1);
855 856 857 858
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
    gen_set_label(l1);
}

859
static inline void gen_op_logic_cc(TCGv dst)
860
{
861 862
    tcg_gen_mov_tl(cpu_cc_dst, dst);

863
    gen_cc_clear_icc();
864
    gen_cc_NZ_icc(cpu_cc_dst);
865 866
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
867
    gen_cc_NZ_xcc(cpu_cc_dst);
868
#endif
869 870
}

871 872 873 874 875 876 877 878 879 880 881 882 883 884 885
// 1
static inline void gen_op_eval_ba(TCGv dst)
{
    tcg_gen_movi_tl(dst, 1);
}

// Z
static inline void gen_op_eval_be(TCGv dst, TCGv src)
{
    gen_mov_reg_Z(dst, src);
}

// Z | (N ^ V)
static inline void gen_op_eval_ble(TCGv dst, TCGv src)
{
886
    gen_mov_reg_N(cpu_tmp0, src);
887
    gen_mov_reg_V(dst, src);
888 889 890
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
    gen_mov_reg_Z(cpu_tmp0, src);
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
891 892 893 894 895
}

// N ^ V
static inline void gen_op_eval_bl(TCGv dst, TCGv src)
{
896
    gen_mov_reg_V(cpu_tmp0, src);
897
    gen_mov_reg_N(dst, src);
898
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
899 900 901 902 903
}

// C | Z
static inline void gen_op_eval_bleu(TCGv dst, TCGv src)
{
904
    gen_mov_reg_Z(cpu_tmp0, src);
905
    gen_mov_reg_C(dst, src);
906
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942
}

// C
static inline void gen_op_eval_bcs(TCGv dst, TCGv src)
{
    gen_mov_reg_C(dst, src);
}

// V
static inline void gen_op_eval_bvs(TCGv dst, TCGv src)
{
    gen_mov_reg_V(dst, src);
}

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

// N
static inline void gen_op_eval_bneg(TCGv dst, TCGv src)
{
    gen_mov_reg_N(dst, src);
}

// !Z
static inline void gen_op_eval_bne(TCGv dst, TCGv src)
{
    gen_mov_reg_Z(dst, src);
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !(Z | (N ^ V))
static inline void gen_op_eval_bg(TCGv dst, TCGv src)
{
943
    gen_mov_reg_N(cpu_tmp0, src);
944
    gen_mov_reg_V(dst, src);
945 946 947
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
    gen_mov_reg_Z(cpu_tmp0, src);
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
948 949 950 951 952 953
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !(N ^ V)
static inline void gen_op_eval_bge(TCGv dst, TCGv src)
{
954
    gen_mov_reg_V(cpu_tmp0, src);
955
    gen_mov_reg_N(dst, src);
956
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
957 958 959 960 961 962
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !(C | Z)
static inline void gen_op_eval_bgu(TCGv dst, TCGv src)
{
963
    gen_mov_reg_Z(cpu_tmp0, src);
964
    gen_mov_reg_C(dst, src);
965
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !C
static inline void gen_op_eval_bcc(TCGv dst, TCGv src)
{
    gen_mov_reg_C(dst, src);
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !N
static inline void gen_op_eval_bpos(TCGv dst, TCGv src)
{
    gen_mov_reg_N(dst, src);
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !V
static inline void gen_op_eval_bvc(TCGv dst, TCGv src)
{
    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)
{
1000
    tcg_gen_shri_tl(reg, src, FSR_FCC0_SHIFT + fcc_offset);
1001 1002 1003 1004 1005 1006
    tcg_gen_andi_tl(reg, reg, 0x1);
}

static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
                                    unsigned int fcc_offset)
{
1007
    tcg_gen_shri_tl(reg, src, FSR_FCC1_SHIFT + fcc_offset);
1008 1009 1010 1011 1012 1013 1014 1015
    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);
1016 1017
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
1018 1019 1020 1021 1022 1023 1024
}

// 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);
1025 1026
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040
}

// 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);
1041 1042 1043
    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);
1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058
}

// 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);
1059 1060
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1061 1062 1063 1064 1065 1066 1067
}

// 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);
1068 1069
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1070 1071 1072 1073 1074 1075 1076
}

// 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);
1077 1078
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
1079 1080 1081 1082 1083 1084 1085 1086
    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);
1087 1088
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104
    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);
1105 1106 1107
    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);
1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124
    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);
1125 1126
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1127 1128 1129 1130 1131 1132 1133 1134
    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);
1135 1136
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1137 1138 1139
    tcg_gen_xori_tl(dst, dst, 0x1);
}

B
blueswir1 已提交
1140
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
1141
                               target_ulong pc2, TCGv r_cond)
B
bellard 已提交
1142 1143 1144 1145 1146
{
    int l1;

    l1 = gen_new_label();

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

1149
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
B
bellard 已提交
1150 1151

    gen_set_label(l1);
1152
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
B
bellard 已提交
1153 1154
}

B
blueswir1 已提交
1155
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
1156
                                target_ulong pc2, TCGv r_cond)
B
bellard 已提交
1157 1158 1159 1160 1161
{
    int l1;

    l1 = gen_new_label();

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

1164
    gen_goto_tb(dc, 0, pc2, pc1);
B
bellard 已提交
1165 1166

    gen_set_label(l1);
1167
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
B
bellard 已提交
1168 1169
}

1170 1171
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
                                      TCGv r_cond)
B
bellard 已提交
1172 1173 1174 1175 1176
{
    int l1, l2;

    l1 = gen_new_label();
    l2 = gen_new_label();
1177

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

B
blueswir1 已提交
1180
    tcg_gen_movi_tl(cpu_npc, npc1);
B
blueswir1 已提交
1181
    tcg_gen_br(l2);
B
bellard 已提交
1182 1183

    gen_set_label(l1);
B
blueswir1 已提交
1184
    tcg_gen_movi_tl(cpu_npc, npc2);
B
bellard 已提交
1185 1186 1187
    gen_set_label(l2);
}

1188 1189 1190
/* 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 已提交
1191 1192
{
    if (dc->npc == JUMP_PC) {
1193
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
B
bellard 已提交
1194 1195 1196 1197
        dc->npc = DYNAMIC_PC;
    }
}

1198
static inline void save_npc(DisasContext *dc, TCGv cond)
B
bellard 已提交
1199 1200
{
    if (dc->npc == JUMP_PC) {
1201
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
B
bellard 已提交
1202 1203
        dc->npc = DYNAMIC_PC;
    } else if (dc->npc != DYNAMIC_PC) {
B
blueswir1 已提交
1204
        tcg_gen_movi_tl(cpu_npc, dc->npc);
B
bellard 已提交
1205 1206 1207
    }
}

1208
static inline void save_state(DisasContext *dc, TCGv cond)
B
bellard 已提交
1209
{
B
blueswir1 已提交
1210
    tcg_gen_movi_tl(cpu_pc, dc->pc);
1211
    save_npc(dc, cond);
B
bellard 已提交
1212 1213
}

1214
static inline void gen_mov_pc_npc(DisasContext *dc, TCGv cond)
B
bellard 已提交
1215 1216
{
    if (dc->npc == JUMP_PC) {
1217
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
B
blueswir1 已提交
1218
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
B
bellard 已提交
1219 1220
        dc->pc = DYNAMIC_PC;
    } else if (dc->npc == DYNAMIC_PC) {
B
blueswir1 已提交
1221
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
B
bellard 已提交
1222 1223 1224 1225 1226 1227
        dc->pc = DYNAMIC_PC;
    } else {
        dc->pc = dc->npc;
    }
}

1228 1229
static inline void gen_op_next_insn(void)
{
B
blueswir1 已提交
1230 1231
    tcg_gen_mov_tl(cpu_pc, cpu_npc);
    tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
1232 1233
}

1234 1235 1236
static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond)
{
    TCGv r_src;
B
bellard 已提交
1237 1238

#ifdef TARGET_SPARC64
1239
    if (cc)
1240
        r_src = cpu_xcc;
1241
    else
1242
        r_src = cpu_psr;
B
bellard 已提交
1243
#else
1244
    r_src = cpu_psr;
B
bellard 已提交
1245
#endif
1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296
    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;
    }
}
1297

1298
static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
1299
{
1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322
    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 已提交
1323
        gen_op_eval_fbne(r_dst, cpu_fsr, offset);
1324 1325
        break;
    case 0x2:
B
blueswir1 已提交
1326
        gen_op_eval_fblg(r_dst, cpu_fsr, offset);
1327 1328
        break;
    case 0x3:
B
blueswir1 已提交
1329
        gen_op_eval_fbul(r_dst, cpu_fsr, offset);
1330 1331
        break;
    case 0x4:
B
blueswir1 已提交
1332
        gen_op_eval_fbl(r_dst, cpu_fsr, offset);
1333 1334
        break;
    case 0x5:
B
blueswir1 已提交
1335
        gen_op_eval_fbug(r_dst, cpu_fsr, offset);
1336 1337
        break;
    case 0x6:
B
blueswir1 已提交
1338
        gen_op_eval_fbg(r_dst, cpu_fsr, offset);
1339 1340
        break;
    case 0x7:
B
blueswir1 已提交
1341
        gen_op_eval_fbu(r_dst, cpu_fsr, offset);
1342 1343 1344 1345 1346
        break;
    case 0x8:
        gen_op_eval_ba(r_dst);
        break;
    case 0x9:
B
blueswir1 已提交
1347
        gen_op_eval_fbe(r_dst, cpu_fsr, offset);
1348 1349
        break;
    case 0xa:
B
blueswir1 已提交
1350
        gen_op_eval_fbue(r_dst, cpu_fsr, offset);
1351 1352
        break;
    case 0xb:
B
blueswir1 已提交
1353
        gen_op_eval_fbge(r_dst, cpu_fsr, offset);
1354 1355
        break;
    case 0xc:
B
blueswir1 已提交
1356
        gen_op_eval_fbuge(r_dst, cpu_fsr, offset);
1357 1358
        break;
    case 0xd:
B
blueswir1 已提交
1359
        gen_op_eval_fble(r_dst, cpu_fsr, offset);
1360 1361
        break;
    case 0xe:
B
blueswir1 已提交
1362
        gen_op_eval_fbule(r_dst, cpu_fsr, offset);
1363 1364
        break;
    case 0xf:
B
blueswir1 已提交
1365
        gen_op_eval_fbo(r_dst, cpu_fsr, offset);
1366 1367
        break;
    }
1368
}
1369

1370
#ifdef TARGET_SPARC64
1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381
// 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,
};
1382

1383
static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
1384 1385 1386 1387
{
    int l1;

    l1 = gen_new_label();
1388
    tcg_gen_movi_tl(r_dst, 0);
P
pbrook 已提交
1389
    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], r_src, 0, l1);
1390 1391 1392
    tcg_gen_movi_tl(r_dst, 1);
    gen_set_label(l1);
}
B
bellard 已提交
1393
#endif
1394

B
bellard 已提交
1395
/* XXX: potentially incorrect if dynamic npc */
1396 1397
static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
                      TCGv r_cond)
1398
{
1399
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1400
    target_ulong target = dc->pc + offset;
1401

1402
    if (cond == 0x0) {
B
blueswir1 已提交
1403 1404 1405 1406 1407 1408 1409 1410
        /* 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;
        }
1411
    } else if (cond == 0x8) {
B
blueswir1 已提交
1412 1413 1414 1415 1416 1417 1418 1419
        /* unconditional taken */
        if (a) {
            dc->pc = target;
            dc->npc = dc->pc + 4;
        } else {
            dc->pc = dc->npc;
            dc->npc = target;
        }
1420
    } else {
1421 1422
        flush_cond(dc, r_cond);
        gen_cond(r_cond, cc, cond);
B
blueswir1 已提交
1423
        if (a) {
1424
            gen_branch_a(dc, target, dc->npc, r_cond);
1425
            dc->is_br = 1;
B
blueswir1 已提交
1426
        } else {
1427
            dc->pc = dc->npc;
B
bellard 已提交
1428 1429 1430
            dc->jump_pc[0] = target;
            dc->jump_pc[1] = dc->npc + 4;
            dc->npc = JUMP_PC;
B
blueswir1 已提交
1431
        }
1432
    }
1433 1434
}

B
bellard 已提交
1435
/* XXX: potentially incorrect if dynamic npc */
1436 1437
static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
                      TCGv r_cond)
1438 1439
{
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1440 1441
    target_ulong target = dc->pc + offset;

1442
    if (cond == 0x0) {
B
blueswir1 已提交
1443 1444 1445 1446 1447 1448 1449 1450
        /* 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;
        }
1451
    } else if (cond == 0x8) {
B
blueswir1 已提交
1452 1453 1454 1455 1456 1457 1458 1459
        /* unconditional taken */
        if (a) {
            dc->pc = target;
            dc->npc = dc->pc + 4;
        } else {
            dc->pc = dc->npc;
            dc->npc = target;
        }
1460
    } else {
1461 1462
        flush_cond(dc, r_cond);
        gen_fcond(r_cond, cc, cond);
B
blueswir1 已提交
1463
        if (a) {
1464
            gen_branch_a(dc, target, dc->npc, r_cond);
1465
            dc->is_br = 1;
B
blueswir1 已提交
1466
        } else {
1467 1468 1469 1470
            dc->pc = dc->npc;
            dc->jump_pc[0] = target;
            dc->jump_pc[1] = dc->npc + 4;
            dc->npc = JUMP_PC;
B
blueswir1 已提交
1471
        }
1472 1473 1474
    }
}

B
bellard 已提交
1475 1476
#ifdef TARGET_SPARC64
/* XXX: potentially incorrect if dynamic npc */
1477 1478
static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
                          TCGv r_cond, TCGv r_reg)
1479
{
B
bellard 已提交
1480 1481 1482
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
    target_ulong target = dc->pc + offset;

1483 1484
    flush_cond(dc, r_cond);
    gen_cond_reg(r_cond, cond, r_reg);
B
bellard 已提交
1485
    if (a) {
1486
        gen_branch_a(dc, target, dc->npc, r_cond);
B
blueswir1 已提交
1487
        dc->is_br = 1;
B
bellard 已提交
1488
    } else {
B
blueswir1 已提交
1489 1490 1491 1492
        dc->pc = dc->npc;
        dc->jump_pc[0] = target;
        dc->jump_pc[1] = dc->npc + 4;
        dc->npc = JUMP_PC;
B
bellard 已提交
1493
    }
1494 1495
}

B
bellard 已提交
1496
static GenOpFunc * const gen_fcmps[4] = {
1497 1498 1499 1500
    helper_fcmps,
    helper_fcmps_fcc1,
    helper_fcmps_fcc2,
    helper_fcmps_fcc3,
B
bellard 已提交
1501 1502 1503
};

static GenOpFunc * const gen_fcmpd[4] = {
1504 1505 1506 1507
    helper_fcmpd,
    helper_fcmpd_fcc1,
    helper_fcmpd_fcc2,
    helper_fcmpd_fcc3,
B
bellard 已提交
1508
};
1509

B
blueswir1 已提交
1510
static GenOpFunc * const gen_fcmpq[4] = {
1511 1512 1513 1514
    helper_fcmpq,
    helper_fcmpq_fcc1,
    helper_fcmpq_fcc2,
    helper_fcmpq_fcc3,
B
blueswir1 已提交
1515 1516
};

1517
static GenOpFunc * const gen_fcmpes[4] = {
1518 1519 1520 1521
    helper_fcmpes,
    helper_fcmpes_fcc1,
    helper_fcmpes_fcc2,
    helper_fcmpes_fcc3,
1522 1523 1524
};

static GenOpFunc * const gen_fcmped[4] = {
1525 1526 1527 1528
    helper_fcmped,
    helper_fcmped_fcc1,
    helper_fcmped_fcc2,
    helper_fcmped_fcc3,
1529 1530
};

B
blueswir1 已提交
1531
static GenOpFunc * const gen_fcmpeq[4] = {
1532 1533 1534 1535
    helper_fcmpeq,
    helper_fcmpeq_fcc1,
    helper_fcmpeq_fcc2,
    helper_fcmpeq_fcc3,
B
blueswir1 已提交
1536
};
1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600

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

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

static inline void gen_op_fcmpq(int fccno)
{
    tcg_gen_helper_0_0(gen_fcmpq[fccno]);
}

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

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

static inline void gen_op_fcmpeq(int fccno)
{
    tcg_gen_helper_0_0(gen_fcmpeq[fccno]);
}

#else

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

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

static inline void gen_op_fcmpq(int fccno)
{
    tcg_gen_helper_0_0(helper_fcmpq);
}

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

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

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

B
blueswir1 已提交
1601 1602
static inline void gen_op_fpexception_im(int fsr_flags)
{
B
blueswir1 已提交
1603 1604
    TCGv r_const;

1605
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_NMASK);
B
blueswir1 已提交
1606
    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
B
blueswir1 已提交
1607 1608 1609
    r_const = tcg_const_i32(TT_FP_EXCP);
    tcg_gen_helper_0_1(raise_exception, r_const);
    tcg_temp_free(r_const);
B
blueswir1 已提交
1610 1611
}

1612
static int gen_trap_ifnofpu(DisasContext *dc, TCGv r_cond)
B
bellard 已提交
1613 1614 1615
{
#if !defined(CONFIG_USER_ONLY)
    if (!dc->fpu_enabled) {
B
blueswir1 已提交
1616 1617
        TCGv r_const;

1618
        save_state(dc, r_cond);
B
blueswir1 已提交
1619 1620 1621
        r_const = tcg_const_i32(TT_NFPU_INSN);
        tcg_gen_helper_0_1(raise_exception, r_const);
        tcg_temp_free(r_const);
B
bellard 已提交
1622 1623 1624 1625 1626 1627 1628
        dc->is_br = 1;
        return 1;
    }
#endif
    return 0;
}

1629 1630
static inline void gen_op_clear_ieee_excp_and_FTT(void)
{
1631
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_CEXC_NMASK);
1632 1633 1634 1635 1636 1637 1638
}

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

B
blueswir1 已提交
1639 1640
/* asi moves */
#ifdef TARGET_SPARC64
1641
static inline TCGv gen_get_asi(int insn, TCGv r_addr)
B
blueswir1 已提交
1642
{
1643
    int asi;
1644
    TCGv r_asi;
B
blueswir1 已提交
1645 1646

    if (IS_IMM) {
1647 1648
        r_asi = tcg_temp_new(TCG_TYPE_I32);
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
B
blueswir1 已提交
1649 1650
    } else {
        asi = GET_FIELD(insn, 19, 26);
1651
        r_asi = tcg_const_i32(asi);
B
blueswir1 已提交
1652
    }
1653 1654 1655
    return r_asi;
}

B
blueswir1 已提交
1656 1657
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
                              int sign)
1658
{
B
blueswir1 已提交
1659
    TCGv r_asi, r_size, r_sign;
1660

1661
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1662 1663 1664 1665 1666 1667
    r_size = tcg_const_i32(size);
    r_sign = tcg_const_i32(sign);
    tcg_gen_helper_1_4(helper_ld_asi, dst, addr, r_asi, r_size, r_sign);
    tcg_temp_free(r_sign);
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
B
blueswir1 已提交
1668 1669
}

1670
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
B
blueswir1 已提交
1671
{
B
blueswir1 已提交
1672
    TCGv r_asi, r_size;
B
blueswir1 已提交
1673

1674
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1675 1676 1677 1678
    r_size = tcg_const_i32(size);
    tcg_gen_helper_0_4(helper_st_asi, addr, src, r_asi, r_size);
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
B
blueswir1 已提交
1679 1680
}

1681
static inline void gen_ldf_asi(TCGv addr, int insn, int size, int rd)
B
blueswir1 已提交
1682
{
B
blueswir1 已提交
1683
    TCGv r_asi, r_size, r_rd;
B
blueswir1 已提交
1684

1685
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1686 1687 1688 1689 1690 1691
    r_size = tcg_const_i32(size);
    r_rd = tcg_const_i32(rd);
    tcg_gen_helper_0_4(helper_ldf_asi, addr, r_asi, r_size, r_rd);
    tcg_temp_free(r_rd);
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
B
blueswir1 已提交
1692 1693
}

1694
static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
B
blueswir1 已提交
1695
{
B
blueswir1 已提交
1696
    TCGv r_asi, r_size, r_rd;
B
blueswir1 已提交
1697

1698
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1699 1700 1701 1702 1703 1704
    r_size = tcg_const_i32(size);
    r_rd = tcg_const_i32(rd);
    tcg_gen_helper_0_4(helper_stf_asi, addr, r_asi, r_size, r_rd);
    tcg_temp_free(r_rd);
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
B
blueswir1 已提交
1705 1706
}

1707
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
B
blueswir1 已提交
1708
{
B
blueswir1 已提交
1709
    TCGv r_asi, r_size, r_sign;
B
blueswir1 已提交
1710

1711
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1712 1713 1714 1715 1716 1717 1718
    r_size = tcg_const_i32(4);
    r_sign = tcg_const_i32(0);
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
    tcg_temp_free(r_sign);
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, r_asi, r_size);
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
B
blueswir1 已提交
1719
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
B
blueswir1 已提交
1720 1721
}

B
blueswir1 已提交
1722
static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
B
blueswir1 已提交
1723
{
B
blueswir1 已提交
1724
    TCGv r_asi, r_rd;
B
blueswir1 已提交
1725

1726
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1727 1728 1729
    r_rd = tcg_const_i32(rd);
    tcg_gen_helper_0_3(helper_ldda_asi, addr, r_asi, r_rd);
    tcg_temp_free(r_rd);
B
blueswir1 已提交
1730
    tcg_temp_free(r_asi);
1731 1732
}

1733
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1734
{
B
blueswir1 已提交
1735
    TCGv r_temp, r_asi, r_size;
1736

B
blueswir1 已提交
1737
    r_temp = tcg_temp_new(TCG_TYPE_TL);
1738
    gen_movl_reg_TN(rd + 1, r_temp);
1739
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi,
1740
                       r_temp);
B
blueswir1 已提交
1741
    tcg_temp_free(r_temp);
1742
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1743 1744 1745 1746
    r_size = tcg_const_i32(8);
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi, r_size);
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
B
blueswir1 已提交
1747 1748
}

B
blueswir1 已提交
1749 1750
static inline void gen_cas_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
                               int rd)
B
blueswir1 已提交
1751 1752 1753
{
    TCGv r_val1, r_asi;

B
blueswir1 已提交
1754
    r_val1 = tcg_temp_new(TCG_TYPE_TL);
B
blueswir1 已提交
1755
    gen_movl_reg_TN(rd, r_val1);
1756 1757
    r_asi = gen_get_asi(insn, addr);
    tcg_gen_helper_1_4(helper_cas_asi, dst, addr, r_val1, val2, r_asi);
B
blueswir1 已提交
1758 1759
    tcg_temp_free(r_asi);
    tcg_temp_free(r_val1);
B
blueswir1 已提交
1760 1761
}

B
blueswir1 已提交
1762 1763
static inline void gen_casx_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
                                int rd)
B
blueswir1 已提交
1764
{
B
blueswir1 已提交
1765
    TCGv r_asi;
B
blueswir1 已提交
1766

B
blueswir1 已提交
1767
    gen_movl_reg_TN(rd, cpu_tmp64);
1768 1769
    r_asi = gen_get_asi(insn, addr);
    tcg_gen_helper_1_4(helper_casx_asi, dst, addr, cpu_tmp64, val2, r_asi);
B
blueswir1 已提交
1770
    tcg_temp_free(r_asi);
B
blueswir1 已提交
1771 1772 1773 1774
}

#elif !defined(CONFIG_USER_ONLY)

B
blueswir1 已提交
1775 1776
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
                              int sign)
B
blueswir1 已提交
1777
{
B
blueswir1 已提交
1778
    TCGv r_asi, r_size, r_sign;
B
blueswir1 已提交
1779

B
blueswir1 已提交
1780 1781 1782 1783 1784 1785 1786
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(size);
    r_sign = tcg_const_i32(sign);
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
    tcg_temp_free(r_sign);
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
1787
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
B
blueswir1 已提交
1788 1789
}

1790
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
B
blueswir1 已提交
1791
{
B
blueswir1 已提交
1792
    TCGv r_asi, r_size;
B
blueswir1 已提交
1793

1794
    tcg_gen_extu_tl_i64(cpu_tmp64, src);
B
blueswir1 已提交
1795 1796 1797 1798 1799
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(size);
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi, r_size);
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
B
blueswir1 已提交
1800 1801
}

1802
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
B
blueswir1 已提交
1803
{
B
blueswir1 已提交
1804
    TCGv r_asi, r_size, r_sign;
B
blueswir1 已提交
1805

B
blueswir1 已提交
1806 1807 1808 1809 1810 1811 1812 1813
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(4);
    r_sign = tcg_const_i32(0);
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
    tcg_temp_free(r_sign);
    tcg_gen_helper_0_4(helper_st_asi, addr, dst, r_asi, r_size);
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
B
blueswir1 已提交
1814
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
B
blueswir1 已提交
1815 1816
}

B
blueswir1 已提交
1817
static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
B
blueswir1 已提交
1818
{
B
blueswir1 已提交
1819
    TCGv r_asi, r_size, r_sign;
B
blueswir1 已提交
1820

B
blueswir1 已提交
1821 1822 1823 1824 1825 1826 1827
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(8);
    r_sign = tcg_const_i32(0);
    tcg_gen_helper_1_4(helper_ld_asi, cpu_tmp64, addr, r_asi, r_size, r_sign);
    tcg_temp_free(r_sign);
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
B
blueswir1 已提交
1828 1829
    tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
    gen_movl_TN_reg(rd + 1, cpu_tmp0);
B
blueswir1 已提交
1830
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1831
    tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
B
blueswir1 已提交
1832
    gen_movl_TN_reg(rd, hi);
1833 1834
}

1835
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1836
{
B
blueswir1 已提交
1837
    TCGv r_temp, r_asi, r_size;
1838

B
blueswir1 已提交
1839
    r_temp = tcg_temp_new(TCG_TYPE_TL);
1840
    gen_movl_reg_TN(rd + 1, r_temp);
1841
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi, r_temp);
B
blueswir1 已提交
1842 1843 1844 1845 1846 1847
    tcg_temp_free(r_temp);
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(8);
    tcg_gen_helper_0_4(helper_st_asi, addr, cpu_tmp64, r_asi, r_size);
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
B
blueswir1 已提交
1848 1849 1850 1851
}
#endif

#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1852
static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
B
blueswir1 已提交
1853
{
B
blueswir1 已提交
1854
    TCGv r_val, r_asi, r_size;
B
blueswir1 已提交
1855

1856
    gen_ld_asi(dst, addr, insn, 1, 0);
B
blueswir1 已提交
1857

B
blueswir1 已提交
1858 1859 1860 1861 1862 1863 1864
    r_val = tcg_const_i64(0xffULL);
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(1);
    tcg_gen_helper_0_4(helper_st_asi, addr, r_val, r_asi, r_size);
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
    tcg_temp_free(r_val);
B
blueswir1 已提交
1865 1866 1867
}
#endif

1868 1869 1870 1871 1872 1873 1874
static inline TCGv get_src1(unsigned int insn, TCGv def)
{
    TCGv r_rs1 = def;
    unsigned int rs1;

    rs1 = GET_FIELD(insn, 13, 17);
    if (rs1 == 0)
1875
        r_rs1 = tcg_const_tl(0); // XXX how to free?
1876
    else if (rs1 < 8)
1877
        r_rs1 = cpu_gregs[rs1];
1878 1879 1880 1881 1882
    else
        tcg_gen_ld_tl(def, cpu_regwptr, (rs1 - 8) * sizeof(target_ulong));
    return r_rs1;
}

B
blueswir1 已提交
1883 1884 1885 1886 1887 1888 1889
static inline TCGv get_src2(unsigned int insn, TCGv def)
{
    TCGv r_rs2 = def;
    unsigned int rs2;

    if (IS_IMM) { /* immediate */
        rs2 = GET_FIELDs(insn, 19, 31);
B
blueswir1 已提交
1890
        r_rs2 = tcg_const_tl((int)rs2); // XXX how to free?
B
blueswir1 已提交
1891 1892 1893
    } else { /* register */
        rs2 = GET_FIELD(insn, 27, 31);
        if (rs2 == 0)
B
blueswir1 已提交
1894
            r_rs2 = tcg_const_tl(0); // XXX how to free?
B
blueswir1 已提交
1895 1896 1897 1898 1899 1900 1901 1902
        else if (rs2 < 8)
            r_rs2 = cpu_gregs[rs2];
        else
            tcg_gen_ld_tl(def, cpu_regwptr, (rs2 - 8) * sizeof(target_ulong));
    }
    return r_rs2;
}

B
blueswir1 已提交
1903
#define CHECK_IU_FEATURE(dc, FEATURE)                      \
1904
    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
B
blueswir1 已提交
1905 1906
        goto illegal_insn;
#define CHECK_FPU_FEATURE(dc, FEATURE)                     \
1907
    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
B
blueswir1 已提交
1908 1909
        goto nfpu_insn;

B
bellard 已提交
1910
/* before an instruction, dc->pc must be static */
1911 1912 1913
static void disas_sparc_insn(DisasContext * dc)
{
    unsigned int insn, opc, rs1, rs2, rd;
1914

B
blueswir1 已提交
1915 1916
    if (unlikely(loglevel & CPU_LOG_TB_OP))
        tcg_gen_debug_insn_start(dc->pc);
B
bellard 已提交
1917
    insn = ldl_code(dc->pc);
1918
    opc = GET_FIELD(insn, 0, 1);
1919

1920
    rd = GET_FIELD(insn, 2, 6);
1921

1922 1923
    cpu_src1 = tcg_temp_new(TCG_TYPE_TL); // const
    cpu_src2 = tcg_temp_new(TCG_TYPE_TL); // const
1924

1925
    switch (opc) {
B
blueswir1 已提交
1926 1927 1928 1929 1930
    case 0:                     /* branches/sethi */
        {
            unsigned int xop = GET_FIELD(insn, 7, 9);
            int32_t target;
            switch (xop) {
B
bellard 已提交
1931
#ifdef TARGET_SPARC64
B
blueswir1 已提交
1932 1933 1934 1935 1936 1937 1938 1939 1940
            case 0x1:           /* V9 BPcc */
                {
                    int cc;

                    target = GET_FIELD_SP(insn, 0, 18);
                    target = sign_extend(target, 18);
                    target <<= 2;
                    cc = GET_FIELD_SP(insn, 20, 21);
                    if (cc == 0)
1941
                        do_branch(dc, target, insn, 0, cpu_cond);
B
blueswir1 已提交
1942
                    else if (cc == 2)
1943
                        do_branch(dc, target, insn, 1, cpu_cond);
B
blueswir1 已提交
1944 1945 1946 1947 1948 1949 1950
                    else
                        goto illegal_insn;
                    goto jmp_insn;
                }
            case 0x3:           /* V9 BPr */
                {
                    target = GET_FIELD_SP(insn, 0, 13) |
1951
                        (GET_FIELD_SP(insn, 20, 21) << 14);
B
blueswir1 已提交
1952 1953
                    target = sign_extend(target, 16);
                    target <<= 2;
1954
                    cpu_src1 = get_src1(insn, cpu_src1);
1955
                    do_branch_reg(dc, target, insn, cpu_cond, cpu_src1);
B
blueswir1 已提交
1956 1957 1958 1959 1960
                    goto jmp_insn;
                }
            case 0x5:           /* V9 FBPcc */
                {
                    int cc = GET_FIELD_SP(insn, 20, 21);
1961
                    if (gen_trap_ifnofpu(dc, cpu_cond))
B
bellard 已提交
1962
                        goto jmp_insn;
B
blueswir1 已提交
1963 1964 1965
                    target = GET_FIELD_SP(insn, 0, 18);
                    target = sign_extend(target, 19);
                    target <<= 2;
1966
                    do_fbranch(dc, target, insn, cc, cpu_cond);
B
blueswir1 已提交
1967 1968
                    goto jmp_insn;
                }
1969
#else
B
blueswir1 已提交
1970 1971 1972 1973 1974 1975 1976 1977 1978 1979
            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;
1980
                    do_branch(dc, target, insn, 0, cpu_cond);
B
blueswir1 已提交
1981 1982 1983 1984
                    goto jmp_insn;
                }
            case 0x6:           /* FBN+x */
                {
1985
                    if (gen_trap_ifnofpu(dc, cpu_cond))
B
bellard 已提交
1986
                        goto jmp_insn;
B
blueswir1 已提交
1987 1988 1989
                    target = GET_FIELD(insn, 10, 31);
                    target = sign_extend(target, 22);
                    target <<= 2;
1990
                    do_fbranch(dc, target, insn, 0, cpu_cond);
B
blueswir1 已提交
1991 1992 1993 1994 1995
                    goto jmp_insn;
                }
            case 0x4:           /* SETHI */
                if (rd) { // nop
                    uint32_t value = GET_FIELD(insn, 10, 31);
B
blueswir1 已提交
1996 1997 1998 1999 2000
                    TCGv r_const;

                    r_const = tcg_const_tl(value << 10);
                    gen_movl_TN_reg(rd, r_const);
                    tcg_temp_free(r_const);
B
blueswir1 已提交
2001 2002 2003 2004
                }
                break;
            case 0x0:           /* UNIMPL */
            default:
B
bellard 已提交
2005
                goto illegal_insn;
B
blueswir1 已提交
2006 2007 2008 2009
            }
            break;
        }
        break;
2010
    case 1:
B
blueswir1 已提交
2011 2012
        /*CALL*/ {
            target_long target = GET_FIELDs(insn, 2, 31) << 2;
B
blueswir1 已提交
2013
            TCGv r_const;
2014

B
blueswir1 已提交
2015 2016 2017
            r_const = tcg_const_tl(dc->pc);
            gen_movl_TN_reg(15, r_const);
            tcg_temp_free(r_const);
B
blueswir1 已提交
2018
            target += dc->pc;
2019
            gen_mov_pc_npc(dc, cpu_cond);
B
blueswir1 已提交
2020 2021 2022 2023 2024 2025 2026
            dc->npc = target;
        }
        goto jmp_insn;
    case 2:                     /* FPU & Logical Operations */
        {
            unsigned int xop = GET_FIELD(insn, 7, 12);
            if (xop == 0x3a) {  /* generate trap */
2027
                int cond;
B
bellard 已提交
2028

2029
                cpu_src1 = get_src1(insn, cpu_src1);
B
blueswir1 已提交
2030 2031
                if (IS_IMM) {
                    rs2 = GET_FIELD(insn, 25, 31);
2032
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, rs2);
2033 2034
                } else {
                    rs2 = GET_FIELD(insn, 27, 31);
B
blueswir1 已提交
2035
                    if (rs2 != 0) {
2036 2037
                        gen_movl_reg_TN(rs2, cpu_src2);
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
2038 2039
                    } else
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
2040 2041 2042
                }
                cond = GET_FIELD(insn, 3, 6);
                if (cond == 0x8) {
2043 2044
                    save_state(dc, cpu_cond);
                    tcg_gen_helper_0_1(helper_trap, cpu_dst);
2045
                } else if (cond != 0) {
B
blueswir1 已提交
2046
                    TCGv r_cond = tcg_temp_new(TCG_TYPE_TL);
B
bellard 已提交
2047
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2048 2049
                    /* V9 icc/xcc */
                    int cc = GET_FIELD_SP(insn, 11, 12);
B
blueswir1 已提交
2050

2051
                    save_state(dc, cpu_cond);
B
blueswir1 已提交
2052
                    if (cc == 0)
B
blueswir1 已提交
2053
                        gen_cond(r_cond, 0, cond);
B
blueswir1 已提交
2054
                    else if (cc == 2)
B
blueswir1 已提交
2055
                        gen_cond(r_cond, 1, cond);
B
blueswir1 已提交
2056 2057
                    else
                        goto illegal_insn;
B
bellard 已提交
2058
#else
2059
                    save_state(dc, cpu_cond);
B
blueswir1 已提交
2060
                    gen_cond(r_cond, 0, cond);
B
bellard 已提交
2061
#endif
2062
                    tcg_gen_helper_0_2(helper_trapcc, cpu_dst, r_cond);
B
blueswir1 已提交
2063
                    tcg_temp_free(r_cond);
2064
                }
B
bellard 已提交
2065
                gen_op_next_insn();
B
bellard 已提交
2066
                tcg_gen_exit_tb(0);
B
bellard 已提交
2067 2068
                dc->is_br = 1;
                goto jmp_insn;
2069 2070 2071 2072
            } else if (xop == 0x28) {
                rs1 = GET_FIELD(insn, 13, 17);
                switch(rs1) {
                case 0: /* rdy */
2073 2074 2075 2076 2077 2078 2079 2080 2081 2082
#ifndef TARGET_SPARC64
                case 0x01 ... 0x0e: /* undefined in the SPARCv8
                                       manual, rdy on the microSPARC
                                       II */
                case 0x0f:          /* stbar in the SPARCv8 manual,
                                       rdy on the microSPARC II */
                case 0x10 ... 0x1f: /* implementation-dependent in the
                                       SPARCv8 manual, rdy on the
                                       microSPARC II */
#endif
2083
                    tcg_gen_ld_tl(cpu_tmp0, cpu_env,
B
blueswir1 已提交
2084
                                  offsetof(CPUSPARCState, y));
2085
                    gen_movl_TN_reg(rd, cpu_tmp0);
2086
                    break;
B
bellard 已提交
2087
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2088
                case 0x2: /* V9 rdccr */
2089 2090
                    tcg_gen_helper_1_0(helper_rdccr, cpu_dst);
                    gen_movl_TN_reg(rd, cpu_dst);
B
bellard 已提交
2091
                    break;
B
blueswir1 已提交
2092
                case 0x3: /* V9 rdasi */
B
blueswir1 已提交
2093 2094
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, asi));
2095 2096
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
                    gen_movl_TN_reg(rd, cpu_dst);
B
bellard 已提交
2097
                    break;
B
blueswir1 已提交
2098
                case 0x4: /* V9 rdtick */
B
blueswir1 已提交
2099 2100 2101 2102 2103 2104
                    {
                        TCGv r_tickptr;

                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                       offsetof(CPUState, tick));
2105
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst,
B
blueswir1 已提交
2106
                                           r_tickptr);
B
blueswir1 已提交
2107
                        tcg_temp_free(r_tickptr);
2108
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
2109
                    }
B
bellard 已提交
2110
                    break;
B
blueswir1 已提交
2111
                case 0x5: /* V9 rdpc */
B
blueswir1 已提交
2112 2113 2114 2115 2116 2117 2118
                    {
                        TCGv r_const;

                        r_const = tcg_const_tl(dc->pc);
                        gen_movl_TN_reg(rd, r_const);
                        tcg_temp_free(r_const);
                    }
B
blueswir1 已提交
2119 2120
                    break;
                case 0x6: /* V9 rdfprs */
B
blueswir1 已提交
2121 2122
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, fprs));
2123 2124
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
                    gen_movl_TN_reg(rd, cpu_dst);
B
bellard 已提交
2125
                    break;
2126 2127
                case 0xf: /* V9 membar */
                    break; /* no effect */
B
blueswir1 已提交
2128
                case 0x13: /* Graphics Status */
2129
                    if (gen_trap_ifnofpu(dc, cpu_cond))
B
bellard 已提交
2130
                        goto jmp_insn;
2131
                    tcg_gen_ld_tl(cpu_tmp0, cpu_env,
B
blueswir1 已提交
2132
                                  offsetof(CPUSPARCState, gsr));
2133
                    gen_movl_TN_reg(rd, cpu_tmp0);
B
bellard 已提交
2134
                    break;
B
blueswir1 已提交
2135
                case 0x17: /* Tick compare */
2136
                    tcg_gen_ld_tl(cpu_tmp0, cpu_env,
B
blueswir1 已提交
2137
                                  offsetof(CPUSPARCState, tick_cmpr));
2138
                    gen_movl_TN_reg(rd, cpu_tmp0);
B
bellard 已提交
2139
                    break;
B
blueswir1 已提交
2140
                case 0x18: /* System tick */
B
blueswir1 已提交
2141 2142 2143 2144 2145 2146
                    {
                        TCGv r_tickptr;

                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                       offsetof(CPUState, stick));
2147
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst,
B
blueswir1 已提交
2148
                                           r_tickptr);
B
blueswir1 已提交
2149
                        tcg_temp_free(r_tickptr);
2150
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
2151
                    }
B
bellard 已提交
2152
                    break;
B
blueswir1 已提交
2153
                case 0x19: /* System tick compare */
2154
                    tcg_gen_ld_tl(cpu_tmp0, cpu_env,
B
blueswir1 已提交
2155
                                  offsetof(CPUSPARCState, stick_cmpr));
2156
                    gen_movl_TN_reg(rd, cpu_tmp0);
B
bellard 已提交
2157
                    break;
B
blueswir1 已提交
2158 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 */
                case 0x16: /* Softint write */
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
                tcg_gen_helper_1_0(helper_rdpsr, cpu_dst);
B
blueswir1 已提交
2174
#else
2175
                CHECK_IU_FEATURE(dc, HYPV);
B
blueswir1 已提交
2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186
                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
B
blueswir1 已提交
2187 2188
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, hintp));
2189
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
B
blueswir1 已提交
2190 2191
                    break;
                case 5: // htba
B
blueswir1 已提交
2192 2193
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, htba));
2194
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
B
blueswir1 已提交
2195 2196
                    break;
                case 6: // hver
B
blueswir1 已提交
2197 2198
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, hver));
2199
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_tmp32);
B
blueswir1 已提交
2200 2201
                    break;
                case 31: // hstick_cmpr
2202 2203
                    tcg_gen_ld_tl(cpu_dst, cpu_env,
                                  offsetof(CPUSPARCState, hstick_cmpr));
B
blueswir1 已提交
2204 2205 2206 2207 2208
                    break;
                default:
                    goto illegal_insn;
                }
#endif
2209
                gen_movl_TN_reg(rd, cpu_dst);
2210
                break;
B
bellard 已提交
2211
            } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
B
blueswir1 已提交
2212 2213
                if (!supervisor(dc))
                    goto priv_insn;
B
bellard 已提交
2214 2215
#ifdef TARGET_SPARC64
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
2216 2217
                switch (rs1) {
                case 0: // tpc
2218 2219 2220 2221 2222 2223
                    {
                        TCGv r_tsptr;

                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                       offsetof(CPUState, tsptr));
2224
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2225
                                      offsetof(trap_state, tpc));
B
blueswir1 已提交
2226
                        tcg_temp_free(r_tsptr);
2227
                    }
B
blueswir1 已提交
2228 2229
                    break;
                case 1: // tnpc
2230 2231 2232 2233 2234 2235
                    {
                        TCGv r_tsptr;

                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                       offsetof(CPUState, tsptr));
2236
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2237
                                      offsetof(trap_state, tnpc));
B
blueswir1 已提交
2238
                        tcg_temp_free(r_tsptr);
2239
                    }
B
blueswir1 已提交
2240 2241
                    break;
                case 2: // tstate
2242 2243 2244 2245 2246 2247
                    {
                        TCGv r_tsptr;

                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                       offsetof(CPUState, tsptr));
2248
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2249
                                      offsetof(trap_state, tstate));
B
blueswir1 已提交
2250
                        tcg_temp_free(r_tsptr);
2251
                    }
B
blueswir1 已提交
2252 2253
                    break;
                case 3: // tt
2254 2255 2256 2257 2258 2259
                    {
                        TCGv r_tsptr;

                        r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                       offsetof(CPUState, tsptr));
2260
                        tcg_gen_ld_i32(cpu_tmp0, r_tsptr,
2261
                                       offsetof(trap_state, tt));
B
blueswir1 已提交
2262
                        tcg_temp_free(r_tsptr);
2263
                    }
B
blueswir1 已提交
2264 2265
                    break;
                case 4: // tick
B
blueswir1 已提交
2266 2267 2268 2269 2270 2271
                    {
                        TCGv r_tickptr;

                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                       offsetof(CPUState, tick));
2272
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_tmp0,
B
blueswir1 已提交
2273
                                           r_tickptr);
2274
                        gen_movl_TN_reg(rd, cpu_tmp0);
B
blueswir1 已提交
2275
                        tcg_temp_free(r_tickptr);
B
blueswir1 已提交
2276
                    }
B
blueswir1 已提交
2277 2278
                    break;
                case 5: // tba
2279
                    tcg_gen_ld_tl(cpu_tmp0, cpu_env,
B
blueswir1 已提交
2280
                                  offsetof(CPUSPARCState, tbr));
B
blueswir1 已提交
2281 2282
                    break;
                case 6: // pstate
B
blueswir1 已提交
2283 2284
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, pstate));
2285
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
B
blueswir1 已提交
2286 2287
                    break;
                case 7: // tl
B
blueswir1 已提交
2288 2289
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, tl));
2290
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
B
blueswir1 已提交
2291 2292
                    break;
                case 8: // pil
B
blueswir1 已提交
2293 2294
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, psrpil));
2295
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
B
blueswir1 已提交
2296 2297
                    break;
                case 9: // cwp
2298
                    tcg_gen_helper_1_0(helper_rdcwp, cpu_tmp0);
B
blueswir1 已提交
2299 2300
                    break;
                case 10: // cansave
B
blueswir1 已提交
2301 2302
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, cansave));
2303
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
B
blueswir1 已提交
2304 2305
                    break;
                case 11: // canrestore
B
blueswir1 已提交
2306 2307
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, canrestore));
2308
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
B
blueswir1 已提交
2309 2310
                    break;
                case 12: // cleanwin
B
blueswir1 已提交
2311 2312
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, cleanwin));
2313
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
B
blueswir1 已提交
2314 2315
                    break;
                case 13: // otherwin
B
blueswir1 已提交
2316 2317
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, otherwin));
2318
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
B
blueswir1 已提交
2319 2320
                    break;
                case 14: // wstate
B
blueswir1 已提交
2321 2322
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, wstate));
2323
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
B
blueswir1 已提交
2324
                    break;
B
blueswir1 已提交
2325
                case 16: // UA2005 gl
2326
                    CHECK_IU_FEATURE(dc, GL);
B
blueswir1 已提交
2327 2328
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, gl));
2329
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
B
blueswir1 已提交
2330 2331
                    break;
                case 26: // UA2005 strand status
2332
                    CHECK_IU_FEATURE(dc, HYPV);
B
blueswir1 已提交
2333 2334
                    if (!hypervisor(dc))
                        goto priv_insn;
B
blueswir1 已提交
2335 2336
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, ssr));
2337
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
B
blueswir1 已提交
2338
                    break;
B
blueswir1 已提交
2339
                case 31: // ver
2340
                    tcg_gen_ld_tl(cpu_tmp0, cpu_env,
B
blueswir1 已提交
2341
                                  offsetof(CPUSPARCState, version));
B
blueswir1 已提交
2342 2343 2344 2345 2346
                    break;
                case 15: // fq
                default:
                    goto illegal_insn;
                }
B
bellard 已提交
2347
#else
B
blueswir1 已提交
2348 2349
                tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                               offsetof(CPUSPARCState, wim));
2350
                tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
B
bellard 已提交
2351
#endif
2352
                gen_movl_TN_reg(rd, cpu_tmp0);
2353
                break;
B
bellard 已提交
2354 2355
            } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
#ifdef TARGET_SPARC64
2356
                save_state(dc, cpu_cond);
2357
                tcg_gen_helper_0_0(helper_flushw);
B
bellard 已提交
2358
#else
B
blueswir1 已提交
2359 2360
                if (!supervisor(dc))
                    goto priv_insn;
2361 2362
                tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, tbr));
                gen_movl_TN_reg(rd, cpu_tmp0);
B
bellard 已提交
2363
#endif
2364 2365
                break;
#endif
B
blueswir1 已提交
2366
            } else if (xop == 0x34) {   /* FPU Operations */
2367
                if (gen_trap_ifnofpu(dc, cpu_cond))
B
bellard 已提交
2368
                    goto jmp_insn;
B
blueswir1 已提交
2369
                gen_op_clear_ieee_excp_and_FTT();
2370
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
2371 2372 2373 2374 2375 2376 2377 2378 2379
                rs2 = GET_FIELD(insn, 27, 31);
                xop = GET_FIELD(insn, 18, 26);
                switch (xop) {
                    case 0x1: /* fmovs */
                        gen_op_load_fpr_FT0(rs2);
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x5: /* fnegs */
                        gen_op_load_fpr_FT1(rs2);
2380
                        tcg_gen_helper_0_0(helper_fnegs);
B
blueswir1 已提交
2381 2382 2383 2384
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x9: /* fabss */
                        gen_op_load_fpr_FT1(rs2);
2385
                        tcg_gen_helper_0_0(helper_fabss);
B
blueswir1 已提交
2386 2387 2388
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x29: /* fsqrts */
B
blueswir1 已提交
2389
                        CHECK_FPU_FEATURE(dc, FSQRT);
B
blueswir1 已提交
2390
                        gen_op_load_fpr_FT1(rs2);
2391 2392 2393
                        gen_clear_float_exceptions();
                        tcg_gen_helper_0_0(helper_fsqrts);
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2394 2395 2396
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x2a: /* fsqrtd */
B
blueswir1 已提交
2397
                        CHECK_FPU_FEATURE(dc, FSQRT);
B
blueswir1 已提交
2398
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2399 2400 2401
                        gen_clear_float_exceptions();
                        tcg_gen_helper_0_0(helper_fsqrtd);
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2402 2403 2404
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x2b: /* fsqrtq */
B
blueswir1 已提交
2405
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2406
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2407 2408 2409
                        gen_clear_float_exceptions();
                        tcg_gen_helper_0_0(helper_fsqrtq);
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2410 2411
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
B
blueswir1 已提交
2412 2413 2414
                    case 0x41:
                        gen_op_load_fpr_FT0(rs1);
                        gen_op_load_fpr_FT1(rs2);
2415
                        gen_clear_float_exceptions();
2416
                        tcg_gen_helper_0_0(helper_fadds);
2417
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2418 2419 2420 2421 2422
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x42:
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2423
                        gen_clear_float_exceptions();
2424
                        tcg_gen_helper_0_0(helper_faddd);
2425
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2426 2427 2428
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x43: /* faddq */
B
blueswir1 已提交
2429
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2430 2431
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2432
                        gen_clear_float_exceptions();
2433
                        tcg_gen_helper_0_0(helper_faddq);
2434
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2435 2436
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
B
blueswir1 已提交
2437 2438 2439
                    case 0x45:
                        gen_op_load_fpr_FT0(rs1);
                        gen_op_load_fpr_FT1(rs2);
2440
                        gen_clear_float_exceptions();
2441
                        tcg_gen_helper_0_0(helper_fsubs);
2442
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2443 2444 2445 2446 2447
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x46:
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2448
                        gen_clear_float_exceptions();
2449
                        tcg_gen_helper_0_0(helper_fsubd);
2450
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2451 2452 2453
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x47: /* fsubq */
B
blueswir1 已提交
2454
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2455 2456
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2457
                        gen_clear_float_exceptions();
2458
                        tcg_gen_helper_0_0(helper_fsubq);
2459
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2460 2461
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
B
blueswir1 已提交
2462 2463
                    case 0x49: /* fmuls */
                        CHECK_FPU_FEATURE(dc, FMUL);
B
blueswir1 已提交
2464 2465
                        gen_op_load_fpr_FT0(rs1);
                        gen_op_load_fpr_FT1(rs2);
2466
                        gen_clear_float_exceptions();
2467
                        tcg_gen_helper_0_0(helper_fmuls);
2468
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2469 2470
                        gen_op_store_FT0_fpr(rd);
                        break;
B
blueswir1 已提交
2471 2472
                    case 0x4a: /* fmuld */
                        CHECK_FPU_FEATURE(dc, FMUL);
B
blueswir1 已提交
2473 2474
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2475
                        gen_clear_float_exceptions();
2476
                        tcg_gen_helper_0_0(helper_fmuld);
2477
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2478
                        gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2479 2480
                        break;
                    case 0x4b: /* fmulq */
B
blueswir1 已提交
2481 2482
                        CHECK_FPU_FEATURE(dc, FLOAT128);
                        CHECK_FPU_FEATURE(dc, FMUL);
B
blueswir1 已提交
2483 2484
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2485
                        gen_clear_float_exceptions();
2486
                        tcg_gen_helper_0_0(helper_fmulq);
2487
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2488 2489
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
B
blueswir1 已提交
2490 2491 2492
                    case 0x4d:
                        gen_op_load_fpr_FT0(rs1);
                        gen_op_load_fpr_FT1(rs2);
2493
                        gen_clear_float_exceptions();
2494
                        tcg_gen_helper_0_0(helper_fdivs);
2495
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2496 2497 2498 2499 2500
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x4e:
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2501
                        gen_clear_float_exceptions();
2502
                        tcg_gen_helper_0_0(helper_fdivd);
2503
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2504 2505 2506
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x4f: /* fdivq */
B
blueswir1 已提交
2507
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2508 2509
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2510
                        gen_clear_float_exceptions();
2511
                        tcg_gen_helper_0_0(helper_fdivq);
2512
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2513 2514
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
B
blueswir1 已提交
2515
                    case 0x69:
B
blueswir1 已提交
2516
                        CHECK_FPU_FEATURE(dc, FSMULD);
B
blueswir1 已提交
2517 2518
                        gen_op_load_fpr_FT0(rs1);
                        gen_op_load_fpr_FT1(rs2);
2519
                        gen_clear_float_exceptions();
2520
                        tcg_gen_helper_0_0(helper_fsmuld);
2521
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2522 2523 2524
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x6e: /* fdmulq */
B
blueswir1 已提交
2525
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2526 2527
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2528
                        gen_clear_float_exceptions();
2529
                        tcg_gen_helper_0_0(helper_fdmulq);
2530
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2531 2532
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
B
blueswir1 已提交
2533 2534
                    case 0xc4:
                        gen_op_load_fpr_FT1(rs2);
2535
                        gen_clear_float_exceptions();
2536
                        tcg_gen_helper_0_0(helper_fitos);
2537
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2538 2539 2540 2541
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0xc6:
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2542
                        gen_clear_float_exceptions();
2543
                        tcg_gen_helper_0_0(helper_fdtos);
2544
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2545 2546 2547
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0xc7: /* fqtos */
B
blueswir1 已提交
2548
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2549
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2550
                        gen_clear_float_exceptions();
2551
                        tcg_gen_helper_0_0(helper_fqtos);
2552
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2553 2554
                        gen_op_store_FT0_fpr(rd);
                        break;
B
blueswir1 已提交
2555 2556
                    case 0xc8:
                        gen_op_load_fpr_FT1(rs2);
2557
                        tcg_gen_helper_0_0(helper_fitod);
B
blueswir1 已提交
2558 2559 2560 2561
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0xc9:
                        gen_op_load_fpr_FT1(rs2);
2562
                        tcg_gen_helper_0_0(helper_fstod);
B
blueswir1 已提交
2563 2564 2565
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0xcb: /* fqtod */
B
blueswir1 已提交
2566
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2567
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2568
                        gen_clear_float_exceptions();
2569
                        tcg_gen_helper_0_0(helper_fqtod);
2570
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2571 2572
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
B
blueswir1 已提交
2573
                    case 0xcc: /* fitoq */
B
blueswir1 已提交
2574
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2575
                        gen_op_load_fpr_FT1(rs2);
2576
                        tcg_gen_helper_0_0(helper_fitoq);
B
blueswir1 已提交
2577 2578
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
B
blueswir1 已提交
2579
                    case 0xcd: /* fstoq */
B
blueswir1 已提交
2580
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2581
                        gen_op_load_fpr_FT1(rs2);
2582
                        tcg_gen_helper_0_0(helper_fstoq);
B
blueswir1 已提交
2583 2584
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
B
blueswir1 已提交
2585
                    case 0xce: /* fdtoq */
B
blueswir1 已提交
2586
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2587
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2588
                        tcg_gen_helper_0_0(helper_fdtoq);
B
blueswir1 已提交
2589 2590
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
B
blueswir1 已提交
2591 2592
                    case 0xd1:
                        gen_op_load_fpr_FT1(rs2);
2593
                        gen_clear_float_exceptions();
2594
                        tcg_gen_helper_0_0(helper_fstoi);
2595
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2596 2597 2598
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0xd2:
2599
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2600
                        gen_clear_float_exceptions();
2601
                        tcg_gen_helper_0_0(helper_fdtoi);
2602
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2603 2604 2605
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0xd3: /* fqtoi */
B
blueswir1 已提交
2606
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2607
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2608
                        gen_clear_float_exceptions();
2609
                        tcg_gen_helper_0_0(helper_fqtoi);
2610
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2611 2612
                        gen_op_store_FT0_fpr(rd);
                        break;
B
bellard 已提交
2613
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2614 2615 2616 2617
                    case 0x2: /* V9 fmovd */
                        gen_op_load_fpr_DT0(DFPREG(rs2));
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
B
blueswir1 已提交
2618
                    case 0x3: /* V9 fmovq */
B
blueswir1 已提交
2619
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2620 2621 2622
                        gen_op_load_fpr_QT0(QFPREG(rs2));
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
B
blueswir1 已提交
2623 2624
                    case 0x6: /* V9 fnegd */
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2625
                        tcg_gen_helper_0_0(helper_fnegd);
B
blueswir1 已提交
2626 2627
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
B
blueswir1 已提交
2628
                    case 0x7: /* V9 fnegq */
B
blueswir1 已提交
2629
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2630
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2631
                        tcg_gen_helper_0_0(helper_fnegq);
B
blueswir1 已提交
2632 2633
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
B
blueswir1 已提交
2634 2635
                    case 0xa: /* V9 fabsd */
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2636
                        tcg_gen_helper_0_0(helper_fabsd);
B
blueswir1 已提交
2637 2638
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
B
blueswir1 已提交
2639
                    case 0xb: /* V9 fabsq */
B
blueswir1 已提交
2640
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2641
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2642
                        tcg_gen_helper_0_0(helper_fabsq);
B
blueswir1 已提交
2643 2644
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
B
blueswir1 已提交
2645 2646
                    case 0x81: /* V9 fstox */
                        gen_op_load_fpr_FT1(rs2);
2647
                        gen_clear_float_exceptions();
2648
                        tcg_gen_helper_0_0(helper_fstox);
2649
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2650 2651 2652 2653
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x82: /* V9 fdtox */
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2654
                        gen_clear_float_exceptions();
2655
                        tcg_gen_helper_0_0(helper_fdtox);
2656
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2657 2658
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
B
blueswir1 已提交
2659
                    case 0x83: /* V9 fqtox */
B
blueswir1 已提交
2660
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2661
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2662
                        gen_clear_float_exceptions();
2663
                        tcg_gen_helper_0_0(helper_fqtox);
2664
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2665 2666
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
B
blueswir1 已提交
2667 2668
                    case 0x84: /* V9 fxtos */
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2669
                        gen_clear_float_exceptions();
2670
                        tcg_gen_helper_0_0(helper_fxtos);
2671
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2672 2673 2674 2675
                        gen_op_store_FT0_fpr(rd);
                        break;
                    case 0x88: /* V9 fxtod */
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2676
                        gen_clear_float_exceptions();
2677
                        tcg_gen_helper_0_0(helper_fxtod);
2678
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2679 2680 2681
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x8c: /* V9 fxtoq */
B
blueswir1 已提交
2682
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2683
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2684
                        gen_clear_float_exceptions();
2685
                        tcg_gen_helper_0_0(helper_fxtoq);
2686
                        tcg_gen_helper_0_0(helper_check_ieee_exceptions);
B
blueswir1 已提交
2687 2688
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
B
blueswir1 已提交
2689 2690 2691 2692 2693
#endif
                    default:
                        goto illegal_insn;
                }
            } else if (xop == 0x35) {   /* FPU Operations */
B
bellard 已提交
2694
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2695
                int cond;
B
bellard 已提交
2696
#endif
2697
                if (gen_trap_ifnofpu(dc, cpu_cond))
B
bellard 已提交
2698
                    goto jmp_insn;
B
blueswir1 已提交
2699
                gen_op_clear_ieee_excp_and_FTT();
2700
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
2701 2702
                rs2 = GET_FIELD(insn, 27, 31);
                xop = GET_FIELD(insn, 18, 26);
B
bellard 已提交
2703
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2704
                if ((xop & 0x11f) == 0x005) { // V9 fmovsr
B
blueswir1 已提交
2705 2706 2707
                    int l1;

                    l1 = gen_new_label();
B
blueswir1 已提交
2708
                    cond = GET_FIELD_SP(insn, 14, 17);
2709
                    cpu_src1 = get_src1(insn, cpu_src1);
P
pbrook 已提交
2710 2711
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
                                       0, l1);
2712
                    gen_op_load_fpr_FT0(rs2);
B
blueswir1 已提交
2713
                    gen_op_store_FT0_fpr(rd);
B
blueswir1 已提交
2714
                    gen_set_label(l1);
B
blueswir1 已提交
2715 2716
                    break;
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
B
blueswir1 已提交
2717 2718 2719
                    int l1;

                    l1 = gen_new_label();
B
blueswir1 已提交
2720
                    cond = GET_FIELD_SP(insn, 14, 17);
2721
                    cpu_src1 = get_src1(insn, cpu_src1);
P
pbrook 已提交
2722 2723
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
                                       0, l1);
2724
                    gen_op_load_fpr_DT0(DFPREG(rs2));
2725
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
2726
                    gen_set_label(l1);
B
blueswir1 已提交
2727 2728
                    break;
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
B
blueswir1 已提交
2729 2730
                    int l1;

B
blueswir1 已提交
2731
                    CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2732
                    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);
2737
                    gen_op_load_fpr_QT0(QFPREG(rs2));
B
blueswir1 已提交
2738
                    gen_op_store_QT0_fpr(QFPREG(rd));
B
blueswir1 已提交
2739
                    gen_set_label(l1);
B
blueswir1 已提交
2740
                    break;
B
blueswir1 已提交
2741 2742 2743
                }
#endif
                switch (xop) {
B
bellard 已提交
2744
#ifdef TARGET_SPARC64
2745 2746
#define FMOVCC(size_FDQ, fcc)                                           \
                    {                                                   \
2747
                        TCGv r_cond;                                    \
2748 2749 2750 2751 2752 2753
                        int l1;                                         \
                                                                        \
                        l1 = gen_new_label();                           \
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
                        cond = GET_FIELD_SP(insn, 14, 17);              \
                        gen_fcond(r_cond, fcc, cond);                   \
P
pbrook 已提交
2754 2755
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
                                           0, l1);                      \
B
blueswir1 已提交
2756 2757 2758 2759
                        glue(glue(gen_op_load_fpr_, size_FDQ), T0)      \
                            (glue(size_FDQ, FPREG(rs2)));               \
                        glue(glue(gen_op_store_, size_FDQ), T0_fpr)     \
                            (glue(size_FDQ, FPREG(rd)));                \
2760
                        gen_set_label(l1);                              \
B
blueswir1 已提交
2761
                        tcg_temp_free(r_cond);                          \
2762
                    }
B
blueswir1 已提交
2763
                    case 0x001: /* V9 fmovscc %fcc0 */
2764
                        FMOVCC(F, 0);
B
blueswir1 已提交
2765 2766
                        break;
                    case 0x002: /* V9 fmovdcc %fcc0 */
2767
                        FMOVCC(D, 0);
B
blueswir1 已提交
2768 2769
                        break;
                    case 0x003: /* V9 fmovqcc %fcc0 */
B
blueswir1 已提交
2770
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2771
                        FMOVCC(Q, 0);
B
blueswir1 已提交
2772
                        break;
B
blueswir1 已提交
2773
                    case 0x041: /* V9 fmovscc %fcc1 */
2774
                        FMOVCC(F, 1);
B
blueswir1 已提交
2775 2776
                        break;
                    case 0x042: /* V9 fmovdcc %fcc1 */
2777
                        FMOVCC(D, 1);
B
blueswir1 已提交
2778 2779
                        break;
                    case 0x043: /* V9 fmovqcc %fcc1 */
B
blueswir1 已提交
2780
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2781
                        FMOVCC(Q, 1);
B
blueswir1 已提交
2782
                        break;
B
blueswir1 已提交
2783
                    case 0x081: /* V9 fmovscc %fcc2 */
2784
                        FMOVCC(F, 2);
B
blueswir1 已提交
2785 2786
                        break;
                    case 0x082: /* V9 fmovdcc %fcc2 */
2787
                        FMOVCC(D, 2);
B
blueswir1 已提交
2788 2789
                        break;
                    case 0x083: /* V9 fmovqcc %fcc2 */
B
blueswir1 已提交
2790
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2791
                        FMOVCC(Q, 2);
B
blueswir1 已提交
2792
                        break;
B
blueswir1 已提交
2793
                    case 0x0c1: /* V9 fmovscc %fcc3 */
2794
                        FMOVCC(F, 3);
B
blueswir1 已提交
2795 2796
                        break;
                    case 0x0c2: /* V9 fmovdcc %fcc3 */
2797
                        FMOVCC(D, 3);
B
blueswir1 已提交
2798 2799
                        break;
                    case 0x0c3: /* V9 fmovqcc %fcc3 */
B
blueswir1 已提交
2800
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2801
                        FMOVCC(Q, 3);
B
blueswir1 已提交
2802
                        break;
2803 2804 2805
#undef FMOVCC
#define FMOVCC(size_FDQ, icc)                                           \
                    {                                                   \
2806
                        TCGv r_cond;                                    \
2807 2808 2809 2810 2811 2812
                        int l1;                                         \
                                                                        \
                        l1 = gen_new_label();                           \
                        r_cond = tcg_temp_new(TCG_TYPE_TL);             \
                        cond = GET_FIELD_SP(insn, 14, 17);              \
                        gen_cond(r_cond, icc, cond);                    \
P
pbrook 已提交
2813 2814
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
                                           0, l1);                      \
B
blueswir1 已提交
2815 2816 2817 2818
                        glue(glue(gen_op_load_fpr_, size_FDQ), T0)      \
                            (glue(size_FDQ, FPREG(rs2)));               \
                        glue(glue(gen_op_store_, size_FDQ), T0_fpr)     \
                            (glue(size_FDQ, FPREG(rd)));                \
2819
                        gen_set_label(l1);                              \
B
blueswir1 已提交
2820
                        tcg_temp_free(r_cond);                          \
2821 2822
                    }

B
blueswir1 已提交
2823
                    case 0x101: /* V9 fmovscc %icc */
2824
                        FMOVCC(F, 0);
B
blueswir1 已提交
2825 2826
                        break;
                    case 0x102: /* V9 fmovdcc %icc */
2827
                        FMOVCC(D, 0);
B
blueswir1 已提交
2828
                    case 0x103: /* V9 fmovqcc %icc */
B
blueswir1 已提交
2829 2830
                        CHECK_FPU_FEATURE(dc, FLOAT128);
                        FMOVCC(Q, 0);
B
blueswir1 已提交
2831
                        break;
B
blueswir1 已提交
2832
                    case 0x181: /* V9 fmovscc %xcc */
2833
                        FMOVCC(F, 1);
B
blueswir1 已提交
2834 2835
                        break;
                    case 0x182: /* V9 fmovdcc %xcc */
2836
                        FMOVCC(D, 1);
B
blueswir1 已提交
2837 2838
                        break;
                    case 0x183: /* V9 fmovqcc %xcc */
B
blueswir1 已提交
2839
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2840
                        FMOVCC(Q, 1);
B
blueswir1 已提交
2841
                        break;
2842
#undef FMOVCC
B
blueswir1 已提交
2843 2844
#endif
                    case 0x51: /* fcmps, V9 %fcc */
B
blueswir1 已提交
2845 2846
                        gen_op_load_fpr_FT0(rs1);
                        gen_op_load_fpr_FT1(rs2);
2847
                        gen_op_fcmps(rd & 3);
B
blueswir1 已提交
2848
                        break;
B
blueswir1 已提交
2849
                    case 0x52: /* fcmpd, V9 %fcc */
B
blueswir1 已提交
2850 2851
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2852
                        gen_op_fcmpd(rd & 3);
B
blueswir1 已提交
2853
                        break;
B
blueswir1 已提交
2854
                    case 0x53: /* fcmpq, V9 %fcc */
B
blueswir1 已提交
2855
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2856 2857
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2858
                        gen_op_fcmpq(rd & 3);
B
blueswir1 已提交
2859
                        break;
B
blueswir1 已提交
2860 2861 2862
                    case 0x55: /* fcmpes, V9 %fcc */
                        gen_op_load_fpr_FT0(rs1);
                        gen_op_load_fpr_FT1(rs2);
2863
                        gen_op_fcmpes(rd & 3);
B
blueswir1 已提交
2864 2865 2866 2867
                        break;
                    case 0x56: /* fcmped, V9 %fcc */
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2868
                        gen_op_fcmped(rd & 3);
B
blueswir1 已提交
2869
                        break;
B
blueswir1 已提交
2870
                    case 0x57: /* fcmpeq, V9 %fcc */
B
blueswir1 已提交
2871
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2872 2873
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2874
                        gen_op_fcmpeq(rd & 3);
B
blueswir1 已提交
2875
                        break;
B
blueswir1 已提交
2876 2877 2878 2879 2880
                    default:
                        goto illegal_insn;
                }
            } else if (xop == 0x2) {
                // clr/mov shortcut
B
bellard 已提交
2881 2882

                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
2883
                if (rs1 == 0) {
B
blueswir1 已提交
2884
                    // or %g0, x, y -> mov T0, x; mov y, T0
B
blueswir1 已提交
2885
                    if (IS_IMM) {       /* immediate */
B
blueswir1 已提交
2886 2887
                        TCGv r_const;

B
blueswir1 已提交
2888
                        rs2 = GET_FIELDs(insn, 19, 31);
B
blueswir1 已提交
2889 2890 2891
                        r_const = tcg_const_tl((int)rs2);
                        gen_movl_TN_reg(rd, r_const);
                        tcg_temp_free(r_const);
B
blueswir1 已提交
2892 2893
                    } else {            /* register */
                        rs2 = GET_FIELD(insn, 27, 31);
2894
                        gen_movl_reg_TN(rs2, cpu_dst);
B
blueswir1 已提交
2895
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
2896 2897
                    }
                } else {
2898
                    cpu_src1 = get_src1(insn, cpu_src1);
B
blueswir1 已提交
2899 2900
                    if (IS_IMM) {       /* immediate */
                        rs2 = GET_FIELDs(insn, 19, 31);
2901
                        tcg_gen_ori_tl(cpu_dst, cpu_src1, (int)rs2);
B
blueswir1 已提交
2902
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
2903 2904 2905 2906
                    } else {            /* register */
                        // or x, %g0, y -> mov T1, x; mov y, T1
                        rs2 = GET_FIELD(insn, 27, 31);
                        if (rs2 != 0) {
2907 2908
                            gen_movl_reg_TN(rs2, cpu_src2);
                            tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
B
blueswir1 已提交
2909
                            gen_movl_TN_reg(rd, cpu_dst);
2910
                        } else
B
blueswir1 已提交
2911
                            gen_movl_TN_reg(rd, cpu_src1);
B
blueswir1 已提交
2912 2913
                    }
                }
B
bellard 已提交
2914
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2915
            } else if (xop == 0x25) { /* sll, V9 sllx */
2916
                cpu_src1 = get_src1(insn, cpu_src1);
B
blueswir1 已提交
2917
                if (IS_IMM) {   /* immediate */
B
bellard 已提交
2918
                    rs2 = GET_FIELDs(insn, 20, 31);
B
blueswir1 已提交
2919
                    if (insn & (1 << 12)) {
2920
                        tcg_gen_shli_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
B
blueswir1 已提交
2921
                    } else {
B
blueswir1 已提交
2922
                        tcg_gen_shli_i64(cpu_dst, cpu_src1, rs2 & 0x1f);
B
blueswir1 已提交
2923
                    }
B
blueswir1 已提交
2924
                } else {                /* register */
B
bellard 已提交
2925
                    rs2 = GET_FIELD(insn, 27, 31);
2926
                    gen_movl_reg_TN(rs2, cpu_src2);
B
blueswir1 已提交
2927
                    if (insn & (1 << 12)) {
2928
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
B
blueswir1 已提交
2929
                    } else {
2930
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
B
blueswir1 已提交
2931
                    }
B
blueswir1 已提交
2932
                    tcg_gen_shl_i64(cpu_dst, cpu_src1, cpu_tmp0);
B
bellard 已提交
2933
                }
2934
                gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
2935
            } else if (xop == 0x26) { /* srl, V9 srlx */
2936
                cpu_src1 = get_src1(insn, cpu_src1);
B
blueswir1 已提交
2937
                if (IS_IMM) {   /* immediate */
B
bellard 已提交
2938
                    rs2 = GET_FIELDs(insn, 20, 31);
B
blueswir1 已提交
2939
                    if (insn & (1 << 12)) {
2940
                        tcg_gen_shri_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
B
blueswir1 已提交
2941
                    } else {
2942 2943
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
                        tcg_gen_shri_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
B
blueswir1 已提交
2944
                    }
B
blueswir1 已提交
2945
                } else {                /* register */
B
bellard 已提交
2946
                    rs2 = GET_FIELD(insn, 27, 31);
2947
                    gen_movl_reg_TN(rs2, cpu_src2);
B
blueswir1 已提交
2948
                    if (insn & (1 << 12)) {
2949 2950
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
                        tcg_gen_shr_i64(cpu_dst, cpu_src1, cpu_tmp0);
B
blueswir1 已提交
2951
                    } else {
2952 2953 2954
                        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 已提交
2955
                    }
B
bellard 已提交
2956
                }
2957
                gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
2958
            } else if (xop == 0x27) { /* sra, V9 srax */
2959
                cpu_src1 = get_src1(insn, cpu_src1);
B
blueswir1 已提交
2960
                if (IS_IMM) {   /* immediate */
B
bellard 已提交
2961
                    rs2 = GET_FIELDs(insn, 20, 31);
B
blueswir1 已提交
2962
                    if (insn & (1 << 12)) {
2963
                        tcg_gen_sari_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
B
blueswir1 已提交
2964
                    } else {
2965 2966 2967
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
                        tcg_gen_ext_i32_i64(cpu_dst, cpu_dst);
                        tcg_gen_sari_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
B
blueswir1 已提交
2968
                    }
B
blueswir1 已提交
2969
                } else {                /* register */
B
bellard 已提交
2970
                    rs2 = GET_FIELD(insn, 27, 31);
2971
                    gen_movl_reg_TN(rs2, cpu_src2);
B
blueswir1 已提交
2972
                    if (insn & (1 << 12)) {
2973 2974
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
                        tcg_gen_sar_i64(cpu_dst, cpu_src1, cpu_tmp0);
B
blueswir1 已提交
2975
                    } else {
2976 2977
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
B
blueswir1 已提交
2978
                        tcg_gen_ext_i32_i64(cpu_dst, cpu_dst);
2979
                        tcg_gen_sar_i64(cpu_dst, cpu_dst, cpu_tmp0);
B
blueswir1 已提交
2980
                    }
B
bellard 已提交
2981
                }
2982
                gen_movl_TN_reg(rd, cpu_dst);
B
bellard 已提交
2983
#endif
2984
            } else if (xop < 0x36) {
2985
                cpu_src1 = get_src1(insn, cpu_src1);
B
blueswir1 已提交
2986
                cpu_src2 = get_src2(insn, cpu_src2);
2987 2988 2989 2990
                if (xop < 0x20) {
                    switch (xop & ~0x10) {
                    case 0x0:
                        if (xop & 0x10)
2991
                            gen_op_add_cc(cpu_dst, cpu_src1, cpu_src2);
2992
                        else
2993
                            tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
2994 2995
                        break;
                    case 0x1:
2996
                        tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_src2);
2997
                        if (xop & 0x10)
2998
                            gen_op_logic_cc(cpu_dst);
2999 3000
                        break;
                    case 0x2:
3001
                        tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
B
blueswir1 已提交
3002
                        if (xop & 0x10)
3003
                            gen_op_logic_cc(cpu_dst);
B
blueswir1 已提交
3004
                        break;
3005
                    case 0x3:
3006
                        tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3007
                        if (xop & 0x10)
3008
                            gen_op_logic_cc(cpu_dst);
3009 3010 3011
                        break;
                    case 0x4:
                        if (xop & 0x10)
3012
                            gen_op_sub_cc(cpu_dst, cpu_src1, cpu_src2);
3013
                        else
3014
                            tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_src2);
3015 3016
                        break;
                    case 0x5:
3017 3018
                        tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
                        tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_tmp0);
3019
                        if (xop & 0x10)
3020
                            gen_op_logic_cc(cpu_dst);
3021 3022
                        break;
                    case 0x6:
3023 3024
                        tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
                        tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_tmp0);
3025
                        if (xop & 0x10)
3026
                            gen_op_logic_cc(cpu_dst);
3027 3028
                        break;
                    case 0x7:
3029 3030
                        tcg_gen_xori_tl(cpu_tmp0, cpu_src2, -1);
                        tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_tmp0);
3031
                        if (xop & 0x10)
3032
                            gen_op_logic_cc(cpu_dst);
3033 3034 3035
                        break;
                    case 0x8:
                        if (xop & 0x10)
3036
                            gen_op_addx_cc(cpu_dst, cpu_src1, cpu_src2);
3037
                        else {
3038
                            gen_mov_reg_C(cpu_tmp0, cpu_psr);
3039 3040
                            tcg_gen_add_tl(cpu_tmp0, cpu_src2, cpu_tmp0);
                            tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_tmp0);
3041
                        }
3042
                        break;
P
pbrook 已提交
3043
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3044
                    case 0x9: /* V9 mulx */
3045
                        tcg_gen_mul_i64(cpu_dst, cpu_src1, cpu_src2);
P
pbrook 已提交
3046 3047
                        break;
#endif
3048
                    case 0xa:
B
blueswir1 已提交
3049
                        CHECK_IU_FEATURE(dc, MUL);
3050
                        gen_op_umul(cpu_dst, cpu_src1, cpu_src2);
3051
                        if (xop & 0x10)
3052
                            gen_op_logic_cc(cpu_dst);
3053 3054
                        break;
                    case 0xb:
B
blueswir1 已提交
3055
                        CHECK_IU_FEATURE(dc, MUL);
3056
                        gen_op_smul(cpu_dst, cpu_src1, cpu_src2);
3057
                        if (xop & 0x10)
3058
                            gen_op_logic_cc(cpu_dst);
3059 3060 3061
                        break;
                    case 0xc:
                        if (xop & 0x10)
3062
                            gen_op_subx_cc(cpu_dst, cpu_src1, cpu_src2);
3063
                        else {
3064
                            gen_mov_reg_C(cpu_tmp0, cpu_psr);
3065 3066
                            tcg_gen_add_tl(cpu_tmp0, cpu_src2, cpu_tmp0);
                            tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_tmp0);
3067
                        }
3068
                        break;
P
pbrook 已提交
3069
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3070
                    case 0xd: /* V9 udivx */
3071 3072 3073 3074
                        tcg_gen_mov_tl(cpu_cc_src, cpu_src1);
                        tcg_gen_mov_tl(cpu_cc_src2, cpu_src2);
                        gen_trap_ifdivzero_tl(cpu_cc_src2);
                        tcg_gen_divu_i64(cpu_dst, cpu_cc_src, cpu_cc_src2);
P
pbrook 已提交
3075 3076
                        break;
#endif
3077
                    case 0xe:
B
blueswir1 已提交
3078
                        CHECK_IU_FEATURE(dc, DIV);
B
blueswir1 已提交
3079 3080
                        tcg_gen_helper_1_2(helper_udiv, cpu_dst, cpu_src1,
                                           cpu_src2);
3081
                        if (xop & 0x10)
3082
                            gen_op_div_cc(cpu_dst);
3083 3084
                        break;
                    case 0xf:
B
blueswir1 已提交
3085
                        CHECK_IU_FEATURE(dc, DIV);
B
blueswir1 已提交
3086 3087
                        tcg_gen_helper_1_2(helper_sdiv, cpu_dst, cpu_src1,
                                           cpu_src2);
3088
                        if (xop & 0x10)
3089
                            gen_op_div_cc(cpu_dst);
3090 3091 3092 3093
                        break;
                    default:
                        goto illegal_insn;
                    }
3094
                    gen_movl_TN_reg(rd, cpu_dst);
3095 3096
                } else {
                    switch (xop) {
B
blueswir1 已提交
3097
                    case 0x20: /* taddcc */
3098 3099
                        gen_op_tadd_cc(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3100 3101
                        break;
                    case 0x21: /* tsubcc */
3102 3103
                        gen_op_tsub_cc(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3104 3105
                        break;
                    case 0x22: /* taddcctv */
3106 3107 3108
                        save_state(dc, cpu_cond);
                        gen_op_tadd_ccTV(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3109 3110
                        break;
                    case 0x23: /* tsubcctv */
3111 3112 3113
                        save_state(dc, cpu_cond);
                        gen_op_tsub_ccTV(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3114
                        break;
3115
                    case 0x24: /* mulscc */
3116 3117
                        gen_op_mulscc(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
3118
                        break;
B
bellard 已提交
3119
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3120
                    case 0x25:  /* sll */
3121 3122 3123 3124 3125 3126 3127
                        if (IS_IMM) { /* immediate */
                            rs2 = GET_FIELDs(insn, 20, 31);
                            tcg_gen_shli_tl(cpu_dst, cpu_src1, rs2 & 0x1f);
                        } else { /* register */
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
                            tcg_gen_shl_tl(cpu_dst, cpu_src1, cpu_tmp0);
                        }
3128
                        gen_movl_TN_reg(rd, cpu_dst);
3129
                        break;
B
bellard 已提交
3130
                    case 0x26:  /* srl */
3131 3132 3133 3134 3135 3136 3137
                        if (IS_IMM) { /* immediate */
                            rs2 = GET_FIELDs(insn, 20, 31);
                            tcg_gen_shri_tl(cpu_dst, cpu_src1, rs2 & 0x1f);
                        } else { /* register */
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
                            tcg_gen_shr_tl(cpu_dst, cpu_src1, cpu_tmp0);
                        }
3138
                        gen_movl_TN_reg(rd, cpu_dst);
3139
                        break;
B
bellard 已提交
3140
                    case 0x27:  /* sra */
3141 3142 3143 3144 3145 3146 3147
                        if (IS_IMM) { /* immediate */
                            rs2 = GET_FIELDs(insn, 20, 31);
                            tcg_gen_sari_tl(cpu_dst, cpu_src1, rs2 & 0x1f);
                        } else { /* register */
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
                            tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0);
                        }
3148
                        gen_movl_TN_reg(rd, cpu_dst);
3149
                        break;
B
bellard 已提交
3150
#endif
3151 3152 3153
                    case 0x30:
                        {
                            switch(rd) {
B
bellard 已提交
3154
                            case 0: /* wry */
3155 3156
                                tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
                                tcg_gen_st_tl(cpu_tmp0, cpu_env,
B
blueswir1 已提交
3157
                                              offsetof(CPUSPARCState, y));
3158
                                break;
3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169
#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 已提交
3170
                            case 0x2: /* V9 wrccr */
3171 3172
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
                                tcg_gen_helper_0_1(helper_wrccr, cpu_dst);
B
blueswir1 已提交
3173 3174
                                break;
                            case 0x3: /* V9 wrasi */
3175 3176
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
B
blueswir1 已提交
3177 3178
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState, asi));
B
blueswir1 已提交
3179 3180
                                break;
                            case 0x6: /* V9 wrfprs */
3181 3182
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
B
blueswir1 已提交
3183 3184
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState, fprs));
3185
                                save_state(dc, cpu_cond);
3186
                                gen_op_next_insn();
B
bellard 已提交
3187
                                tcg_gen_exit_tb(0);
3188
                                dc->is_br = 1;
B
blueswir1 已提交
3189 3190
                                break;
                            case 0xf: /* V9 sir, nop if user */
B
bellard 已提交
3191
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
3192
                                if (supervisor(dc))
B
blueswir1 已提交
3193
                                    ; // XXX
B
bellard 已提交
3194
#endif
B
blueswir1 已提交
3195 3196
                                break;
                            case 0x13: /* Graphics Status */
3197
                                if (gen_trap_ifnofpu(dc, cpu_cond))
B
bellard 已提交
3198
                                    goto jmp_insn;
3199 3200
                                tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
                                tcg_gen_st_tl(cpu_tmp0, cpu_env,
B
blueswir1 已提交
3201
                                              offsetof(CPUSPARCState, gsr));
B
blueswir1 已提交
3202 3203
                                break;
                            case 0x17: /* Tick compare */
B
bellard 已提交
3204
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
3205 3206
                                if (!supervisor(dc))
                                    goto illegal_insn;
B
bellard 已提交
3207
#endif
B
blueswir1 已提交
3208 3209 3210
                                {
                                    TCGv r_tickptr;

3211
                                    tcg_gen_xor_tl(cpu_tmp0, cpu_src1,
3212
                                                   cpu_src2);
3213
                                    tcg_gen_st_tl(cpu_tmp0, cpu_env,
B
blueswir1 已提交
3214 3215
                                                  offsetof(CPUSPARCState,
                                                           tick_cmpr));
B
blueswir1 已提交
3216 3217 3218 3219
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, tick));
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3220
                                                       r_tickptr, cpu_tmp0);
B
blueswir1 已提交
3221
                                    tcg_temp_free(r_tickptr);
B
blueswir1 已提交
3222
                                }
B
blueswir1 已提交
3223 3224
                                break;
                            case 0x18: /* System tick */
B
bellard 已提交
3225
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
3226 3227
                                if (!supervisor(dc))
                                    goto illegal_insn;
B
bellard 已提交
3228
#endif
B
blueswir1 已提交
3229 3230 3231
                                {
                                    TCGv r_tickptr;

3232 3233
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
                                                   cpu_src2);
B
blueswir1 已提交
3234 3235 3236 3237
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, stick));
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3238
                                                       r_tickptr, cpu_dst);
B
blueswir1 已提交
3239
                                    tcg_temp_free(r_tickptr);
B
blueswir1 已提交
3240
                                }
B
blueswir1 已提交
3241 3242
                                break;
                            case 0x19: /* System tick compare */
B
bellard 已提交
3243
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
3244 3245
                                if (!supervisor(dc))
                                    goto illegal_insn;
B
bellard 已提交
3246
#endif
B
blueswir1 已提交
3247 3248 3249
                                {
                                    TCGv r_tickptr;

3250
                                    tcg_gen_xor_tl(cpu_tmp0, cpu_src1,
3251
                                                   cpu_src2);
3252
                                    tcg_gen_st_tl(cpu_tmp0, cpu_env,
B
blueswir1 已提交
3253 3254
                                                  offsetof(CPUSPARCState,
                                                           stick_cmpr));
B
blueswir1 已提交
3255 3256 3257 3258
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, stick));
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3259
                                                       r_tickptr, cpu_tmp0);
B
blueswir1 已提交
3260
                                    tcg_temp_free(r_tickptr);
B
blueswir1 已提交
3261
                                }
B
blueswir1 已提交
3262
                                break;
B
bellard 已提交
3263

B
blueswir1 已提交
3264
                            case 0x10: /* Performance Control */
B
blueswir1 已提交
3265 3266
                            case 0x11: /* Performance Instrumentation
                                          Counter */
B
blueswir1 已提交
3267 3268 3269 3270
                            case 0x12: /* Dispatch Control */
                            case 0x14: /* Softint set */
                            case 0x15: /* Softint clear */
                            case 0x16: /* Softint write */
B
bellard 已提交
3271
#endif
B
bellard 已提交
3272
                            default:
3273 3274 3275 3276
                                goto illegal_insn;
                            }
                        }
                        break;
3277
#if !defined(CONFIG_USER_ONLY)
3278
                    case 0x31: /* wrpsr, V9 saved, restored */
3279
                        {
B
blueswir1 已提交
3280 3281
                            if (!supervisor(dc))
                                goto priv_insn;
B
bellard 已提交
3282
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3283 3284
                            switch (rd) {
                            case 0:
3285
                                tcg_gen_helper_0_0(helper_saved);
B
blueswir1 已提交
3286 3287
                                break;
                            case 1:
3288
                                tcg_gen_helper_0_0(helper_restored);
B
blueswir1 已提交
3289
                                break;
B
blueswir1 已提交
3290 3291 3292 3293 3294
                            case 2: /* UA2005 allclean */
                            case 3: /* UA2005 otherw */
                            case 4: /* UA2005 normalw */
                            case 5: /* UA2005 invalw */
                                // XXX
B
blueswir1 已提交
3295
                            default:
B
bellard 已提交
3296 3297 3298
                                goto illegal_insn;
                            }
#else
3299 3300 3301
                            tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
                            tcg_gen_helper_0_1(helper_wrpsr, cpu_dst);
                            save_state(dc, cpu_cond);
B
bellard 已提交
3302
                            gen_op_next_insn();
B
bellard 已提交
3303
                            tcg_gen_exit_tb(0);
B
blueswir1 已提交
3304
                            dc->is_br = 1;
B
bellard 已提交
3305
#endif
3306 3307
                        }
                        break;
3308
                    case 0x32: /* wrwim, V9 wrpr */
3309
                        {
B
blueswir1 已提交
3310 3311
                            if (!supervisor(dc))
                                goto priv_insn;
3312
                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
B
bellard 已提交
3313
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3314 3315
                            switch (rd) {
                            case 0: // tpc
3316 3317 3318 3319 3320 3321
                                {
                                    TCGv r_tsptr;

                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                                   offsetof(CPUState, tsptr));
3322
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3323
                                                  offsetof(trap_state, tpc));
B
blueswir1 已提交
3324
                                    tcg_temp_free(r_tsptr);
3325
                                }
B
blueswir1 已提交
3326 3327
                                break;
                            case 1: // tnpc
3328 3329 3330 3331 3332 3333
                                {
                                    TCGv r_tsptr;

                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                                   offsetof(CPUState, tsptr));
3334
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3335
                                                  offsetof(trap_state, tnpc));
B
blueswir1 已提交
3336
                                    tcg_temp_free(r_tsptr);
3337
                                }
B
blueswir1 已提交
3338 3339
                                break;
                            case 2: // tstate
3340 3341 3342 3343 3344 3345
                                {
                                    TCGv r_tsptr;

                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                                   offsetof(CPUState, tsptr));
3346
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
B
blueswir1 已提交
3347 3348
                                                  offsetof(trap_state,
                                                           tstate));
B
blueswir1 已提交
3349
                                    tcg_temp_free(r_tsptr);
3350
                                }
B
blueswir1 已提交
3351 3352
                                break;
                            case 3: // tt
3353 3354 3355 3356 3357 3358
                                {
                                    TCGv r_tsptr;

                                    r_tsptr = tcg_temp_new(TCG_TYPE_PTR);
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                                   offsetof(CPUState, tsptr));
3359
                                    tcg_gen_st_i32(cpu_tmp0, r_tsptr,
3360
                                                   offsetof(trap_state, tt));
B
blueswir1 已提交
3361
                                    tcg_temp_free(r_tsptr);
3362
                                }
B
blueswir1 已提交
3363 3364
                                break;
                            case 4: // tick
B
blueswir1 已提交
3365 3366 3367 3368 3369 3370 3371
                                {
                                    TCGv r_tickptr;

                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, tick));
                                    tcg_gen_helper_0_2(helper_tick_set_count,
3372
                                                       r_tickptr, cpu_tmp0);
B
blueswir1 已提交
3373
                                    tcg_temp_free(r_tickptr);
B
blueswir1 已提交
3374
                                }
B
blueswir1 已提交
3375 3376
                                break;
                            case 5: // tba
3377
                                tcg_gen_st_tl(cpu_tmp0, cpu_env,
B
blueswir1 已提交
3378
                                              offsetof(CPUSPARCState, tbr));
B
blueswir1 已提交
3379 3380
                                break;
                            case 6: // pstate
3381
                                save_state(dc, cpu_cond);
3382
                                tcg_gen_helper_0_1(helper_wrpstate, cpu_tmp0);
P
pbrook 已提交
3383
                                gen_op_next_insn();
B
bellard 已提交
3384
                                tcg_gen_exit_tb(0);
P
pbrook 已提交
3385
                                dc->is_br = 1;
B
blueswir1 已提交
3386 3387
                                break;
                            case 7: // tl
3388
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3389 3390
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState, tl));
B
blueswir1 已提交
3391 3392
                                break;
                            case 8: // pil
3393
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3394 3395 3396
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState,
                                                        psrpil));
B
blueswir1 已提交
3397 3398
                                break;
                            case 9: // cwp
3399
                                tcg_gen_helper_0_1(helper_wrcwp, cpu_tmp0);
B
blueswir1 已提交
3400 3401
                                break;
                            case 10: // cansave
3402
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3403 3404 3405
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState,
                                                        cansave));
B
blueswir1 已提交
3406 3407
                                break;
                            case 11: // canrestore
3408
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3409 3410 3411
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState,
                                                        canrestore));
B
blueswir1 已提交
3412 3413
                                break;
                            case 12: // cleanwin
3414
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3415 3416 3417
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState,
                                                        cleanwin));
B
blueswir1 已提交
3418 3419
                                break;
                            case 13: // otherwin
3420
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3421 3422 3423
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState,
                                                        otherwin));
B
blueswir1 已提交
3424 3425
                                break;
                            case 14: // wstate
3426
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3427 3428 3429
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState,
                                                        wstate));
B
blueswir1 已提交
3430
                                break;
B
blueswir1 已提交
3431
                            case 16: // UA2005 gl
3432
                                CHECK_IU_FEATURE(dc, GL);
3433
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3434 3435
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState, gl));
B
blueswir1 已提交
3436 3437
                                break;
                            case 26: // UA2005 strand status
3438
                                CHECK_IU_FEATURE(dc, HYPV);
B
blueswir1 已提交
3439 3440
                                if (!hypervisor(dc))
                                    goto priv_insn;
3441
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3442 3443
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState, ssr));
B
blueswir1 已提交
3444
                                break;
B
blueswir1 已提交
3445 3446 3447
                            default:
                                goto illegal_insn;
                            }
B
bellard 已提交
3448
#else
3449
                            tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3450 3451 3452
                            if (dc->def->nwindows != 32)
                                tcg_gen_andi_tl(cpu_tmp32, cpu_tmp32,
                                                (1 << dc->def->nwindows) - 1);
B
blueswir1 已提交
3453 3454
                            tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                           offsetof(CPUSPARCState, wim));
B
bellard 已提交
3455
#endif
3456 3457
                        }
                        break;
B
blueswir1 已提交
3458
                    case 0x33: /* wrtbr, UA2005 wrhpr */
3459
                        {
B
blueswir1 已提交
3460
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3461 3462
                            if (!supervisor(dc))
                                goto priv_insn;
3463 3464
                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
                            tcg_gen_st_tl(cpu_tmp0, cpu_env,
B
blueswir1 已提交
3465
                                          offsetof(CPUSPARCState, tbr));
B
blueswir1 已提交
3466
#else
3467
                            CHECK_IU_FEATURE(dc, HYPV);
B
blueswir1 已提交
3468 3469
                            if (!hypervisor(dc))
                                goto priv_insn;
3470
                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
B
blueswir1 已提交
3471 3472 3473
                            switch (rd) {
                            case 0: // hpstate
                                // XXX gen_op_wrhpstate();
3474
                                save_state(dc, cpu_cond);
B
blueswir1 已提交
3475
                                gen_op_next_insn();
B
bellard 已提交
3476
                                tcg_gen_exit_tb(0);
B
blueswir1 已提交
3477 3478 3479 3480 3481 3482
                                dc->is_br = 1;
                                break;
                            case 1: // htstate
                                // XXX gen_op_wrhtstate();
                                break;
                            case 3: // hintp
3483
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3484 3485
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState, hintp));
B
blueswir1 已提交
3486 3487
                                break;
                            case 5: // htba
3488
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3489 3490
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState, htba));
B
blueswir1 已提交
3491 3492
                                break;
                            case 31: // hstick_cmpr
B
blueswir1 已提交
3493 3494 3495
                                {
                                    TCGv r_tickptr;

3496
                                    tcg_gen_st_tl(cpu_tmp0, cpu_env,
B
blueswir1 已提交
3497 3498
                                                  offsetof(CPUSPARCState,
                                                           hstick_cmpr));
B
blueswir1 已提交
3499 3500 3501 3502
                                    r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, hstick));
                                    tcg_gen_helper_0_2(helper_tick_set_limit,
3503
                                                       r_tickptr, cpu_tmp0);
B
blueswir1 已提交
3504
                                    tcg_temp_free(r_tickptr);
B
blueswir1 已提交
3505
                                }
B
blueswir1 已提交
3506 3507 3508 3509 3510 3511
                                break;
                            case 6: // hver readonly
                            default:
                                goto illegal_insn;
                            }
#endif
3512 3513 3514
                        }
                        break;
#endif
B
bellard 已提交
3515
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3516 3517 3518 3519
                    case 0x2c: /* V9 movcc */
                        {
                            int cc = GET_FIELD_SP(insn, 11, 12);
                            int cond = GET_FIELD_SP(insn, 14, 17);
B
blueswir1 已提交
3520
                            TCGv r_cond;
3521 3522
                            int l1;

B
blueswir1 已提交
3523
                            r_cond = tcg_temp_new(TCG_TYPE_TL);
B
blueswir1 已提交
3524 3525
                            if (insn & (1 << 18)) {
                                if (cc == 0)
B
blueswir1 已提交
3526
                                    gen_cond(r_cond, 0, cond);
B
blueswir1 已提交
3527
                                else if (cc == 2)
B
blueswir1 已提交
3528
                                    gen_cond(r_cond, 1, cond);
B
blueswir1 已提交
3529 3530 3531
                                else
                                    goto illegal_insn;
                            } else {
B
blueswir1 已提交
3532
                                gen_fcond(r_cond, cc, cond);
B
blueswir1 已提交
3533
                            }
3534 3535 3536

                            l1 = gen_new_label();

P
pbrook 已提交
3537
                            tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
3538
                            if (IS_IMM) {       /* immediate */
B
blueswir1 已提交
3539 3540
                                TCGv r_const;

3541
                                rs2 = GET_FIELD_SPs(insn, 0, 10);
B
blueswir1 已提交
3542 3543 3544
                                r_const = tcg_const_tl((int)rs2);
                                gen_movl_TN_reg(rd, r_const);
                                tcg_temp_free(r_const);
3545 3546
                            } else {
                                rs2 = GET_FIELD_SP(insn, 0, 4);
B
blueswir1 已提交
3547 3548
                                gen_movl_reg_TN(rs2, cpu_tmp0);
                                gen_movl_TN_reg(rd, cpu_tmp0);
3549 3550
                            }
                            gen_set_label(l1);
B
blueswir1 已提交
3551
                            tcg_temp_free(r_cond);
B
blueswir1 已提交
3552 3553 3554
                            break;
                        }
                    case 0x2d: /* V9 sdivx */
3555 3556
                        gen_op_sdivx(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3557 3558 3559
                        break;
                    case 0x2e: /* V9 popc */
                        {
B
blueswir1 已提交
3560
                            cpu_src2 = get_src2(insn, cpu_src2);
3561 3562 3563
                            tcg_gen_helper_1_1(helper_popc, cpu_dst,
                                               cpu_src2);
                            gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3564 3565 3566 3567
                        }
                    case 0x2f: /* V9 movr */
                        {
                            int cond = GET_FIELD_SP(insn, 10, 12);
3568 3569
                            int l1;

3570
                            cpu_src1 = get_src1(insn, cpu_src1);
3571 3572 3573

                            l1 = gen_new_label();

P
pbrook 已提交
3574 3575
                            tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond],
                                              cpu_src1, 0, l1);
B
blueswir1 已提交
3576
                            if (IS_IMM) {       /* immediate */
B
blueswir1 已提交
3577 3578
                                TCGv r_const;

B
blueswir1 已提交
3579
                                rs2 = GET_FIELD_SPs(insn, 0, 9);
B
blueswir1 已提交
3580 3581 3582
                                r_const = tcg_const_tl((int)rs2);
                                gen_movl_TN_reg(rd, r_const);
                                tcg_temp_free(r_const);
3583
                            } else {
B
blueswir1 已提交
3584
                                rs2 = GET_FIELD_SP(insn, 0, 4);
B
blueswir1 已提交
3585 3586
                                gen_movl_reg_TN(rs2, cpu_tmp0);
                                gen_movl_TN_reg(rd, cpu_tmp0);
B
blueswir1 已提交
3587
                            }
3588
                            gen_set_label(l1);
B
blueswir1 已提交
3589 3590 3591 3592 3593 3594 3595
                            break;
                        }
#endif
                    default:
                        goto illegal_insn;
                    }
                }
3596 3597 3598 3599 3600
            } 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);
3601
                if (gen_trap_ifnofpu(dc, cpu_cond))
B
blueswir1 已提交
3602
                    goto jmp_insn;
3603 3604

                switch (opf) {
B
blueswir1 已提交
3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619
                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 已提交
3620
                    CHECK_FPU_FEATURE(dc, VIS1);
3621
                    cpu_src1 = get_src1(insn, cpu_src1);
3622 3623 3624 3625
                    gen_movl_reg_TN(rs2, cpu_src2);
                    tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
                                       cpu_src2);
                    gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3626 3627
                    break;
                case 0x012: /* VIS I array16 */
B
blueswir1 已提交
3628
                    CHECK_FPU_FEATURE(dc, VIS1);
3629
                    cpu_src1 = get_src1(insn, cpu_src1);
3630 3631 3632 3633 3634
                    gen_movl_reg_TN(rs2, cpu_src2);
                    tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
                                       cpu_src2);
                    tcg_gen_shli_i64(cpu_dst, cpu_dst, 1);
                    gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3635 3636
                    break;
                case 0x014: /* VIS I array32 */
B
blueswir1 已提交
3637
                    CHECK_FPU_FEATURE(dc, VIS1);
3638
                    cpu_src1 = get_src1(insn, cpu_src1);
3639 3640 3641 3642 3643
                    gen_movl_reg_TN(rs2, cpu_src2);
                    tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
                                       cpu_src2);
                    tcg_gen_shli_i64(cpu_dst, cpu_dst, 2);
                    gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3644
                    break;
3645
                case 0x018: /* VIS I alignaddr */
B
blueswir1 已提交
3646
                    CHECK_FPU_FEATURE(dc, VIS1);
3647
                    cpu_src1 = get_src1(insn, cpu_src1);
3648 3649 3650 3651
                    gen_movl_reg_TN(rs2, cpu_src2);
                    tcg_gen_helper_1_2(helper_alignaddr, cpu_dst, cpu_src1,
                                       cpu_src2);
                    gen_movl_TN_reg(rd, cpu_dst);
3652
                    break;
B
blueswir1 已提交
3653
                case 0x019: /* VIS II bmask */
3654 3655
                case 0x01a: /* VIS I alignaddrl */
                    // XXX
B
blueswir1 已提交
3656 3657
                    goto illegal_insn;
                case 0x020: /* VIS I fcmple16 */
B
blueswir1 已提交
3658
                    CHECK_FPU_FEATURE(dc, VIS1);
3659 3660
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3661
                    tcg_gen_helper_0_0(helper_fcmple16);
3662
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3663 3664
                    break;
                case 0x022: /* VIS I fcmpne16 */
B
blueswir1 已提交
3665
                    CHECK_FPU_FEATURE(dc, VIS1);
3666 3667
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3668
                    tcg_gen_helper_0_0(helper_fcmpne16);
3669
                    gen_op_store_DT0_fpr(DFPREG(rd));
3670
                    break;
B
blueswir1 已提交
3671
                case 0x024: /* VIS I fcmple32 */
B
blueswir1 已提交
3672
                    CHECK_FPU_FEATURE(dc, VIS1);
3673 3674
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3675
                    tcg_gen_helper_0_0(helper_fcmple32);
3676
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3677 3678
                    break;
                case 0x026: /* VIS I fcmpne32 */
B
blueswir1 已提交
3679
                    CHECK_FPU_FEATURE(dc, VIS1);
3680 3681
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3682
                    tcg_gen_helper_0_0(helper_fcmpne32);
3683
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3684 3685
                    break;
                case 0x028: /* VIS I fcmpgt16 */
B
blueswir1 已提交
3686
                    CHECK_FPU_FEATURE(dc, VIS1);
3687 3688
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3689
                    tcg_gen_helper_0_0(helper_fcmpgt16);
3690
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3691 3692
                    break;
                case 0x02a: /* VIS I fcmpeq16 */
B
blueswir1 已提交
3693
                    CHECK_FPU_FEATURE(dc, VIS1);
3694 3695
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3696
                    tcg_gen_helper_0_0(helper_fcmpeq16);
3697
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3698 3699
                    break;
                case 0x02c: /* VIS I fcmpgt32 */
B
blueswir1 已提交
3700
                    CHECK_FPU_FEATURE(dc, VIS1);
3701 3702
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3703
                    tcg_gen_helper_0_0(helper_fcmpgt32);
3704
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3705 3706
                    break;
                case 0x02e: /* VIS I fcmpeq32 */
B
blueswir1 已提交
3707
                    CHECK_FPU_FEATURE(dc, VIS1);
3708 3709
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3710
                    tcg_gen_helper_0_0(helper_fcmpeq32);
3711
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3712 3713
                    break;
                case 0x031: /* VIS I fmul8x16 */
B
blueswir1 已提交
3714
                    CHECK_FPU_FEATURE(dc, VIS1);
3715 3716
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3717
                    tcg_gen_helper_0_0(helper_fmul8x16);
3718
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3719 3720
                    break;
                case 0x033: /* VIS I fmul8x16au */
B
blueswir1 已提交
3721
                    CHECK_FPU_FEATURE(dc, VIS1);
3722 3723
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3724
                    tcg_gen_helper_0_0(helper_fmul8x16au);
3725
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3726 3727
                    break;
                case 0x035: /* VIS I fmul8x16al */
B
blueswir1 已提交
3728
                    CHECK_FPU_FEATURE(dc, VIS1);
3729 3730
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3731
                    tcg_gen_helper_0_0(helper_fmul8x16al);
3732
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3733 3734
                    break;
                case 0x036: /* VIS I fmul8sux16 */
B
blueswir1 已提交
3735
                    CHECK_FPU_FEATURE(dc, VIS1);
3736 3737
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3738
                    tcg_gen_helper_0_0(helper_fmul8sux16);
3739
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3740 3741
                    break;
                case 0x037: /* VIS I fmul8ulx16 */
B
blueswir1 已提交
3742
                    CHECK_FPU_FEATURE(dc, VIS1);
3743 3744
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3745
                    tcg_gen_helper_0_0(helper_fmul8ulx16);
3746
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3747 3748
                    break;
                case 0x038: /* VIS I fmuld8sux16 */
B
blueswir1 已提交
3749
                    CHECK_FPU_FEATURE(dc, VIS1);
3750 3751
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3752
                    tcg_gen_helper_0_0(helper_fmuld8sux16);
3753
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3754 3755
                    break;
                case 0x039: /* VIS I fmuld8ulx16 */
B
blueswir1 已提交
3756
                    CHECK_FPU_FEATURE(dc, VIS1);
3757 3758
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3759
                    tcg_gen_helper_0_0(helper_fmuld8ulx16);
3760
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3761 3762 3763 3764 3765 3766 3767
                    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;
3768
                case 0x048: /* VIS I faligndata */
B
blueswir1 已提交
3769
                    CHECK_FPU_FEATURE(dc, VIS1);
3770 3771
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3772
                    tcg_gen_helper_0_0(helper_faligndata);
3773
                    gen_op_store_DT0_fpr(DFPREG(rd));
3774
                    break;
B
blueswir1 已提交
3775
                case 0x04b: /* VIS I fpmerge */
B
blueswir1 已提交
3776
                    CHECK_FPU_FEATURE(dc, VIS1);
3777 3778
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3779
                    tcg_gen_helper_0_0(helper_fpmerge);
3780
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3781 3782 3783 3784 3785
                    break;
                case 0x04c: /* VIS II bshuffle */
                    // XXX
                    goto illegal_insn;
                case 0x04d: /* VIS I fexpand */
B
blueswir1 已提交
3786
                    CHECK_FPU_FEATURE(dc, VIS1);
3787 3788
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3789
                    tcg_gen_helper_0_0(helper_fexpand);
3790
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3791 3792
                    break;
                case 0x050: /* VIS I fpadd16 */
B
blueswir1 已提交
3793
                    CHECK_FPU_FEATURE(dc, VIS1);
3794 3795
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3796
                    tcg_gen_helper_0_0(helper_fpadd16);
3797
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3798 3799
                    break;
                case 0x051: /* VIS I fpadd16s */
B
blueswir1 已提交
3800
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
3801 3802
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
3803
                    tcg_gen_helper_0_0(helper_fpadd16s);
B
blueswir1 已提交
3804 3805 3806
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x052: /* VIS I fpadd32 */
B
blueswir1 已提交
3807
                    CHECK_FPU_FEATURE(dc, VIS1);
3808 3809
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3810
                    tcg_gen_helper_0_0(helper_fpadd32);
3811
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3812 3813
                    break;
                case 0x053: /* VIS I fpadd32s */
B
blueswir1 已提交
3814
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
3815 3816
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
3817
                    tcg_gen_helper_0_0(helper_fpadd32s);
B
blueswir1 已提交
3818 3819 3820
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x054: /* VIS I fpsub16 */
B
blueswir1 已提交
3821
                    CHECK_FPU_FEATURE(dc, VIS1);
3822 3823
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3824
                    tcg_gen_helper_0_0(helper_fpsub16);
3825
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3826 3827
                    break;
                case 0x055: /* VIS I fpsub16s */
B
blueswir1 已提交
3828
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
3829 3830
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
3831
                    tcg_gen_helper_0_0(helper_fpsub16s);
B
blueswir1 已提交
3832 3833 3834
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x056: /* VIS I fpsub32 */
B
blueswir1 已提交
3835
                    CHECK_FPU_FEATURE(dc, VIS1);
3836 3837
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3838
                    tcg_gen_helper_0_0(helper_fpadd32);
3839
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3840 3841
                    break;
                case 0x057: /* VIS I fpsub32s */
B
blueswir1 已提交
3842
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
3843 3844
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
3845
                    tcg_gen_helper_0_0(helper_fpsub32s);
B
blueswir1 已提交
3846 3847
                    gen_op_store_FT0_fpr(rd);
                    break;
3848
                case 0x060: /* VIS I fzero */
B
blueswir1 已提交
3849
                    CHECK_FPU_FEATURE(dc, VIS1);
3850
                    tcg_gen_helper_0_0(helper_movl_DT0_0);
3851
                    gen_op_store_DT0_fpr(DFPREG(rd));
3852 3853
                    break;
                case 0x061: /* VIS I fzeros */
B
blueswir1 已提交
3854
                    CHECK_FPU_FEATURE(dc, VIS1);
3855
                    tcg_gen_helper_0_0(helper_movl_FT0_0);
3856 3857
                    gen_op_store_FT0_fpr(rd);
                    break;
B
blueswir1 已提交
3858
                case 0x062: /* VIS I fnor */
B
blueswir1 已提交
3859
                    CHECK_FPU_FEATURE(dc, VIS1);
3860 3861
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3862
                    tcg_gen_helper_0_0(helper_fnor);
3863
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3864 3865
                    break;
                case 0x063: /* VIS I fnors */
B
blueswir1 已提交
3866
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
3867 3868
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
3869
                    tcg_gen_helper_0_0(helper_fnors);
B
blueswir1 已提交
3870 3871 3872
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x064: /* VIS I fandnot2 */
B
blueswir1 已提交
3873
                    CHECK_FPU_FEATURE(dc, VIS1);
3874 3875
                    gen_op_load_fpr_DT1(DFPREG(rs1));
                    gen_op_load_fpr_DT0(DFPREG(rs2));
3876
                    tcg_gen_helper_0_0(helper_fandnot);
3877
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3878 3879
                    break;
                case 0x065: /* VIS I fandnot2s */
B
blueswir1 已提交
3880
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
3881 3882
                    gen_op_load_fpr_FT1(rs1);
                    gen_op_load_fpr_FT0(rs2);
3883
                    tcg_gen_helper_0_0(helper_fandnots);
B
blueswir1 已提交
3884 3885 3886
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x066: /* VIS I fnot2 */
B
blueswir1 已提交
3887
                    CHECK_FPU_FEATURE(dc, VIS1);
3888
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3889
                    tcg_gen_helper_0_0(helper_fnot);
3890
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3891 3892
                    break;
                case 0x067: /* VIS I fnot2s */
B
blueswir1 已提交
3893
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
3894
                    gen_op_load_fpr_FT1(rs2);
3895
                    tcg_gen_helper_0_0(helper_fnot);
B
blueswir1 已提交
3896 3897 3898
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x068: /* VIS I fandnot1 */
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
                    tcg_gen_helper_0_0(helper_fandnot);
3903
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3904 3905
                    break;
                case 0x069: /* VIS I fandnot1s */
B
blueswir1 已提交
3906
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
3907 3908
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
3909
                    tcg_gen_helper_0_0(helper_fandnots);
B
blueswir1 已提交
3910 3911 3912
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x06a: /* VIS I fnot1 */
B
blueswir1 已提交
3913
                    CHECK_FPU_FEATURE(dc, VIS1);
3914
                    gen_op_load_fpr_DT1(DFPREG(rs1));
3915
                    tcg_gen_helper_0_0(helper_fnot);
3916
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3917 3918
                    break;
                case 0x06b: /* VIS I fnot1s */
B
blueswir1 已提交
3919
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
3920
                    gen_op_load_fpr_FT1(rs1);
3921
                    tcg_gen_helper_0_0(helper_fnot);
B
blueswir1 已提交
3922 3923 3924
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x06c: /* VIS I fxor */
B
blueswir1 已提交
3925
                    CHECK_FPU_FEATURE(dc, VIS1);
3926 3927
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3928
                    tcg_gen_helper_0_0(helper_fxor);
3929
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3930 3931
                    break;
                case 0x06d: /* VIS I fxors */
B
blueswir1 已提交
3932
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
3933 3934
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
3935
                    tcg_gen_helper_0_0(helper_fxors);
B
blueswir1 已提交
3936 3937 3938
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x06e: /* VIS I fnand */
B
blueswir1 已提交
3939
                    CHECK_FPU_FEATURE(dc, VIS1);
3940 3941
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3942
                    tcg_gen_helper_0_0(helper_fnand);
3943
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3944 3945
                    break;
                case 0x06f: /* VIS I fnands */
B
blueswir1 已提交
3946
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
3947 3948
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
3949
                    tcg_gen_helper_0_0(helper_fnands);
B
blueswir1 已提交
3950 3951 3952
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x070: /* VIS I fand */
B
blueswir1 已提交
3953
                    CHECK_FPU_FEATURE(dc, VIS1);
3954 3955
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3956
                    tcg_gen_helper_0_0(helper_fand);
3957
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3958 3959
                    break;
                case 0x071: /* VIS I fands */
B
blueswir1 已提交
3960
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
3961 3962
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
3963
                    tcg_gen_helper_0_0(helper_fands);
B
blueswir1 已提交
3964 3965 3966
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x072: /* VIS I fxnor */
B
blueswir1 已提交
3967
                    CHECK_FPU_FEATURE(dc, VIS1);
3968 3969
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
3970
                    tcg_gen_helper_0_0(helper_fxnor);
3971
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3972 3973
                    break;
                case 0x073: /* VIS I fxnors */
B
blueswir1 已提交
3974
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
3975 3976
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
3977
                    tcg_gen_helper_0_0(helper_fxnors);
B
blueswir1 已提交
3978 3979
                    gen_op_store_FT0_fpr(rd);
                    break;
3980
                case 0x074: /* VIS I fsrc1 */
B
blueswir1 已提交
3981
                    CHECK_FPU_FEATURE(dc, VIS1);
3982 3983
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_store_DT0_fpr(DFPREG(rd));
3984 3985
                    break;
                case 0x075: /* VIS I fsrc1s */
B
blueswir1 已提交
3986
                    CHECK_FPU_FEATURE(dc, VIS1);
3987 3988 3989
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_store_FT0_fpr(rd);
                    break;
B
blueswir1 已提交
3990
                case 0x076: /* VIS I fornot2 */
B
blueswir1 已提交
3991
                    CHECK_FPU_FEATURE(dc, VIS1);
3992 3993
                    gen_op_load_fpr_DT1(DFPREG(rs1));
                    gen_op_load_fpr_DT0(DFPREG(rs2));
3994
                    tcg_gen_helper_0_0(helper_fornot);
3995
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
3996 3997
                    break;
                case 0x077: /* VIS I fornot2s */
B
blueswir1 已提交
3998
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
3999 4000
                    gen_op_load_fpr_FT1(rs1);
                    gen_op_load_fpr_FT0(rs2);
4001
                    tcg_gen_helper_0_0(helper_fornots);
B
blueswir1 已提交
4002 4003
                    gen_op_store_FT0_fpr(rd);
                    break;
4004
                case 0x078: /* VIS I fsrc2 */
B
blueswir1 已提交
4005
                    CHECK_FPU_FEATURE(dc, VIS1);
4006 4007
                    gen_op_load_fpr_DT0(DFPREG(rs2));
                    gen_op_store_DT0_fpr(DFPREG(rd));
4008 4009
                    break;
                case 0x079: /* VIS I fsrc2s */
B
blueswir1 已提交
4010
                    CHECK_FPU_FEATURE(dc, VIS1);
4011 4012 4013
                    gen_op_load_fpr_FT0(rs2);
                    gen_op_store_FT0_fpr(rd);
                    break;
B
blueswir1 已提交
4014
                case 0x07a: /* VIS I fornot1 */
B
blueswir1 已提交
4015
                    CHECK_FPU_FEATURE(dc, VIS1);
4016 4017
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
4018
                    tcg_gen_helper_0_0(helper_fornot);
4019
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
4020 4021
                    break;
                case 0x07b: /* VIS I fornot1s */
B
blueswir1 已提交
4022
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4023 4024
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
4025
                    tcg_gen_helper_0_0(helper_fornots);
B
blueswir1 已提交
4026 4027 4028
                    gen_op_store_FT0_fpr(rd);
                    break;
                case 0x07c: /* VIS I for */
B
blueswir1 已提交
4029
                    CHECK_FPU_FEATURE(dc, VIS1);
4030 4031
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
4032
                    tcg_gen_helper_0_0(helper_for);
4033
                    gen_op_store_DT0_fpr(DFPREG(rd));
B
blueswir1 已提交
4034 4035
                    break;
                case 0x07d: /* VIS I fors */
B
blueswir1 已提交
4036
                    CHECK_FPU_FEATURE(dc, VIS1);
B
blueswir1 已提交
4037 4038
                    gen_op_load_fpr_FT0(rs1);
                    gen_op_load_fpr_FT1(rs2);
4039
                    tcg_gen_helper_0_0(helper_fors);
B
blueswir1 已提交
4040 4041
                    gen_op_store_FT0_fpr(rd);
                    break;
4042
                case 0x07e: /* VIS I fone */
B
blueswir1 已提交
4043
                    CHECK_FPU_FEATURE(dc, VIS1);
4044
                    tcg_gen_helper_0_0(helper_movl_DT0_1);
4045
                    gen_op_store_DT0_fpr(DFPREG(rd));
4046 4047
                    break;
                case 0x07f: /* VIS I fones */
B
blueswir1 已提交
4048
                    CHECK_FPU_FEATURE(dc, VIS1);
4049
                    tcg_gen_helper_0_0(helper_movl_FT0_1);
4050 4051
                    gen_op_store_FT0_fpr(rd);
                    break;
B
blueswir1 已提交
4052 4053 4054 4055
                case 0x080: /* VIS I shutdown */
                case 0x081: /* VIS II siam */
                    // XXX
                    goto illegal_insn;
4056 4057 4058 4059
                default:
                    goto illegal_insn;
                }
#else
B
blueswir1 已提交
4060
                goto ncp_insn;
4061 4062
#endif
            } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
4063
#ifdef TARGET_SPARC64
B
blueswir1 已提交
4064
                goto illegal_insn;
4065
#else
B
blueswir1 已提交
4066
                goto ncp_insn;
4067
#endif
B
bellard 已提交
4068
#ifdef TARGET_SPARC64
B
blueswir1 已提交
4069
            } else if (xop == 0x39) { /* V9 return */
B
blueswir1 已提交
4070 4071
                TCGv r_const;

4072
                save_state(dc, cpu_cond);
4073
                cpu_src1 = get_src1(insn, cpu_src1);
B
blueswir1 已提交
4074 4075
                if (IS_IMM) {   /* immediate */
                    rs2 = GET_FIELDs(insn, 19, 31);
4076
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, (int)rs2);
B
blueswir1 已提交
4077
                } else {                /* register */
B
bellard 已提交
4078
                    rs2 = GET_FIELD(insn, 27, 31);
B
blueswir1 已提交
4079
                    if (rs2) {
4080 4081
                        gen_movl_reg_TN(rs2, cpu_src2);
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
4082 4083
                    } else
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
B
bellard 已提交
4084
                }
4085
                tcg_gen_helper_0_0(helper_restore);
4086
                gen_mov_pc_npc(dc, cpu_cond);
B
blueswir1 已提交
4087 4088 4089
                r_const = tcg_const_i32(3);
                tcg_gen_helper_0_2(helper_check_align, cpu_dst, r_const);
                tcg_temp_free(r_const);
4090
                tcg_gen_mov_tl(cpu_npc, cpu_dst);
B
blueswir1 已提交
4091 4092
                dc->npc = DYNAMIC_PC;
                goto jmp_insn;
B
bellard 已提交
4093
#endif
B
blueswir1 已提交
4094
            } else {
4095
                cpu_src1 = get_src1(insn, cpu_src1);
B
blueswir1 已提交
4096 4097
                if (IS_IMM) {   /* immediate */
                    rs2 = GET_FIELDs(insn, 19, 31);
4098
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, (int)rs2);
B
blueswir1 已提交
4099
                } else {                /* register */
B
bellard 已提交
4100
                    rs2 = GET_FIELD(insn, 27, 31);
B
blueswir1 已提交
4101
                    if (rs2) {
4102 4103
                        gen_movl_reg_TN(rs2, cpu_src2);
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
4104 4105
                    } else
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
4106
                }
B
blueswir1 已提交
4107 4108 4109
                switch (xop) {
                case 0x38:      /* jmpl */
                    {
B
blueswir1 已提交
4110 4111 4112 4113 4114
                        TCGv r_const;

                        r_const = tcg_const_tl(dc->pc);
                        gen_movl_TN_reg(rd, r_const);
                        tcg_temp_free(r_const);
4115
                        gen_mov_pc_npc(dc, cpu_cond);
B
blueswir1 已提交
4116
                        r_const = tcg_const_i32(3);
B
blueswir1 已提交
4117
                        tcg_gen_helper_0_2(helper_check_align, cpu_dst,
B
blueswir1 已提交
4118 4119
                                           r_const);
                        tcg_temp_free(r_const);
4120
                        tcg_gen_mov_tl(cpu_npc, cpu_dst);
B
blueswir1 已提交
4121 4122 4123
                        dc->npc = DYNAMIC_PC;
                    }
                    goto jmp_insn;
B
bellard 已提交
4124
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
B
blueswir1 已提交
4125 4126
                case 0x39:      /* rett, V9 return */
                    {
B
blueswir1 已提交
4127 4128
                        TCGv r_const;

B
blueswir1 已提交
4129 4130
                        if (!supervisor(dc))
                            goto priv_insn;
4131
                        gen_mov_pc_npc(dc, cpu_cond);
B
blueswir1 已提交
4132
                        r_const = tcg_const_i32(3);
B
blueswir1 已提交
4133
                        tcg_gen_helper_0_2(helper_check_align, cpu_dst,
B
blueswir1 已提交
4134 4135
                                           r_const);
                        tcg_temp_free(r_const);
4136
                        tcg_gen_mov_tl(cpu_npc, cpu_dst);
B
blueswir1 已提交
4137
                        dc->npc = DYNAMIC_PC;
B
blueswir1 已提交
4138
                        tcg_gen_helper_0_0(helper_rett);
B
blueswir1 已提交
4139 4140 4141 4142
                    }
                    goto jmp_insn;
#endif
                case 0x3b: /* flush */
4143
                    if (!((dc)->def->features & CPU_FEATURE_FLUSH))
B
blueswir1 已提交
4144
                        goto unimp_flush;
4145
                    tcg_gen_helper_0_1(helper_flush, cpu_dst);
B
blueswir1 已提交
4146 4147
                    break;
                case 0x3c:      /* save */
4148
                    save_state(dc, cpu_cond);
4149
                    tcg_gen_helper_0_0(helper_save);
4150
                    gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
4151 4152
                    break;
                case 0x3d:      /* restore */
4153
                    save_state(dc, cpu_cond);
4154
                    tcg_gen_helper_0_0(helper_restore);
4155
                    gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
4156
                    break;
B
bellard 已提交
4157
#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
B
blueswir1 已提交
4158 4159 4160 4161 4162 4163 4164 4165
                case 0x3e:      /* V9 done/retry */
                    {
                        switch (rd) {
                        case 0:
                            if (!supervisor(dc))
                                goto priv_insn;
                            dc->npc = DYNAMIC_PC;
                            dc->pc = DYNAMIC_PC;
B
blueswir1 已提交
4166
                            tcg_gen_helper_0_0(helper_done);
B
blueswir1 已提交
4167 4168 4169 4170 4171 4172
                            goto jmp_insn;
                        case 1:
                            if (!supervisor(dc))
                                goto priv_insn;
                            dc->npc = DYNAMIC_PC;
                            dc->pc = DYNAMIC_PC;
B
blueswir1 已提交
4173
                            tcg_gen_helper_0_0(helper_retry);
B
blueswir1 已提交
4174 4175 4176 4177 4178 4179 4180 4181 4182 4183
                            goto jmp_insn;
                        default:
                            goto illegal_insn;
                        }
                    }
                    break;
#endif
                default:
                    goto illegal_insn;
                }
4184
            }
B
blueswir1 已提交
4185 4186 4187 4188 4189 4190
            break;
        }
        break;
    case 3:                     /* load/store instructions */
        {
            unsigned int xop = GET_FIELD(insn, 7, 12);
4191 4192

            cpu_src1 = get_src1(insn, cpu_src1);
B
blueswir1 已提交
4193
            if (xop == 0x3c || xop == 0x3e) { // V9 casa/casxa
4194
                rs2 = GET_FIELD(insn, 27, 31);
4195
                gen_movl_reg_TN(rs2, cpu_src2);
B
blueswir1 已提交
4196 4197
                tcg_gen_mov_tl(cpu_addr, cpu_src1);
            } else if (IS_IMM) {     /* immediate */
B
blueswir1 已提交
4198
                rs2 = GET_FIELDs(insn, 19, 31);
4199
                tcg_gen_addi_tl(cpu_addr, cpu_src1, (int)rs2);
B
blueswir1 已提交
4200 4201 4202
            } else {            /* register */
                rs2 = GET_FIELD(insn, 27, 31);
                if (rs2 != 0) {
4203 4204
                    gen_movl_reg_TN(rs2, cpu_src2);
                    tcg_gen_add_tl(cpu_addr, cpu_src1, cpu_src2);
4205 4206
                } else
                    tcg_gen_mov_tl(cpu_addr, cpu_src1);
B
blueswir1 已提交
4207
            }
B
blueswir1 已提交
4208 4209 4210
            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
                (xop > 0x17 && xop <= 0x1d ) ||
                (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
B
blueswir1 已提交
4211
                switch (xop) {
B
blueswir1 已提交
4212
                case 0x0:       /* load unsigned word */
B
blueswir1 已提交
4213
                    gen_address_mask(dc, cpu_addr);
4214
                    tcg_gen_qemu_ld32u(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4215 4216
                    break;
                case 0x1:       /* load unsigned byte */
B
blueswir1 已提交
4217
                    gen_address_mask(dc, cpu_addr);
4218
                    tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4219 4220
                    break;
                case 0x2:       /* load unsigned halfword */
B
blueswir1 已提交
4221
                    gen_address_mask(dc, cpu_addr);
4222
                    tcg_gen_qemu_ld16u(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4223 4224 4225
                    break;
                case 0x3:       /* load double word */
                    if (rd & 1)
4226
                        goto illegal_insn;
B
blueswir1 已提交
4227
                    else {
B
blueswir1 已提交
4228 4229
                        TCGv r_const;

4230
                        save_state(dc, cpu_cond);
B
blueswir1 已提交
4231
                        r_const = tcg_const_i32(7);
B
blueswir1 已提交
4232
                        tcg_gen_helper_0_2(helper_check_align, cpu_addr,
B
blueswir1 已提交
4233 4234
                                           r_const); // XXX remove
                        tcg_temp_free(r_const);
B
blueswir1 已提交
4235
                        gen_address_mask(dc, cpu_addr);
4236
                        tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
4237 4238 4239
                        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 已提交
4240
                        tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
4241 4242
                        tcg_gen_trunc_i64_tl(cpu_val, cpu_tmp64);
                        tcg_gen_andi_tl(cpu_val, cpu_val, 0xffffffffULL);
B
blueswir1 已提交
4243
                    }
B
blueswir1 已提交
4244 4245
                    break;
                case 0x9:       /* load signed byte */
B
blueswir1 已提交
4246
                    gen_address_mask(dc, cpu_addr);
4247
                    tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4248 4249
                    break;
                case 0xa:       /* load signed halfword */
B
blueswir1 已提交
4250
                    gen_address_mask(dc, cpu_addr);
4251
                    tcg_gen_qemu_ld16s(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4252 4253
                    break;
                case 0xd:       /* ldstub -- XXX: should be atomically */
B
blueswir1 已提交
4254 4255 4256
                    {
                        TCGv r_const;

B
blueswir1 已提交
4257
                        gen_address_mask(dc, cpu_addr);
B
blueswir1 已提交
4258 4259 4260 4261 4262
                        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 已提交
4263
                    break;
B
blueswir1 已提交
4264 4265
                case 0x0f:      /* swap register with memory. Also
                                   atomically */
B
blueswir1 已提交
4266
                    CHECK_IU_FEATURE(dc, SWAP);
4267
                    gen_movl_reg_TN(rd, cpu_val);
B
blueswir1 已提交
4268
                    gen_address_mask(dc, cpu_addr);
4269 4270 4271
                    tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
                    tcg_gen_extu_i32_tl(cpu_val, cpu_tmp32);
B
blueswir1 已提交
4272
                    break;
B
bellard 已提交
4273
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
B
blueswir1 已提交
4274
                case 0x10:      /* load word alternate */
B
bellard 已提交
4275
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4276 4277 4278 4279
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
blueswir1 已提交
4280
#endif
4281
                    save_state(dc, cpu_cond);
4282
                    gen_ld_asi(cpu_val, cpu_addr, insn, 4, 0);
B
blueswir1 已提交
4283 4284
                    break;
                case 0x11:      /* load unsigned byte alternate */
B
bellard 已提交
4285
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4286 4287 4288 4289 4290
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
#endif
4291
                    save_state(dc, cpu_cond);
4292
                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 0);
B
blueswir1 已提交
4293 4294
                    break;
                case 0x12:      /* load unsigned halfword alternate */
B
bellard 已提交
4295
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4296 4297 4298 4299
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
bellard 已提交
4300
#endif
4301
                    save_state(dc, cpu_cond);
4302
                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 0);
B
blueswir1 已提交
4303 4304
                    break;
                case 0x13:      /* load double word alternate */
B
bellard 已提交
4305
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4306 4307 4308 4309
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
bellard 已提交
4310
#endif
B
blueswir1 已提交
4311
                    if (rd & 1)
4312
                        goto illegal_insn;
4313
                    save_state(dc, cpu_cond);
B
blueswir1 已提交
4314 4315
                    gen_ldda_asi(cpu_val, cpu_addr, insn, rd);
                    goto skip_move;
B
blueswir1 已提交
4316
                case 0x19:      /* load signed byte alternate */
B
bellard 已提交
4317
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4318 4319 4320 4321 4322
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
#endif
4323
                    save_state(dc, cpu_cond);
4324
                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 1);
B
blueswir1 已提交
4325 4326
                    break;
                case 0x1a:      /* load signed halfword alternate */
B
bellard 已提交
4327
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4328 4329 4330 4331
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
bellard 已提交
4332
#endif
4333
                    save_state(dc, cpu_cond);
4334
                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 1);
B
blueswir1 已提交
4335 4336
                    break;
                case 0x1d:      /* ldstuba -- XXX: should be atomically */
B
bellard 已提交
4337
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4338 4339 4340 4341 4342
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
#endif
4343
                    save_state(dc, cpu_cond);
4344
                    gen_ldstub_asi(cpu_val, cpu_addr, insn);
B
blueswir1 已提交
4345
                    break;
B
blueswir1 已提交
4346 4347
                case 0x1f:      /* swap reg with alt. memory. Also
                                   atomically */
B
blueswir1 已提交
4348
                    CHECK_IU_FEATURE(dc, SWAP);
B
bellard 已提交
4349
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4350 4351 4352 4353
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
blueswir1 已提交
4354
#endif
4355
                    save_state(dc, cpu_cond);
4356 4357
                    gen_movl_reg_TN(rd, cpu_val);
                    gen_swap_asi(cpu_val, cpu_addr, insn);
B
blueswir1 已提交
4358
                    break;
B
bellard 已提交
4359 4360

#ifndef TARGET_SPARC64
B
blueswir1 已提交
4361 4362 4363 4364
                case 0x30: /* ldc */
                case 0x31: /* ldcsr */
                case 0x33: /* lddc */
                    goto ncp_insn;
B
bellard 已提交
4365 4366 4367
#endif
#endif
#ifdef TARGET_SPARC64
B
blueswir1 已提交
4368
                case 0x08: /* V9 ldsw */
B
blueswir1 已提交
4369
                    gen_address_mask(dc, cpu_addr);
4370
                    tcg_gen_qemu_ld32s(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4371 4372
                    break;
                case 0x0b: /* V9 ldx */
B
blueswir1 已提交
4373
                    gen_address_mask(dc, cpu_addr);
4374
                    tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4375 4376
                    break;
                case 0x18: /* V9 ldswa */
4377
                    save_state(dc, cpu_cond);
4378
                    gen_ld_asi(cpu_val, cpu_addr, insn, 4, 1);
B
blueswir1 已提交
4379 4380
                    break;
                case 0x1b: /* V9 ldxa */
4381
                    save_state(dc, cpu_cond);
4382
                    gen_ld_asi(cpu_val, cpu_addr, insn, 8, 0);
B
blueswir1 已提交
4383 4384 4385 4386
                    break;
                case 0x2d: /* V9 prefetch, no effect */
                    goto skip_move;
                case 0x30: /* V9 ldfa */
4387
                    save_state(dc, cpu_cond);
4388
                    gen_ldf_asi(cpu_addr, insn, 4, rd);
4389
                    goto skip_move;
B
blueswir1 已提交
4390
                case 0x33: /* V9 lddfa */
4391
                    save_state(dc, cpu_cond);
4392
                    gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd));
4393
                    goto skip_move;
B
blueswir1 已提交
4394 4395 4396
                case 0x3d: /* V9 prefetcha, no effect */
                    goto skip_move;
                case 0x32: /* V9 ldqfa */
B
blueswir1 已提交
4397
                    CHECK_FPU_FEATURE(dc, FLOAT128);
4398
                    save_state(dc, cpu_cond);
4399
                    gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd));
B
blueswir1 已提交
4400
                    goto skip_move;
B
blueswir1 已提交
4401 4402 4403 4404
#endif
                default:
                    goto illegal_insn;
                }
4405
                gen_movl_TN_reg(rd, cpu_val);
B
blueswir1 已提交
4406
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
B
blueswir1 已提交
4407
            skip_move: ;
B
bellard 已提交
4408
#endif
B
blueswir1 已提交
4409
            } else if (xop >= 0x20 && xop < 0x24) {
4410
                if (gen_trap_ifnofpu(dc, cpu_cond))
B
bellard 已提交
4411
                    goto jmp_insn;
4412
                save_state(dc, cpu_cond);
B
blueswir1 已提交
4413 4414
                switch (xop) {
                case 0x20:      /* load fpreg */
B
blueswir1 已提交
4415
                    gen_address_mask(dc, cpu_addr);
4416
                    tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
4417 4418
                    tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUState, fpr[rd]));
B
blueswir1 已提交
4419 4420
                    break;
                case 0x21:      /* load fsr */
B
blueswir1 已提交
4421
                    gen_address_mask(dc, cpu_addr);
4422
                    tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
4423 4424
                    tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUState, ft0));
4425
                    tcg_gen_helper_0_0(helper_ldfsr);
B
blueswir1 已提交
4426 4427
                    break;
                case 0x22:      /* load quad fpreg */
B
blueswir1 已提交
4428 4429 4430 4431 4432 4433 4434 4435 4436
                    {
                        TCGv r_const;

                        CHECK_FPU_FEATURE(dc, FLOAT128);
                        r_const = tcg_const_i32(dc->mem_idx);
                        tcg_gen_helper_0_2(helper_ldqf, cpu_addr, r_const);
                        tcg_temp_free(r_const);
                        gen_op_store_QT0_fpr(QFPREG(rd));
                    }
B
blueswir1 已提交
4437
                    break;
B
blueswir1 已提交
4438
                case 0x23:      /* load double fpreg */
B
blueswir1 已提交
4439 4440 4441 4442 4443 4444 4445 4446
                    {
                        TCGv r_const;

                        r_const = tcg_const_i32(dc->mem_idx);
                        tcg_gen_helper_0_2(helper_lddf, cpu_addr, r_const);
                        tcg_temp_free(r_const);
                        gen_op_store_DT0_fpr(DFPREG(rd));
                    }
B
blueswir1 已提交
4447 4448 4449 4450 4451 4452
                    break;
                default:
                    goto illegal_insn;
                }
            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) || \
                       xop == 0xe || xop == 0x1e) {
4453
                gen_movl_reg_TN(rd, cpu_val);
B
blueswir1 已提交
4454
                switch (xop) {
B
blueswir1 已提交
4455
                case 0x4: /* store word */
B
blueswir1 已提交
4456
                    gen_address_mask(dc, cpu_addr);
4457
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4458
                    break;
B
blueswir1 已提交
4459
                case 0x5: /* store byte */
B
blueswir1 已提交
4460
                    gen_address_mask(dc, cpu_addr);
4461
                    tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4462
                    break;
B
blueswir1 已提交
4463
                case 0x6: /* store halfword */
B
blueswir1 已提交
4464
                    gen_address_mask(dc, cpu_addr);
4465
                    tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4466
                    break;
B
blueswir1 已提交
4467
                case 0x7: /* store double word */
B
blueswir1 已提交
4468
                    if (rd & 1)
4469
                        goto illegal_insn;
B
blueswir1 已提交
4470
                    else {
B
blueswir1 已提交
4471
                        TCGv r_low, r_const;
B
blueswir1 已提交
4472

4473
                        save_state(dc, cpu_cond);
B
blueswir1 已提交
4474
                        gen_address_mask(dc, cpu_addr);
B
blueswir1 已提交
4475
                        r_const = tcg_const_i32(7);
4476
                        tcg_gen_helper_0_2(helper_check_align, cpu_addr,
B
blueswir1 已提交
4477 4478
                                           r_const); // XXX remove
                        tcg_temp_free(r_const);
B
blueswir1 已提交
4479
                        r_low = tcg_temp_new(TCG_TYPE_TL);
B
blueswir1 已提交
4480
                        gen_movl_reg_TN(rd + 1, r_low);
4481
                        tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, cpu_val,
B
blueswir1 已提交
4482
                                           r_low);
B
blueswir1 已提交
4483
                        tcg_temp_free(r_low);
4484
                        tcg_gen_qemu_st64(cpu_tmp64, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4485
                    }
B
blueswir1 已提交
4486
                    break;
B
bellard 已提交
4487
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
B
blueswir1 已提交
4488
                case 0x14: /* store word alternate */
B
bellard 已提交
4489
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4490 4491 4492 4493
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
blueswir1 已提交
4494
#endif
4495
                    save_state(dc, cpu_cond);
4496
                    gen_st_asi(cpu_val, cpu_addr, insn, 4);
B
bellard 已提交
4497
                    break;
B
blueswir1 已提交
4498
                case 0x15: /* store byte alternate */
B
bellard 已提交
4499
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4500 4501 4502 4503
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
bellard 已提交
4504
#endif
4505
                    save_state(dc, cpu_cond);
4506
                    gen_st_asi(cpu_val, cpu_addr, insn, 1);
B
bellard 已提交
4507
                    break;
B
blueswir1 已提交
4508
                case 0x16: /* store halfword alternate */
B
bellard 已提交
4509
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4510 4511 4512 4513
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
blueswir1 已提交
4514
#endif
4515
                    save_state(dc, cpu_cond);
4516
                    gen_st_asi(cpu_val, cpu_addr, insn, 2);
B
bellard 已提交
4517
                    break;
B
blueswir1 已提交
4518
                case 0x17: /* store double word alternate */
B
bellard 已提交
4519
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4520 4521 4522 4523
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
bellard 已提交
4524
#endif
B
blueswir1 已提交
4525
                    if (rd & 1)
4526
                        goto illegal_insn;
B
blueswir1 已提交
4527
                    else {
4528
                        save_state(dc, cpu_cond);
4529
                        gen_stda_asi(cpu_val, cpu_addr, insn, rd);
B
blueswir1 已提交
4530
                    }
B
bellard 已提交
4531
                    break;
B
bellard 已提交
4532
#endif
B
bellard 已提交
4533
#ifdef TARGET_SPARC64
B
blueswir1 已提交
4534
                case 0x0e: /* V9 stx */
B
blueswir1 已提交
4535
                    gen_address_mask(dc, cpu_addr);
4536
                    tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4537 4538
                    break;
                case 0x1e: /* V9 stxa */
4539
                    save_state(dc, cpu_cond);
4540
                    gen_st_asi(cpu_val, cpu_addr, insn, 8);
B
blueswir1 已提交
4541
                    break;
B
bellard 已提交
4542
#endif
B
blueswir1 已提交
4543 4544 4545 4546
                default:
                    goto illegal_insn;
                }
            } else if (xop > 0x23 && xop < 0x28) {
4547
                if (gen_trap_ifnofpu(dc, cpu_cond))
B
bellard 已提交
4548
                    goto jmp_insn;
4549
                save_state(dc, cpu_cond);
B
blueswir1 已提交
4550
                switch (xop) {
4551
                case 0x24: /* store fpreg */
B
blueswir1 已提交
4552
                    gen_address_mask(dc, cpu_addr);
4553 4554
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUState, fpr[rd]));
4555
                    tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4556 4557
                    break;
                case 0x25: /* stfsr, V9 stxfsr */
B
blueswir1 已提交
4558
                    gen_address_mask(dc, cpu_addr);
B
blueswir1 已提交
4559
                    tcg_gen_helper_0_0(helper_stfsr);
4560 4561
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUState, ft0));
4562
                    tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4563
                    break;
B
blueswir1 已提交
4564 4565 4566
                case 0x26:
#ifdef TARGET_SPARC64
                    /* V9 stqf, store quad fpreg */
B
blueswir1 已提交
4567 4568 4569 4570 4571 4572 4573 4574 4575
                    {
                        TCGv r_const;

                        CHECK_FPU_FEATURE(dc, FLOAT128);
                        gen_op_load_fpr_QT0(QFPREG(rd));
                        r_const = tcg_const_i32(dc->mem_idx);
                        tcg_gen_helper_0_2(helper_stqf, cpu_addr, r_const);
                        tcg_temp_free(r_const);
                    }
B
blueswir1 已提交
4576 4577 4578 4579 4580 4581
                    break;
#else /* !TARGET_SPARC64 */
                    /* stdfq, store floating point queue */
#if defined(CONFIG_USER_ONLY)
                    goto illegal_insn;
#else
B
blueswir1 已提交
4582 4583
                    if (!supervisor(dc))
                        goto priv_insn;
4584
                    if (gen_trap_ifnofpu(dc, cpu_cond))
B
blueswir1 已提交
4585 4586
                        goto jmp_insn;
                    goto nfq_insn;
B
blueswir1 已提交
4587
#endif
B
blueswir1 已提交
4588
#endif
B
blueswir1 已提交
4589
                case 0x27: /* store double fpreg */
B
blueswir1 已提交
4590 4591 4592 4593 4594 4595 4596 4597
                    {
                        TCGv r_const;

                        gen_op_load_fpr_DT0(DFPREG(rd));
                        r_const = tcg_const_i32(dc->mem_idx);
                        tcg_gen_helper_0_2(helper_stdf, cpu_addr, r_const);
                        tcg_temp_free(r_const);
                    }
B
blueswir1 已提交
4598 4599 4600 4601 4602
                    break;
                default:
                    goto illegal_insn;
                }
            } else if (xop > 0x33 && xop < 0x3f) {
4603
                save_state(dc, cpu_cond);
B
blueswir1 已提交
4604
                switch (xop) {
4605
#ifdef TARGET_SPARC64
B
blueswir1 已提交
4606
                case 0x34: /* V9 stfa */
4607
                    gen_op_load_fpr_FT0(rd);
4608
                    gen_stf_asi(cpu_addr, insn, 4, rd);
B
blueswir1 已提交
4609
                    break;
B
blueswir1 已提交
4610
                case 0x36: /* V9 stqfa */
B
blueswir1 已提交
4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621
                    {
                        TCGv r_const;

                        CHECK_FPU_FEATURE(dc, FLOAT128);
                        r_const = tcg_const_i32(7);
                        tcg_gen_helper_0_2(helper_check_align, cpu_addr,
                                           r_const);
                        tcg_temp_free(r_const);
                        gen_op_load_fpr_QT0(QFPREG(rd));
                        gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd));
                    }
B
blueswir1 已提交
4622
                    break;
B
blueswir1 已提交
4623
                case 0x37: /* V9 stdfa */
4624
                    gen_op_load_fpr_DT0(DFPREG(rd));
4625
                    gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
B
blueswir1 已提交
4626 4627
                    break;
                case 0x3c: /* V9 casa */
B
blueswir1 已提交
4628
                    gen_cas_asi(cpu_val, cpu_addr, cpu_src2, insn, rd);
4629
                    gen_movl_TN_reg(rd, cpu_val);
B
blueswir1 已提交
4630 4631
                    break;
                case 0x3e: /* V9 casxa */
B
blueswir1 已提交
4632
                    gen_casx_asi(cpu_val, cpu_addr, cpu_src2, insn, rd);
4633
                    gen_movl_TN_reg(rd, cpu_val);
B
blueswir1 已提交
4634
                    break;
4635
#else
B
blueswir1 已提交
4636 4637 4638 4639 4640 4641 4642 4643 4644
                case 0x34: /* stc */
                case 0x35: /* stcsr */
                case 0x36: /* stdcq */
                case 0x37: /* stdc */
                    goto ncp_insn;
#endif
                default:
                    goto illegal_insn;
                }
4645
            }
B
blueswir1 已提交
4646 4647 4648 4649
            else
                goto illegal_insn;
        }
        break;
4650 4651
    }
    /* default case for non jump instructions */
B
bellard 已提交
4652
    if (dc->npc == DYNAMIC_PC) {
B
blueswir1 已提交
4653 4654
        dc->pc = DYNAMIC_PC;
        gen_op_next_insn();
B
bellard 已提交
4655 4656
    } else if (dc->npc == JUMP_PC) {
        /* we can do a static jump */
4657
        gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
B
bellard 已提交
4658 4659
        dc->is_br = 1;
    } else {
B
blueswir1 已提交
4660 4661
        dc->pc = dc->npc;
        dc->npc = dc->npc + 4;
4662
    }
B
bellard 已提交
4663
 jmp_insn:
4664 4665
    return;
 illegal_insn:
B
blueswir1 已提交
4666 4667 4668 4669 4670 4671 4672 4673 4674
    {
        TCGv r_const;

        save_state(dc, cpu_cond);
        r_const = tcg_const_i32(TT_ILL_INSN);
        tcg_gen_helper_0_1(raise_exception, r_const);
        tcg_temp_free(r_const);
        dc->is_br = 1;
    }
4675
    return;
B
blueswir1 已提交
4676
 unimp_flush:
B
blueswir1 已提交
4677 4678 4679 4680 4681 4682 4683 4684 4685
    {
        TCGv r_const;

        save_state(dc, cpu_cond);
        r_const = tcg_const_i32(TT_UNIMP_FLUSH);
        tcg_gen_helper_0_1(raise_exception, r_const);
        tcg_temp_free(r_const);
        dc->is_br = 1;
    }
B
blueswir1 已提交
4686
    return;
B
bellard 已提交
4687
#if !defined(CONFIG_USER_ONLY)
4688
 priv_insn:
B
blueswir1 已提交
4689 4690 4691 4692 4693 4694 4695 4696 4697
    {
        TCGv r_const;

        save_state(dc, cpu_cond);
        r_const = tcg_const_i32(TT_PRIV_INSN);
        tcg_gen_helper_0_1(raise_exception, r_const);
        tcg_temp_free(r_const);
        dc->is_br = 1;
    }
B
bellard 已提交
4698
    return;
B
blueswir1 已提交
4699
#endif
B
bellard 已提交
4700
 nfpu_insn:
4701
    save_state(dc, cpu_cond);
B
bellard 已提交
4702 4703
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
    dc->is_br = 1;
4704
    return;
B
blueswir1 已提交
4705
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
B
blueswir1 已提交
4706
 nfq_insn:
4707
    save_state(dc, cpu_cond);
B
blueswir1 已提交
4708 4709 4710 4711
    gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
    dc->is_br = 1;
    return;
#endif
4712 4713
#ifndef TARGET_SPARC64
 ncp_insn:
B
blueswir1 已提交
4714 4715 4716 4717 4718 4719 4720 4721 4722
    {
        TCGv r_const;

        save_state(dc, cpu_cond);
        r_const = tcg_const_i32(TT_NCP_INSN);
        tcg_gen_helper_0_1(raise_exception, r_const);
        tcg_temp_free(r_const);
        dc->is_br = 1;
    }
4723 4724
    return;
#endif
4725 4726
}

4727 4728
static inline void gen_intermediate_code_internal(TranslationBlock * tb,
                                                  int spc, CPUSPARCState *env)
4729
{
B
bellard 已提交
4730
    target_ulong pc_start, last_pc;
4731 4732
    uint16_t *gen_opc_end;
    DisasContext dc1, *dc = &dc1;
4733
    int j, lj = -1;
P
pbrook 已提交
4734 4735
    int num_insns;
    int max_insns;
4736 4737 4738

    memset(dc, 0, sizeof(DisasContext));
    dc->tb = tb;
B
bellard 已提交
4739
    pc_start = tb->pc;
4740
    dc->pc = pc_start;
B
bellard 已提交
4741
    last_pc = dc->pc;
B
bellard 已提交
4742
    dc->npc = (target_ulong) tb->cs_base;
B
blueswir1 已提交
4743
    dc->mem_idx = cpu_mmu_index(env);
4744 4745
    dc->def = env->def;
    if ((dc->def->features & CPU_FEATURE_FLOAT))
B
blueswir1 已提交
4746
        dc->fpu_enabled = cpu_fpu_enabled(env);
4747
    else
B
blueswir1 已提交
4748
        dc->fpu_enabled = 0;
B
blueswir1 已提交
4749 4750 4751
#ifdef TARGET_SPARC64
    dc->address_mask_32bit = env->pstate & PS_AM;
#endif
4752 4753
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;

B
blueswir1 已提交
4754
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
B
blueswir1 已提交
4755 4756
    cpu_tmp32 = tcg_temp_new(TCG_TYPE_I32);
    cpu_tmp64 = tcg_temp_new(TCG_TYPE_I64);
B
blueswir1 已提交
4757 4758 4759 4760

    cpu_dst = tcg_temp_local_new(TCG_TYPE_TL);

    // loads and stores
B
blueswir1 已提交
4761
    cpu_val = tcg_temp_local_new(TCG_TYPE_TL);
B
blueswir1 已提交
4762
    cpu_addr = tcg_temp_local_new(TCG_TYPE_TL);
B
blueswir1 已提交
4763

P
pbrook 已提交
4764 4765 4766 4767 4768
    num_insns = 0;
    max_insns = tb->cflags & CF_COUNT_MASK;
    if (max_insns == 0)
        max_insns = CF_COUNT_MASK;
    gen_icount_start();
4769
    do {
4770 4771 4772
        if (env->nb_breakpoints > 0) {
            for(j = 0; j < env->nb_breakpoints; j++) {
                if (env->breakpoints[j] == dc->pc) {
B
blueswir1 已提交
4773
                    if (dc->pc != pc_start)
4774
                        save_state(dc, cpu_cond);
B
blueswir1 已提交
4775
                    tcg_gen_helper_0_0(helper_debug);
B
bellard 已提交
4776
                    tcg_gen_exit_tb(0);
B
blueswir1 已提交
4777
                    dc->is_br = 1;
B
bellard 已提交
4778
                    goto exit_gen_loop;
4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792
                }
            }
        }
        if (spc) {
            if (loglevel > 0)
                fprintf(logfile, "Search PC...\n");
            j = gen_opc_ptr - gen_opc_buf;
            if (lj < j) {
                lj++;
                while (lj < j)
                    gen_opc_instr_start[lj++] = 0;
                gen_opc_pc[lj] = dc->pc;
                gen_opc_npc[lj] = dc->npc;
                gen_opc_instr_start[lj] = 1;
P
pbrook 已提交
4793
                gen_opc_icount[lj] = num_insns;
4794 4795
            }
        }
P
pbrook 已提交
4796 4797
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
            gen_io_start();
B
blueswir1 已提交
4798 4799
        last_pc = dc->pc;
        disas_sparc_insn(dc);
P
pbrook 已提交
4800
        num_insns++;
B
blueswir1 已提交
4801 4802 4803 4804 4805 4806

        if (dc->is_br)
            break;
        /* if the next PC is different, we abort now */
        if (dc->pc != (last_pc + 4))
            break;
B
bellard 已提交
4807 4808 4809 4810
        /* 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 已提交
4811 4812 4813
        /* if single step mode, we generate only one instruction and
           generate an exception */
        if (env->singlestep_enabled) {
B
blueswir1 已提交
4814
            tcg_gen_movi_tl(cpu_pc, dc->pc);
B
bellard 已提交
4815
            tcg_gen_exit_tb(0);
B
bellard 已提交
4816 4817
            break;
        }
4818
    } while ((gen_opc_ptr < gen_opc_end) &&
P
pbrook 已提交
4819 4820
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32) &&
             num_insns < max_insns);
B
bellard 已提交
4821 4822

 exit_gen_loop:
B
blueswir1 已提交
4823
    tcg_temp_free(cpu_addr);
B
blueswir1 已提交
4824
    tcg_temp_free(cpu_val);
B
blueswir1 已提交
4825
    tcg_temp_free(cpu_dst);
B
blueswir1 已提交
4826 4827 4828
    tcg_temp_free(cpu_tmp64);
    tcg_temp_free(cpu_tmp32);
    tcg_temp_free(cpu_tmp0);
P
pbrook 已提交
4829 4830
    if (tb->cflags & CF_LAST_IO)
        gen_io_end();
B
bellard 已提交
4831
    if (!dc->is_br) {
4832
        if (dc->pc != DYNAMIC_PC &&
B
bellard 已提交
4833 4834
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
            /* static PC and NPC: we can use direct chaining */
B
blueswir1 已提交
4835
            gen_goto_tb(dc, 0, dc->pc, dc->npc);
B
bellard 已提交
4836 4837
        } else {
            if (dc->pc != DYNAMIC_PC)
B
blueswir1 已提交
4838
                tcg_gen_movi_tl(cpu_pc, dc->pc);
4839
            save_npc(dc, cpu_cond);
B
bellard 已提交
4840
            tcg_gen_exit_tb(0);
B
bellard 已提交
4841 4842
        }
    }
P
pbrook 已提交
4843
    gen_icount_end(tb, num_insns);
4844
    *gen_opc_ptr = INDEX_op_end;
4845 4846 4847 4848 4849 4850 4851 4852 4853 4854
    if (spc) {
        j = gen_opc_ptr - gen_opc_buf;
        lj++;
        while (lj <= j)
            gen_opc_instr_start[lj++] = 0;
#if 0
        if (loglevel > 0) {
            page_dump(logfile);
        }
#endif
4855 4856
        gen_opc_jump_pc[0] = dc->jump_pc[0];
        gen_opc_jump_pc[1] = dc->jump_pc[1];
4857
    } else {
B
bellard 已提交
4858
        tb->size = last_pc + 4 - pc_start;
P
pbrook 已提交
4859
        tb->icount = num_insns;
4860
    }
4861
#ifdef DEBUG_DISAS
B
bellard 已提交
4862
    if (loglevel & CPU_LOG_TB_IN_ASM) {
B
blueswir1 已提交
4863 4864 4865 4866
        fprintf(logfile, "--------------\n");
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
        target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
        fprintf(logfile, "\n");
4867
    }
4868 4869 4870
#endif
}

4871
void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
4872
{
4873
    gen_intermediate_code_internal(tb, 0, env);
4874 4875
}

4876
void gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
4877
{
4878
    gen_intermediate_code_internal(tb, 1, env);
4879 4880
}

4881
void gen_intermediate_code_init(CPUSPARCState *env)
B
bellard 已提交
4882
{
B
blueswir1 已提交
4883
    unsigned int i;
4884
    static int inited;
B
blueswir1 已提交
4885 4886 4887 4888 4889 4890 4891 4892 4893 4894
    static const char * const gregnames[8] = {
        NULL, // g0 not used
        "g1",
        "g2",
        "g3",
        "g4",
        "g5",
        "g6",
        "g7",
    };
B
bellard 已提交
4895

B
blueswir1 已提交
4896 4897 4898 4899 4900
    /* init various static tables */
    if (!inited) {
        inited = 1;

        cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
B
blueswir1 已提交
4901 4902 4903
        cpu_regwptr = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
                                         offsetof(CPUState, regwptr),
                                         "regwptr");
B
blueswir1 已提交
4904
#ifdef TARGET_SPARC64
4905 4906 4907
        cpu_xcc = tcg_global_mem_new(TCG_TYPE_I32,
                                     TCG_AREG0, offsetof(CPUState, xcc),
                                     "xcc");
B
blueswir1 已提交
4908
#endif
B
bellard 已提交
4909
        cpu_cond = tcg_global_mem_new(TCG_TYPE_TL,
B
blueswir1 已提交
4910 4911
                                      TCG_AREG0, offsetof(CPUState, cond),
                                      "cond");
4912 4913 4914
        cpu_cc_src = tcg_global_mem_new(TCG_TYPE_TL,
                                        TCG_AREG0, offsetof(CPUState, cc_src),
                                        "cc_src");
B
blueswir1 已提交
4915 4916 4917
        cpu_cc_src2 = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
                                         offsetof(CPUState, cc_src2),
                                         "cc_src2");
4918 4919 4920 4921 4922 4923
        cpu_cc_dst = tcg_global_mem_new(TCG_TYPE_TL,
                                        TCG_AREG0, offsetof(CPUState, cc_dst),
                                        "cc_dst");
        cpu_psr = tcg_global_mem_new(TCG_TYPE_I32,
                                     TCG_AREG0, offsetof(CPUState, psr),
                                     "psr");
B
blueswir1 已提交
4924 4925 4926
        cpu_fsr = tcg_global_mem_new(TCG_TYPE_TL,
                                     TCG_AREG0, offsetof(CPUState, fsr),
                                     "fsr");
B
blueswir1 已提交
4927 4928 4929 4930 4931 4932
        cpu_pc = tcg_global_mem_new(TCG_TYPE_TL,
                                    TCG_AREG0, offsetof(CPUState, pc),
                                    "pc");
        cpu_npc = tcg_global_mem_new(TCG_TYPE_TL,
                                    TCG_AREG0, offsetof(CPUState, npc),
                                    "npc");
B
blueswir1 已提交
4933 4934 4935 4936
        for (i = 1; i < 8; i++)
            cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
                                              offsetof(CPUState, gregs[i]),
                                              gregnames[i]);
B
blueswir1 已提交
4937 4938 4939 4940 4941
        /* register helpers */

#undef DEF_HELPER
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
#include "helper.h"
B
blueswir1 已提交
4942
    }
B
bellard 已提交
4943
}
A
aurel32 已提交
4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963

void gen_pc_load(CPUState *env, TranslationBlock *tb,
                unsigned long searched_pc, int pc_pos, void *puc)
{
    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) {
        target_ulong t2 = (target_ulong)(unsigned long)puc;
        /* jump PC: use T2 and the jump targets of the translation */
        if (t2)
            env->npc = gen_opc_jump_pc[0];
        else
            env->npc = gen_opc_jump_pc[1];
    } else {
        env->npc = npc;
    }
}