translate.c 183.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 42
static TCGv cpu_env, cpu_T[2], cpu_regwptr;
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

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

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

B
bellard 已提交
66 67 68 69 70
// 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 已提交
71
#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
B
bellard 已提交
72 73

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

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

89 90
#define IS_IMM (insn & (1<<13))

B
blueswir1 已提交
91 92 93
/* floating point registers moves */
static void gen_op_load_fpr_FT0(unsigned int src)
{
B
blueswir1 已提交
94 95
    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 已提交
96
}
B
blueswir1 已提交
97 98 99

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

B
blueswir1 已提交
104 105
static void gen_op_store_FT0_fpr(unsigned int dst)
{
B
blueswir1 已提交
106 107
    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 已提交
108 109 110 111
}

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

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

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

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

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

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

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

B
blueswir1 已提交
202
#ifdef TARGET_ABI32
B
blueswir1 已提交
203
#define ABI32_MASK(addr) tcg_gen_andi_tl(addr, addr, 0xffffffffULL);
B
blueswir1 已提交
204 205 206
#else
#define ABI32_MASK(addr)
#endif
207

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

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

230
static inline void gen_goto_tb(DisasContext *s, int tb_num,
231 232 233 234 235 236 237 238
                               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 已提交
239
        tcg_gen_goto_tb(tb_num);
B
blueswir1 已提交
240 241
        tcg_gen_movi_tl(cpu_pc, pc);
        tcg_gen_movi_tl(cpu_npc, npc);
B
bellard 已提交
242
        tcg_gen_exit_tb((long)tb + tb_num);
243 244
    } else {
        /* jump to another page: currently not optimized */
B
blueswir1 已提交
245 246
        tcg_gen_movi_tl(cpu_pc, pc);
        tcg_gen_movi_tl(cpu_npc, npc);
B
bellard 已提交
247
        tcg_gen_exit_tb(0);
248 249 250
    }
}

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

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

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

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

280
static inline void gen_cc_clear_icc(void)
281 282
{
    tcg_gen_movi_i32(cpu_psr, 0);
283 284
}

285
#ifdef TARGET_SPARC64
286 287
static inline void gen_cc_clear_xcc(void)
{
288 289
    tcg_gen_movi_i32(cpu_xcc, 0);
}
290
#endif
291 292 293 294 295 296 297

/* old op:
    if (!T0)
        env->psr |= PSR_ZERO;
    if ((int32_t) T0 < 0)
        env->psr |= PSR_NEG;
*/
298
static inline void gen_cc_NZ_icc(TCGv dst)
299
{
B
blueswir1 已提交
300
    TCGv r_temp;
301 302 303 304
    int l1, l2;

    l1 = gen_new_label();
    l2 = gen_new_label();
B
blueswir1 已提交
305 306
    r_temp = tcg_temp_new(TCG_TYPE_TL);
    tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
P
pbrook 已提交
307
    tcg_gen_brcondi_tl(TCG_COND_NE, r_temp, 0, l1);
308 309
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_ZERO);
    gen_set_label(l1);
B
blueswir1 已提交
310
    tcg_gen_ext_i32_tl(r_temp, dst);
P
pbrook 已提交
311
    tcg_gen_brcondi_tl(TCG_COND_GE, r_temp, 0, l2);
312 313
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_NEG);
    gen_set_label(l2);
B
blueswir1 已提交
314
    tcg_temp_free(r_temp);
315 316
}

317
#ifdef TARGET_SPARC64
318 319 320 321 322 323
static inline void gen_cc_NZ_xcc(TCGv dst)
{
    int l1, l2;

    l1 = gen_new_label();
    l2 = gen_new_label();
P
pbrook 已提交
324
    tcg_gen_brcondi_tl(TCG_COND_NE, dst, 0, l1);
325 326
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_ZERO);
    gen_set_label(l1);
P
pbrook 已提交
327
    tcg_gen_brcondi_tl(TCG_COND_GE, dst, 0, l2);
328 329
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_NEG);
    gen_set_label(l2);
330
}
331
#endif
332 333 334 335 336

/* old op:
    if (T0 < src1)
        env->psr |= PSR_CARRY;
*/
337
static inline void gen_cc_C_add_icc(TCGv dst, TCGv src1)
338
{
B
blueswir1 已提交
339
    TCGv r_temp;
340 341 342
    int l1;

    l1 = gen_new_label();
B
blueswir1 已提交
343 344 345
    r_temp = tcg_temp_new(TCG_TYPE_TL);
    tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
    tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l1);
346 347
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
    gen_set_label(l1);
B
blueswir1 已提交
348
    tcg_temp_free(r_temp);
349 350
}

351
#ifdef TARGET_SPARC64
352 353 354
static inline void gen_cc_C_add_xcc(TCGv dst, TCGv src1)
{
    int l1;
355

356 357 358 359
    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);
360
}
361
#endif
362 363 364 365 366

/* old op:
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
        env->psr |= PSR_OVF;
*/
367
static inline void gen_cc_V_add_icc(TCGv dst, TCGv src1, TCGv src2)
368
{
369
    TCGv r_temp;
370 371 372 373

    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);
374 375 376
    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, (1 << 31));
B
blueswir1 已提交
377 378
    tcg_gen_shri_tl(r_temp, r_temp, 31 - PSR_OVF_SHIFT);
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
B
blueswir1 已提交
379
    tcg_temp_free(r_temp);
B
blueswir1 已提交
380
    tcg_gen_or_i32(cpu_psr, cpu_psr, cpu_tmp32);
381 382
}

383
#ifdef TARGET_SPARC64
384 385 386 387 388 389 390 391 392 393
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 已提交
394 395
    tcg_gen_shri_tl(r_temp, r_temp, 63 - PSR_OVF_SHIFT);
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
B
blueswir1 已提交
396
    tcg_temp_free(r_temp);
B
blueswir1 已提交
397
    tcg_gen_or_i32(cpu_xcc, cpu_xcc, cpu_tmp32);
398
}
399
#endif
400 401 402

static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
{
B
blueswir1 已提交
403
    TCGv r_temp, r_const;
404 405 406 407 408 409 410
    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);
411 412 413
    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, (1 << 31));
P
pbrook 已提交
414
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
B
blueswir1 已提交
415 416 417
    r_const = tcg_const_i32(TT_TOVF);
    tcg_gen_helper_0_1(raise_exception, r_const);
    tcg_temp_free(r_const);
418
    gen_set_label(l1);
B
blueswir1 已提交
419
    tcg_temp_free(r_temp);
420 421 422 423 424 425 426
}

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

    l1 = gen_new_label();
427 428
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
P
pbrook 已提交
429
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
430 431 432 433 434 435 436
    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 已提交
437
    TCGv r_const;
438 439

    l1 = gen_new_label();
440 441
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
P
pbrook 已提交
442
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
B
blueswir1 已提交
443 444 445
    r_const = tcg_const_i32(TT_TOVF);
    tcg_gen_helper_0_1(raise_exception, r_const);
    tcg_temp_free(r_const);
446 447 448
    gen_set_label(l1);
}

449
static inline void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2)
450
{
451
    tcg_gen_mov_tl(cpu_cc_src, src1);
452
    tcg_gen_mov_tl(cpu_cc_src2, src2);
453
    tcg_gen_add_tl(dst, src1, src2);
454
    tcg_gen_mov_tl(cpu_cc_dst, dst);
455
    gen_cc_clear_icc();
456 457 458
    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);
459 460
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
461 462 463
    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);
464
#endif
465 466
}

467
static inline void gen_op_addx_cc(TCGv dst, TCGv src1, TCGv src2)
468
{
469
    tcg_gen_mov_tl(cpu_cc_src, src1);
470
    tcg_gen_mov_tl(cpu_cc_src2, src2);
471
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
472
    tcg_gen_add_tl(dst, src1, cpu_tmp0);
473
    gen_cc_clear_icc();
474
    gen_cc_C_add_icc(dst, cpu_cc_src);
475 476
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
477
    gen_cc_C_add_xcc(dst, cpu_cc_src);
478
#endif
479
    tcg_gen_add_tl(dst, dst, cpu_cc_src2);
480 481 482 483
    tcg_gen_mov_tl(cpu_cc_dst, dst);
    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);
484
#ifdef TARGET_SPARC64
485 486 487
    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);
488
#endif
489 490
}

491
static inline void gen_op_tadd_cc(TCGv dst, TCGv src1, TCGv src2)
492
{
493
    tcg_gen_mov_tl(cpu_cc_src, src1);
494
    tcg_gen_mov_tl(cpu_cc_src2, src2);
495
    tcg_gen_add_tl(dst, src1, src2);
496
    tcg_gen_mov_tl(cpu_cc_dst, dst);
497
    gen_cc_clear_icc();
498 499 500
    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);
501
    gen_cc_V_tag(cpu_cc_src, cpu_cc_src2);
502 503
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
504 505 506
    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);
507
#endif
508 509
}

510
static inline void gen_op_tadd_ccTV(TCGv dst, TCGv src1, TCGv src2)
511
{
512
    tcg_gen_mov_tl(cpu_cc_src, src1);
513 514
    tcg_gen_mov_tl(cpu_cc_src2, src2);
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
515
    tcg_gen_add_tl(dst, src1, src2);
516
    tcg_gen_mov_tl(cpu_cc_dst, dst);
517
    gen_add_tv(dst, cpu_cc_src, cpu_cc_src2);
518
    gen_cc_clear_icc();
519 520
    gen_cc_NZ_icc(cpu_cc_dst);
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
521 522
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
523 524 525
    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);
526
#endif
527 528 529 530 531 532
}

/* old op:
    if (src1 < T1)
        env->psr |= PSR_CARRY;
*/
533
static inline void gen_cc_C_sub_icc(TCGv src1, TCGv src2)
534
{
B
blueswir1 已提交
535
    TCGv r_temp1, r_temp2;
536 537 538
    int l1;

    l1 = gen_new_label();
B
blueswir1 已提交
539 540 541 542 543
    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);
544 545
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
    gen_set_label(l1);
B
blueswir1 已提交
546 547
    tcg_temp_free(r_temp1);
    tcg_temp_free(r_temp2);
548 549
}

550
#ifdef TARGET_SPARC64
551 552 553
static inline void gen_cc_C_sub_xcc(TCGv src1, TCGv src2)
{
    int l1;
554

555 556 557 558
    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);
559
}
560
#endif
561 562 563 564 565

