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

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

   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
19
   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
20 21 22 23 24 25 26 27 28 29 30
 */

#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

P
pbrook 已提交
34 35 36
#define GEN_HELPER 1
#include "helper.h"

37 38
#define DEBUG_DISAS

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

P
pbrook 已提交
69 70
#include "gen-icount.h"

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

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

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

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

B
blueswir1 已提交
103 104 105
#define UA2005_HTRAP_MASK 0xff
#define V8_TRAP_MASK 0x7f

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

112 113
#define IS_IMM (insn & (1<<13))

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

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

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

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

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

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

175 176
/* moves */
#ifdef CONFIG_USER_ONLY
B
bellard 已提交
177
#define supervisor(dc) 0
178
#ifdef TARGET_SPARC64
B
blueswir1 已提交
179
#define hypervisor(dc) 0
180
#endif
B
bellard 已提交
181
#else
B
blueswir1 已提交
182
#define supervisor(dc) (dc->mem_idx >= 1)
183 184
#ifdef TARGET_SPARC64
#define hypervisor(dc) (dc->mem_idx == 2)
B
blueswir1 已提交
185
#else
B
bellard 已提交
186
#endif
187 188
#endif

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

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

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

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

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

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

P
pbrook 已提交
256
static inline void gen_mov_reg_Z(TCGv reg, TCGv_i32 src)
257
{
B
blueswir1 已提交
258
    tcg_gen_extu_i32_tl(reg, src);
B
blueswir1 已提交
259
    tcg_gen_shri_tl(reg, reg, PSR_ZERO_SHIFT);
260 261 262
    tcg_gen_andi_tl(reg, reg, 0x1);
}

P
pbrook 已提交
263
static inline void gen_mov_reg_V(TCGv reg, TCGv_i32 src)
264
{
B
blueswir1 已提交
265
    tcg_gen_extu_i32_tl(reg, src);
B
blueswir1 已提交
266
    tcg_gen_shri_tl(reg, reg, PSR_OVF_SHIFT);
267 268 269
    tcg_gen_andi_tl(reg, reg, 0x1);
}

P
pbrook 已提交
270
static inline void gen_mov_reg_C(TCGv reg, TCGv_i32 src)
271
{
B
blueswir1 已提交
272
    tcg_gen_extu_i32_tl(reg, src);
B
blueswir1 已提交
273
    tcg_gen_shri_tl(reg, reg, PSR_CARRY_SHIFT);
274 275 276
    tcg_gen_andi_tl(reg, reg, 0x1);
}

277
static inline void gen_cc_clear_icc(void)
278 279
{
    tcg_gen_movi_i32(cpu_psr, 0);
280 281
}

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

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

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

314
#ifdef TARGET_SPARC64
315 316 317 318 319 320
static inline void gen_cc_NZ_xcc(TCGv dst)
{
    int l1, l2;

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

/* old op:
    if (T0 < src1)
        env->psr |= PSR_CARRY;
*/
334
static inline void gen_cc_C_add_icc(TCGv dst, TCGv src1)
335
{
336
    TCGv r_temp1, r_temp2;
337 338 339
    int l1;

    l1 = gen_new_label();
P
pbrook 已提交
340 341
    r_temp1 = tcg_temp_new();
    r_temp2 = tcg_temp_new();
342 343 344
    tcg_gen_andi_tl(r_temp1, dst, 0xffffffffULL);
    tcg_gen_andi_tl(r_temp2, src1, 0xffffffffULL);
    tcg_gen_brcond_tl(TCG_COND_GEU, r_temp1, r_temp2, l1);
345 346
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
    gen_set_label(l1);
347 348
    tcg_temp_free(r_temp1);
    tcg_temp_free(r_temp2);
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

P
pbrook 已提交
371
    r_temp = tcg_temp_new();
372
    tcg_gen_xor_tl(r_temp, src1, src2);
B
blueswir1 已提交
373
    tcg_gen_not_tl(r_temp, r_temp);
374 375
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
376
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 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
static inline void gen_cc_V_add_xcc(TCGv dst, TCGv src1, TCGv src2)
{
    TCGv r_temp;

P
pbrook 已提交
388
    r_temp = tcg_temp_new();
389
    tcg_gen_xor_tl(r_temp, src1, src2);
B
blueswir1 已提交
390
    tcg_gen_not_tl(r_temp, r_temp);
391 392 393
    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)
{
P
pbrook 已提交
403 404
    TCGv r_temp;
    TCGv_i32 r_const;
405 406 407 408
    int l1;

    l1 = gen_new_label();

P
pbrook 已提交
409
    r_temp = tcg_temp_new();
410
    tcg_gen_xor_tl(r_temp, src1, src2);
B
blueswir1 已提交
411
    tcg_gen_not_tl(r_temp, r_temp);
412 413
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
414
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
P
pbrook 已提交
415
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
B
blueswir1 已提交
416
    r_const = tcg_const_i32(TT_TOVF);
P
pbrook 已提交
417 418
    gen_helper_raise_exception(r_const);
    tcg_temp_free_i32(r_const);
419
    gen_set_label(l1);
B
blueswir1 已提交
420
    tcg_temp_free(r_temp);
421 422 423 424 425 426 427
}

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

    l1 = gen_new_label();
428 429
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
P
pbrook 已提交
430
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
431 432 433 434
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
    gen_set_label(l1);
}

B
Blue Swirl 已提交
435 436 437 438 439 440 441 442 443 444 445 446
static inline void gen_op_logic_cc(TCGv dst)
{
    tcg_gen_mov_tl(cpu_cc_dst, dst);

    gen_cc_clear_icc();
    gen_cc_NZ_icc(cpu_cc_dst);
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
    gen_cc_NZ_xcc(cpu_cc_dst);
#endif
}

447 448 449
static inline void gen_tag_tv(TCGv src1, TCGv src2)
{
    int l1;
P
pbrook 已提交
450
    TCGv_i32 r_const;
451 452

    l1 = gen_new_label();
453 454
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
P
pbrook 已提交
455
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
B
blueswir1 已提交
456
    r_const = tcg_const_i32(TT_TOVF);
P
pbrook 已提交
457 458
    gen_helper_raise_exception(r_const);
    tcg_temp_free_i32(r_const);
459 460 461
    gen_set_label(l1);
}

462 463 464 465 466
static inline void gen_op_addi_cc(TCGv dst, TCGv src1, target_long src2)
{
    tcg_gen_mov_tl(cpu_cc_src, src1);
    tcg_gen_movi_tl(cpu_cc_src2, src2);
    tcg_gen_addi_tl(cpu_cc_dst, cpu_cc_src, src2);
B
Blue Swirl 已提交
467
    tcg_gen_mov_tl(dst, cpu_cc_dst);
468 469
}

470
static inline void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2)
471
{
472
    tcg_gen_mov_tl(cpu_cc_src, src1);
473
    tcg_gen_mov_tl(cpu_cc_src2, src2);
474
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
B
Blue Swirl 已提交
475
    tcg_gen_mov_tl(dst, cpu_cc_dst);
476 477 478
}

static inline void gen_op_addxi_cc(TCGv dst, TCGv src1, target_long src2)
479
{
480
    tcg_gen_mov_tl(cpu_cc_src, src1);
481
    tcg_gen_movi_tl(cpu_cc_src2, src2);
482
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
483
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_tmp0);
484
    tcg_gen_addi_tl(cpu_cc_dst, cpu_cc_dst, src2);
B
Blue Swirl 已提交
485
    tcg_gen_mov_tl(dst, cpu_cc_dst);
486 487 488 489 490 491 492 493 494
}

static inline void gen_op_addx_cc(TCGv dst, TCGv src1, TCGv src2)
{
    tcg_gen_mov_tl(cpu_cc_src, src1);
    tcg_gen_mov_tl(cpu_cc_src2, src2);
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_tmp0);
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_dst, cpu_cc_src2);
B
Blue Swirl 已提交
495
    tcg_gen_mov_tl(dst, cpu_cc_dst);
496 497
}

498
static inline void gen_op_tadd_cc(TCGv dst, TCGv src1, TCGv src2)
499
{
500
    tcg_gen_mov_tl(cpu_cc_src, src1);
501
    tcg_gen_mov_tl(cpu_cc_src2, src2);
502
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
503
    gen_cc_clear_icc();
504 505 506
    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);
507
    gen_cc_V_tag(cpu_cc_src, cpu_cc_src2);
508 509
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
510 511 512
    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);
513
#endif
514
    tcg_gen_mov_tl(dst, cpu_cc_dst);
515 516
}

517
static inline void gen_op_tadd_ccTV(TCGv dst, TCGv src1, TCGv src2)
518
{
519
    tcg_gen_mov_tl(cpu_cc_src, src1);
520 521
    tcg_gen_mov_tl(cpu_cc_src2, src2);
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
522 523
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
    gen_add_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
524
    gen_cc_clear_icc();
525 526
    gen_cc_NZ_icc(cpu_cc_dst);
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
527 528
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
529 530 531
    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);
532
#endif
533
    tcg_gen_mov_tl(dst, cpu_cc_dst);
534 535 536 537 538 539
}

/* old op:
    if (src1 < T1)
        env->psr |= PSR_CARRY;
*/
540
static inline void gen_cc_C_sub_icc(TCGv src1, TCGv src2)
541
{
B
blueswir1 已提交
542
    TCGv r_temp1, r_temp2;
543 544 545
    int l1;

    l1 = gen_new_label();
P
pbrook 已提交
546 547
    r_temp1 = tcg_temp_new();
    r_temp2 = tcg_temp_new();
B
blueswir1 已提交
548 549 550
    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);
551 552
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
    gen_set_label(l1);
B
blueswir1 已提交
553 554
    tcg_temp_free(r_temp1);
    tcg_temp_free(r_temp2);
555 556
}

557
#ifdef TARGET_SPARC64
558 559 560
static inline void gen_cc_C_sub_xcc(TCGv src1, TCGv src2)
{
    int l1;
561

562 563 564 565
    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);
566
}
567
#endif
568 569 570 571 572

/* old op:
    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
        env->psr |= PSR_OVF;
*/
573
static inline void gen_cc_V_sub_icc(TCGv dst, TCGv src1, TCGv src2)
574
{
575
    TCGv r_temp;
576

P
pbrook 已提交
577
    r_temp = tcg_temp_new();
578
    tcg_gen_xor_tl(r_temp, src1, src2);
579 580
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
581
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
B
blueswir1 已提交
582 583 584
    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 已提交
585
    tcg_temp_free(r_temp);
586 587
}

588
#ifdef TARGET_SPARC64
589 590 591 592
static inline void gen_cc_V_sub_xcc(TCGv dst, TCGv src1, TCGv src2)
{
    TCGv r_temp;

P
pbrook 已提交
593
    r_temp = tcg_temp_new();
594 595 596 597
    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 已提交
598 599 600
    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 已提交
601
    tcg_temp_free(r_temp);
602
}
603
#endif
604 605 606

static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
{
P
pbrook 已提交
607 608
    TCGv r_temp;
    TCGv_i32 r_const;
609 610 611 612
    int l1;

    l1 = gen_new_label();

P
pbrook 已提交
613
    r_temp = tcg_temp_new();
614
    tcg_gen_xor_tl(r_temp, src1, src2);
615 616
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
617
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
P
pbrook 已提交
618
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
B
blueswir1 已提交
619
    r_const = tcg_const_i32(TT_TOVF);
P
pbrook 已提交
620 621
    gen_helper_raise_exception(r_const);
    tcg_temp_free_i32(r_const);
622
    gen_set_label(l1);
B
blueswir1 已提交
623
    tcg_temp_free(r_temp);
624 625
}

626
static inline void gen_op_sub_cc2(TCGv dst)
627
{
628
    gen_cc_clear_icc();
629
    gen_cc_NZ_icc(cpu_cc_dst);
630
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
631
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
632 633
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
634
    gen_cc_NZ_xcc(cpu_cc_dst);
635
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
636
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
637
#endif
638
    tcg_gen_mov_tl(dst, cpu_cc_dst);
639 640
}

641 642 643 644
static inline void gen_op_subi_cc(TCGv dst, TCGv src1, target_long src2)
{
    tcg_gen_mov_tl(cpu_cc_src, src1);
    tcg_gen_movi_tl(cpu_cc_src2, src2);
B
Blue Swirl 已提交
645 646 647 648 649 650 651
    if (src2 == 0) {
        tcg_gen_mov_tl(dst, src1);
        gen_op_logic_cc(dst);
    } else {
        tcg_gen_subi_tl(cpu_cc_dst, cpu_cc_src, src2);
        gen_op_sub_cc2(dst);
    }
652 653 654
}

static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2)
655
{
656
    tcg_gen_mov_tl(cpu_cc_src, src1);
657
    tcg_gen_mov_tl(cpu_cc_src2, src2);
658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
    gen_op_sub_cc2(dst);
}

static inline void gen_op_subx_cc2(TCGv 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);
#ifdef TARGET_SPARC64
    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);
#endif
    tcg_gen_mov_tl(dst, cpu_cc_dst);
}

static inline void gen_op_subxi_cc(TCGv dst, TCGv src1, target_long src2)
{
    tcg_gen_mov_tl(cpu_cc_src, src1);
    tcg_gen_movi_tl(cpu_cc_src2, src2);
679
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
680
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_tmp0);
681
    gen_cc_clear_icc();
682
    gen_cc_C_sub_icc(cpu_cc_dst, cpu_cc_src);
683 684
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
685
    gen_cc_C_sub_xcc(cpu_cc_dst, cpu_cc_src);
686
#endif
687 688 689 690 691 692 693 694 695 696 697
    tcg_gen_subi_tl(cpu_cc_dst, cpu_cc_dst, src2);
    gen_op_subx_cc2(dst);
}

static inline void gen_op_subx_cc(TCGv dst, TCGv src1, TCGv src2)
{
    tcg_gen_mov_tl(cpu_cc_src, src1);
    tcg_gen_mov_tl(cpu_cc_src2, src2);
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_tmp0);
    gen_cc_clear_icc();
698
    gen_cc_C_sub_icc(cpu_cc_dst, cpu_cc_src);
699
#ifdef TARGET_SPARC64
700
    gen_cc_clear_xcc();
701
    gen_cc_C_sub_xcc(cpu_cc_dst, cpu_cc_src);
702
#endif
703 704
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_dst, cpu_cc_src2);
    gen_op_subx_cc2(dst);
705 706
}