/* old op:
    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
        env->psr |= PSR_OVF;
*/
566
static inline void gen_cc_V_sub_icc(TCGv dst, TCGv src1, TCGv src2)
567
{
568
    TCGv r_temp;
569 570 571

    r_temp = tcg_temp_new(TCG_TYPE_TL);
    tcg_gen_xor_tl(r_temp, src1, src2);
572 573 574
    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, (1 << 31));
B
blueswir1 已提交
575 576 577
    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 已提交
578
    tcg_temp_free(r_temp);
579 580
}

581
#ifdef TARGET_SPARC64
582 583 584 585 586 587 588 589 590
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 已提交
591 592 593
    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 已提交
594
    tcg_temp_free(r_temp);
595
}
596
#endif
597 598 599

static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
{
B
blueswir1 已提交
600
    TCGv r_temp, r_const;
601 602 603 604 605 606
    int l1;

    l1 = gen_new_label();

    r_temp = tcg_temp_new(TCG_TYPE_TL);
    tcg_gen_xor_tl(r_temp, src1, src2);
607 608 609
    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, (1 << 31));
P
pbrook 已提交
610
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
B
blueswir1 已提交
611 612 613
    r_const = tcg_const_i32(TT_TOVF);
    tcg_gen_helper_0_1(raise_exception, r_const);
    tcg_temp_free(r_const);
614
    gen_set_label(l1);
B
blueswir1 已提交
615
    tcg_temp_free(r_temp);
616 617
}

618
static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2)
619
{
620
    tcg_gen_mov_tl(cpu_cc_src, src1);
621
    tcg_gen_mov_tl(cpu_cc_src2, src2);
622
    tcg_gen_sub_tl(dst, src1, src2);
623
    tcg_gen_mov_tl(cpu_cc_dst, dst);
624
    gen_cc_clear_icc();
625
    gen_cc_NZ_icc(cpu_cc_dst);
626
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
627
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
628 629
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
630
    gen_cc_NZ_xcc(cpu_cc_dst);
631
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
632
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
633
#endif
634 635
}

636
static inline void gen_op_subx_cc(TCGv dst, TCGv src1, TCGv src2)
637
{
638
    tcg_gen_mov_tl(cpu_cc_src, src1);
639
    tcg_gen_mov_tl(cpu_cc_src2, src2);
640
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
641
    tcg_gen_sub_tl(dst, src1, cpu_tmp0);
642
    gen_cc_clear_icc();
643
    gen_cc_C_sub_icc(dst, cpu_cc_src);
644 645
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
646
    gen_cc_C_sub_xcc(dst, cpu_cc_src);
647
#endif
648
    tcg_gen_sub_tl(dst, dst, cpu_cc_src2);
649 650 651 652
    tcg_gen_mov_tl(cpu_cc_dst, dst);
    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);
653
#ifdef TARGET_SPARC64
654 655 656
    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);
657
#endif
658 659
}

660
static inline void gen_op_tsub_cc(TCGv dst, TCGv src1, TCGv src2)
661
{
662
    tcg_gen_mov_tl(cpu_cc_src, src1);
663
    tcg_gen_mov_tl(cpu_cc_src2, src2);
664
    tcg_gen_sub_tl(dst, src1, src2);
665
    tcg_gen_mov_tl(cpu_cc_dst, dst);
666
    gen_cc_clear_icc();
667
    gen_cc_NZ_icc(cpu_cc_dst);
668
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
669
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
670
    gen_cc_V_tag(cpu_cc_src, cpu_cc_src2);
671 672
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
673
    gen_cc_NZ_xcc(cpu_cc_dst);
674
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
675
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
676
#endif
677 678
}

679
static inline void gen_op_tsub_ccTV(TCGv dst, TCGv src1, TCGv src2)
680
{
681
    tcg_gen_mov_tl(cpu_cc_src, src1);
682 683
    tcg_gen_mov_tl(cpu_cc_src2, src2);
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
684
    tcg_gen_sub_tl(dst, src1, src2);
685
    tcg_gen_mov_tl(cpu_cc_dst, dst);
686
    gen_sub_tv(dst, cpu_cc_src, cpu_cc_src2);
687
    gen_cc_clear_icc();
688
    gen_cc_NZ_icc(cpu_cc_dst);
689
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
690 691
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
692
    gen_cc_NZ_xcc(cpu_cc_dst);
693
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
694
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
695
#endif
696 697
}

698
static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
B
blueswir1 已提交
699
{
B
blueswir1 已提交
700
    TCGv r_temp, r_temp2;
701
    int l1;
B
blueswir1 已提交
702 703 704

    l1 = gen_new_label();
    r_temp = tcg_temp_new(TCG_TYPE_TL);
B
blueswir1 已提交
705
    r_temp2 = tcg_temp_new(TCG_TYPE_I32);
B
blueswir1 已提交
706 707 708 709 710

    /* old op:
    if (!(env->y & 1))
        T1 = 0;
    */
711
    tcg_gen_mov_tl(cpu_cc_src, src1);
B
blueswir1 已提交
712 713 714
    tcg_gen_ld32u_tl(r_temp, cpu_env, offsetof(CPUSPARCState, y));
    tcg_gen_trunc_tl_i32(r_temp2, r_temp);
    tcg_gen_andi_i32(r_temp2, r_temp2, 0x1);
715
    tcg_gen_mov_tl(cpu_cc_src2, src2);
P
pbrook 已提交
716
    tcg_gen_brcondi_i32(TCG_COND_NE, r_temp2, 0, l1);
B
blueswir1 已提交
717
    tcg_gen_movi_tl(cpu_cc_src2, 0);
718
    gen_set_label(l1);
B
blueswir1 已提交
719 720 721

    // b2 = T0 & 1;
    // env->y = (b2 << 31) | (env->y >> 1);
722
    tcg_gen_trunc_tl_i32(r_temp2, cpu_cc_src);
B
blueswir1 已提交
723 724
    tcg_gen_andi_i32(r_temp2, r_temp2, 0x1);
    tcg_gen_shli_i32(r_temp2, r_temp2, 31);
B
blueswir1 已提交
725 726
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, y));
    tcg_gen_shri_i32(cpu_tmp32, cpu_tmp32, 1);
B
blueswir1 已提交
727
    tcg_gen_or_i32(cpu_tmp32, cpu_tmp32, r_temp2);
B
blueswir1 已提交
728
    tcg_temp_free(r_temp2);
B
blueswir1 已提交
729
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, y));
B
blueswir1 已提交
730 731 732 733 734

    // 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 已提交
735
    tcg_temp_free(r_temp);
B
blueswir1 已提交
736 737 738 739

    // T0 = (b1 << 31) | (T0 >> 1);
    // src1 = T0;
    tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
740
    tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
B
blueswir1 已提交
741 742 743
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);

    /* do addition and update flags */
744
    tcg_gen_add_tl(dst, cpu_cc_src, cpu_cc_src2);
745
    tcg_gen_mov_tl(cpu_cc_dst, dst);
B
blueswir1 已提交
746

747
    gen_cc_clear_icc();
748 749 750
    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);
B
blueswir1 已提交
751 752
}

753
static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
B
blueswir1 已提交
754 755 756 757 758 759
{
    TCGv r_temp, r_temp2;

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

760 761
    tcg_gen_extu_tl_i64(r_temp, src2);
    tcg_gen_extu_tl_i64(r_temp2, src1);
B
blueswir1 已提交
762 763 764 765 766
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);

    tcg_gen_shri_i64(r_temp, r_temp2, 32);
    tcg_gen_trunc_i64_i32(r_temp, r_temp);
    tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
B
blueswir1 已提交
767
    tcg_temp_free(r_temp);
B
blueswir1 已提交
768
#ifdef TARGET_SPARC64
769
    tcg_gen_mov_i64(dst, r_temp2);
B
blueswir1 已提交
770
#else
771
    tcg_gen_trunc_i64_tl(dst, r_temp2);
B
blueswir1 已提交
772
#endif
B
blueswir1 已提交
773
    tcg_temp_free(r_temp2);
B
blueswir1 已提交
774 775
}

776
static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
B
blueswir1 已提交
777 778 779 780 781 782
{
    TCGv r_temp, r_temp2;

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

783 784
    tcg_gen_ext_tl_i64(r_temp, src2);
    tcg_gen_ext_tl_i64(r_temp2, src1);
B
blueswir1 已提交
785 786 787 788 789
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);

    tcg_gen_shri_i64(r_temp, r_temp2, 32);
    tcg_gen_trunc_i64_i32(r_temp, r_temp);
    tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
B
blueswir1 已提交
790
    tcg_temp_free(r_temp);
B
blueswir1 已提交
791
#ifdef TARGET_SPARC64
792
    tcg_gen_mov_i64(dst, r_temp2);
B
blueswir1 已提交
793
#else
794
    tcg_gen_trunc_i64_tl(dst, r_temp2);
B
blueswir1 已提交
795
#endif
B
blueswir1 已提交
796
    tcg_temp_free(r_temp2);
B
blueswir1 已提交
797 798
}

B
blueswir1 已提交
799
#ifdef TARGET_SPARC64
B
blueswir1 已提交
800
static inline void gen_trap_ifdivzero_tl(TCGv divisor)
B
blueswir1 已提交
801
{
B
blueswir1 已提交
802
    TCGv r_const;
B
blueswir1 已提交
803 804 805
    int l1;

    l1 = gen_new_label();
P
pbrook 已提交
806
    tcg_gen_brcondi_tl(TCG_COND_NE, divisor, 0, l1);
B
blueswir1 已提交
807 808 809
    r_const = tcg_const_i32(TT_DIV_ZERO);
    tcg_gen_helper_0_1(raise_exception, r_const);
    tcg_temp_free(r_const);
B
blueswir1 已提交
810 811 812
    gen_set_label(l1);
}

813
static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
B
blueswir1 已提交
814 815 816 817 818
{
    int l1, l2;

    l1 = gen_new_label();
    l2 = gen_new_label();
819 820
    tcg_gen_mov_tl(cpu_cc_src, src1);
    tcg_gen_mov_tl(cpu_cc_src2, src2);
821
    gen_trap_ifdivzero_tl(src2);
P
pbrook 已提交
822 823
    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);
824
    tcg_gen_movi_i64(dst, INT64_MIN);
B
blueswir1 已提交
825
    tcg_gen_br(l2);
B
blueswir1 已提交
826
    gen_set_label(l1);
827
    tcg_gen_div_i64(dst, cpu_cc_src, cpu_cc_src2);
B
blueswir1 已提交
828 829 830 831
    gen_set_label(l2);
}
#endif

832
static inline void gen_op_div_cc(TCGv dst)
833 834 835
{
    int l1;

836
    tcg_gen_mov_tl(cpu_cc_dst, dst);
837
    gen_cc_clear_icc();
838
    gen_cc_NZ_icc(cpu_cc_dst);
839
    l1 = gen_new_label();
B
blueswir1 已提交
840
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, cc_src2));
P
pbrook 已提交
841
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
842 843 844 845
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
    gen_set_label(l1);
}

846
static inline void gen_op_logic_cc(TCGv dst)
847
{
848 849
    tcg_gen_mov_tl(cpu_cc_dst, dst);

850
    gen_cc_clear_icc();
851
    gen_cc_NZ_icc(cpu_cc_dst);
852 853
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
854
    gen_cc_NZ_xcc(cpu_cc_dst);
855
#endif
856 857
}

858 859 860 861 862 863 864 865 866 867 868 869 870 871 872
// 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)
{
873
    gen_mov_reg_N(cpu_tmp0, src);
874
    gen_mov_reg_V(dst, src);
875 876 877
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
    gen_mov_reg_Z(cpu_tmp0, src);
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
878 879 880 881 882
}

// N ^ V
static inline void gen_op_eval_bl(TCGv dst, TCGv src)
{
883
    gen_mov_reg_V(cpu_tmp0, src);
884
    gen_mov_reg_N(dst, src);
885
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
886 887 888 889 890
}

// C | Z
static inline void gen_op_eval_bleu(TCGv dst, TCGv src)
{
891
    gen_mov_reg_Z(cpu_tmp0, src);
892
    gen_mov_reg_C(dst, src);
893
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929
}

// 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)
{
930
    gen_mov_reg_N(cpu_tmp0, src);
931
    gen_mov_reg_V(dst, src);
932 933 934
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
    gen_mov_reg_Z(cpu_tmp0, src);
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
935 936 937 938 939 940
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !(N ^ V)
static inline void gen_op_eval_bge(TCGv dst, TCGv src)
{
941
    gen_mov_reg_V(cpu_tmp0, src);
942
    gen_mov_reg_N(dst, src);
943
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
944 945 946 947 948 949
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !(C | Z)
static inline void gen_op_eval_bgu(TCGv dst, TCGv src)
{
950
    gen_mov_reg_Z(cpu_tmp0, src);
951
    gen_mov_reg_C(dst, src);
952
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986
    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)
{
B
blueswir1 已提交
987
    tcg_gen_extu_i32_tl(reg, src);
B
blueswir1 已提交
988
    tcg_gen_shri_tl(reg, reg, FSR_FCC0_SHIFT + fcc_offset);
989 990 991 992 993 994
    tcg_gen_andi_tl(reg, reg, 0x1);
}

static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
                                    unsigned int fcc_offset)
{
B
blueswir1 已提交
995
    tcg_gen_extu_i32_tl(reg, src);
B
blueswir1 已提交
996
    tcg_gen_shri_tl(reg, reg, FSR_FCC1_SHIFT + fcc_offset);
997 998 999 1000 1001 1002 1003 1004
    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);
1005 1006
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
1007 1008 1009 1010 1011 1012 1013
}

// 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);
1014 1015
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029
}

// 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);
1030 1031 1032
    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);
1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047
}

// 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);
1048 1049
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1050 1051 1052 1053 1054 1055 1056
}

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

// 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);
1066 1067
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
1068 1069 1070 1071 1072 1073 1074 1075
    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);
1076 1077
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093
    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);
1094 1095 1096
    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);
1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113
    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);
1114 1115
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1116 1117 1118 1119 1120 1121 1122 1123
    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);
1124 1125
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1126 1127 1128
    tcg_gen_xori_tl(dst, dst, 0x1);
}

B
blueswir1 已提交
1129
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
1130
                               target_ulong pc2, TCGv r_cond)
B
bellard 已提交
1131 1132 1133 1134 1135
{
    int l1;

    l1 = gen_new_label();

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

1138
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
B
bellard 已提交
1139 1140

    gen_set_label(l1);
1141
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
B
bellard 已提交
1142 1143
}

B
blueswir1 已提交
1144
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
1145
                                target_ulong pc2, TCGv r_cond)
B
bellard 已提交
1146 1147 1148 1149 1150
{
    int l1;

    l1 = gen_new_label();

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

1153
    gen_goto_tb(dc, 0, pc2, pc1);
B
bellard 已提交
1154 1155

    gen_set_label(l1);
1156
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
B
bellard 已提交
1157 1158
}

1159 1160
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
                                      TCGv r_cond)
B
bellard 已提交
1161 1162 1163 1164 1165
{
    int l1, l2;

    l1 = gen_new_label();
    l2 = gen_new_label();
1166

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

B
blueswir1 已提交
1169
    tcg_gen_movi_tl(cpu_npc, npc1);
B
blueswir1 已提交
1170
    tcg_gen_br(l2);
B
bellard 已提交
1171 1172

    gen_set_label(l1);
B
blueswir1 已提交
1173
    tcg_gen_movi_tl(cpu_npc, npc2);
B
bellard 已提交
1174 1175 1176
    gen_set_label(l2);
}

1177 1178 1179
/* 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 已提交
1180 1181
{
    if (dc->npc == JUMP_PC) {
1182
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
B
bellard 已提交
1183 1184 1185 1186
        dc->npc = DYNAMIC_PC;
    }
}

1187
static inline void save_npc(DisasContext *dc, TCGv cond)
B
bellard 已提交
1188 1189
{
    if (dc->npc == JUMP_PC) {
1190
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
B
bellard 已提交
1191 1192
        dc->npc = DYNAMIC_PC;
    } else if (dc->npc != DYNAMIC_PC) {
B
blueswir1 已提交
1193
        tcg_gen_movi_tl(cpu_npc, dc->npc);
B
bellard 已提交
1194 1195 1196
    }
}

1197
static inline void save_state(DisasContext *dc, TCGv cond)
B
bellard 已提交
1198
{
B
blueswir1 已提交
1199
    tcg_gen_movi_tl(cpu_pc, dc->pc);
1200
    save_npc(dc, cond);
B
bellard 已提交
1201 1202
}

1203
static inline void gen_mov_pc_npc(DisasContext *dc, TCGv cond)
B
bellard 已提交
1204 1205
{
    if (dc->npc == JUMP_PC) {
1206
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
B
blueswir1 已提交
1207
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
B
bellard 已提交
1208 1209
        dc->pc = DYNAMIC_PC;
    } else if (dc->npc == DYNAMIC_PC) {
B
blueswir1 已提交
1210
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
B
bellard 已提交
1211 1212 1213 1214 1215 1216
        dc->pc = DYNAMIC_PC;
    } else {
        dc->pc = dc->npc;
    }
}

1217 1218
static inline void gen_op_next_insn(void)
{
B
blueswir1 已提交
1219 1220
    tcg_gen_mov_tl(cpu_pc, cpu_npc);
    tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
1221 1222
}

1223 1224 1225
static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond)
{
    TCGv r_src;
B
bellard 已提交
1226 1227

#ifdef TARGET_SPARC64
1228
    if (cc)
1229
        r_src = cpu_xcc;
1230
    else
1231
        r_src = cpu_psr;
B
bellard 已提交
1232
#else
1233
    r_src = cpu_psr;
B
bellard 已提交
1234
#endif
1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 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
    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;
    }
}
1286

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

1359
#ifdef TARGET_SPARC64
1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370
// 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,
};
1371

1372
static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
1373 1374 1375 1376
{
    int l1;

    l1 = gen_new_label();
1377
    tcg_gen_movi_tl(r_dst, 0);
P
pbrook 已提交
1378
    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], r_src, 0, l1);
1379 1380 1381
    tcg_gen_movi_tl(r_dst, 1);
    gen_set_label(l1);
}
B
bellard 已提交
1382
#endif
1383

B
bellard 已提交
1384
/* XXX: potentially incorrect if dynamic npc */
1385 1386
static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
                      TCGv r_cond)
1387
{
1388
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1389
    target_ulong target = dc->pc + offset;
1390

1391
    if (cond == 0x0) {
B
blueswir1 已提交
1392 1393 1394 1395 1396 1397 1398 1399
        /* 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;
        }
1400
    } else if (cond == 0x8) {
B
blueswir1 已提交
1401 1402 1403 1404 1405 1406 1407 1408
        /* unconditional taken */
        if (a) {
            dc->pc = target;
            dc->npc = dc->pc + 4;
        } else {
            dc->pc = dc->npc;
            dc->npc = target;
        }
1409
    } else {
1410 1411
        flush_cond(dc, r_cond);
        gen_cond(r_cond, cc, cond);
B
blueswir1 已提交
1412
        if (a) {
1413
            gen_branch_a(dc, target, dc->npc, r_cond);
1414
            dc->is_br = 1;
B
blueswir1 已提交
1415
        } else {
1416
            dc->pc = dc->npc;
B
bellard 已提交
1417 1418 1419
            dc->jump_pc[0] = target;
            dc->jump_pc[1] = dc->npc + 4;
            dc->npc = JUMP_PC;
B
blueswir1 已提交
1420
        }
1421
    }
1422 1423
}

B
bellard 已提交
1424
/* XXX: potentially incorrect if dynamic npc */
1425 1426
static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
                      TCGv r_cond)
1427 1428
{
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1429 1430
    target_ulong target = dc->pc + offset;

1431
    if (cond == 0x0) {
B
blueswir1 已提交
1432 1433 1434 1435 1436 1437 1438 1439
        /* 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;
        }
1440
    } else if (cond == 0x8) {
B
blueswir1 已提交
1441 1442 1443 1444 1445 1446 1447 1448
        /* unconditional taken */
        if (a) {
            dc->pc = target;
            dc->npc = dc->pc + 4;
        } else {
            dc->pc = dc->npc;
            dc->npc = target;
        }
1449
    } else {
1450 1451
        flush_cond(dc, r_cond);
        gen_fcond(r_cond, cc, cond);
B
blueswir1 已提交
1452
        if (a) {
1453
            gen_branch_a(dc, target, dc->npc, r_cond);
1454
            dc->is_br = 1;
B
blueswir1 已提交
1455
        } else {
1456 1457 1458 1459
            dc->pc = dc->npc;
            dc->jump_pc[0] = target;
            dc->jump_pc[1] = dc->npc + 4;
            dc->npc = JUMP_PC;
B
blueswir1 已提交
1460
        }
1461 1462 1463
    }
}

B
bellard 已提交
1464 1465
#ifdef TARGET_SPARC64
/* XXX: potentially incorrect if dynamic npc */
1466 1467
static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
                          TCGv r_cond, TCGv r_reg)