707
static inline void gen_op_tsub_cc(TCGv dst, TCGv src1, TCGv src2)
708
{
709
    tcg_gen_mov_tl(cpu_cc_src, src1);
710
    tcg_gen_mov_tl(cpu_cc_src2, src2);
711
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
712
    gen_cc_clear_icc();
713
    gen_cc_NZ_icc(cpu_cc_dst);
714
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
715
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
716
    gen_cc_V_tag(cpu_cc_src, cpu_cc_src2);
717 718
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
719
    gen_cc_NZ_xcc(cpu_cc_dst);
720
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
721
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
722
#endif
723
    tcg_gen_mov_tl(dst, cpu_cc_dst);
724 725
}

726
static inline void gen_op_tsub_ccTV(TCGv dst, TCGv src1, TCGv src2)
727
{
728
    tcg_gen_mov_tl(cpu_cc_src, src1);
729 730
    tcg_gen_mov_tl(cpu_cc_src2, src2);
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
731 732
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
    gen_sub_tv(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
733
    gen_cc_clear_icc();
734
    gen_cc_NZ_icc(cpu_cc_dst);
735
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
736 737
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
738
    gen_cc_NZ_xcc(cpu_cc_dst);
739
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
740
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
741
#endif
742
    tcg_gen_mov_tl(dst, cpu_cc_dst);
743 744
}

745
static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
B
blueswir1 已提交
746
{
B
blueswir1 已提交
747
    TCGv r_temp;
748
    int l1;
B
blueswir1 已提交
749 750

    l1 = gen_new_label();
P
pbrook 已提交
751
    r_temp = tcg_temp_new();
B
blueswir1 已提交
752 753 754 755 756

    /* old op:
    if (!(env->y & 1))
        T1 = 0;
    */
757
    tcg_gen_andi_tl(cpu_cc_src, src1, 0xffffffff);
758
    tcg_gen_andi_tl(r_temp, cpu_y, 0x1);
759
    tcg_gen_andi_tl(cpu_cc_src2, src2, 0xffffffff);
B
blueswir1 已提交
760
    tcg_gen_brcondi_tl(TCG_COND_NE, r_temp, 0, l1);
B
blueswir1 已提交
761
    tcg_gen_movi_tl(cpu_cc_src2, 0);
762
    gen_set_label(l1);
B
blueswir1 已提交
763 764 765

    // b2 = T0 & 1;
    // env->y = (b2 << 31) | (env->y >> 1);
B
blueswir1 已提交
766 767
    tcg_gen_andi_tl(r_temp, cpu_cc_src, 0x1);
    tcg_gen_shli_tl(r_temp, r_temp, 31);
768
    tcg_gen_shri_tl(cpu_tmp0, cpu_y, 1);
769
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x7fffffff);
770 771
    tcg_gen_or_tl(cpu_tmp0, cpu_tmp0, r_temp);
    tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
B
blueswir1 已提交
772 773 774 775 776

    // 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 已提交
777
    tcg_temp_free(r_temp);
B
blueswir1 已提交
778 779 780 781

    // T0 = (b1 << 31) | (T0 >> 1);
    // src1 = T0;
    tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
782
    tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
B
blueswir1 已提交
783 784 785
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);

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

788
    gen_cc_clear_icc();
789 790 791
    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);
792
    tcg_gen_mov_tl(dst, cpu_cc_dst);
B
blueswir1 已提交
793 794
}

795
static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
B
blueswir1 已提交
796
{
P
pbrook 已提交
797
    TCGv_i64 r_temp, r_temp2;
B
blueswir1 已提交
798

P
pbrook 已提交
799 800
    r_temp = tcg_temp_new_i64();
    r_temp2 = tcg_temp_new_i64();
B
blueswir1 已提交
801

B
blueswir1 已提交
802 803
    tcg_gen_extu_tl_i64(r_temp, src2);
    tcg_gen_extu_tl_i64(r_temp2, src1);
B
blueswir1 已提交
804 805 806
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);

    tcg_gen_shri_i64(r_temp, r_temp2, 32);
B
blueswir1 已提交
807
    tcg_gen_trunc_i64_tl(cpu_tmp0, r_temp);
P
pbrook 已提交
808
    tcg_temp_free_i64(r_temp);
809
    tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
B
blueswir1 已提交
810
#ifdef TARGET_SPARC64
811
    tcg_gen_mov_i64(dst, r_temp2);
B
blueswir1 已提交
812
#else
813
    tcg_gen_trunc_i64_tl(dst, r_temp2);
B
blueswir1 已提交
814
#endif
P
pbrook 已提交
815
    tcg_temp_free_i64(r_temp2);
B
blueswir1 已提交
816 817
}

818
static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
B
blueswir1 已提交
819
{
P
pbrook 已提交
820
    TCGv_i64 r_temp, r_temp2;
B
blueswir1 已提交
821

P
pbrook 已提交
822 823
    r_temp = tcg_temp_new_i64();
    r_temp2 = tcg_temp_new_i64();
B
blueswir1 已提交
824

B
blueswir1 已提交
825 826
    tcg_gen_ext_tl_i64(r_temp, src2);
    tcg_gen_ext_tl_i64(r_temp2, src1);
B
blueswir1 已提交
827 828 829
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);

    tcg_gen_shri_i64(r_temp, r_temp2, 32);
B
blueswir1 已提交
830
    tcg_gen_trunc_i64_tl(cpu_tmp0, r_temp);
P
pbrook 已提交
831
    tcg_temp_free_i64(r_temp);
832
    tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
B
blueswir1 已提交
833
#ifdef TARGET_SPARC64
834
    tcg_gen_mov_i64(dst, r_temp2);
B
blueswir1 已提交
835
#else
836
    tcg_gen_trunc_i64_tl(dst, r_temp2);
B
blueswir1 已提交
837
#endif
P
pbrook 已提交
838
    tcg_temp_free_i64(r_temp2);
B
blueswir1 已提交
839 840
}

B
blueswir1 已提交
841
#ifdef TARGET_SPARC64
B
blueswir1 已提交
842
static inline void gen_trap_ifdivzero_tl(TCGv divisor)
B
blueswir1 已提交
843
{
P
pbrook 已提交
844
    TCGv_i32 r_const;
B
blueswir1 已提交
845 846 847
    int l1;

    l1 = gen_new_label();
P
pbrook 已提交
848
    tcg_gen_brcondi_tl(TCG_COND_NE, divisor, 0, l1);
B
blueswir1 已提交
849
    r_const = tcg_const_i32(TT_DIV_ZERO);
P
pbrook 已提交
850 851
    gen_helper_raise_exception(r_const);
    tcg_temp_free_i32(r_const);
B
blueswir1 已提交
852 853 854
    gen_set_label(l1);
}

855
static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
B
blueswir1 已提交
856 857 858 859 860
{
    int l1, l2;

    l1 = gen_new_label();
    l2 = gen_new_label();
861 862
    tcg_gen_mov_tl(cpu_cc_src, src1);
    tcg_gen_mov_tl(cpu_cc_src2, src2);
863
    gen_trap_ifdivzero_tl(cpu_cc_src2);
P
pbrook 已提交
864 865
    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);
866
    tcg_gen_movi_i64(dst, INT64_MIN);
B
blueswir1 已提交
867
    tcg_gen_br(l2);
B
blueswir1 已提交
868
    gen_set_label(l1);
869
    tcg_gen_div_i64(dst, cpu_cc_src, cpu_cc_src2);
B
blueswir1 已提交
870 871 872 873
    gen_set_label(l2);
}
#endif

874
static inline void gen_op_div_cc(TCGv dst)
875 876 877
{
    int l1;

878
    tcg_gen_mov_tl(cpu_cc_dst, dst);
879
    gen_cc_clear_icc();
880
    gen_cc_NZ_icc(cpu_cc_dst);
881
    l1 = gen_new_label();
882
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cc_src2, 0, l1);
883 884 885 886
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
    gen_set_label(l1);
}

887 888 889 890 891 892 893
// 1
static inline void gen_op_eval_ba(TCGv dst)
{
    tcg_gen_movi_tl(dst, 1);
}

// Z
P
pbrook 已提交
894
static inline void gen_op_eval_be(TCGv dst, TCGv_i32 src)
895 896 897 898 899
{
    gen_mov_reg_Z(dst, src);
}

// Z | (N ^ V)
P
pbrook 已提交
900
static inline void gen_op_eval_ble(TCGv dst, TCGv_i32 src)
901
{
902
    gen_mov_reg_N(cpu_tmp0, src);
903
    gen_mov_reg_V(dst, src);
904 905 906
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
    gen_mov_reg_Z(cpu_tmp0, src);
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
907 908 909
}

// N ^ V
P
pbrook 已提交
910
static inline void gen_op_eval_bl(TCGv dst, TCGv_i32 src)
911
{
912
    gen_mov_reg_V(cpu_tmp0, src);
913
    gen_mov_reg_N(dst, src);
914
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
915 916 917
}

// C | Z
P
pbrook 已提交
918
static inline void gen_op_eval_bleu(TCGv dst, TCGv_i32 src)
919
{
920
    gen_mov_reg_Z(cpu_tmp0, src);
921
    gen_mov_reg_C(dst, src);
922
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
923 924 925
}

// C
P
pbrook 已提交
926
static inline void gen_op_eval_bcs(TCGv dst, TCGv_i32 src)
927 928 929 930 931
{
    gen_mov_reg_C(dst, src);
}

// V
P
pbrook 已提交
932
static inline void gen_op_eval_bvs(TCGv dst, TCGv_i32 src)
933 934 935 936 937 938 939 940 941 942 943
{
    gen_mov_reg_V(dst, src);
}

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

// N
P
pbrook 已提交
944
static inline void gen_op_eval_bneg(TCGv dst, TCGv_i32 src)
945 946 947 948 949
{
    gen_mov_reg_N(dst, src);
}

// !Z
P
pbrook 已提交
950
static inline void gen_op_eval_bne(TCGv dst, TCGv_i32 src)
951 952 953 954 955 956
{
    gen_mov_reg_Z(dst, src);
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !(Z | (N ^ V))
P
pbrook 已提交
957
static inline void gen_op_eval_bg(TCGv dst, TCGv_i32 src)
958
{
959
    gen_mov_reg_N(cpu_tmp0, src);
960
    gen_mov_reg_V(dst, src);
961 962 963
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
    gen_mov_reg_Z(cpu_tmp0, src);
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
964 965 966 967
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !(N ^ V)
P
pbrook 已提交
968
static inline void gen_op_eval_bge(TCGv dst, TCGv_i32 src)
969
{
970
    gen_mov_reg_V(cpu_tmp0, src);
971
    gen_mov_reg_N(dst, src);
972
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
973 974 975 976
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !(C | Z)
P
pbrook 已提交
977
static inline void gen_op_eval_bgu(TCGv dst, TCGv_i32 src)
978
{
979
    gen_mov_reg_Z(cpu_tmp0, src);
980
    gen_mov_reg_C(dst, src);
981
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
982 983 984 985
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !C
P
pbrook 已提交
986
static inline void gen_op_eval_bcc(TCGv dst, TCGv_i32 src)
987 988 989 990 991 992
{
    gen_mov_reg_C(dst, src);
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !N
P
pbrook 已提交
993
static inline void gen_op_eval_bpos(TCGv dst, TCGv_i32 src)
994 995 996 997 998 999
{
    gen_mov_reg_N(dst, src);
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !V
P
pbrook 已提交
1000
static inline void gen_op_eval_bvc(TCGv dst, TCGv_i32 src)
1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015
{
    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)
{
1016
    tcg_gen_shri_tl(reg, src, FSR_FCC0_SHIFT + fcc_offset);
1017 1018 1019 1020 1021 1022
    tcg_gen_andi_tl(reg, reg, 0x1);
}

static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
                                    unsigned int fcc_offset)
{
1023
    tcg_gen_shri_tl(reg, src, FSR_FCC1_SHIFT + fcc_offset);
1024 1025 1026 1027 1028 1029 1030 1031
    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);
1032 1033
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
1034 1035 1036 1037 1038 1039 1040
}

// 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);
1041 1042
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056
}

// 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);
1057 1058 1059
    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);
1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074
}

// 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);
1075 1076
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1077 1078 1079 1080 1081 1082 1083
}

// 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);
1084 1085
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1086 1087 1088 1089 1090 1091 1092
}

// 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);
1093 1094
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
1095 1096 1097 1098 1099 1100 1101 1102
    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);
1103 1104
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120
    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);
1121 1122 1123
    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);
1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140
    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);
1141 1142
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1143 1144 1145 1146 1147 1148 1149 1150
    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);
1151 1152
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1153 1154 1155
    tcg_gen_xori_tl(dst, dst, 0x1);
}

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

    l1 = gen_new_label();

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

1165
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
B
bellard 已提交
1166 1167

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

B
blueswir1 已提交
1171
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
1172
                                target_ulong pc2, TCGv r_cond)
B
bellard 已提交
1173 1174 1175 1176 1177
{
    int l1;

    l1 = gen_new_label();

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

1180
    gen_goto_tb(dc, 0, pc2, pc1);
B
bellard 已提交
1181 1182

    gen_set_label(l1);
1183
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
B
bellard 已提交
1184 1185
}

1186 1187
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
                                      TCGv r_cond)
B
bellard 已提交
1188 1189 1190 1191 1192
{
    int l1, l2;

    l1 = gen_new_label();
    l2 = gen_new_label();
1193

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

B
blueswir1 已提交
1196
    tcg_gen_movi_tl(cpu_npc, npc1);
B
blueswir1 已提交
1197
    tcg_gen_br(l2);
B
bellard 已提交
1198 1199

    gen_set_label(l1);
B
blueswir1 已提交
1200
    tcg_gen_movi_tl(cpu_npc, npc2);
B
bellard 已提交
1201 1202 1203
    gen_set_label(l2);
}