1468
{
B
bellard 已提交
1469 1470 1471
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
    target_ulong target = dc->pc + offset;

1472 1473
    flush_cond(dc, r_cond);
    gen_cond_reg(r_cond, cond, r_reg);
B
bellard 已提交
1474
    if (a) {
1475
        gen_branch_a(dc, target, dc->npc, r_cond);
B
blueswir1 已提交
1476
        dc->is_br = 1;
B
bellard 已提交
1477
    } else {
B
blueswir1 已提交
1478 1479 1480 1481
        dc->pc = dc->npc;
        dc->jump_pc[0] = target;
        dc->jump_pc[1] = dc->npc + 4;
        dc->npc = JUMP_PC;
B
bellard 已提交
1482
    }
1483 1484
}

B
bellard 已提交
1485
static GenOpFunc * const gen_fcmps[4] = {
1486 1487 1488 1489
    helper_fcmps,
    helper_fcmps_fcc1,
    helper_fcmps_fcc2,
    helper_fcmps_fcc3,
B
bellard 已提交
1490 1491 1492
};

static GenOpFunc * const gen_fcmpd[4] = {
1493 1494 1495 1496
    helper_fcmpd,
    helper_fcmpd_fcc1,
    helper_fcmpd_fcc2,
    helper_fcmpd_fcc3,
B
bellard 已提交
1497
};
1498

B
blueswir1 已提交
1499
static GenOpFunc * const gen_fcmpq[4] = {
1500 1501 1502 1503
    helper_fcmpq,
    helper_fcmpq_fcc1,
    helper_fcmpq_fcc2,
    helper_fcmpq_fcc3,
B
blueswir1 已提交
1504 1505
};

1506
static GenOpFunc * const gen_fcmpes[4] = {
1507 1508 1509 1510
    helper_fcmpes,
    helper_fcmpes_fcc1,
    helper_fcmpes_fcc2,
    helper_fcmpes_fcc3,
1511 1512 1513
};

static GenOpFunc * const gen_fcmped[4] = {
1514 1515 1516 1517
    helper_fcmped,
    helper_fcmped_fcc1,
    helper_fcmped_fcc2,
    helper_fcmped_fcc3,
1518 1519
};

B
blueswir1 已提交
1520
static GenOpFunc * const gen_fcmpeq[4] = {
1521 1522 1523 1524
    helper_fcmpeq,
    helper_fcmpeq_fcc1,
    helper_fcmpeq_fcc2,
    helper_fcmpeq_fcc3,
B
blueswir1 已提交
1525
};
1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 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

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 已提交
1590 1591
static inline void gen_op_fpexception_im(int fsr_flags)
{
B
blueswir1 已提交
1592 1593
    TCGv r_const;

B
blueswir1 已提交
1594 1595
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~FSR_FTT_MASK);
    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
B
blueswir1 已提交
1596 1597 1598
    r_const = tcg_const_i32(TT_FP_EXCP);
    tcg_gen_helper_0_1(raise_exception, r_const);
    tcg_temp_free(r_const);
B
blueswir1 已提交
1599 1600
}

1601
static int gen_trap_ifnofpu(DisasContext *dc, TCGv r_cond)
B
bellard 已提交
1602 1603 1604
{
#if !defined(CONFIG_USER_ONLY)
    if (!dc->fpu_enabled) {
B
blueswir1 已提交
1605 1606
        TCGv r_const;

1607
        save_state(dc, r_cond);
B
blueswir1 已提交
1608 1609 1610
        r_const = tcg_const_i32(TT_NFPU_INSN);
        tcg_gen_helper_0_1(raise_exception, r_const);
        tcg_temp_free(r_const);
B
bellard 已提交
1611 1612 1613 1614 1615 1616 1617
        dc->is_br = 1;
        return 1;
    }
#endif
    return 0;
}

1618 1619
static inline void gen_op_clear_ieee_excp_and_FTT(void)
{
B
blueswir1 已提交
1620
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~(FSR_FTT_MASK | FSR_CEXC_MASK));
1621 1622 1623 1624 1625 1626 1627
}

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

B
blueswir1 已提交
1628 1629
/* asi moves */
#ifdef TARGET_SPARC64
1630
static inline TCGv gen_get_asi(int insn, TCGv r_addr)
B
blueswir1 已提交
1631 1632
{
    int asi, offset;
1633
    TCGv r_asi;
B
blueswir1 已提交
1634 1635

    if (IS_IMM) {
1636
        r_asi = tcg_temp_new(TCG_TYPE_I32);
B
blueswir1 已提交
1637
        offset = GET_FIELD(insn, 25, 31);
1638 1639
        tcg_gen_addi_tl(r_addr, r_addr, offset);
        tcg_gen_ld_i32(r_asi, cpu_env, offsetof(CPUSPARCState, asi));
B
blueswir1 已提交
1640 1641
    } else {
        asi = GET_FIELD(insn, 19, 26);
1642
        r_asi = tcg_const_i32(asi);
B
blueswir1 已提交
1643
    }
1644 1645 1646
    return r_asi;
}

B
blueswir1 已提交
1647 1648
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
                              int sign)
1649
{
B
blueswir1 已提交
1650
    TCGv r_asi, r_size, r_sign;
1651

1652
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1653 1654 1655 1656 1657 1658
    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 已提交
1659 1660
}

1661
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
B
blueswir1 已提交
1662
{
B
blueswir1 已提交
1663
    TCGv r_asi, r_size;
B
blueswir1 已提交
1664

1665
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1666 1667 1668 1669
    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 已提交
1670 1671
}

1672
static inline void gen_ldf_asi(TCGv addr, int insn, int size, int rd)
B
blueswir1 已提交
1673
{
B
blueswir1 已提交
1674
    TCGv r_asi, r_size, r_rd;
B
blueswir1 已提交
1675

1676
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1677 1678 1679 1680 1681 1682
    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 已提交
1683 1684
}

1685
static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
B
blueswir1 已提交
1686
{
B
blueswir1 已提交
1687
    TCGv r_asi, r_size, r_rd;
B
blueswir1 已提交
1688

1689
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1690 1691 1692 1693 1694 1695
    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 已提交
1696 1697
}

1698
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
B
blueswir1 已提交
1699
{
B
blueswir1 已提交
1700
    TCGv r_asi, r_size, r_sign;
B
blueswir1 已提交
1701

1702
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1703 1704 1705 1706 1707 1708 1709
    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 已提交
1710
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
B
blueswir1 已提交
1711 1712
}

1713
static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn)
B
blueswir1 已提交
1714
{
B
blueswir1 已提交
1715
    TCGv r_asi, r_size, r_sign;
B
blueswir1 已提交
1716

1717
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1718 1719 1720 1721 1722 1723
    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);
1724
    tcg_gen_andi_i64(lo, cpu_tmp64, 0xffffffffULL);
B
blueswir1 已提交
1725
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1726
    tcg_gen_andi_i64(hi, cpu_tmp64, 0xffffffffULL);
1727 1728
}

1729
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1730
{
B
blueswir1 已提交
1731
    TCGv r_temp, r_asi, r_size;
1732

B
blueswir1 已提交
1733
    r_temp = tcg_temp_new(TCG_TYPE_TL);
1734
    gen_movl_reg_TN(rd + 1, r_temp);
1735
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi,
1736
                       r_temp);
B
blueswir1 已提交
1737
    tcg_temp_free(r_temp);
1738
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1739 1740 1741 1742
    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 已提交
1743 1744
}

B
blueswir1 已提交
1745 1746
static inline void gen_cas_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
                               int rd)
B
blueswir1 已提交
1747 1748 1749
{
    TCGv r_val1, r_asi;

B
blueswir1 已提交
1750
    r_val1 = tcg_temp_new(TCG_TYPE_TL);
B
blueswir1 已提交
1751
    gen_movl_reg_TN(rd, r_val1);
1752 1753
    r_asi = gen_get_asi(insn, addr);
    tcg_gen_helper_1_4(helper_cas_asi, dst, addr, r_val1, val2, r_asi);
B
blueswir1 已提交
1754 1755
    tcg_temp_free(r_asi);
    tcg_temp_free(r_val1);
B
blueswir1 已提交
1756 1757
}

B
blueswir1 已提交
1758 1759
static inline void gen_casx_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
                                int rd)
B
blueswir1 已提交
1760
{
B
blueswir1 已提交
1761
    TCGv r_asi;
B
blueswir1 已提交
1762

B
blueswir1 已提交
1763
    gen_movl_reg_TN(rd, cpu_tmp64);
1764 1765
    r_asi = gen_get_asi(insn, addr);
    tcg_gen_helper_1_4(helper_casx_asi, dst, addr, cpu_tmp64, val2, r_asi);
B
blueswir1 已提交
1766
    tcg_temp_free(r_asi);
B
blueswir1 已提交
1767 1768 1769 1770
}

#elif !defined(CONFIG_USER_ONLY)

B
blueswir1 已提交
1771 1772
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
                              int sign)
B
blueswir1 已提交
1773
{
B
blueswir1 已提交
1774
    TCGv r_asi, r_size, r_sign;
B
blueswir1 已提交
1775

B
blueswir1 已提交
1776 1777 1778 1779 1780 1781 1782
    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);
1783
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
B
blueswir1 已提交
1784 1785
}

1786
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
B
blueswir1 已提交
1787
{
B
blueswir1 已提交
1788
    TCGv r_asi, r_size;
B
blueswir1 已提交
1789

1790
    tcg_gen_extu_tl_i64(cpu_tmp64, src);
B
blueswir1 已提交
1791 1792 1793 1794 1795
    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 已提交
1796 1797
}

1798
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
B
blueswir1 已提交
1799
{
B
blueswir1 已提交
1800
    TCGv r_asi, r_size, r_sign;
B
blueswir1 已提交
1801

B
blueswir1 已提交
1802 1803 1804 1805 1806 1807 1808 1809
    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 已提交
1810
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
B
blueswir1 已提交
1811 1812
}

1813
static inline void gen_ldda_asi(TCGv lo, TCGv hi, TCGv addr, int insn)
B
blueswir1 已提交
1814
{
B
blueswir1 已提交
1815
    TCGv r_asi, r_size, r_sign;
B
blueswir1 已提交
1816

B
blueswir1 已提交
1817 1818 1819 1820 1821 1822 1823
    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);
1824
    tcg_gen_trunc_i64_tl(lo, cpu_tmp64);
B
blueswir1 已提交
1825
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1826
    tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
1827 1828
}