1204 1205 1206
/* 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 已提交
1207 1208
{
    if (dc->npc == JUMP_PC) {
1209
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
B
bellard 已提交
1210 1211 1212 1213
        dc->npc = DYNAMIC_PC;
    }
}

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

1224
static inline void save_state(DisasContext *dc, TCGv cond)
B
bellard 已提交
1225
{
B
blueswir1 已提交
1226
    tcg_gen_movi_tl(cpu_pc, dc->pc);
1227
    save_npc(dc, cond);
B
bellard 已提交
1228 1229
}

1230
static inline void gen_mov_pc_npc(DisasContext *dc, TCGv cond)
B
bellard 已提交
1231 1232
{
    if (dc->npc == JUMP_PC) {
1233
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
B
blueswir1 已提交
1234
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
B
bellard 已提交
1235 1236
        dc->pc = DYNAMIC_PC;
    } else if (dc->npc == DYNAMIC_PC) {
B
blueswir1 已提交
1237
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
B
bellard 已提交
1238 1239 1240 1241 1242 1243
        dc->pc = DYNAMIC_PC;
    } else {
        dc->pc = dc->npc;
    }
}

1244 1245
static inline void gen_op_next_insn(void)
{
B
blueswir1 已提交
1246 1247
    tcg_gen_mov_tl(cpu_pc, cpu_npc);
    tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
1248 1249
}

1250 1251
static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond,
                            DisasContext *dc)
1252
{
P
pbrook 已提交
1253
    TCGv_i32 r_src;
B
bellard 已提交
1254 1255

#ifdef TARGET_SPARC64
1256
    if (cc)
1257
        r_src = cpu_xcc;
1258
    else
1259
        r_src = cpu_psr;
B
bellard 已提交
1260
#else
1261
    r_src = cpu_psr;
B
bellard 已提交
1262
#endif
1263 1264 1265 1266 1267 1268 1269 1270
    switch (dc->cc_op) {
    case CC_OP_FLAGS:
        break;
    default:
        gen_helper_compute_psr();
        dc->cc_op = CC_OP_FLAGS;
        break;
    }
1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321
    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;
    }
}
1322

1323
static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
1324
{
1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347
    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 已提交
1348
        gen_op_eval_fbne(r_dst, cpu_fsr, offset);
1349 1350
        break;
    case 0x2:
B
blueswir1 已提交
1351
        gen_op_eval_fblg(r_dst, cpu_fsr, offset);
1352 1353
        break;
    case 0x3:
B
blueswir1 已提交
1354
        gen_op_eval_fbul(r_dst, cpu_fsr, offset);
1355 1356
        break;
    case 0x4:
B
blueswir1 已提交
1357
        gen_op_eval_fbl(r_dst, cpu_fsr, offset);
1358 1359
        break;
    case 0x5:
B
blueswir1 已提交
1360
        gen_op_eval_fbug(r_dst, cpu_fsr, offset);
1361 1362
        break;
    case 0x6:
B
blueswir1 已提交
1363
        gen_op_eval_fbg(r_dst, cpu_fsr, offset);
1364 1365
        break;
    case 0x7:
B
blueswir1 已提交
1366
        gen_op_eval_fbu(r_dst, cpu_fsr, offset);
1367 1368 1369 1370 1371
        break;
    case 0x8:
        gen_op_eval_ba(r_dst);
        break;
    case 0x9:
B
blueswir1 已提交
1372
        gen_op_eval_fbe(r_dst, cpu_fsr, offset);
1373 1374
        break;
    case 0xa:
B
blueswir1 已提交
1375
        gen_op_eval_fbue(r_dst, cpu_fsr, offset);
1376 1377
        break;
    case 0xb:
B
blueswir1 已提交
1378
        gen_op_eval_fbge(r_dst, cpu_fsr, offset);
1379 1380
        break;
    case 0xc:
B
blueswir1 已提交
1381
        gen_op_eval_fbuge(r_dst, cpu_fsr, offset);
1382 1383
        break;
    case 0xd:
B
blueswir1 已提交
1384
        gen_op_eval_fble(r_dst, cpu_fsr, offset);
1385 1386
        break;
    case 0xe:
B
blueswir1 已提交
1387
        gen_op_eval_fbule(r_dst, cpu_fsr, offset);
1388 1389
        break;
    case 0xf:
B
blueswir1 已提交
1390
        gen_op_eval_fbo(r_dst, cpu_fsr, offset);
1391 1392
        break;
    }
1393
}
1394

1395
#ifdef TARGET_SPARC64
1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406
// 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,
};
1407

1408
static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
1409 1410 1411 1412
{
    int l1;

    l1 = gen_new_label();
1413
    tcg_gen_movi_tl(r_dst, 0);
P
pbrook 已提交
1414
    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], r_src, 0, l1);
1415 1416 1417
    tcg_gen_movi_tl(r_dst, 1);
    gen_set_label(l1);
}
B
bellard 已提交
1418
#endif
1419

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

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

B
bellard 已提交
1460
/* XXX: potentially incorrect if dynamic npc */
1461 1462
static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
                      TCGv r_cond)
1463 1464
{
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1465 1466
    target_ulong target = dc->pc + offset;

1467
    if (cond == 0x0) {
B
blueswir1 已提交
1468 1469 1470 1471 1472 1473 1474 1475
        /* 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;
        }
1476
    } else if (cond == 0x8) {
B
blueswir1 已提交
1477 1478 1479 1480 1481 1482 1483 1484
        /* unconditional taken */
        if (a) {
            dc->pc = target;
            dc->npc = dc->pc + 4;
        } else {
            dc->pc = dc->npc;
            dc->npc = target;
        }
1485
    } else {
1486 1487
        flush_cond(dc, r_cond);
        gen_fcond(r_cond, cc, cond);
B
blueswir1 已提交
1488
        if (a) {
1489
            gen_branch_a(dc, target, dc->npc, r_cond);
1490
            dc->is_br = 1;
B
blueswir1 已提交
1491
        } else {
1492 1493 1494 1495
            dc->pc = dc->npc;
            dc->jump_pc[0] = target;
            dc->jump_pc[1] = dc->npc + 4;
            dc->npc = JUMP_PC;
B
blueswir1 已提交
1496
        }
1497 1498 1499
    }
}

B
bellard 已提交
1500 1501
#ifdef TARGET_SPARC64
/* XXX: potentially incorrect if dynamic npc */
1502 1503
static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
                          TCGv r_cond, TCGv r_reg)
1504
{
B
bellard 已提交
1505 1506 1507
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
    target_ulong target = dc->pc + offset;

1508 1509
    flush_cond(dc, r_cond);
    gen_cond_reg(r_cond, cond, r_reg);
B
bellard 已提交
1510
    if (a) {
1511
        gen_branch_a(dc, target, dc->npc, r_cond);
B
blueswir1 已提交
1512
        dc->is_br = 1;
B
bellard 已提交
1513
    } else {
B
blueswir1 已提交
1514 1515 1516 1517
        dc->pc = dc->npc;
        dc->jump_pc[0] = target;
        dc->jump_pc[1] = dc->npc + 4;
        dc->npc = JUMP_PC;
B
bellard 已提交
1518
    }
1519 1520
}

P
pbrook 已提交
1521
static inline void gen_op_fcmps(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
1522
{
B
blueswir1 已提交
1523 1524
    switch (fccno) {
    case 0:
P
pbrook 已提交
1525
        gen_helper_fcmps(r_rs1, r_rs2);
B
blueswir1 已提交
1526 1527
        break;
    case 1:
P
pbrook 已提交
1528
        gen_helper_fcmps_fcc1(r_rs1, r_rs2);
B
blueswir1 已提交
1529 1530
        break;
    case 2:
P
pbrook 已提交
1531
        gen_helper_fcmps_fcc2(r_rs1, r_rs2);
B
blueswir1 已提交
1532 1533
        break;
    case 3:
P
pbrook 已提交
1534
        gen_helper_fcmps_fcc3(r_rs1, r_rs2);
B
blueswir1 已提交
1535 1536
        break;
    }
1537 1538 1539 1540
}

static inline void gen_op_fcmpd(int fccno)
{
P
pbrook 已提交
1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554
    switch (fccno) {
    case 0:
        gen_helper_fcmpd();
        break;
    case 1:
        gen_helper_fcmpd_fcc1();
        break;
    case 2:
        gen_helper_fcmpd_fcc2();
        break;
    case 3:
        gen_helper_fcmpd_fcc3();
        break;
    }
1555 1556 1557 1558
}

static inline void gen_op_fcmpq(int fccno)
{
P
pbrook 已提交
1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572
    switch (fccno) {
    case 0:
        gen_helper_fcmpq();
        break;
    case 1:
        gen_helper_fcmpq_fcc1();
        break;
    case 2:
        gen_helper_fcmpq_fcc2();
        break;
    case 3:
        gen_helper_fcmpq_fcc3();
        break;
    }
1573 1574
}

P
pbrook 已提交
1575
static inline void gen_op_fcmpes(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
1576
{
B
blueswir1 已提交
1577 1578
    switch (fccno) {
    case 0:
P
pbrook 已提交
1579
        gen_helper_fcmpes(r_rs1, r_rs2);
B
blueswir1 已提交
1580 1581
        break;
    case 1:
P
pbrook 已提交
1582
        gen_helper_fcmpes_fcc1(r_rs1, r_rs2);
B
blueswir1 已提交
1583 1584
        break;
    case 2:
P
pbrook 已提交
1585
        gen_helper_fcmpes_fcc2(r_rs1, r_rs2);
B
blueswir1 已提交
1586 1587
        break;
    case 3:
P
pbrook 已提交
1588
        gen_helper_fcmpes_fcc3(r_rs1, r_rs2);
B
blueswir1 已提交
1589 1590
        break;
    }
1591 1592 1593 1594
}

static inline void gen_op_fcmped(int fccno)
{
P
pbrook 已提交
1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608
    switch (fccno) {
    case 0:
        gen_helper_fcmped();
        break;
    case 1:
        gen_helper_fcmped_fcc1();
        break;
    case 2:
        gen_helper_fcmped_fcc2();
        break;
    case 3:
        gen_helper_fcmped_fcc3();
        break;
    }
1609 1610 1611 1612
}

static inline void gen_op_fcmpeq(int fccno)
{
P
pbrook 已提交
1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626
    switch (fccno) {
    case 0:
        gen_helper_fcmpeq();
        break;
    case 1:
        gen_helper_fcmpeq_fcc1();
        break;
    case 2:
        gen_helper_fcmpeq_fcc2();
        break;
    case 3:
        gen_helper_fcmpeq_fcc3();
        break;
    }
1627 1628 1629 1630
}

#else

B
blueswir1 已提交
1631
static inline void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2)
1632
{
P
pbrook 已提交
1633
    gen_helper_fcmps(r_rs1, r_rs2);
1634 1635 1636 1637
}

static inline void gen_op_fcmpd(int fccno)
{
P
pbrook 已提交
1638
    gen_helper_fcmpd();
1639 1640 1641 1642
}

static inline void gen_op_fcmpq(int fccno)
{
P
pbrook 已提交
1643
    gen_helper_fcmpq();
1644 1645
}

B
blueswir1 已提交
1646
static inline void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2)
1647
{
P
pbrook 已提交
1648
    gen_helper_fcmpes(r_rs1, r_rs2);
1649 1650 1651 1652
}

static inline void gen_op_fcmped(int fccno)
{
P
pbrook 已提交
1653
    gen_helper_fcmped();
1654 1655 1656 1657
}

static inline void gen_op_fcmpeq(int fccno)
{
P
pbrook 已提交
1658
    gen_helper_fcmpeq();
1659 1660 1661
}
#endif

B
blueswir1 已提交
1662 1663
static inline void gen_op_fpexception_im(int fsr_flags)
{
P
pbrook 已提交
1664
    TCGv_i32 r_const;
B
blueswir1 已提交
1665

1666
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_NMASK);
B
blueswir1 已提交
1667
    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
B
blueswir1 已提交
1668
    r_const = tcg_const_i32(TT_FP_EXCP);
P
pbrook 已提交
1669 1670
    gen_helper_raise_exception(r_const);
    tcg_temp_free_i32(r_const);
B
blueswir1 已提交
1671 1672
}

1673
static int gen_trap_ifnofpu(DisasContext *dc, TCGv r_cond)
B
bellard 已提交
1674 1675 1676
{
#if !defined(CONFIG_USER_ONLY)
    if (!dc->fpu_enabled) {
P
pbrook 已提交
1677
        TCGv_i32 r_const;
B
blueswir1 已提交
1678

1679
        save_state(dc, r_cond);
B
blueswir1 已提交
1680
        r_const = tcg_const_i32(TT_NFPU_INSN);
P
pbrook 已提交
1681 1682
        gen_helper_raise_exception(r_const);
        tcg_temp_free_i32(r_const);
B
bellard 已提交
1683 1684 1685 1686 1687 1688 1689
        dc->is_br = 1;
        return 1;
    }
#endif
    return 0;
}

1690 1691
static inline void gen_op_clear_ieee_excp_and_FTT(void)
{
1692
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_CEXC_NMASK);
1693 1694 1695 1696
}

static inline void gen_clear_float_exceptions(void)
{
P
pbrook 已提交
1697
    gen_helper_clear_float_exceptions();
1698 1699
}

B
blueswir1 已提交
1700 1701
/* asi moves */
#ifdef TARGET_SPARC64
P
pbrook 已提交
1702
static inline TCGv_i32 gen_get_asi(int insn, TCGv r_addr)
B
blueswir1 已提交
1703
{
1704
    int asi;
P
pbrook 已提交
1705
    TCGv_i32 r_asi;
B
blueswir1 已提交
1706 1707

    if (IS_IMM) {
P
pbrook 已提交
1708
        r_asi = tcg_temp_new_i32();
1709
        tcg_gen_mov_i32(r_asi, cpu_asi);
B
blueswir1 已提交
1710 1711
    } else {
        asi = GET_FIELD(insn, 19, 26);
1712
        r_asi = tcg_const_i32(asi);
B
blueswir1 已提交
1713
    }
1714 1715 1716
    return r_asi;
}

B
blueswir1 已提交
1717 1718
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
                              int sign)
1719
{
P
pbrook 已提交
1720
    TCGv_i32 r_asi, r_size, r_sign;
1721

1722
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1723 1724
    r_size = tcg_const_i32(size);
    r_sign = tcg_const_i32(sign);
P
pbrook 已提交
1725 1726 1727 1728
    gen_helper_ld_asi(dst, addr, r_asi, r_size, r_sign);
    tcg_temp_free_i32(r_sign);
    tcg_temp_free_i32(r_size);
    tcg_temp_free_i32(r_asi);
B
blueswir1 已提交
1729 1730
}

1731
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
B
blueswir1 已提交
1732
{
P
pbrook 已提交
1733
    TCGv_i32 r_asi, r_size;
B
blueswir1 已提交
1734

1735
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1736
    r_size = tcg_const_i32(size);
P
pbrook 已提交
1737 1738 1739
    gen_helper_st_asi(addr, src, r_asi, r_size);
    tcg_temp_free_i32(r_size);
    tcg_temp_free_i32(r_asi);
B
blueswir1 已提交
1740 1741
}

1742
static inline void gen_ldf_asi(TCGv addr, int insn, int size, int rd)
B
blueswir1 已提交
1743
{
P
pbrook 已提交
1744
    TCGv_i32 r_asi, r_size, r_rd;
B
blueswir1 已提交
1745

1746
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1747 1748
    r_size = tcg_const_i32(size);
    r_rd = tcg_const_i32(rd);
P
pbrook 已提交
1749 1750 1751 1752
    gen_helper_ldf_asi(addr, r_asi, r_size, r_rd);
    tcg_temp_free_i32(r_rd);
    tcg_temp_free_i32(r_size);
    tcg_temp_free_i32(r_asi);
B
blueswir1 已提交
1753 1754
}

1755
static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
B
blueswir1 已提交
1756
{
P
pbrook 已提交
1757
    TCGv_i32 r_asi, r_size, r_rd;
B
blueswir1 已提交
1758

1759
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1760 1761
    r_size = tcg_const_i32(size);
    r_rd = tcg_const_i32(rd);
P
pbrook 已提交
1762 1763 1764 1765
    gen_helper_stf_asi(addr, r_asi, r_size, r_rd);
    tcg_temp_free_i32(r_rd);
    tcg_temp_free_i32(r_size);
    tcg_temp_free_i32(r_asi);
B
blueswir1 已提交
1766 1767
}

1768
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
B
blueswir1 已提交
1769
{
P
pbrook 已提交
1770
    TCGv_i32 r_asi, r_size, r_sign;
B
blueswir1 已提交
1771

1772
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1773 1774
    r_size = tcg_const_i32(4);
    r_sign = tcg_const_i32(0);
P
pbrook 已提交
1775 1776 1777 1778 1779
    gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
    tcg_temp_free_i32(r_sign);
    gen_helper_st_asi(addr, dst, r_asi, r_size);
    tcg_temp_free_i32(r_size);
    tcg_temp_free_i32(r_asi);
B
blueswir1 已提交
1780
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
B
blueswir1 已提交
1781 1782
}

B
blueswir1 已提交
1783
static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
B
blueswir1 已提交
1784
{
P
pbrook 已提交
1785
    TCGv_i32 r_asi, r_rd;
B
blueswir1 已提交
1786

1787
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1788
    r_rd = tcg_const_i32(rd);
P
pbrook 已提交
1789 1790 1791
    gen_helper_ldda_asi(addr, r_asi, r_rd);
    tcg_temp_free_i32(r_rd);
    tcg_temp_free_i32(r_asi);
1792 1793
}

1794
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1795
{
P
pbrook 已提交
1796
    TCGv_i32 r_asi, r_size;
1797 1798

    gen_movl_reg_TN(rd + 1, cpu_tmp0);
1799
    tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, hi);
1800
    r_asi = gen_get_asi(insn, addr);
B
blueswir1 已提交
1801
    r_size = tcg_const_i32(8);
P
pbrook 已提交
1802 1803 1804
    gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
    tcg_temp_free_i32(r_size);
    tcg_temp_free_i32(r_asi);
B
blueswir1 已提交
1805 1806
}

B
blueswir1 已提交
1807 1808
static inline void gen_cas_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
                               int rd)
B
blueswir1 已提交
1809
{
P
pbrook 已提交
1810 1811
    TCGv r_val1;
    TCGv_i32 r_asi;
B
blueswir1 已提交
1812

P
pbrook 已提交
1813
    r_val1 = tcg_temp_new();
B
blueswir1 已提交
1814
    gen_movl_reg_TN(rd, r_val1);
1815
    r_asi = gen_get_asi(insn, addr);
P
pbrook 已提交
1816 1817
    gen_helper_cas_asi(dst, addr, r_val1, val2, r_asi);
    tcg_temp_free_i32(r_asi);
B
blueswir1 已提交
1818
    tcg_temp_free(r_val1);
B
blueswir1 已提交
1819 1820
}

B
blueswir1 已提交
1821 1822
static inline void gen_casx_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
                                int rd)
B
blueswir1 已提交
1823
{
P
pbrook 已提交
1824
    TCGv_i32 r_asi;
B
blueswir1 已提交
1825

B
blueswir1 已提交
1826
    gen_movl_reg_TN(rd, cpu_tmp64);
1827
    r_asi = gen_get_asi(insn, addr);
P
pbrook 已提交
1828 1829
    gen_helper_casx_asi(dst, addr, cpu_tmp64, val2, r_asi);
    tcg_temp_free_i32(r_asi);
B
blueswir1 已提交
1830 1831 1832 1833
}

#elif !defined(CONFIG_USER_ONLY)

B
blueswir1 已提交
1834 1835
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
                              int sign)
B
blueswir1 已提交
1836
{
P
pbrook 已提交
1837
    TCGv_i32 r_asi, r_size, r_sign;
B
blueswir1 已提交
1838

B
blueswir1 已提交
1839 1840 1841
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(size);
    r_sign = tcg_const_i32(sign);
P
pbrook 已提交
1842
    gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
B
blueswir1 已提交
1843 1844 1845
    tcg_temp_free(r_sign);
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
1846
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
B
blueswir1 已提交
1847 1848
}

1849
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
B
blueswir1 已提交
1850
{
P
pbrook 已提交
1851
    TCGv_i32 r_asi, r_size;
B
blueswir1 已提交
1852

1853
    tcg_gen_extu_tl_i64(cpu_tmp64, src);
B
blueswir1 已提交
1854 1855
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(size);
P
pbrook 已提交
1856
    gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
B
blueswir1 已提交
1857 1858
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
B
blueswir1 已提交
1859 1860
}

1861
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
B
blueswir1 已提交
1862
{
P
pbrook 已提交
1863 1864
    TCGv_i32 r_asi, r_size, r_sign;
    TCGv_i64 r_val;
B
blueswir1 已提交
1865

B
blueswir1 已提交
1866 1867 1868
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(4);
    r_sign = tcg_const_i32(0);
P
pbrook 已提交
1869
    gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
B
blueswir1 已提交
1870
    tcg_temp_free(r_sign);
P
pbrook 已提交
1871 1872 1873 1874
    r_val = tcg_temp_new_i64();
    tcg_gen_extu_tl_i64(r_val, dst);
    gen_helper_st_asi(addr, r_val, r_asi, r_size);
    tcg_temp_free_i64(r_val);
B
blueswir1 已提交
1875 1876
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
B
blueswir1 已提交
1877
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
B
blueswir1 已提交
1878 1879
}

B
blueswir1 已提交
1880
static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
B
blueswir1 已提交
1881
{
P
pbrook 已提交
1882
    TCGv_i32 r_asi, r_size, r_sign;
B
blueswir1 已提交
1883

B
blueswir1 已提交
1884 1885 1886
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(8);
    r_sign = tcg_const_i32(0);
P
pbrook 已提交
1887
    gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
B
blueswir1 已提交
1888 1889 1890
    tcg_temp_free(r_sign);
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
B
blueswir1 已提交
1891 1892
    tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
    gen_movl_TN_reg(rd + 1, cpu_tmp0);
B
blueswir1 已提交
1893
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1894
    tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
B
blueswir1 已提交
1895
    gen_movl_TN_reg(rd, hi);
1896 1897
}

1898
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1899
{
P
pbrook 已提交
1900
    TCGv_i32 r_asi, r_size;
1901 1902

    gen_movl_reg_TN(rd + 1, cpu_tmp0);
1903
    tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, hi);
B
blueswir1 已提交
1904 1905
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(8);
P
pbrook 已提交
1906
    gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
B
blueswir1 已提交
1907 1908
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
B
blueswir1 已提交
1909 1910 1911 1912
}
#endif

#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1913
static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
B
blueswir1 已提交
1914
{
P
pbrook 已提交
1915 1916
    TCGv_i64 r_val;
    TCGv_i32 r_asi, r_size;
B
blueswir1 已提交
1917

1918
    gen_ld_asi(dst, addr, insn, 1, 0);
B
blueswir1 已提交
1919

B
blueswir1 已提交
1920 1921 1922
    r_val = tcg_const_i64(0xffULL);
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(1);
P
pbrook 已提交
1923 1924 1925 1926
    gen_helper_st_asi(addr, r_val, r_asi, r_size);
    tcg_temp_free_i32(r_size);
    tcg_temp_free_i32(r_asi);
    tcg_temp_free_i64(r_val);
B
blueswir1 已提交
1927 1928 1929
}
#endif

1930 1931 1932 1933 1934 1935 1936
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)
1937
        r_rs1 = tcg_const_tl(0); // XXX how to free?
1938
    else if (rs1 < 8)
1939
        r_rs1 = cpu_gregs[rs1];
1940 1941 1942 1943 1944
    else
        tcg_gen_ld_tl(def, cpu_regwptr, (rs1 - 8) * sizeof(target_ulong));
    return r_rs1;
}