1829
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1830
{
B
blueswir1 已提交
1831
    TCGv r_temp, r_asi, r_size;
1832

B
blueswir1 已提交
1833
    r_temp = tcg_temp_new(TCG_TYPE_TL);
1834
    gen_movl_reg_TN(rd + 1, r_temp);
1835
    tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, hi, r_temp);
B
blueswir1 已提交
1836 1837 1838 1839 1840 1841
    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 已提交
1842 1843 1844 1845
}
#endif

#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1846
static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
B
blueswir1 已提交
1847
{
B
blueswir1 已提交
1848
    TCGv r_val, r_asi, r_size;
B
blueswir1 已提交
1849

1850
    gen_ld_asi(dst, addr, insn, 1, 0);
B
blueswir1 已提交
1851

B
blueswir1 已提交
1852 1853 1854 1855 1856 1857 1858
    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 已提交
1859 1860 1861
}
#endif

1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878
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)
        //r_rs1 = tcg_const_tl(0);
        tcg_gen_movi_tl(def, 0);
    else if (rs1 < 8)
        //r_rs1 = cpu_gregs[rs1];
        tcg_gen_mov_tl(def, cpu_gregs[rs1]);
    else
        tcg_gen_ld_tl(def, cpu_regwptr, (rs1 - 8) * sizeof(target_ulong));
    return r_rs1;
}

B
blueswir1 已提交
1879 1880 1881 1882 1883 1884 1885
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 已提交
1886
        r_rs2 = tcg_const_tl((int)rs2); // XXX how to free?
B
blueswir1 已提交
1887 1888 1889
    } else { /* register */
        rs2 = GET_FIELD(insn, 27, 31);
        if (rs2 == 0)
B
blueswir1 已提交
1890
            r_rs2 = tcg_const_tl(0); // XXX how to free?
B
blueswir1 已提交
1891 1892 1893 1894 1895 1896 1897 1898
        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 已提交
1899 1900 1901 1902 1903 1904 1905
#define CHECK_IU_FEATURE(dc, FEATURE)                      \
    if (!((dc)->features & CPU_FEATURE_ ## FEATURE))       \
        goto illegal_insn;
#define CHECK_FPU_FEATURE(dc, FEATURE)                     \
    if (!((dc)->features & CPU_FEATURE_ ## FEATURE))       \
        goto nfpu_insn;

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

B
blueswir1 已提交
1911 1912
    if (unlikely(loglevel & CPU_LOG_TB_OP))
        tcg_gen_debug_insn_start(dc->pc);
B
bellard 已提交
1913
    insn = ldl_code(dc->pc);
1914
    opc = GET_FIELD(insn, 0, 1);
1915

1916
    rd = GET_FIELD(insn, 2, 6);
1917 1918 1919 1920 1921 1922 1923 1924 1925

    cpu_dst = cpu_T[0];
    cpu_src1 = cpu_T[0]; // const
    cpu_src2 = cpu_T[1]; // const

    // loads and stores
    cpu_addr = cpu_T[0];
    cpu_val = cpu_T[1];

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

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

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

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

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

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

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

                        r_tickptr = tcg_temp_new(TCG_TYPE_PTR);
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                       offsetof(CPUState, stick));
2148
                        tcg_gen_helper_1_1(helper_tick_get_count, cpu_dst,
B
blueswir1 已提交
2149
                                           r_tickptr);
B
blueswir1 已提交
2150
                        tcg_temp_free(r_tickptr);
2151
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
2152
                    }
B
bellard 已提交
2153
                    break;
B
blueswir1 已提交
2154
                case 0x19: /* System tick compare */
B
blueswir1 已提交
2155 2156
                    tcg_gen_ld_tl(cpu_dst, cpu_env,
                                  offsetof(CPUSPARCState, stick_cmpr));
2157
                    gen_movl_TN_reg(rd, cpu_dst);
B
bellard 已提交
2158
                    break;
B
blueswir1 已提交
2159 2160 2161 2162 2163 2164
                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 已提交
2165 2166
#endif
                default:
2167 2168
                    goto illegal_insn;
                }
2169
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
2170
            } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
B
bellard 已提交
2171
#ifndef TARGET_SPARC64
B
blueswir1 已提交
2172 2173
                if (!supervisor(dc))
                    goto priv_insn;
2174
                tcg_gen_helper_1_0(helper_rdpsr, cpu_dst);
B
blueswir1 已提交
2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186
#else
                if (!hypervisor(dc))
                    goto priv_insn;
                rs1 = GET_FIELD(insn, 13, 17);
                switch (rs1) {
                case 0: // hpstate
                    // gen_op_rdhpstate();
                    break;
                case 1: // htstate
                    // gen_op_rdhtstate();
                    break;
                case 3: // hintp
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
                    tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
B
blueswir1 已提交
2203 2204
                    tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, hstick_cmpr));
B
blueswir1 已提交
2205 2206 2207 2208 2209
                    break;
                default:
                    goto illegal_insn;
                }
#endif
2210
                gen_movl_TN_reg(rd, cpu_dst);
2211
                break;
B
bellard 已提交
2212
            } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
B
blueswir1 已提交
2213 2214
                if (!supervisor(dc))
                    goto priv_insn;
B
bellard 已提交
2215 2216
#ifdef TARGET_SPARC64
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
2217 2218
                switch (rs1) {
                case 0: // tpc
2219 2220 2221 2222 2223 2224
                    {
                        TCGv r_tsptr;

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

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

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

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

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

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

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

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

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

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

B
blueswir1 已提交
2886
                        rs2 = GET_FIELDs(insn, 19, 31);
B
blueswir1 已提交
2887 2888 2889
                        r_const = tcg_const_tl((int)rs2);
                        gen_movl_TN_reg(rd, r_const);
                        tcg_temp_free(r_const);
B
blueswir1 已提交
2890 2891
                    } else {            /* register */
                        rs2 = GET_FIELD(insn, 27, 31);
2892
                        gen_movl_reg_TN(rs2, cpu_dst);
B
blueswir1 已提交
2893
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
2894 2895
                    }
                } else {
2896
                    cpu_src1 = get_src1(insn, cpu_src1);
B
blueswir1 已提交
2897 2898
                    if (IS_IMM) {       /* immediate */
                        rs2 = GET_FIELDs(insn, 19, 31);
2899
                        tcg_gen_ori_tl(cpu_dst, cpu_src1, (int)rs2);
B
blueswir1 已提交
2900
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
2901 2902 2903 2904
                    } else {            /* register */
                        // or x, %g0, y -> mov T1, x; mov y, T1
                        rs2 = GET_FIELD(insn, 27, 31);
                        if (rs2 != 0) {
2905 2906
                            gen_movl_reg_TN(rs2, cpu_src2);
                            tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
B
blueswir1 已提交
2907
                            gen_movl_TN_reg(rd, cpu_dst);
2908
                        } else
B
blueswir1 已提交
2909
                            gen_movl_TN_reg(rd, cpu_src1);
B
blueswir1 已提交
2910 2911
                    }
                }