B
blueswir1 已提交
1945 1946 1947 1948 1949
static inline TCGv get_src2(unsigned int insn, TCGv def)
{
    TCGv r_rs2 = def;

    if (IS_IMM) { /* immediate */
B
Blue Swirl 已提交
1950 1951 1952 1953
        target_long simm;

        simm = GET_FIELDs(insn, 19, 31);
        r_rs2 = tcg_const_tl(simm); // XXX how to free?
B
blueswir1 已提交
1954
    } else { /* register */
B
Blue Swirl 已提交
1955 1956
        unsigned int rs2;

B
blueswir1 已提交
1957 1958
        rs2 = GET_FIELD(insn, 27, 31);
        if (rs2 == 0)
B
blueswir1 已提交
1959
            r_rs2 = tcg_const_tl(0); // XXX how to free?
B
blueswir1 已提交
1960 1961 1962 1963 1964 1965 1966 1967
        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 已提交
1968
#define CHECK_IU_FEATURE(dc, FEATURE)                      \
1969
    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
B
blueswir1 已提交
1970 1971
        goto illegal_insn;
#define CHECK_FPU_FEATURE(dc, FEATURE)                     \
1972
    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
B
blueswir1 已提交
1973 1974
        goto nfpu_insn;

B
bellard 已提交
1975
/* before an instruction, dc->pc must be static */
1976 1977 1978
static void disas_sparc_insn(DisasContext * dc)
{
    unsigned int insn, opc, rs1, rs2, rd;
B
Blue Swirl 已提交
1979
    target_long simm;
1980

1981
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
B
blueswir1 已提交
1982
        tcg_gen_debug_insn_start(dc->pc);
B
bellard 已提交
1983
    insn = ldl_code(dc->pc);
1984
    opc = GET_FIELD(insn, 0, 1);
1985

1986
    rd = GET_FIELD(insn, 2, 6);
1987

P
pbrook 已提交
1988 1989
    cpu_src1 = tcg_temp_new(); // const
    cpu_src2 = tcg_temp_new(); // const
1990

1991
    switch (opc) {
B
blueswir1 已提交
1992 1993 1994 1995 1996
    case 0:                     /* branches/sethi */
        {
            unsigned int xop = GET_FIELD(insn, 7, 9);
            int32_t target;
            switch (xop) {
B
bellard 已提交
1997
#ifdef TARGET_SPARC64
B
blueswir1 已提交
1998 1999 2000 2001 2002 2003 2004 2005 2006
            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)
2007
                        do_branch(dc, target, insn, 0, cpu_cond);
B
blueswir1 已提交
2008
                    else if (cc == 2)
2009
                        do_branch(dc, target, insn, 1, cpu_cond);
B
blueswir1 已提交
2010 2011 2012 2013 2014 2015 2016
                    else
                        goto illegal_insn;
                    goto jmp_insn;
                }
            case 0x3:           /* V9 BPr */
                {
                    target = GET_FIELD_SP(insn, 0, 13) |
2017
                        (GET_FIELD_SP(insn, 20, 21) << 14);
B
blueswir1 已提交
2018 2019
                    target = sign_extend(target, 16);
                    target <<= 2;
2020
                    cpu_src1 = get_src1(insn, cpu_src1);
2021
                    do_branch_reg(dc, target, insn, cpu_cond, cpu_src1);
B
blueswir1 已提交
2022 2023 2024 2025 2026
                    goto jmp_insn;
                }
            case 0x5:           /* V9 FBPcc */
                {
                    int cc = GET_FIELD_SP(insn, 20, 21);
2027
                    if (gen_trap_ifnofpu(dc, cpu_cond))
B
bellard 已提交
2028
                        goto jmp_insn;
B
blueswir1 已提交
2029 2030 2031
                    target = GET_FIELD_SP(insn, 0, 18);
                    target = sign_extend(target, 19);
                    target <<= 2;
2032
                    do_fbranch(dc, target, insn, cc, cpu_cond);
B
blueswir1 已提交
2033 2034
                    goto jmp_insn;
                }
2035
#else
B
blueswir1 已提交
2036 2037 2038 2039 2040 2041 2042 2043 2044 2045
            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;
2046
                    do_branch(dc, target, insn, 0, cpu_cond);
B
blueswir1 已提交
2047 2048 2049 2050
                    goto jmp_insn;
                }
            case 0x6:           /* FBN+x */
                {
2051
                    if (gen_trap_ifnofpu(dc, cpu_cond))
B
bellard 已提交
2052
                        goto jmp_insn;
B
blueswir1 已提交
2053 2054 2055
                    target = GET_FIELD(insn, 10, 31);
                    target = sign_extend(target, 22);
                    target <<= 2;
2056
                    do_fbranch(dc, target, insn, 0, cpu_cond);
B
blueswir1 已提交
2057 2058 2059 2060 2061
                    goto jmp_insn;
                }
            case 0x4:           /* SETHI */
                if (rd) { // nop
                    uint32_t value = GET_FIELD(insn, 10, 31);
B
blueswir1 已提交
2062 2063 2064 2065 2066
                    TCGv r_const;

                    r_const = tcg_const_tl(value << 10);
                    gen_movl_TN_reg(rd, r_const);
                    tcg_temp_free(r_const);
B
blueswir1 已提交
2067 2068 2069 2070
                }
                break;
            case 0x0:           /* UNIMPL */
            default:
B
bellard 已提交
2071
                goto illegal_insn;
B
blueswir1 已提交
2072 2073 2074 2075
            }
            break;
        }
        break;
B
Blue Swirl 已提交
2076 2077
    case 1:                     /*CALL*/
        {
B
blueswir1 已提交
2078
            target_long target = GET_FIELDs(insn, 2, 31) << 2;
B
blueswir1 已提交
2079
            TCGv r_const;
2080

B
blueswir1 已提交
2081 2082 2083
            r_const = tcg_const_tl(dc->pc);
            gen_movl_TN_reg(15, r_const);
            tcg_temp_free(r_const);
B
blueswir1 已提交
2084
            target += dc->pc;
2085
            gen_mov_pc_npc(dc, cpu_cond);
B
blueswir1 已提交
2086 2087 2088 2089 2090 2091 2092
            dc->npc = target;
        }
        goto jmp_insn;
    case 2:                     /* FPU & Logical Operations */
        {
            unsigned int xop = GET_FIELD(insn, 7, 12);
            if (xop == 0x3a) {  /* generate trap */
2093
                int cond;
B
bellard 已提交
2094

2095
                cpu_src1 = get_src1(insn, cpu_src1);
B
blueswir1 已提交
2096 2097
                if (IS_IMM) {
                    rs2 = GET_FIELD(insn, 25, 31);
2098
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, rs2);
2099 2100
                } else {
                    rs2 = GET_FIELD(insn, 27, 31);
B
blueswir1 已提交
2101
                    if (rs2 != 0) {
2102 2103
                        gen_movl_reg_TN(rs2, cpu_src2);
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
2104 2105
                    } else
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
2106 2107 2108
                }
                cond = GET_FIELD(insn, 3, 6);
                if (cond == 0x8) {
2109
                    save_state(dc, cpu_cond);
B
blueswir1 已提交
2110 2111 2112 2113 2114 2115
                    if ((dc->def->features & CPU_FEATURE_HYPV) &&
                        supervisor(dc))
                        tcg_gen_andi_tl(cpu_dst, cpu_dst, UA2005_HTRAP_MASK);
                    else
                        tcg_gen_andi_tl(cpu_dst, cpu_dst, V8_TRAP_MASK);
                    tcg_gen_addi_tl(cpu_dst, cpu_dst, TT_TRAP);
P
pbrook 已提交
2116 2117
                    tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
                    gen_helper_raise_exception(cpu_tmp32);
2118
                } else if (cond != 0) {
P
pbrook 已提交
2119
                    TCGv r_cond = tcg_temp_new();
B
blueswir1 已提交
2120
                    int l1;
B
bellard 已提交
2121
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2122 2123
                    /* V9 icc/xcc */
                    int cc = GET_FIELD_SP(insn, 11, 12);
B
blueswir1 已提交
2124

2125
                    save_state(dc, cpu_cond);
B
blueswir1 已提交
2126
                    if (cc == 0)
2127
                        gen_cond(r_cond, 0, cond, dc);
B
blueswir1 已提交
2128
                    else if (cc == 2)
2129
                        gen_cond(r_cond, 1, cond, dc);
B
blueswir1 已提交
2130 2131
                    else
                        goto illegal_insn;
B
bellard 已提交
2132
#else
2133
                    save_state(dc, cpu_cond);
2134
                    gen_cond(r_cond, 0, cond, dc);
B
bellard 已提交
2135
#endif
B
blueswir1 已提交
2136 2137 2138 2139 2140 2141 2142 2143 2144
                    l1 = gen_new_label();
                    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);

                    if ((dc->def->features & CPU_FEATURE_HYPV) &&
                        supervisor(dc))
                        tcg_gen_andi_tl(cpu_dst, cpu_dst, UA2005_HTRAP_MASK);
                    else
                        tcg_gen_andi_tl(cpu_dst, cpu_dst, V8_TRAP_MASK);
                    tcg_gen_addi_tl(cpu_dst, cpu_dst, TT_TRAP);
P
pbrook 已提交
2145 2146
                    tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
                    gen_helper_raise_exception(cpu_tmp32);
B
blueswir1 已提交
2147 2148

                    gen_set_label(l1);
B
blueswir1 已提交
2149
                    tcg_temp_free(r_cond);
2150
                }
B
bellard 已提交
2151
                gen_op_next_insn();
B
bellard 已提交
2152
                tcg_gen_exit_tb(0);
B
bellard 已提交
2153 2154
                dc->is_br = 1;
                goto jmp_insn;
2155 2156 2157 2158
            } else if (xop == 0x28) {
                rs1 = GET_FIELD(insn, 13, 17);
                switch(rs1) {
                case 0: /* rdy */
2159 2160 2161 2162 2163 2164 2165 2166 2167 2168
#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
2169
                    gen_movl_TN_reg(rd, cpu_y);
2170
                    break;
B
bellard 已提交
2171
#ifdef TARGET_SPARC64
B
blueswir1 已提交
2172
                case 0x2: /* V9 rdccr */
2173
                    gen_helper_compute_psr();
P
pbrook 已提交
2174
                    gen_helper_rdccr(cpu_dst);
2175
                    gen_movl_TN_reg(rd, cpu_dst);
B
bellard 已提交
2176
                    break;
B
blueswir1 已提交
2177
                case 0x3: /* V9 rdasi */
2178
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_asi);
2179
                    gen_movl_TN_reg(rd, cpu_dst);
B
bellard 已提交
2180
                    break;
B
blueswir1 已提交
2181
                case 0x4: /* V9 rdtick */
B
blueswir1 已提交
2182
                    {
P
pbrook 已提交
2183
                        TCGv_ptr r_tickptr;
B
blueswir1 已提交
2184

P
pbrook 已提交
2185
                        r_tickptr = tcg_temp_new_ptr();
B
blueswir1 已提交
2186 2187
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                       offsetof(CPUState, tick));
P
pbrook 已提交
2188 2189
                        gen_helper_tick_get_count(cpu_dst, r_tickptr);
                        tcg_temp_free_ptr(r_tickptr);
2190
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
2191
                    }
B
bellard 已提交
2192
                    break;
B
blueswir1 已提交
2193
                case 0x5: /* V9 rdpc */
B
blueswir1 已提交
2194 2195 2196 2197 2198 2199 2200
                    {
                        TCGv r_const;

                        r_const = tcg_const_tl(dc->pc);
                        gen_movl_TN_reg(rd, r_const);
                        tcg_temp_free(r_const);
                    }
B
blueswir1 已提交
2201 2202
                    break;
                case 0x6: /* V9 rdfprs */
2203
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_fprs);
2204
                    gen_movl_TN_reg(rd, cpu_dst);
B
bellard 已提交
2205
                    break;
2206 2207
                case 0xf: /* V9 membar */
                    break; /* no effect */
B
blueswir1 已提交
2208
                case 0x13: /* Graphics Status */
2209
                    if (gen_trap_ifnofpu(dc, cpu_cond))
B
bellard 已提交
2210
                        goto jmp_insn;
2211
                    gen_movl_TN_reg(rd, cpu_gsr);
B
bellard 已提交
2212
                    break;
2213 2214 2215 2216
                case 0x16: /* Softint */
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_softint);
                    gen_movl_TN_reg(rd, cpu_dst);
                    break;
B
blueswir1 已提交
2217
                case 0x17: /* Tick compare */
2218
                    gen_movl_TN_reg(rd, cpu_tick_cmpr);
B
bellard 已提交
2219
                    break;
B
blueswir1 已提交
2220
                case 0x18: /* System tick */
B
blueswir1 已提交
2221
                    {
P
pbrook 已提交
2222
                        TCGv_ptr r_tickptr;
B
blueswir1 已提交
2223

P
pbrook 已提交
2224
                        r_tickptr = tcg_temp_new_ptr();
B
blueswir1 已提交
2225 2226
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                       offsetof(CPUState, stick));
P
pbrook 已提交
2227 2228
                        gen_helper_tick_get_count(cpu_dst, r_tickptr);
                        tcg_temp_free_ptr(r_tickptr);
2229
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
2230
                    }
B
bellard 已提交
2231
                    break;
B
blueswir1 已提交
2232
                case 0x19: /* System tick compare */
2233
                    gen_movl_TN_reg(rd, cpu_stick_cmpr);
B
bellard 已提交
2234
                    break;
B
blueswir1 已提交
2235 2236 2237 2238 2239
                case 0x10: /* Performance Control */
                case 0x11: /* Performance Instrumentation Counter */
                case 0x12: /* Dispatch Control */
                case 0x14: /* Softint set, WO */
                case 0x15: /* Softint clear, WO */
B
bellard 已提交
2240 2241
#endif
                default:
2242 2243
                    goto illegal_insn;
                }
2244
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
2245
            } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
B
bellard 已提交
2246
#ifndef TARGET_SPARC64
B
blueswir1 已提交
2247 2248
                if (!supervisor(dc))
                    goto priv_insn;
2249 2250
                gen_helper_compute_psr();
                dc->cc_op = CC_OP_FLAGS;
P
pbrook 已提交
2251
                gen_helper_rdpsr(cpu_dst);
B
blueswir1 已提交
2252
#else
2253
                CHECK_IU_FEATURE(dc, HYPV);
B
blueswir1 已提交
2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264
                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
2265
                    tcg_gen_mov_tl(cpu_dst, cpu_hintp);
B
blueswir1 已提交
2266 2267
                    break;
                case 5: // htba
2268
                    tcg_gen_mov_tl(cpu_dst, cpu_htba);
B
blueswir1 已提交
2269 2270
                    break;
                case 6: // hver
2271
                    tcg_gen_mov_tl(cpu_dst, cpu_hver);
B
blueswir1 已提交
2272 2273
                    break;
                case 31: // hstick_cmpr
2274
                    tcg_gen_mov_tl(cpu_dst, cpu_hstick_cmpr);
B
blueswir1 已提交
2275 2276 2277 2278 2279
                    break;
                default:
                    goto illegal_insn;
                }
#endif
2280
                gen_movl_TN_reg(rd, cpu_dst);
2281
                break;
B
bellard 已提交
2282
            } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
B
blueswir1 已提交
2283 2284
                if (!supervisor(dc))
                    goto priv_insn;
B
bellard 已提交
2285 2286
#ifdef TARGET_SPARC64
                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
2287 2288
                switch (rs1) {
                case 0: // tpc
2289
                    {
P
pbrook 已提交
2290
                        TCGv_ptr r_tsptr;
2291

P
pbrook 已提交
2292
                        r_tsptr = tcg_temp_new_ptr();
2293 2294
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                       offsetof(CPUState, tsptr));
P
pbrook 已提交
2295
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2296
                                      offsetof(trap_state, tpc));
P
pbrook 已提交
2297
                        tcg_temp_free_ptr(r_tsptr);
2298
                    }
B
blueswir1 已提交
2299 2300
                    break;
                case 1: // tnpc
2301
                    {
P
pbrook 已提交
2302
                        TCGv_ptr r_tsptr;
2303

P
pbrook 已提交
2304
                        r_tsptr = tcg_temp_new_ptr();
2305 2306
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                       offsetof(CPUState, tsptr));
2307
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2308
                                      offsetof(trap_state, tnpc));
P
pbrook 已提交
2309
                        tcg_temp_free_ptr(r_tsptr);
2310
                    }
B
blueswir1 已提交
2311 2312
                    break;
                case 2: // tstate
2313
                    {
P
pbrook 已提交
2314
                        TCGv_ptr r_tsptr;
2315

P
pbrook 已提交
2316
                        r_tsptr = tcg_temp_new_ptr();
2317 2318
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                       offsetof(CPUState, tsptr));
2319
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2320
                                      offsetof(trap_state, tstate));
P
pbrook 已提交
2321
                        tcg_temp_free_ptr(r_tsptr);
2322
                    }
B
blueswir1 已提交
2323 2324
                    break;
                case 3: // tt
2325
                    {
P
pbrook 已提交
2326
                        TCGv_ptr r_tsptr;
2327

P
pbrook 已提交
2328
                        r_tsptr = tcg_temp_new_ptr();
2329 2330
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                       offsetof(CPUState, tsptr));
P
pbrook 已提交
2331
                        tcg_gen_ld_i32(cpu_tmp32, r_tsptr,
2332
                                       offsetof(trap_state, tt));
P
pbrook 已提交
2333 2334
                        tcg_temp_free_ptr(r_tsptr);
                        tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2335
                    }
B
blueswir1 已提交
2336 2337
                    break;
                case 4: // tick
B
blueswir1 已提交
2338
                    {
P
pbrook 已提交
2339
                        TCGv_ptr r_tickptr;
B
blueswir1 已提交
2340

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

                    l1 = gen_new_label();
B
blueswir1 已提交
2755
                    cond = GET_FIELD_SP(insn, 14, 17);
2756
                    cpu_src1 = get_src1(insn, cpu_src1);
P
pbrook 已提交
2757 2758
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
                                       0, l1);
B
blueswir1 已提交
2759
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);
B
blueswir1 已提交
2760
                    gen_set_label(l1);
B
blueswir1 已提交
2761 2762
                    break;
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
B
blueswir1 已提交
2763 2764 2765
                    int l1;

                    l1 = gen_new_label();
B
blueswir1 已提交
2766
                    cond = GET_FIELD_SP(insn, 14, 17);
2767
                    cpu_src1 = get_src1(insn, cpu_src1);
P
pbrook 已提交
2768 2769
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
                                       0, l1);
B
blueswir1 已提交
2770 2771
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)]);
                    tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], cpu_fpr[DFPREG(rs2) + 1]);
B
blueswir1 已提交
2772
                    gen_set_label(l1);
B
blueswir1 已提交
2773 2774
                    break;
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
B
blueswir1 已提交
2775 2776
                    int l1;

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

B
blueswir1 已提交
2947
                    case 0x101: /* V9 fmovscc %icc */
B
blueswir1 已提交
2948
                        FMOVSCC(0);
B
blueswir1 已提交
2949 2950
                        break;
                    case 0x102: /* V9 fmovdcc %icc */
B
blueswir1 已提交
2951
                        FMOVDCC(0);
B
blueswir1 已提交
2952
                    case 0x103: /* V9 fmovqcc %icc */
B
blueswir1 已提交
2953
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2954
                        FMOVQCC(0);
B
blueswir1 已提交
2955
                        break;
B
blueswir1 已提交
2956
                    case 0x181: /* V9 fmovscc %xcc */
B
blueswir1 已提交
2957
                        FMOVSCC(1);
B
blueswir1 已提交
2958 2959
                        break;
                    case 0x182: /* V9 fmovdcc %xcc */
B
blueswir1 已提交
2960
                        FMOVDCC(1);
B
blueswir1 已提交
2961 2962
                        break;
                    case 0x183: /* V9 fmovqcc %xcc */
B
blueswir1 已提交
2963
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2964
                        FMOVQCC(1);
B
blueswir1 已提交
2965
                        break;
B
blueswir1 已提交
2966 2967 2968
#undef FMOVSCC
#undef FMOVDCC
#undef FMOVQCC
B
blueswir1 已提交
2969 2970
#endif
                    case 0x51: /* fcmps, V9 %fcc */
B
blueswir1 已提交
2971
                        gen_op_fcmps(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]);
B
blueswir1 已提交
2972
                        break;
B
blueswir1 已提交
2973
                    case 0x52: /* fcmpd, V9 %fcc */
B
blueswir1 已提交
2974 2975
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2976
                        gen_op_fcmpd(rd & 3);
B
blueswir1 已提交
2977
                        break;
B
blueswir1 已提交
2978
                    case 0x53: /* fcmpq, V9 %fcc */
B
blueswir1 已提交
2979
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2980 2981
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2982
                        gen_op_fcmpq(rd & 3);
B
blueswir1 已提交
2983
                        break;
B
blueswir1 已提交
2984
                    case 0x55: /* fcmpes, V9 %fcc */
B
blueswir1 已提交
2985
                        gen_op_fcmpes(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]);
B
blueswir1 已提交
2986 2987 2988 2989
                        break;
                    case 0x56: /* fcmped, V9 %fcc */
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2990
                        gen_op_fcmped(rd & 3);
B
blueswir1 已提交
2991
                        break;
B
blueswir1 已提交
2992
                    case 0x57: /* fcmpeq, V9 %fcc */
B
blueswir1 已提交
2993
                        CHECK_FPU_FEATURE(dc, FLOAT128);
B
blueswir1 已提交
2994 2995
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2996
                        gen_op_fcmpeq(rd & 3);
B
blueswir1 已提交
2997
                        break;
B
blueswir1 已提交
2998 2999 3000 3001 3002
                    default:
                        goto illegal_insn;
                }
            } else if (xop == 0x2) {
                // clr/mov shortcut
B
bellard 已提交
3003 3004

                rs1 = GET_FIELD(insn, 13, 17);
B
blueswir1 已提交
3005
                if (rs1 == 0) {
B
blueswir1 已提交
3006
                    // or %g0, x, y -> mov T0, x; mov y, T0
B
blueswir1 已提交
3007
                    if (IS_IMM) {       /* immediate */
B
blueswir1 已提交
3008 3009
                        TCGv r_const;

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

3486
                                    tcg_gen_xor_tl(cpu_tick_cmpr, cpu_src1,
3487
                                                   cpu_src2);
P
pbrook 已提交
3488
                                    r_tickptr = tcg_temp_new_ptr();
B
blueswir1 已提交
3489 3490
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, tick));
P
pbrook 已提交
3491 3492 3493
                                    gen_helper_tick_set_limit(r_tickptr,
                                                              cpu_tick_cmpr);
                                    tcg_temp_free_ptr(r_tickptr);
B
blueswir1 已提交
3494
                                }
B
blueswir1 已提交
3495 3496
                                break;
                            case 0x18: /* System tick */
B
bellard 已提交
3497
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
3498 3499
                                if (!supervisor(dc))
                                    goto illegal_insn;
B
bellard 已提交
3500
#endif
B
blueswir1 已提交
3501
                                {
P
pbrook 已提交
3502
                                    TCGv_ptr r_tickptr;
B
blueswir1 已提交
3503

3504 3505
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
                                                   cpu_src2);
P
pbrook 已提交
3506
                                    r_tickptr = tcg_temp_new_ptr();
B
blueswir1 已提交
3507 3508
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, stick));
P
pbrook 已提交
3509 3510 3511
                                    gen_helper_tick_set_count(r_tickptr,
                                                              cpu_dst);
                                    tcg_temp_free_ptr(r_tickptr);
B
blueswir1 已提交
3512
                                }
B
blueswir1 已提交
3513 3514
                                break;
                            case 0x19: /* System tick compare */
B
bellard 已提交
3515
#if !defined(CONFIG_USER_ONLY)
B
blueswir1 已提交
3516 3517
                                if (!supervisor(dc))
                                    goto illegal_insn;
B
bellard 已提交
3518
#endif
B
blueswir1 已提交
3519
                                {
P
pbrook 已提交
3520
                                    TCGv_ptr r_tickptr;
B
blueswir1 已提交
3521

3522
                                    tcg_gen_xor_tl(cpu_stick_cmpr, cpu_src1,
3523
                                                   cpu_src2);
P
pbrook 已提交
3524
                                    r_tickptr = tcg_temp_new_ptr();
B
blueswir1 已提交
3525 3526
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, stick));
P
pbrook 已提交
3527 3528 3529
                                    gen_helper_tick_set_limit(r_tickptr,
                                                              cpu_stick_cmpr);
                                    tcg_temp_free_ptr(r_tickptr);
B
blueswir1 已提交
3530
                                }
B
blueswir1 已提交
3531
                                break;
B
bellard 已提交
3532

B
blueswir1 已提交
3533
                            case 0x10: /* Performance Control */
B
blueswir1 已提交
3534 3535
                            case 0x11: /* Performance Instrumentation
                                          Counter */
B
blueswir1 已提交
3536
                            case 0x12: /* Dispatch Control */
B
bellard 已提交
3537
#endif
B
bellard 已提交
3538
                            default:
3539 3540 3541 3542
                                goto illegal_insn;
                            }
                        }
                        break;
3543
#if !defined(CONFIG_USER_ONLY)
3544
                    case 0x31: /* wrpsr, V9 saved, restored */
3545
                        {
B
blueswir1 已提交
3546 3547
                            if (!supervisor(dc))
                                goto priv_insn;
B
bellard 已提交
3548
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3549 3550
                            switch (rd) {
                            case 0:
P
pbrook 已提交
3551
                                gen_helper_saved();
B
blueswir1 已提交
3552 3553
                                break;
                            case 1:
P
pbrook 已提交
3554
                                gen_helper_restored();
B
blueswir1 已提交
3555
                                break;
B
blueswir1 已提交
3556 3557 3558 3559 3560
                            case 2: /* UA2005 allclean */
                            case 3: /* UA2005 otherw */
                            case 4: /* UA2005 normalw */
                            case 5: /* UA2005 invalw */
                                // XXX
B
blueswir1 已提交
3561
                            default:
B
bellard 已提交
3562 3563 3564
                                goto illegal_insn;
                            }
#else
3565
                            tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
P
pbrook 已提交
3566
                            gen_helper_wrpsr(cpu_dst);
3567 3568
                            tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS);
                            dc->cc_op = CC_OP_FLAGS;
3569
                            save_state(dc, cpu_cond);
B
bellard 已提交
3570
                            gen_op_next_insn();
B
bellard 已提交
3571
                            tcg_gen_exit_tb(0);
B
blueswir1 已提交
3572
                            dc->is_br = 1;
B
bellard 已提交
3573
#endif
3574 3575
                        }
                        break;
3576
                    case 0x32: /* wrwim, V9 wrpr */
3577
                        {
B
blueswir1 已提交
3578 3579
                            if (!supervisor(dc))
                                goto priv_insn;
3580
                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
B
bellard 已提交
3581
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3582 3583
                            switch (rd) {
                            case 0: // tpc
3584
                                {
P
pbrook 已提交
3585
                                    TCGv_ptr r_tsptr;
3586

P
pbrook 已提交
3587
                                    r_tsptr = tcg_temp_new_ptr();
3588 3589
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                                   offsetof(CPUState, tsptr));
3590
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3591
                                                  offsetof(trap_state, tpc));
P
pbrook 已提交
3592
                                    tcg_temp_free_ptr(r_tsptr);
3593
                                }
B
blueswir1 已提交
3594 3595
                                break;
                            case 1: // tnpc
3596
                                {
P
pbrook 已提交
3597
                                    TCGv_ptr r_tsptr;
3598

P
pbrook 已提交
3599
                                    r_tsptr = tcg_temp_new_ptr();
3600 3601
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                                   offsetof(CPUState, tsptr));
3602
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3603
                                                  offsetof(trap_state, tnpc));
P
pbrook 已提交
3604
                                    tcg_temp_free_ptr(r_tsptr);
3605
                                }
B
blueswir1 已提交
3606 3607
                                break;
                            case 2: // tstate
3608
                                {
P
pbrook 已提交
3609
                                    TCGv_ptr r_tsptr;
3610

P
pbrook 已提交
3611
                                    r_tsptr = tcg_temp_new_ptr();
3612 3613
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                                   offsetof(CPUState, tsptr));
3614
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
B
blueswir1 已提交
3615 3616
                                                  offsetof(trap_state,
                                                           tstate));
P
pbrook 已提交
3617
                                    tcg_temp_free_ptr(r_tsptr);
3618
                                }
B
blueswir1 已提交
3619 3620
                                break;
                            case 3: // tt
3621
                                {
P
pbrook 已提交
3622
                                    TCGv_ptr r_tsptr;
3623

P
pbrook 已提交
3624
                                    r_tsptr = tcg_temp_new_ptr();
3625 3626
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                                   offsetof(CPUState, tsptr));
B
blueswir1 已提交
3627 3628
                                    tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
                                    tcg_gen_st_i32(cpu_tmp32, r_tsptr,
3629
                                                   offsetof(trap_state, tt));
P
pbrook 已提交
3630
                                    tcg_temp_free_ptr(r_tsptr);
3631
                                }
B
blueswir1 已提交
3632 3633
                                break;
                            case 4: // tick
B
blueswir1 已提交
3634
                                {
P
pbrook 已提交
3635
                                    TCGv_ptr r_tickptr;
B
blueswir1 已提交
3636

P
pbrook 已提交
3637
                                    r_tickptr = tcg_temp_new_ptr();
B
blueswir1 已提交
3638 3639
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, tick));
P
pbrook 已提交
3640 3641 3642
                                    gen_helper_tick_set_count(r_tickptr,
                                                              cpu_tmp0);
                                    tcg_temp_free_ptr(r_tickptr);
B
blueswir1 已提交
3643
                                }
B
blueswir1 已提交
3644 3645
                                break;
                            case 5: // tba
3646
                                tcg_gen_mov_tl(cpu_tbr, cpu_tmp0);
B
blueswir1 已提交
3647 3648
                                break;
                            case 6: // pstate
3649
                                save_state(dc, cpu_cond);
P
pbrook 已提交
3650
                                gen_helper_wrpstate(cpu_tmp0);
P
pbrook 已提交
3651
                                gen_op_next_insn();
B
bellard 已提交
3652
                                tcg_gen_exit_tb(0);
P
pbrook 已提交
3653
                                dc->is_br = 1;
B
blueswir1 已提交
3654 3655
                                break;
                            case 7: // tl
3656
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3657 3658
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState, tl));
B
blueswir1 已提交
3659 3660
                                break;
                            case 8: // pil
3661
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3662 3663 3664
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState,
                                                        psrpil));
B
blueswir1 已提交
3665 3666
                                break;
                            case 9: // cwp
P
pbrook 已提交
3667
                                gen_helper_wrcwp(cpu_tmp0);
B
blueswir1 已提交
3668 3669
                                break;
                            case 10: // cansave
3670
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3671 3672 3673
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState,
                                                        cansave));
B
blueswir1 已提交
3674 3675
                                break;
                            case 11: // canrestore
3676
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3677 3678 3679
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState,
                                                        canrestore));
B
blueswir1 已提交
3680 3681
                                break;
                            case 12: // cleanwin
3682
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3683 3684 3685
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState,
                                                        cleanwin));
B
blueswir1 已提交
3686 3687
                                break;
                            case 13: // otherwin
3688
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3689 3690 3691
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState,
                                                        otherwin));
B
blueswir1 已提交
3692 3693
                                break;
                            case 14: // wstate
3694
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3695 3696 3697
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState,
                                                        wstate));
B
blueswir1 已提交
3698
                                break;
B
blueswir1 已提交
3699
                            case 16: // UA2005 gl
3700
                                CHECK_IU_FEATURE(dc, GL);
3701
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3702 3703
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState, gl));
B
blueswir1 已提交
3704 3705
                                break;
                            case 26: // UA2005 strand status
3706
                                CHECK_IU_FEATURE(dc, HYPV);
B
blueswir1 已提交
3707 3708
                                if (!hypervisor(dc))
                                    goto priv_insn;
B
blueswir1 已提交
3709
                                tcg_gen_mov_tl(cpu_ssr, cpu_tmp0);
B
blueswir1 已提交
3710
                                break;
B
blueswir1 已提交
3711 3712 3713
                            default:
                                goto illegal_insn;
                            }
B
bellard 已提交
3714
#else
3715
                            tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
B
blueswir1 已提交
3716 3717 3718
                            if (dc->def->nwindows != 32)
                                tcg_gen_andi_tl(cpu_tmp32, cpu_tmp32,
                                                (1 << dc->def->nwindows) - 1);
3719
                            tcg_gen_mov_i32(cpu_wim, cpu_tmp32);
B
bellard 已提交
3720
#endif
3721 3722
                        }
                        break;
B
blueswir1 已提交
3723
                    case 0x33: /* wrtbr, UA2005 wrhpr */
3724
                        {
B
blueswir1 已提交
3725
#ifndef TARGET_SPARC64
B
blueswir1 已提交
3726 3727
                            if (!supervisor(dc))
                                goto priv_insn;
3728
                            tcg_gen_xor_tl(cpu_tbr, cpu_src1, cpu_src2);
B
blueswir1 已提交
3729
#else
3730
                            CHECK_IU_FEATURE(dc, HYPV);
B
blueswir1 已提交
3731 3732
                            if (!hypervisor(dc))
                                goto priv_insn;
3733
                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
B
blueswir1 已提交
3734 3735 3736
                            switch (rd) {
                            case 0: // hpstate
                                // XXX gen_op_wrhpstate();
3737
                                save_state(dc, cpu_cond);
B
blueswir1 已提交
3738
                                gen_op_next_insn();
B
bellard 已提交
3739
                                tcg_gen_exit_tb(0);
B
blueswir1 已提交
3740 3741 3742 3743 3744 3745
                                dc->is_br = 1;
                                break;
                            case 1: // htstate
                                // XXX gen_op_wrhtstate();
                                break;
                            case 3: // hintp
3746
                                tcg_gen_mov_tl(cpu_hintp, cpu_tmp0);
B
blueswir1 已提交
3747 3748
                                break;
                            case 5: // htba
3749
                                tcg_gen_mov_tl(cpu_htba, cpu_tmp0);
B
blueswir1 已提交
3750 3751
                                break;
                            case 31: // hstick_cmpr
B
blueswir1 已提交
3752
                                {
P
pbrook 已提交
3753
                                    TCGv_ptr r_tickptr;
B
blueswir1 已提交
3754

3755
                                    tcg_gen_mov_tl(cpu_hstick_cmpr, cpu_tmp0);
P
pbrook 已提交
3756
                                    r_tickptr = tcg_temp_new_ptr();
B
blueswir1 已提交
3757 3758
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, hstick));
P
pbrook 已提交
3759 3760 3761
                                    gen_helper_tick_set_limit(r_tickptr,
                                                              cpu_hstick_cmpr);
                                    tcg_temp_free_ptr(r_tickptr);
B
blueswir1 已提交
3762
                                }