B
bellard 已提交
2912
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2913
            } else if (xop == 0x25) { /* sll, V9 sllx */
2914
                cpu_src1 = get_src1(insn, cpu_src1);
B
blueswir1 已提交
2915
                if (IS_IMM) {   /* immediate */
B
bellard 已提交
2916
                    rs2 = GET_FIELDs(insn, 20, 31);
B
blueswir1 已提交
2917
                    if (insn & (1 << 12)) {
2918
                        tcg_gen_shli_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
B
blueswir1 已提交
2919
                    } else {
2920 2921
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
                        tcg_gen_shli_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
B
blueswir1 已提交
2922
                    }
B
blueswir1 已提交
2923
                } else {                /* register */
B
bellard 已提交
2924
                    rs2 = GET_FIELD(insn, 27, 31);
2925
                    gen_movl_reg_TN(rs2, cpu_src2);
B
blueswir1 已提交
2926
                    if (insn & (1 << 12)) {
2927 2928
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
                        tcg_gen_shl_i64(cpu_dst, cpu_src1, cpu_tmp0);
B
blueswir1 已提交
2929
                    } else {
2930 2931 2932
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
                        tcg_gen_shl_i64(cpu_dst, cpu_dst, cpu_tmp0);
B
blueswir1 已提交
2933
                    }
B
bellard 已提交
2934
                }
2935
                gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
2936
            } else if (xop == 0x26) { /* srl, V9 srlx */
2937
                cpu_src1 = get_src1(insn, cpu_src1);
B
blueswir1 已提交
2938
                if (IS_IMM) {   /* immediate */
B
bellard 已提交
2939
                    rs2 = GET_FIELDs(insn, 20, 31);
B
blueswir1 已提交
2940
                    if (insn & (1 << 12)) {
2941
                        tcg_gen_shri_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
B
blueswir1 已提交
2942
                    } else {
2943 2944
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
                        tcg_gen_shri_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
B
blueswir1 已提交
2945
                    }
B
blueswir1 已提交
2946
                } else {                /* register */
B
bellard 已提交
2947
                    rs2 = GET_FIELD(insn, 27, 31);
2948
                    gen_movl_reg_TN(rs2, cpu_src2);
B
blueswir1 已提交
2949
                    if (insn & (1 << 12)) {
2950 2951
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
                        tcg_gen_shr_i64(cpu_dst, cpu_src1, cpu_tmp0);
B
blueswir1 已提交
2952
                    } else {
2953 2954 2955
                        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 已提交
2956
                    }
B
bellard 已提交
2957
                }
2958
                gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
2959
            } else if (xop == 0x27) { /* sra, V9 srax */
2960
                cpu_src1 = get_src1(insn, cpu_src1);
B
blueswir1 已提交
2961
                if (IS_IMM) {   /* immediate */
B
bellard 已提交
2962
                    rs2 = GET_FIELDs(insn, 20, 31);
B
blueswir1 已提交
2963
                    if (insn & (1 << 12)) {
2964
                        tcg_gen_sari_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
B
blueswir1 已提交
2965
                    } else {
2966 2967 2968
                        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 已提交
2969
                    }
B
blueswir1 已提交
2970
                } else {                /* register */
B
bellard 已提交
2971
                    rs2 = GET_FIELD(insn, 27, 31);
2972
                    gen_movl_reg_TN(rs2, cpu_src2);
B
blueswir1 已提交
2973
                    if (insn & (1 << 12)) {
2974 2975
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
                        tcg_gen_sar_i64(cpu_dst, cpu_src1, cpu_tmp0);
B
blueswir1 已提交
2976
                    } else {
2977 2978 2979
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
                        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
                        gen_trap_ifdivzero_tl(cpu_src2);
                        tcg_gen_divu_i64(cpu_dst, cpu_src1, cpu_src2);
P
pbrook 已提交
3073 3074
                        break;
#endif
3075
                    case 0xe:
B
blueswir1 已提交
3076
                        CHECK_IU_FEATURE(dc, DIV);
B
blueswir1 已提交
3077 3078
                        tcg_gen_helper_1_2(helper_udiv, cpu_dst, cpu_src1,
                                           cpu_src2);
3079
                        if (xop & 0x10)
3080
                            gen_op_div_cc(cpu_dst);
3081 3082
                        break;
                    case 0xf:
B
blueswir1 已提交
3083
                        CHECK_IU_FEATURE(dc, DIV);
B
blueswir1 已提交
3084 3085
                        tcg_gen_helper_1_2(helper_sdiv, cpu_dst, cpu_src1,
                                           cpu_src2);
3086
                        if (xop & 0x10)
3087
                            gen_op_div_cc(cpu_dst);
3088 3089 3090 3091
                        break;
                    default:
                        goto illegal_insn;
                    }
3092
                    gen_movl_TN_reg(rd, cpu_dst);
3093 3094
                } else {
                    switch (xop) {
B
blueswir1 已提交
3095
                    case 0x20: /* taddcc */
3096 3097
                        gen_op_tadd_cc(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3098 3099
                        break;
                    case 0x21: /* tsubcc */
3100 3101
                        gen_op_tsub_cc(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3102 3103
                        break;
                    case 0x22: /* taddcctv */
3104 3105 3106
                        save_state(dc, cpu_cond);
                        gen_op_tadd_ccTV(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3107 3108
                        break;
                    case 0x23: /* tsubcctv */
3109 3110 3111
                        save_state(dc, cpu_cond);
                        gen_op_tsub_ccTV(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3112
                        break;
3113
                    case 0x24: /* mulscc */
3114 3115
                        gen_op_mulscc(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
3116
                        break;
B
bellard 已提交
3117
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3118
                    case 0x25:  /* sll */
3119 3120 3121 3122 3123 3124 3125
                        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);
                        }
3126
                        gen_movl_TN_reg(rd, cpu_dst);
3127
                        break;
B
bellard 已提交
3128
                    case 0x26:  /* srl */
3129 3130 3131 3132 3133 3134 3135
                        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);
                        }
3136
                        gen_movl_TN_reg(rd, cpu_dst);
3137
                        break;
B
bellard 已提交
3138
                    case 0x27:  /* sra */
3139 3140 3141 3142 3143 3144 3145
                        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);
                        }
3146
                        gen_movl_TN_reg(rd, cpu_dst);
3147
                        break;
B
bellard 已提交
3148
#endif
3149 3150 3151
                    case 0x30:
                        {
                            switch(rd) {
B
bellard 已提交
3152
                            case 0: /* wry */
3153
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
B
blueswir1 已提交
3154 3155
                                tcg_gen_st_tl(cpu_dst, cpu_env,
                                              offsetof(CPUSPARCState, y));
3156
                                break;
3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167
#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 已提交
3168
                            case 0x2: /* V9 wrccr */
3169 3170
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
                                tcg_gen_helper_0_1(helper_wrccr, cpu_dst);
B
blueswir1 已提交
3171 3172
                                break;
                            case 0x3: /* V9 wrasi */
3173 3174
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
B
blueswir1 已提交
3175 3176
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState, asi));
B
blueswir1 已提交
3177 3178
                                break;
                            case 0x6: /* V9 wrfprs */
3179 3180
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
B
blueswir1 已提交
3181 3182
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState, fprs));
3183
                                save_state(dc, cpu_cond);
3184
                                gen_op_next_insn();
B
bellard 已提交
3185
                                tcg_gen_exit_tb(0);
3186
                                dc->is_br = 1;
B
blueswir1 已提交
3187 3188
                                break;
                            case 0xf: /* V9 sir, nop if user */
B
bellard 已提交
3189
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
3190
                                if (supervisor(dc))
B
blueswir1 已提交
3191
                                    ; // XXX
B
bellard 已提交
3192
#endif
B
blueswir1 已提交
3193 3194
                                break;
                            case 0x13: /* Graphics Status */
3195
                                if (gen_trap_ifnofpu(dc, cpu_cond))
B
bellard 已提交
3196
                                    goto jmp_insn;
3197
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
B
blueswir1 已提交
3198 3199
                                tcg_gen_st_tl(cpu_dst, cpu_env,
                                              offsetof(CPUSPARCState, gsr));
B
blueswir1 已提交
3200 3201
                                break;
                            case 0x17: /* Tick compare */
B
bellard 已提交
3202
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
3203 3204
                                if (!supervisor(dc))
                                    goto illegal_insn;
B
bellard 已提交
3205
#endif
B
blueswir1 已提交
3206 3207 3208
                                {
                                    TCGv r_tickptr;

3209 3210
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
                                                   cpu_src2);
B
blueswir1 已提交
3211 3212 3213
                                    tcg_gen_st_tl(cpu_dst, cpu_env,
                                                  offsetof(CPUSPARCState,
                                                           tick_cmpr));
B
blueswir1 已提交
3214 3215 3216 3217
                                    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,
3218
                                                       r_tickptr, cpu_dst);
B
blueswir1 已提交
3219
                                    tcg_temp_free(r_tickptr);
B
blueswir1 已提交
3220
                                }
B
blueswir1 已提交
3221 3222
                                break;
                            case 0x18: /* System tick */
B
bellard 已提交
3223
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
3224 3225
                                if (!supervisor(dc))
                                    goto illegal_insn;
B
bellard 已提交
3226
#endif
B
blueswir1 已提交
3227 3228 3229
                                {
                                    TCGv r_tickptr;

3230 3231
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
                                                   cpu_src2);
B
blueswir1 已提交
3232 3233 3234 3235
                                    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,
3236
                                                       r_tickptr, cpu_dst);
B
blueswir1 已提交
3237
                                    tcg_temp_free(r_tickptr);
B
blueswir1 已提交
3238
                                }
B
blueswir1 已提交
3239 3240
                                break;
                            case 0x19: /* System tick compare */
B
bellard 已提交
3241
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
3242 3243
                                if (!supervisor(dc))
                                    goto illegal_insn;
B
bellard 已提交
3244
#endif
B
blueswir1 已提交
3245 3246 3247
                                {
                                    TCGv r_tickptr;

3248 3249
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
                                                   cpu_src2);
B
blueswir1 已提交
3250 3251 3252
                                    tcg_gen_st_tl(cpu_dst, cpu_env,
                                                  offsetof(CPUSPARCState,
                                                           stick_cmpr));
B
blueswir1 已提交
3253 3254 3255 3256
                                    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,
3257
                                                       r_tickptr, cpu_dst);
B
blueswir1 已提交
3258
                                    tcg_temp_free(r_tickptr);
B
blueswir1 已提交
3259
                                }
B
blueswir1 已提交
3260
                                break;
B
bellard 已提交
3261

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

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

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

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

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

B
blueswir1 已提交
3490 3491 3492
                                    tcg_gen_st_tl(cpu_dst, cpu_env,
                                                  offsetof(CPUSPARCState,
                                                           hstick_cmpr));
B
blueswir1 已提交
3493 3494 3495 3496
                                    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,
3497
                                                       r_tickptr, cpu_dst);
B
blueswir1 已提交
3498
                                    tcg_temp_free(r_tickptr);
B
blueswir1 已提交
3499
                                }
B
blueswir1 已提交
3500 3501 3502 3503 3504 3505
                                break;
                            case 6: // hver readonly
                            default:
                                goto illegal_insn;
                            }
#endif
3506 3507 3508
                        }
                        break;
#endif
B
bellard 已提交
3509
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3510 3511 3512 3513
                    case 0x2c: /* V9 movcc */
                        {
                            int cc = GET_FIELD_SP(insn, 11, 12);
                            int cond = GET_FIELD_SP(insn, 14, 17);
B
blueswir1 已提交
3514
                            TCGv r_cond;
3515 3516
                            int l1;

B
blueswir1 已提交
3517
                            r_cond = tcg_temp_new(TCG_TYPE_TL);
B
blueswir1 已提交
3518 3519
                            if (insn & (1 << 18)) {
                                if (cc == 0)
B
blueswir1 已提交
3520
                                    gen_cond(r_cond, 0, cond);
B
blueswir1 已提交
3521
                                else if (cc == 2)
B
blueswir1 已提交
3522
                                    gen_cond(r_cond, 1, cond);
B
blueswir1 已提交
3523 3524 3525
                                else
                                    goto illegal_insn;
                            } else {
B
blueswir1 已提交
3526
                                gen_fcond(r_cond, cc, cond);
B
blueswir1 已提交
3527
                            }
3528 3529 3530

                            l1 = gen_new_label();

P
pbrook 已提交
3531
                            tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
3532
                            if (IS_IMM) {       /* immediate */
B
blueswir1 已提交
3533 3534
                                TCGv r_const;

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

3564
                            cpu_src1 = get_src1(insn, cpu_src1);
3565 3566 3567

                            l1 = gen_new_label();

P
pbrook 已提交
3568 3569
                            tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond],
                                              cpu_src1, 0, l1);
B
blueswir1 已提交
3570
                            if (IS_IMM) {       /* immediate */
B
blueswir1 已提交
3571 3572
                                TCGv r_const;

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

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

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

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

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

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

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

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

#ifndef TARGET_SPARC64
B
blueswir1 已提交
4357 4358 4359 4360
                case 0x30: /* ldc */
                case 0x31: /* ldcsr */
                case 0x33: /* lddc */
                    goto ncp_insn;
B
bellard 已提交
4361 4362 4363
#endif
#endif
#ifdef TARGET_SPARC64
B
blueswir1 已提交
4364
                case 0x08: /* V9 ldsw */
4365 4366
                    ABI32_MASK(cpu_addr);
                    tcg_gen_qemu_ld32s(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4367 4368
                    break;
                case 0x0b: /* V9 ldx */
4369 4370
                    ABI32_MASK(cpu_addr);
                    tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4371 4372
                    break;
                case 0x18: /* V9 ldswa */
4373
                    save_state(dc, cpu_cond);
4374
                    gen_ld_asi(cpu_val, cpu_addr, insn, 4, 1);
B
blueswir1 已提交
4375 4376
                    break;
                case 0x1b: /* V9 ldxa */
4377
                    save_state(dc, cpu_cond);
4378
                    gen_ld_asi(cpu_val, cpu_addr, insn, 8, 0);
B
blueswir1 已提交
4379 4380 4381 4382
                    break;
                case 0x2d: /* V9 prefetch, no effect */
                    goto skip_move;
                case 0x30: /* V9 ldfa */
4383
                    save_state(dc, cpu_cond);
4384
                    gen_ldf_asi(cpu_addr, insn, 4, rd);
4385
                    goto skip_move;
B
blueswir1 已提交
4386
                case 0x33: /* V9 lddfa */
4387
                    save_state(dc, cpu_cond);
4388
                    gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd));