B
blueswir1 已提交
3763 3764 3765 3766 3767 3768
                                break;
                            case 6: // hver readonly
                            default:
                                goto illegal_insn;
                            }
#endif
3769 3770 3771
                        }
                        break;
#endif
B
bellard 已提交
3772
#ifdef TARGET_SPARC64
B
blueswir1 已提交
3773 3774 3775 3776
                    case 0x2c: /* V9 movcc */
                        {
                            int cc = GET_FIELD_SP(insn, 11, 12);
                            int cond = GET_FIELD_SP(insn, 14, 17);
B
blueswir1 已提交
3777
                            TCGv r_cond;
3778 3779
                            int l1;

P
pbrook 已提交
3780
                            r_cond = tcg_temp_new();
B
blueswir1 已提交
3781 3782
                            if (insn & (1 << 18)) {
                                if (cc == 0)
3783
                                    gen_cond(r_cond, 0, cond, dc);
B
blueswir1 已提交
3784
                                else if (cc == 2)
3785
                                    gen_cond(r_cond, 1, cond, dc);
B
blueswir1 已提交
3786 3787 3788
                                else
                                    goto illegal_insn;
                            } else {
B
blueswir1 已提交
3789
                                gen_fcond(r_cond, cc, cond);
B
blueswir1 已提交
3790
                            }
3791 3792 3793

                            l1 = gen_new_label();

P
pbrook 已提交
3794
                            tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
3795
                            if (IS_IMM) {       /* immediate */
B
blueswir1 已提交
3796 3797
                                TCGv r_const;

B
Blue Swirl 已提交
3798 3799
                                simm = GET_FIELD_SPs(insn, 0, 10);
                                r_const = tcg_const_tl(simm);
B
blueswir1 已提交
3800 3801
                                gen_movl_TN_reg(rd, r_const);
                                tcg_temp_free(r_const);
3802 3803
                            } else {
                                rs2 = GET_FIELD_SP(insn, 0, 4);
B
blueswir1 已提交
3804 3805
                                gen_movl_reg_TN(rs2, cpu_tmp0);
                                gen_movl_TN_reg(rd, cpu_tmp0);
3806 3807
                            }
                            gen_set_label(l1);
B
blueswir1 已提交
3808
                            tcg_temp_free(r_cond);
B
blueswir1 已提交
3809 3810 3811
                            break;
                        }
                    case 0x2d: /* V9 sdivx */
3812 3813
                        gen_op_sdivx(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3814 3815 3816
                        break;
                    case 0x2e: /* V9 popc */
                        {
B
blueswir1 已提交
3817
                            cpu_src2 = get_src2(insn, cpu_src2);
P
pbrook 已提交
3818
                            gen_helper_popc(cpu_dst, cpu_src2);
3819
                            gen_movl_TN_reg(rd, cpu_dst);
B
blueswir1 已提交
3820 3821 3822 3823
                        }
                    case 0x2f: /* V9 movr */
                        {
                            int cond = GET_FIELD_SP(insn, 10, 12);
3824 3825
                            int l1;

3826
                            cpu_src1 = get_src1(insn, cpu_src1);
3827 3828 3829

                            l1 = gen_new_label();

P
pbrook 已提交
3830 3831
                            tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond],
                                              cpu_src1, 0, l1);
B
blueswir1 已提交
3832
                            if (IS_IMM) {       /* immediate */
B
blueswir1 已提交
3833 3834
                                TCGv r_const;

B
Blue Swirl 已提交
3835 3836
                                simm = GET_FIELD_SPs(insn, 0, 9);
                                r_const = tcg_const_tl(simm);
B
blueswir1 已提交
3837 3838
                                gen_movl_TN_reg(rd, r_const);
                                tcg_temp_free(r_const);
3839
                            } else {
B
blueswir1 已提交
3840
                                rs2 = GET_FIELD_SP(insn, 0, 4);
B
blueswir1 已提交
3841 3842
                                gen_movl_reg_TN(rs2, cpu_tmp0);
                                gen_movl_TN_reg(rd, cpu_tmp0);
B
blueswir1 已提交
3843
                            }
3844
                            gen_set_label(l1);
B
blueswir1 已提交
3845 3846 3847 3848 3849 3850 3851
                            break;
                        }
#endif
                    default:
                        goto illegal_insn;
                    }
                }
3852 3853 3854 3855 3856
            } 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);
3857
                if (gen_trap_ifnofpu(dc, cpu_cond))
B
blueswir1 已提交
3858
                    goto jmp_insn;
3859 3860

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

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

P
pbrook 已提交
4330 4331 4332
                        r_pc = tcg_const_tl(dc->pc);
                        gen_movl_TN_reg(rd, r_pc);
                        tcg_temp_free(r_pc);
4333
                        gen_mov_pc_npc(dc, cpu_cond);
B
blueswir1 已提交
4334
                        r_const = tcg_const_i32(3);
P
pbrook 已提交
4335 4336
                        gen_helper_check_align(cpu_dst, r_const);
                        tcg_temp_free_i32(r_const);
4337
                        tcg_gen_mov_tl(cpu_npc, cpu_dst);
B
blueswir1 已提交
4338 4339 4340
                        dc->npc = DYNAMIC_PC;
                    }
                    goto jmp_insn;
B
bellard 已提交
4341
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
B
blueswir1 已提交
4342 4343
                case 0x39:      /* rett, V9 return */
                    {
P
pbrook 已提交
4344
                        TCGv_i32 r_const;
B
blueswir1 已提交
4345

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

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

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

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

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

                        CHECK_FPU_FEATURE(dc, FLOAT128);
                        r_const = tcg_const_i32(dc->mem_idx);
P
pbrook 已提交
4654 4655
                        gen_helper_ldqf(cpu_addr, r_const);
                        tcg_temp_free_i32(r_const);
B
blueswir1 已提交
4656 4657
                        gen_op_store_QT0_fpr(QFPREG(rd));
                    }
B
blueswir1 已提交
4658
                    break;
4659
                case 0x23:      /* lddf, load double fpreg */
B
blueswir1 已提交
4660
                    {
P
pbrook 已提交
4661
                        TCGv_i32 r_const;
B
blueswir1 已提交
4662 4663

                        r_const = tcg_const_i32(dc->mem_idx);
P
pbrook 已提交
4664 4665
                        gen_helper_lddf(cpu_addr, r_const);
                        tcg_temp_free_i32(r_const);
B
blueswir1 已提交
4666 4667
                        gen_op_store_DT0_fpr(DFPREG(rd));
                    }
B
blueswir1 已提交
4668 4669 4670 4671
                    break;
                default:
                    goto illegal_insn;
                }
B
Blue Swirl 已提交
4672
            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) ||
B
blueswir1 已提交
4673
                       xop == 0xe || xop == 0x1e) {
4674
                gen_movl_reg_TN(rd, cpu_val);
B
blueswir1 已提交
4675
                switch (xop) {
4676
                case 0x4: /* st, store word */
B
blueswir1 已提交
4677
                    gen_address_mask(dc, cpu_addr);
4678
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4679
                    break;
4680
                case 0x5: /* stb, store byte */
B
blueswir1 已提交
4681
                    gen_address_mask(dc, cpu_addr);
4682
                    tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4683
                    break;
4684
                case 0x6: /* sth, store halfword */
B
blueswir1 已提交
4685
                    gen_address_mask(dc, cpu_addr);
4686
                    tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx);
B
blueswir1 已提交
4687
                    break;
4688
                case 0x7: /* std, store double word */
B
blueswir1 已提交
4689
                    if (rd & 1)
4690
                        goto illegal_insn;
B
blueswir1 已提交
4691
                    else {
P
pbrook 已提交
4692
                        TCGv_i32 r_const;
B
blueswir1 已提交
4693

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

                        CHECK_FPU_FEATURE(dc, FLOAT128);
                        gen_op_load_fpr_QT0(QFPREG(rd));
                        r_const = tcg_const_i32(dc->mem_idx);
P
pbrook 已提交
4795 4796
                        gen_helper_stqf(cpu_addr, r_const);
                        tcg_temp_free_i32(r_const);
B
blueswir1 已提交
4797
                    }
B
blueswir1 已提交
4798 4799 4800 4801 4802 4803
                    break;
#else /* !TARGET_SPARC64 */
                    /* stdfq, store floating point queue */
#if defined(CONFIG_USER_ONLY)
                    goto illegal_insn;
#else
B
blueswir1 已提交
4804 4805
                    if (!supervisor(dc))
                        goto priv_insn;
4806
                    if (gen_trap_ifnofpu(dc, cpu_cond))
B
blueswir1 已提交
4807 4808
                        goto jmp_insn;
                    goto nfq_insn;
B
blueswir1 已提交
4809
#endif
B
blueswir1 已提交
4810
#endif
4811
                case 0x27: /* stdf, store double fpreg */
B
blueswir1 已提交
4812
                    {
P
pbrook 已提交
4813
                        TCGv_i32 r_const;
B
blueswir1 已提交
4814 4815 4816

                        gen_op_load_fpr_DT0(DFPREG(rd));
                        r_const = tcg_const_i32(dc->mem_idx);
P
pbrook 已提交
4817 4818
                        gen_helper_stdf(cpu_addr, r_const);
                        tcg_temp_free_i32(r_const);
B
blueswir1 已提交
4819
                    }
B
blueswir1 已提交
4820 4821 4822 4823 4824
                    break;
                default:
                    goto illegal_insn;
                }
            } else if (xop > 0x33 && xop < 0x3f) {
4825
                save_state(dc, cpu_cond);
B
blueswir1 已提交
4826
                switch (xop) {
4827
#ifdef TARGET_SPARC64
B
blueswir1 已提交
4828
                case 0x34: /* V9 stfa */
4829
                    gen_stf_asi(cpu_addr, insn, 4, rd);
B
blueswir1 已提交
4830
                    break;
B
blueswir1 已提交
4831
                case 0x36: /* V9 stqfa */
B
blueswir1 已提交
4832
                    {
P
pbrook 已提交
4833
                        TCGv_i32 r_const;
B
blueswir1 已提交
4834 4835 4836

                        CHECK_FPU_FEATURE(dc, FLOAT128);
                        r_const = tcg_const_i32(7);
P
pbrook 已提交
4837 4838
                        gen_helper_check_align(cpu_addr, r_const);
                        tcg_temp_free_i32(r_const);
B
blueswir1 已提交
4839 4840 4841
                        gen_op_load_fpr_QT0(QFPREG(rd));
                        gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd));
                    }
B
blueswir1 已提交
4842
                    break;
B
blueswir1 已提交
4843
                case 0x37: /* V9 stdfa */
4844
                    gen_op_load_fpr_DT0(DFPREG(rd));
4845
                    gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
B
blueswir1 已提交
4846 4847
                    break;
                case 0x3c: /* V9 casa */
B
blueswir1 已提交
4848
                    gen_cas_asi(cpu_val, cpu_addr, cpu_src2, insn, rd);
4849
                    gen_movl_TN_reg(rd, cpu_val);
B
blueswir1 已提交
4850 4851
                    break;
                case 0x3e: /* V9 casxa */
B
blueswir1 已提交
4852
                    gen_casx_asi(cpu_val, cpu_addr, cpu_src2, insn, rd);
4853
                    gen_movl_TN_reg(rd, cpu_val);
B
blueswir1 已提交
4854
                    break;
4855
#else
B
blueswir1 已提交
4856 4857 4858 4859 4860 4861 4862 4863 4864
                case 0x34: /* stc */
                case 0x35: /* stcsr */
                case 0x36: /* stdcq */
                case 0x37: /* stdc */
                    goto ncp_insn;
#endif
                default:
                    goto illegal_insn;
                }
B
Blue Swirl 已提交
4865
            } else
B
blueswir1 已提交
4866 4867 4868
                goto illegal_insn;
        }
        break;
4869 4870
    }
    /* default case for non jump instructions */
B
bellard 已提交
4871
    if (dc->npc == DYNAMIC_PC) {
B
blueswir1 已提交
4872 4873
        dc->pc = DYNAMIC_PC;
        gen_op_next_insn();
B
bellard 已提交
4874 4875
    } else if (dc->npc == JUMP_PC) {
        /* we can do a static jump */
4876
        gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
B
bellard 已提交
4877 4878
        dc->is_br = 1;
    } else {
B
blueswir1 已提交
4879 4880
        dc->pc = dc->npc;
        dc->npc = dc->npc + 4;
4881
    }
B
bellard 已提交
4882
 jmp_insn:
4883 4884
    return;
 illegal_insn:
B
blueswir1 已提交
4885
    {
P
pbrook 已提交
4886
        TCGv_i32 r_const;
B
blueswir1 已提交
4887 4888 4889

        save_state(dc, cpu_cond);
        r_const = tcg_const_i32(TT_ILL_INSN);
P
pbrook 已提交
4890 4891
        gen_helper_raise_exception(r_const);
        tcg_temp_free_i32(r_const);
B
blueswir1 已提交
4892 4893
        dc->is_br = 1;
    }
4894
    return;
B
blueswir1 已提交
4895
 unimp_flush:
B
blueswir1 已提交
4896
    {
P
pbrook 已提交
4897
        TCGv_i32 r_const;
B
blueswir1 已提交
4898 4899 4900

        save_state(dc, cpu_cond);
        r_const = tcg_const_i32(TT_UNIMP_FLUSH);
P
pbrook 已提交
4901 4902
        gen_helper_raise_exception(r_const);
        tcg_temp_free_i32(r_const);
B
blueswir1 已提交
4903 4904
        dc->is_br = 1;
    }