4389
                    goto skip_move;
B
blueswir1 已提交
4390 4391 4392
                case 0x3d: /* V9 prefetcha, no effect */
                    goto skip_move;
                case 0x32: /* V9 ldqfa */
B
blueswir1 已提交
4393
                    CHECK_FPU_FEATURE(dc, FLOAT128);
4394
                    save_state(dc, cpu_cond);
4395
                    gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd));
B
blueswir1 已提交
4396
                    goto skip_move;
B
blueswir1 已提交
4397 4398 4399 4400
#endif
                default:
                    goto illegal_insn;
                }
4401
                gen_movl_TN_reg(rd, cpu_val);
B
bellard 已提交
4402
#ifdef TARGET_SPARC64
B
blueswir1 已提交
4403
            skip_move: ;
B
bellard 已提交
4404
#endif
B
blueswir1 已提交
4405
            } else if (xop >= 0x20 && xop < 0x24) {
4406
                if (gen_trap_ifnofpu(dc, cpu_cond))
B
bellard 已提交
4407
                    goto jmp_insn;
4408
                save_state(dc, cpu_cond);
B
blueswir1 已提交
4409 4410
                switch (xop) {
                case 0x20:      /* load fpreg */
4411
                    ABI32_MASK(cpu_addr);
4412
                    tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
4413 4414
                    tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUState, fpr[rd]));
B
blueswir1 已提交
4415 4416
                    break;
                case 0x21:      /* load fsr */
4417
                    ABI32_MASK(cpu_addr);
4418
                    tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
4419 4420
                    tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUState, ft0));
4421
                    tcg_gen_helper_0_0(helper_ldfsr);
B
blueswir1 已提交
4422 4423
                    break;
                case 0x22:      /* load quad fpreg */
B
blueswir1 已提交
4424 4425 4426 4427 4428 4429 4430 4431 4432
                    {
                        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 已提交
4433
                    break;
B
blueswir1 已提交
4434
                case 0x23:      /* load double fpreg */
B
blueswir1 已提交
4435 4436 4437 4438 4439 4440 4441 4442
                    {
                        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 已提交
4443 4444 4445 4446 4447 4448
                    break;
                default:
                    goto illegal_insn;
                }
            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) || \
                       xop == 0xe || xop == 0x1e) {
4449
                gen_movl_reg_TN(rd, cpu_val);
B
blueswir1 已提交
4450
                switch (xop) {
B
blueswir1 已提交
4451
                case 0x4: /* store word */
4452 4453
                    ABI32_MASK(cpu_addr);
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4454
                    break;
B
blueswir1 已提交
4455
                case 0x5: /* store byte */
4456 4457
                    ABI32_MASK(cpu_addr);
                    tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4458
                    break;
B
blueswir1 已提交
4459
                case 0x6: /* store halfword */
4460 4461
                    ABI32_MASK(cpu_addr);
                    tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4462
                    break;
B
blueswir1 已提交
4463
                case 0x7: /* store double word */
B
blueswir1 已提交
4464
                    if (rd & 1)
4465
                        goto illegal_insn;
B
blueswir1 已提交
4466
                    else {
B
blueswir1 已提交
4467
                        TCGv r_low, r_const;
B
blueswir1 已提交
4468

4469 4470
                        save_state(dc, cpu_cond);
                        ABI32_MASK(cpu_addr);
B
blueswir1 已提交
4471
                        r_const = tcg_const_i32(7);
4472
                        tcg_gen_helper_0_2(helper_check_align, cpu_addr,
B
blueswir1 已提交
4473 4474
                                           r_const); // XXX remove
                        tcg_temp_free(r_const);
B
blueswir1 已提交
4475
                        r_low = tcg_temp_new(TCG_TYPE_TL);
B
blueswir1 已提交
4476
                        gen_movl_reg_TN(rd + 1, r_low);
4477
                        tcg_gen_helper_1_2(helper_pack64, cpu_tmp64, cpu_val,
B
blueswir1 已提交
4478
                                           r_low);
B
blueswir1 已提交
4479
                        tcg_temp_free(r_low);
4480
                        tcg_gen_qemu_st64(cpu_tmp64, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4481
                    }
B
blueswir1 已提交
4482
                    break;
B
bellard 已提交
4483
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
B
blueswir1 已提交
4484
                case 0x14: /* store word alternate */
B
bellard 已提交
4485
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4486 4487 4488 4489
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
blueswir1 已提交
4490
#endif
4491
                    save_state(dc, cpu_cond);
4492
                    gen_st_asi(cpu_val, cpu_addr, insn, 4);
B
bellard 已提交
4493
                    break;
B
blueswir1 已提交
4494
                case 0x15: /* store byte alternate */
B
bellard 已提交
4495
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4496 4497 4498 4499
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
bellard 已提交
4500
#endif
4501
                    save_state(dc, cpu_cond);
4502
                    gen_st_asi(cpu_val, cpu_addr, insn, 1);
B
bellard 已提交
4503
                    break;
B
blueswir1 已提交
4504
                case 0x16: /* store halfword alternate */
B
bellard 已提交
4505
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4506 4507 4508 4509
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
blueswir1 已提交
4510
#endif
4511
                    save_state(dc, cpu_cond);
4512
                    gen_st_asi(cpu_val, cpu_addr, insn, 2);
B
bellard 已提交
4513
                    break;
B
blueswir1 已提交
4514
                case 0x17: /* store double word alternate */
B
bellard 已提交
4515
#ifndef TARGET_SPARC64
B
blueswir1 已提交
4516 4517 4518 4519
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
B
bellard 已提交
4520
#endif
B
blueswir1 已提交
4521
                    if (rd & 1)
4522
                        goto illegal_insn;
B
blueswir1 已提交
4523
                    else {
4524
                        save_state(dc, cpu_cond);
4525
                        gen_stda_asi(cpu_val, cpu_addr, insn, rd);
B
blueswir1 已提交
4526
                    }
B
bellard 已提交
4527
                    break;
B
bellard 已提交
4528
#endif
B
bellard 已提交
4529
#ifdef TARGET_SPARC64
B
blueswir1 已提交
4530
                case 0x0e: /* V9 stx */
4531 4532
                    ABI32_MASK(cpu_addr);
                    tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4533 4534
                    break;
                case 0x1e: /* V9 stxa */
4535
                    save_state(dc, cpu_cond);
4536
                    gen_st_asi(cpu_val, cpu_addr, insn, 8);
B
blueswir1 已提交
4537
                    break;
B
bellard 已提交
4538
#endif
B
blueswir1 已提交
4539 4540 4541 4542
                default:
                    goto illegal_insn;
                }
            } else if (xop > 0x23 && xop < 0x28) {
4543
                if (gen_trap_ifnofpu(dc, cpu_cond))
B
bellard 已提交
4544
                    goto jmp_insn;
4545
                save_state(dc, cpu_cond);
B
blueswir1 已提交
4546
                switch (xop) {
4547
                case 0x24: /* store fpreg */
4548
                    ABI32_MASK(cpu_addr);
4549 4550
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUState, fpr[rd]));
4551
                    tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4552 4553
                    break;
                case 0x25: /* stfsr, V9 stxfsr */
4554
                    ABI32_MASK(cpu_addr);
B
blueswir1 已提交
4555
                    tcg_gen_helper_0_0(helper_stfsr);
4556 4557
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUState, ft0));
4558
                    tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4559
                    break;
B
blueswir1 已提交
4560 4561 4562
                case 0x26:
#ifdef TARGET_SPARC64
                    /* V9 stqf, store quad fpreg */
B
blueswir1 已提交
4563 4564 4565 4566 4567 4568 4569 4570 4571
                    {
                        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 已提交
4572 4573 4574 4575 4576 4577
                    break;
#else /* !TARGET_SPARC64 */
                    /* stdfq, store floating point queue */
#if defined(CONFIG_USER_ONLY)
                    goto illegal_insn;
#else
B
blueswir1 已提交
4578 4579
                    if (!supervisor(dc))
                        goto priv_insn;
4580
                    if (gen_trap_ifnofpu(dc, cpu_cond))
B
blueswir1 已提交
4581 4582
                        goto jmp_insn;
                    goto nfq_insn;
B
blueswir1 已提交
4583
#endif
B
blueswir1 已提交
4584
#endif
B
blueswir1 已提交
4585
                case 0x27: /* store double fpreg */
B
blueswir1 已提交
4586 4587 4588 4589 4590 4591 4592 4593
                    {
                        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 已提交
4594 4595 4596 4597 4598
                    break;
                default:
                    goto illegal_insn;
                }
            } else if (xop > 0x33 && xop < 0x3f) {
4599
                save_state(dc, cpu_cond);
B
blueswir1 已提交
4600
                switch (xop) {
4601
#ifdef TARGET_SPARC64
B
blueswir1 已提交
4602
                case 0x34: /* V9 stfa */
4603
                    gen_op_load_fpr_FT0(rd);
4604
                    gen_stf_asi(cpu_addr, insn, 4, rd);
B
blueswir1 已提交
4605
                    break;
B
blueswir1 已提交
4606
                case 0x36: /* V9 stqfa */
B
blueswir1 已提交
4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617
                    {
                        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 已提交
4618
                    break;
B
blueswir1 已提交
4619
                case 0x37: /* V9 stdfa */
4620
                    gen_op_load_fpr_DT0(DFPREG(rd));
4621
                    gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
B
blueswir1 已提交
4622 4623
                    break;
                case 0x3c: /* V9 casa */
4624 4625
                    gen_cas_asi(cpu_val, cpu_addr, cpu_val, insn, rd);
                    gen_movl_TN_reg(rd, cpu_val);
B
blueswir1 已提交
4626 4627
                    break;
                case 0x3e: /* V9 casxa */
4628 4629
                    gen_casx_asi(cpu_val, cpu_addr, cpu_val, insn, rd);
                    gen_movl_TN_reg(rd, cpu_val);
B
blueswir1 已提交
4630
                    break;
4631
#else
B
blueswir1 已提交
4632 4633 4634 4635 4636 4637 4638 4639 4640
                case 0x34: /* stc */
                case 0x35: /* stcsr */
                case 0x36: /* stdcq */
                case 0x37: /* stdc */
                    goto ncp_insn;
#endif
                default:
                    goto illegal_insn;
                }
4641
            }
B
blueswir1 已提交
4642 4643 4644 4645
            else
                goto illegal_insn;
        }
        break;