B
blueswir1 已提交
4905
    return;
B
bellard 已提交
4906
#if !defined(CONFIG_USER_ONLY)
4907
 priv_insn:
B
blueswir1 已提交
4908
    {
P
pbrook 已提交
4909
        TCGv_i32 r_const;
B
blueswir1 已提交
4910 4911 4912

        save_state(dc, cpu_cond);
        r_const = tcg_const_i32(TT_PRIV_INSN);
P
pbrook 已提交
4913 4914
        gen_helper_raise_exception(r_const);
        tcg_temp_free_i32(r_const);
B
blueswir1 已提交
4915 4916
        dc->is_br = 1;
    }
B
bellard 已提交
4917
    return;
B
blueswir1 已提交
4918
#endif
B
bellard 已提交
4919
 nfpu_insn:
4920
    save_state(dc, cpu_cond);
B
bellard 已提交
4921 4922
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
    dc->is_br = 1;
4923
    return;
B
blueswir1 已提交
4924
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
B
blueswir1 已提交
4925
 nfq_insn:
4926
    save_state(dc, cpu_cond);
B
blueswir1 已提交
4927 4928 4929 4930
    gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
    dc->is_br = 1;
    return;
#endif
4931 4932
#ifndef TARGET_SPARC64
 ncp_insn:
B
blueswir1 已提交
4933 4934 4935 4936 4937
    {
        TCGv r_const;

        save_state(dc, cpu_cond);
        r_const = tcg_const_i32(TT_NCP_INSN);
P
pbrook 已提交
4938
        gen_helper_raise_exception(r_const);
B
blueswir1 已提交
4939 4940 4941
        tcg_temp_free(r_const);
        dc->is_br = 1;
    }
4942 4943
    return;
#endif
4944 4945
}

4946 4947
static inline void gen_intermediate_code_internal(TranslationBlock * tb,
                                                  int spc, CPUSPARCState *env)
4948
{
B
bellard 已提交
4949
    target_ulong pc_start, last_pc;
4950 4951
    uint16_t *gen_opc_end;
    DisasContext dc1, *dc = &dc1;
4952
    CPUBreakpoint *bp;
4953
    int j, lj = -1;
P
pbrook 已提交
4954 4955
    int num_insns;
    int max_insns;
4956 4957 4958

    memset(dc, 0, sizeof(DisasContext));
    dc->tb = tb;
B
bellard 已提交
4959
    pc_start = tb->pc;
4960
    dc->pc = pc_start;
B
bellard 已提交
4961
    last_pc = dc->pc;
B
bellard 已提交
4962
    dc->npc = (target_ulong) tb->cs_base;
4963
    dc->cc_op = CC_OP_DYNAMIC;
B
blueswir1 已提交
4964
    dc->mem_idx = cpu_mmu_index(env);
4965 4966
    dc->def = env->def;
    if ((dc->def->features & CPU_FEATURE_FLOAT))
B
blueswir1 已提交
4967
        dc->fpu_enabled = cpu_fpu_enabled(env);
4968
    else
B
blueswir1 已提交
4969
        dc->fpu_enabled = 0;
B
blueswir1 已提交
4970 4971 4972
#ifdef TARGET_SPARC64
    dc->address_mask_32bit = env->pstate & PS_AM;
#endif
4973 4974
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;

P
pbrook 已提交
4975 4976 4977
    cpu_tmp0 = tcg_temp_new();
    cpu_tmp32 = tcg_temp_new_i32();
    cpu_tmp64 = tcg_temp_new_i64();
B
blueswir1 已提交
4978

P
pbrook 已提交
4979
    cpu_dst = tcg_temp_local_new();
B
blueswir1 已提交
4980 4981

    // loads and stores
P
pbrook 已提交
4982 4983
    cpu_val = tcg_temp_local_new();
    cpu_addr = tcg_temp_local_new();
B
blueswir1 已提交
4984

P
pbrook 已提交
4985 4986 4987 4988 4989
    num_insns = 0;
    max_insns = tb->cflags & CF_COUNT_MASK;
    if (max_insns == 0)
        max_insns = CF_COUNT_MASK;
    gen_icount_start();
4990
    do {
4991 4992
        if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
            TAILQ_FOREACH(bp, &env->breakpoints, entry) {
4993
                if (bp->pc == dc->pc) {
B
blueswir1 已提交
4994
                    if (dc->pc != pc_start)
4995
                        save_state(dc, cpu_cond);
P
pbrook 已提交
4996
                    gen_helper_debug();
B
bellard 已提交
4997
                    tcg_gen_exit_tb(0);
B
blueswir1 已提交
4998
                    dc->is_br = 1;
B
bellard 已提交
4999
                    goto exit_gen_loop;
5000 5001 5002 5003
                }
            }
        }
        if (spc) {
5004
            qemu_log("Search PC...\n");
5005 5006 5007 5008 5009 5010 5011 5012
            j = gen_opc_ptr - gen_opc_buf;
            if (lj < j) {
                lj++;
                while (lj < j)
                    gen_opc_instr_start[lj++] = 0;
                gen_opc_pc[lj] = dc->pc;
                gen_opc_npc[lj] = dc->npc;
                gen_opc_instr_start[lj] = 1;
P
pbrook 已提交
5013
                gen_opc_icount[lj] = num_insns;
5014 5015
            }
        }
P
pbrook 已提交
5016 5017
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
            gen_io_start();
B
blueswir1 已提交
5018 5019
        last_pc = dc->pc;
        disas_sparc_insn(dc);
P
pbrook 已提交
5020
        num_insns++;
B
blueswir1 已提交
5021 5022 5023 5024 5025 5026

        if (dc->is_br)
            break;
        /* if the next PC is different, we abort now */
        if (dc->pc != (last_pc + 4))
            break;
B
bellard 已提交
5027 5028 5029 5030
        /* 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 已提交
5031 5032
        /* if single step mode, we generate only one instruction and
           generate an exception */
5033
        if (env->singlestep_enabled || singlestep) {
B
blueswir1 已提交
5034
            tcg_gen_movi_tl(cpu_pc, dc->pc);
B
bellard 已提交
5035
            tcg_gen_exit_tb(0);
B
bellard 已提交
5036 5037
            break;
        }
5038
    } while ((gen_opc_ptr < gen_opc_end) &&
P
pbrook 已提交
5039 5040
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32) &&
             num_insns < max_insns);
B
bellard 已提交
5041 5042

 exit_gen_loop:
B
blueswir1 已提交
5043
    tcg_temp_free(cpu_addr);
B
blueswir1 已提交
5044
    tcg_temp_free(cpu_val);
B
blueswir1 已提交
5045
    tcg_temp_free(cpu_dst);
P
pbrook 已提交
5046 5047
    tcg_temp_free_i64(cpu_tmp64);
    tcg_temp_free_i32(cpu_tmp32);
B
blueswir1 已提交
5048
    tcg_temp_free(cpu_tmp0);
P
pbrook 已提交
5049 5050
    if (tb->cflags & CF_LAST_IO)
        gen_io_end();
B
bellard 已提交
5051
    if (!dc->is_br) {
5052
        if (dc->pc != DYNAMIC_PC &&
B
bellard 已提交
5053 5054
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
            /* static PC and NPC: we can use direct chaining */
B
blueswir1 已提交
5055
            gen_goto_tb(dc, 0, dc->pc, dc->npc);
B
bellard 已提交
5056 5057
        } else {
            if (dc->pc != DYNAMIC_PC)
B
blueswir1 已提交
5058
                tcg_gen_movi_tl(cpu_pc, dc->pc);
5059
            save_npc(dc, cpu_cond);
B
bellard 已提交
5060
            tcg_gen_exit_tb(0);
B
bellard 已提交
5061 5062
        }
    }
P
pbrook 已提交
5063
    gen_icount_end(tb, num_insns);
5064
    *gen_opc_ptr = INDEX_op_end;
5065 5066 5067 5068 5069 5070
    if (spc) {
        j = gen_opc_ptr - gen_opc_buf;
        lj++;
        while (lj <= j)
            gen_opc_instr_start[lj++] = 0;
#if 0
5071
        log_page_dump();
5072
#endif
5073 5074
        gen_opc_jump_pc[0] = dc->jump_pc[0];
        gen_opc_jump_pc[1] = dc->jump_pc[1];
5075
    } else {
B
bellard 已提交
5076
        tb->size = last_pc + 4 - pc_start;
P
pbrook 已提交
5077
        tb->icount = num_insns;
5078
    }
5079
#ifdef DEBUG_DISAS
5080
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
5081 5082 5083 5084
        qemu_log("--------------\n");
        qemu_log("IN: %s\n", lookup_symbol(pc_start));
        log_target_disas(pc_start, last_pc + 4 - pc_start, 0);
        qemu_log("\n");
5085
    }
5086 5087 5088
#endif
}

5089
void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
5090
{
5091
    gen_intermediate_code_internal(tb, 0, env);
5092 5093
}

5094
void gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
5095
{
5096
    gen_intermediate_code_internal(tb, 1, env);
5097 5098
}

5099
void gen_intermediate_code_init(CPUSPARCState *env)
B
bellard 已提交
5100
{
B
blueswir1 已提交
5101
    unsigned int i;
5102
    static int inited;
B
blueswir1 已提交
5103 5104 5105 5106 5107 5108 5109 5110 5111 5112
    static const char * const gregnames[8] = {
        NULL, // g0 not used
        "g1",
        "g2",
        "g3",
        "g4",
        "g5",
        "g6",
        "g7",
    };
B
blueswir1 已提交
5113 5114 5115 5116 5117 5118 5119 5120 5121 5122
    static const char * const fregnames[64] = {
        "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
        "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
        "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
        "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
        "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
        "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47",
        "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55",
        "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63",
    };
B
bellard 已提交
5123

B
blueswir1 已提交
5124 5125 5126 5127
    /* init various static tables */
    if (!inited) {
        inited = 1;

P
pbrook 已提交
5128 5129 5130 5131
        cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
        cpu_regwptr = tcg_global_mem_new_ptr(TCG_AREG0,
                                             offsetof(CPUState, regwptr),
                                             "regwptr");
B
blueswir1 已提交
5132
#ifdef TARGET_SPARC64
P
pbrook 已提交
5133 5134 5135 5136 5137 5138 5139
        cpu_xcc = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, xcc),
                                         "xcc");
        cpu_asi = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, asi),
                                         "asi");
        cpu_fprs = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, fprs),
                                          "fprs");
        cpu_gsr = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, gsr),
5140
                                     "gsr");
P
pbrook 已提交
5141
        cpu_tick_cmpr = tcg_global_mem_new(TCG_AREG0,
5142 5143
                                           offsetof(CPUState, tick_cmpr),
                                           "tick_cmpr");
P
pbrook 已提交
5144
        cpu_stick_cmpr = tcg_global_mem_new(TCG_AREG0,
5145 5146
                                            offsetof(CPUState, stick_cmpr),
                                            "stick_cmpr");
P
pbrook 已提交
5147
        cpu_hstick_cmpr = tcg_global_mem_new(TCG_AREG0,
5148 5149
                                             offsetof(CPUState, hstick_cmpr),
                                             "hstick_cmpr");
P
pbrook 已提交
5150
        cpu_hintp = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, hintp),
5151
                                       "hintp");
P
pbrook 已提交
5152 5153 5154 5155 5156
        cpu_htba = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, htba),
                                      "htba");
        cpu_hver = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, hver),
                                      "hver");
        cpu_ssr = tcg_global_mem_new(TCG_AREG0,
5157
                                     offsetof(CPUState, ssr), "ssr");
P
pbrook 已提交
5158
        cpu_ver = tcg_global_mem_new(TCG_AREG0,
5159
                                     offsetof(CPUState, version), "ver");
P
pbrook 已提交
5160 5161 5162
        cpu_softint = tcg_global_mem_new_i32(TCG_AREG0,
                                             offsetof(CPUState, softint),
                                             "softint");
5163
#else
P
pbrook 已提交
5164
        cpu_wim = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, wim),
5165
                                     "wim");
B
blueswir1 已提交
5166
#endif
P
pbrook 已提交
5167
        cpu_cond = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cond),
B
blueswir1 已提交
5168
                                      "cond");
P
pbrook 已提交
5169
        cpu_cc_src = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_src),
5170
                                        "cc_src");
P
pbrook 已提交
5171
        cpu_cc_src2 = tcg_global_mem_new(TCG_AREG0,
B
blueswir1 已提交
5172 5173
                                         offsetof(CPUState, cc_src2),
                                         "cc_src2");
P
pbrook 已提交
5174
        cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_dst),
5175
                                        "cc_dst");
5176 5177
        cpu_cc_op = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, cc_op),
                                           "cc_op");
P
pbrook 已提交
5178 5179 5180
        cpu_psr = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, psr),
                                         "psr");
        cpu_fsr = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, fsr),
B
blueswir1 已提交
5181
                                     "fsr");
P
pbrook 已提交
5182
        cpu_pc = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, pc),
B
blueswir1 已提交
5183
                                    "pc");
P
pbrook 已提交
5184 5185 5186
        cpu_npc = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, npc),
                                     "npc");
        cpu_y = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, y), "y");
5187
#ifndef CONFIG_USER_ONLY
P
pbrook 已提交
5188
        cpu_tbr = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, tbr),
5189 5190
                                     "tbr");
#endif
B
blueswir1 已提交
5191
        for (i = 1; i < 8; i++)
P
pbrook 已提交
5192
            cpu_gregs[i] = tcg_global_mem_new(TCG_AREG0,
B
blueswir1 已提交
5193 5194
                                              offsetof(CPUState, gregs[i]),
                                              gregnames[i]);
B
blueswir1 已提交
5195
        for (i = 0; i < TARGET_FPREGS; i++)
P
pbrook 已提交
5196 5197 5198
            cpu_fpr[i] = tcg_global_mem_new_i32(TCG_AREG0,
                                                offsetof(CPUState, fpr[i]),
                                                fregnames[i]);
B
blueswir1 已提交
5199

B
blueswir1 已提交
5200 5201
        /* register helpers */

P
pbrook 已提交
5202
#define GEN_HELPER 2
B
blueswir1 已提交
5203
#include "helper.h"
B
blueswir1 已提交
5204
    }
B
bellard 已提交
5205
}
A
aurel32 已提交
5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225

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