4646 4647
    }
    /* default case for non jump instructions */
B
bellard 已提交
4648
    if (dc->npc == DYNAMIC_PC) {
B
blueswir1 已提交
4649 4650
        dc->pc = DYNAMIC_PC;
        gen_op_next_insn();
B
bellard 已提交
4651 4652
    } else if (dc->npc == JUMP_PC) {
        /* we can do a static jump */
4653
        gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
B
bellard 已提交
4654 4655
        dc->is_br = 1;
    } else {
B
blueswir1 已提交
4656 4657
        dc->pc = dc->npc;
        dc->npc = dc->npc + 4;
4658
    }
B
bellard 已提交
4659
 jmp_insn:
4660 4661
    return;
 illegal_insn:
B
blueswir1 已提交
4662 4663 4664 4665 4666 4667 4668 4669 4670
    {
        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;
    }
4671
    return;
B
blueswir1 已提交
4672
 unimp_flush:
B
blueswir1 已提交
4673 4674 4675 4676 4677 4678 4679 4680 4681
    {
        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 已提交
4682
    return;
B
bellard 已提交
4683
#if !defined(CONFIG_USER_ONLY)
4684
 priv_insn:
B
blueswir1 已提交
4685 4686 4687 4688 4689 4690 4691 4692 4693
    {
        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 已提交
4694
    return;
B
blueswir1 已提交
4695
#endif
B
bellard 已提交
4696
 nfpu_insn:
4697
    save_state(dc, cpu_cond);
B
bellard 已提交
4698 4699
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
    dc->is_br = 1;
4700
    return;
B
blueswir1 已提交
4701
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
B
blueswir1 已提交
4702
 nfq_insn:
4703
    save_state(dc, cpu_cond);
B
blueswir1 已提交
4704 4705 4706 4707
    gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
    dc->is_br = 1;
    return;
#endif
4708 4709
#ifndef TARGET_SPARC64
 ncp_insn:
B
blueswir1 已提交
4710 4711 4712 4713 4714 4715 4716 4717 4718
    {
        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;
    }
4719 4720
    return;
#endif
4721 4722
}

4723
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
B
blueswir1 已提交
4724
                                                 int spc, CPUSPARCState *env)
4725
{
B
bellard 已提交
4726
    target_ulong pc_start, last_pc;
4727 4728
    uint16_t *gen_opc_end;
    DisasContext dc1, *dc = &dc1;
4729
    int j, lj = -1;
4730 4731 4732

    memset(dc, 0, sizeof(DisasContext));
    dc->tb = tb;
B
bellard 已提交
4733
    pc_start = tb->pc;
4734
    dc->pc = pc_start;
B
bellard 已提交
4735
    last_pc = dc->pc;
B
bellard 已提交
4736
    dc->npc = (target_ulong) tb->cs_base;
B
blueswir1 已提交
4737
    dc->mem_idx = cpu_mmu_index(env);
B
blueswir1 已提交
4738 4739 4740 4741 4742 4743 4744 4745
    dc->features = env->features;
    if ((dc->features & CPU_FEATURE_FLOAT)) {
        dc->fpu_enabled = cpu_fpu_enabled(env);
#if defined(CONFIG_USER_ONLY)
        dc->features |= CPU_FEATURE_FLOAT128;
#endif
    } else
        dc->fpu_enabled = 0;
4746 4747
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;

B
blueswir1 已提交
4748
    cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
B
blueswir1 已提交
4749 4750
    cpu_tmp32 = tcg_temp_new(TCG_TYPE_I32);
    cpu_tmp64 = tcg_temp_new(TCG_TYPE_I64);
B
blueswir1 已提交
4751

4752
    do {
4753 4754 4755
        if (env->nb_breakpoints > 0) {
            for(j = 0; j < env->nb_breakpoints; j++) {
                if (env->breakpoints[j] == dc->pc) {
B
blueswir1 已提交
4756
                    if (dc->pc != pc_start)
4757
                        save_state(dc, cpu_cond);
B
blueswir1 已提交
4758
                    tcg_gen_helper_0_0(helper_debug);
B
bellard 已提交
4759
                    tcg_gen_exit_tb(0);
B
blueswir1 已提交
4760
                    dc->is_br = 1;
B
bellard 已提交
4761
                    goto exit_gen_loop;
4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777
                }
            }
        }
        if (spc) {
            if (loglevel > 0)
                fprintf(logfile, "Search PC...\n");
            j = gen_opc_ptr - gen_opc_buf;
            if (lj < j) {
                lj++;
                while (lj < j)
                    gen_opc_instr_start[lj++] = 0;
                gen_opc_pc[lj] = dc->pc;
                gen_opc_npc[lj] = dc->npc;
                gen_opc_instr_start[lj] = 1;
            }
        }
B
blueswir1 已提交
4778 4779 4780 4781 4782 4783 4784 4785
        last_pc = dc->pc;
        disas_sparc_insn(dc);

        if (dc->is_br)
            break;
        /* if the next PC is different, we abort now */
        if (dc->pc != (last_pc + 4))
            break;
B
bellard 已提交
4786 4787 4788 4789
        /* 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 已提交
4790 4791 4792
        /* if single step mode, we generate only one instruction and
           generate an exception */
        if (env->singlestep_enabled) {
B
blueswir1 已提交
4793
            tcg_gen_movi_tl(cpu_pc, dc->pc);
B
bellard 已提交
4794
            tcg_gen_exit_tb(0);
B
bellard 已提交
4795 4796
            break;
        }
4797
    } while ((gen_opc_ptr < gen_opc_end) &&
B
blueswir1 已提交
4798
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
B
bellard 已提交
4799 4800

 exit_gen_loop:
B
blueswir1 已提交
4801 4802 4803
    tcg_temp_free(cpu_tmp64);
    tcg_temp_free(cpu_tmp32);
    tcg_temp_free(cpu_tmp0);
B
bellard 已提交
4804
    if (!dc->is_br) {
4805
        if (dc->pc != DYNAMIC_PC &&
B
bellard 已提交
4806 4807
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
            /* static PC and NPC: we can use direct chaining */
B
blueswir1 已提交
4808
            gen_goto_tb(dc, 0, dc->pc, dc->npc);
B
bellard 已提交
4809 4810
        } else {
            if (dc->pc != DYNAMIC_PC)
B
blueswir1 已提交
4811
                tcg_gen_movi_tl(cpu_pc, dc->pc);
4812
            save_npc(dc, cpu_cond);
B
bellard 已提交
4813
            tcg_gen_exit_tb(0);
B
bellard 已提交
4814 4815
        }
    }
4816
    *gen_opc_ptr = INDEX_op_end;
4817 4818 4819 4820 4821 4822 4823 4824 4825 4826
    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
4827 4828
        gen_opc_jump_pc[0] = dc->jump_pc[0];
        gen_opc_jump_pc[1] = dc->jump_pc[1];
4829
    } else {
B
bellard 已提交
4830
        tb->size = last_pc + 4 - pc_start;
4831
    }
4832
#ifdef DEBUG_DISAS
B
bellard 已提交
4833
    if (loglevel & CPU_LOG_TB_IN_ASM) {
B
blueswir1 已提交
4834 4835 4836 4837
        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");
4838
    }
4839
#endif
4840
    return 0;
4841 4842
}

4843
int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
4844
{
4845
    return gen_intermediate_code_internal(tb, 0, env);
4846 4847
}

4848
int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
4849
{
4850
    return gen_intermediate_code_internal(tb, 1, env);
4851 4852
}

4853
void gen_intermediate_code_init(CPUSPARCState *env)
B
bellard 已提交
4854
{
B
blueswir1 已提交
4855
    unsigned int i;
4856
    static int inited;
B
blueswir1 已提交
4857 4858 4859 4860 4861 4862 4863 4864 4865 4866
    static const char * const gregnames[8] = {
        NULL, // g0 not used
        "g1",
        "g2",
        "g3",
        "g4",
        "g5",
        "g6",
        "g7",
    };
B
bellard 已提交
4867

B
blueswir1 已提交
4868 4869 4870 4871 4872
    /* init various static tables */
    if (!inited) {
        inited = 1;

        cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
B
blueswir1 已提交
4873 4874 4875
        cpu_regwptr = tcg_global_mem_new(TCG_TYPE_PTR, TCG_AREG0,
                                         offsetof(CPUState, regwptr),
                                         "regwptr");
B
blueswir1 已提交
4876
#ifdef TARGET_SPARC64
4877 4878 4879
        cpu_xcc = tcg_global_mem_new(TCG_TYPE_I32,
                                     TCG_AREG0, offsetof(CPUState, xcc),
                                     "xcc");
B
blueswir1 已提交
4880
#endif
B
bellard 已提交
4881 4882 4883 4884 4885 4886
        /* XXX: T0 and T1 should be temporaries */
        cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
                                      TCG_AREG0, offsetof(CPUState, t0), "T0");
        cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
                                      TCG_AREG0, offsetof(CPUState, t1), "T1");
        cpu_cond = tcg_global_mem_new(TCG_TYPE_TL,
B
blueswir1 已提交
4887 4888
                                      TCG_AREG0, offsetof(CPUState, cond),
                                      "cond");
4889 4890 4891
        cpu_cc_src = tcg_global_mem_new(TCG_TYPE_TL,
                                        TCG_AREG0, offsetof(CPUState, cc_src),
                                        "cc_src");
B
blueswir1 已提交
4892 4893 4894
        cpu_cc_src2 = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
                                         offsetof(CPUState, cc_src2),
                                         "cc_src2");
4895 4896 4897 4898 4899 4900
        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 已提交
4901 4902 4903
        cpu_fsr = tcg_global_mem_new(TCG_TYPE_TL,
                                     TCG_AREG0, offsetof(CPUState, fsr),
                                     "fsr");
B
blueswir1 已提交
4904 4905 4906 4907 4908 4909
        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 已提交
4910 4911 4912 4913
        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 已提交
4914 4915 4916 4917 4918
        /* register helpers */

#undef DEF_HELPER
#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
#include "helper.h"
B
blueswir1 已提交
4919
    }
B
bellard 已提交
4920
}
A
aurel32 已提交
4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940

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