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

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

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

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

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

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

#include "cpu.h"
#include "exec-all.h"
#include "disas.h"
blueswir1's avatar
blueswir1 committed
31
#include "helper.h"
bellard's avatar
bellard committed
32
#include "tcg-op.h"
33
34
35

#define DEBUG_DISAS

bellard's avatar
bellard committed
36
37
38
39
#define DYNAMIC_PC  1 /* dynamic pc value */
#define JUMP_PC     2 /* dynamic pc value which takes only two values
                         according to jump_pc[T2] */

blueswir1's avatar
blueswir1 committed
40
/* global register indexes */
blueswir1's avatar
blueswir1 committed
41
42
static TCGv cpu_env, cpu_T[2], cpu_regwptr;
static TCGv cpu_cc_src, cpu_cc_src2, cpu_cc_dst;
blueswir1's avatar
blueswir1 committed
43
static TCGv cpu_psr, cpu_fsr, cpu_pc, cpu_npc, cpu_gregs[8];
44
static TCGv cpu_cond, cpu_src1, cpu_src2, cpu_dst, cpu_addr, cpu_val;
45
46
47
#ifdef TARGET_SPARC64
static TCGv cpu_xcc;
#endif
blueswir1's avatar
blueswir1 committed
48
/* local register indexes (only used inside old micro ops) */
blueswir1's avatar
blueswir1 committed
49
static TCGv cpu_tmp0, cpu_tmp32, cpu_tmp64;
blueswir1's avatar
blueswir1 committed
50

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

bellard's avatar
bellard committed
62
// This function uses non-native bit order
63
64
65
#define GET_FIELD(X, FROM, TO) \
  ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))

bellard's avatar
bellard committed
66
67
68
69
70
// This function uses the order in the manuals, i.e. bit 0 is 2^0
#define GET_FIELD_SP(X, FROM, TO) \
    GET_FIELD(X, 31 - (TO), 31 - (FROM))

#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
blueswir1's avatar
blueswir1 committed
71
#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
bellard's avatar
bellard committed
72
73

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

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

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

blueswir1's avatar
blueswir1 committed
91
92
93
/* floating point registers moves */
static void gen_op_load_fpr_FT0(unsigned int src)
{
blueswir1's avatar
blueswir1 committed
94
95
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft0));
bellard's avatar
bellard committed
96
}
blueswir1's avatar
blueswir1 committed
97
98
99

static void gen_op_load_fpr_FT1(unsigned int src)
{
blueswir1's avatar
blueswir1 committed
100
101
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft1));
102
103
}

blueswir1's avatar
blueswir1 committed
104
105
static void gen_op_store_FT0_fpr(unsigned int dst)
{
blueswir1's avatar
blueswir1 committed
106
107
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft0));
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst]));
blueswir1's avatar
blueswir1 committed
108
109
110
111
}

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

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

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

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

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

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

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

blueswir1's avatar
blueswir1 committed
202
#ifdef TARGET_ABI32
blueswir1's avatar
blueswir1 committed
203
#define ABI32_MASK(addr) tcg_gen_andi_tl(addr, addr, 0xffffffffULL);
blueswir1's avatar
blueswir1 committed
204
205
206
#else
#define ABI32_MASK(addr)
#endif
207

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

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

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

    tb = s->tb;
    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
        (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK))  {
        /* jump to same page: we can use a direct jump */
bellard's avatar
bellard committed
239
        tcg_gen_goto_tb(tb_num);
blueswir1's avatar
blueswir1 committed
240
241
        tcg_gen_movi_tl(cpu_pc, pc);
        tcg_gen_movi_tl(cpu_npc, npc);
bellard's avatar
bellard committed
242
        tcg_gen_exit_tb((long)tb + tb_num);
243
244
    } else {
        /* jump to another page: currently not optimized */
blueswir1's avatar
blueswir1 committed
245
246
        tcg_gen_movi_tl(cpu_pc, pc);
        tcg_gen_movi_tl(cpu_npc, npc);
bellard's avatar
bellard committed
247
        tcg_gen_exit_tb(0);
248
249
250
    }
}

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

static inline void gen_mov_reg_Z(TCGv reg, TCGv src)
{
blueswir1's avatar
blueswir1 committed
261
    tcg_gen_extu_i32_tl(reg, src);
blueswir1's avatar
blueswir1 committed
262
    tcg_gen_shri_tl(reg, reg, PSR_ZERO_SHIFT);
263
264
265
266
267
    tcg_gen_andi_tl(reg, reg, 0x1);
}

static inline void gen_mov_reg_V(TCGv reg, TCGv src)
{
blueswir1's avatar
blueswir1 committed
268
    tcg_gen_extu_i32_tl(reg, src);
blueswir1's avatar
blueswir1 committed
269
    tcg_gen_shri_tl(reg, reg, PSR_OVF_SHIFT);
270
271
272
273
274
    tcg_gen_andi_tl(reg, reg, 0x1);
}

static inline void gen_mov_reg_C(TCGv reg, TCGv src)
{
blueswir1's avatar
blueswir1 committed
275
    tcg_gen_extu_i32_tl(reg, src);
blueswir1's avatar
blueswir1 committed
276
    tcg_gen_shri_tl(reg, reg, PSR_CARRY_SHIFT);
277
278
279
    tcg_gen_andi_tl(reg, reg, 0x1);
}

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

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

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

    l1 = gen_new_label();
    l2 = gen_new_label();
blueswir1's avatar
blueswir1 committed
305
306
    r_temp = tcg_temp_new(TCG_TYPE_TL);
    tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
pbrook's avatar
pbrook committed
307
    tcg_gen_brcondi_tl(TCG_COND_NE, r_temp, 0, l1);
308
309
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_ZERO);
    gen_set_label(l1);
blueswir1's avatar
blueswir1 committed
310
    tcg_gen_ext_i32_tl(r_temp, dst);
pbrook's avatar
pbrook committed
311
    tcg_gen_brcondi_tl(TCG_COND_GE, r_temp, 0, l2);
312
313
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_NEG);
    gen_set_label(l2);
314
315
}

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

    l1 = gen_new_label();
    l2 = gen_new_label();
pbrook's avatar
pbrook committed
323
    tcg_gen_brcondi_tl(TCG_COND_NE, dst, 0, l1);
324
325
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_ZERO);
    gen_set_label(l1);
pbrook's avatar
pbrook committed
326
    tcg_gen_brcondi_tl(TCG_COND_GE, dst, 0, l2);
327
328
    tcg_gen_ori_i32(cpu_xcc, cpu_xcc, PSR_NEG);
    gen_set_label(l2);
329
}
330
#endif
331
332
333
334
335

/* old op:
    if (T0 < src1)
        env->psr |= PSR_CARRY;
*/
336
static inline void gen_cc_C_add_icc(TCGv dst, TCGv src1)
337
{
blueswir1's avatar
blueswir1 committed
338
    TCGv r_temp;
339
340
341
    int l1;

    l1 = gen_new_label();
blueswir1's avatar
blueswir1 committed
342
343
344
    r_temp = tcg_temp_new(TCG_TYPE_TL);
    tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
    tcg_gen_brcond_tl(TCG_COND_GEU, dst, src1, l1);
345
346
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
    gen_set_label(l1);
347
348
}

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

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

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

    r_temp = tcg_temp_new(TCG_TYPE_TL);
    tcg_gen_xor_tl(r_temp, src1, src2);
    tcg_gen_xori_tl(r_temp, r_temp, -1);
372
373
374
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
blueswir1's avatar
blueswir1 committed
375
376
377
    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);
378
379
}

380
#ifdef TARGET_SPARC64
381
382
383
384
385
386
387
388
389
390
static inline void gen_cc_V_add_xcc(TCGv dst, TCGv src1, TCGv src2)
{
    TCGv r_temp;

    r_temp = tcg_temp_new(TCG_TYPE_TL);
    tcg_gen_xor_tl(r_temp, src1, src2);
    tcg_gen_xori_tl(r_temp, r_temp, -1);
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
blueswir1's avatar
blueswir1 committed
391
392
393
    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);
394
}
395
#endif
396
397
398

static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
{
399
    TCGv r_temp;
400
401
402
403
404
405
406
    int l1;

    l1 = gen_new_label();

    r_temp = tcg_temp_new(TCG_TYPE_TL);
    tcg_gen_xor_tl(r_temp, src1, src2);
    tcg_gen_xori_tl(r_temp, r_temp, -1);
407
408
409
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
pbrook's avatar
pbrook committed
410
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
blueswir1's avatar
blueswir1 committed
411
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
412
413
414
415
416
417
418
419
    gen_set_label(l1);
}

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

    l1 = gen_new_label();
420
421
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
pbrook's avatar
pbrook committed
422
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
423
424
425
426
427
428
429
430
431
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
    gen_set_label(l1);
}

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

    l1 = gen_new_label();
432
433
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
pbrook's avatar
pbrook committed
434
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
blueswir1's avatar
blueswir1 committed
435
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
436
437
438
    gen_set_label(l1);
}

439
static inline void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2)
440
{
441
    tcg_gen_mov_tl(cpu_cc_src, src1);
442
    tcg_gen_mov_tl(cpu_cc_src2, src2);
443
    tcg_gen_add_tl(dst, src1, src2);
444
    tcg_gen_mov_tl(cpu_cc_dst, dst);
445
    gen_cc_clear_icc();
446
447
448
    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);
449
450
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
451
452
453
    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);
454
#endif
455
456
}

457
static inline void gen_op_addx_cc(TCGv dst, TCGv src1, TCGv src2)
458
{
459
    tcg_gen_mov_tl(cpu_cc_src, src1);
460
    tcg_gen_mov_tl(cpu_cc_src2, src2);
461
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
462
    tcg_gen_add_tl(dst, src1, cpu_tmp0);
463
    gen_cc_clear_icc();
464
    gen_cc_C_add_icc(dst, cpu_cc_src);
465
466
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
467
    gen_cc_C_add_xcc(dst, cpu_cc_src);
468
#endif
469
    tcg_gen_add_tl(dst, dst, cpu_cc_src2);
470
471
472
473
    tcg_gen_mov_tl(cpu_cc_dst, dst);
    gen_cc_NZ_icc(cpu_cc_dst);
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
    gen_cc_V_add_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
474
#ifdef TARGET_SPARC64
475
476
477
    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);
478
#endif
479
480
}

481
static inline void gen_op_tadd_cc(TCGv dst, TCGv src1, TCGv src2)
482
{
483
    tcg_gen_mov_tl(cpu_cc_src, src1);
484
    tcg_gen_mov_tl(cpu_cc_src2, src2);
485
    tcg_gen_add_tl(dst, src1, src2);
486
    tcg_gen_mov_tl(cpu_cc_dst, dst);
487
    gen_cc_clear_icc();
488
489
490
    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);
491
    gen_cc_V_tag(cpu_cc_src, cpu_cc_src2);
492
493
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
494
495
496
    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);
497
#endif
498
499
}

500
static inline void gen_op_tadd_ccTV(TCGv dst, TCGv src1, TCGv src2)
501
{
502
    tcg_gen_mov_tl(cpu_cc_src, src1);
503
504
    tcg_gen_mov_tl(cpu_cc_src2, src2);
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
505
    tcg_gen_add_tl(dst, src1, src2);
506
    tcg_gen_mov_tl(cpu_cc_dst, dst);
507
    gen_add_tv(dst, cpu_cc_src, cpu_cc_src2);
508
    gen_cc_clear_icc();
509
510
    gen_cc_NZ_icc(cpu_cc_dst);
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
511
512
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
513
514
515
    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);
516
#endif
517
518
519
520
521
522
}

/* old op:
    if (src1 < T1)
        env->psr |= PSR_CARRY;
*/
523
static inline void gen_cc_C_sub_icc(TCGv src1, TCGv src2)
524
{
blueswir1's avatar
blueswir1 committed
525
    TCGv r_temp1, r_temp2;
526
527
528
    int l1;

    l1 = gen_new_label();
blueswir1's avatar
blueswir1 committed
529
530
531
532
533
    r_temp1 = tcg_temp_new(TCG_TYPE_TL);
    r_temp2 = tcg_temp_new(TCG_TYPE_TL);
    tcg_gen_andi_tl(r_temp1, src1, 0xffffffffULL);
    tcg_gen_andi_tl(r_temp2, src2, 0xffffffffULL);
    tcg_gen_brcond_tl(TCG_COND_GEU, r_temp1, r_temp2, l1);
534
535
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
    gen_set_label(l1);
536
537
}

538
#ifdef TARGET_SPARC64
539
540
541
static inline void gen_cc_C_sub_xcc(TCGv src1, TCGv src2)
{
    int l1;
542

543
544
545
546
    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);
547
}
548
#endif
549
550
551
552
553

/* old op:
    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
        env->psr |= PSR_OVF;
*/
554
static inline void gen_cc_V_sub_icc(TCGv dst, TCGv src1, TCGv src2)
555
{
556
    TCGv r_temp;
557
558
559

    r_temp = tcg_temp_new(TCG_TYPE_TL);
    tcg_gen_xor_tl(r_temp, src1, src2);
560
561
562
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
blueswir1's avatar
blueswir1 committed
563
564
565
    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);
566
567
}

568
#ifdef TARGET_SPARC64
569
570
571
572
573
574
575
576
577
static inline void gen_cc_V_sub_xcc(TCGv dst, TCGv src1, TCGv src2)
{
    TCGv r_temp;

    r_temp = tcg_temp_new(TCG_TYPE_TL);
    tcg_gen_xor_tl(r_temp, src1, src2);
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 63));
blueswir1's avatar
blueswir1 committed
578
579
580
    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);
581
}
582
#endif
583
584
585

static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
{
586
    TCGv r_temp;
587
588
589
590
591
592
    int l1;

    l1 = gen_new_label();

    r_temp = tcg_temp_new(TCG_TYPE_TL);
    tcg_gen_xor_tl(r_temp, src1, src2);
593
594
595
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
    tcg_gen_andi_tl(r_temp, r_temp, (1 << 31));
pbrook's avatar
pbrook committed
596
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
blueswir1's avatar
blueswir1 committed
597
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_TOVF));
598
599
600
    gen_set_label(l1);
}

601
static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2)
602
{
603
    tcg_gen_mov_tl(cpu_cc_src, src1);
604
    tcg_gen_mov_tl(cpu_cc_src2, src2);
605
    tcg_gen_sub_tl(dst, src1, src2);
606
    tcg_gen_mov_tl(cpu_cc_dst, dst);
607
    gen_cc_clear_icc();
608
    gen_cc_NZ_icc(cpu_cc_dst);
609
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
610
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
611
612
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
613
    gen_cc_NZ_xcc(cpu_cc_dst);
614
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
615
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
616
#endif
617
618
}

619
static inline void gen_op_subx_cc(TCGv dst, TCGv src1, TCGv src2)
620
{
621
    tcg_gen_mov_tl(cpu_cc_src, src1);
622
    tcg_gen_mov_tl(cpu_cc_src2, src2);
623
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
624
    tcg_gen_sub_tl(dst, src1, cpu_tmp0);
625
    gen_cc_clear_icc();
626
    gen_cc_C_sub_icc(dst, cpu_cc_src);
627
628
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
629
    gen_cc_C_sub_xcc(dst, cpu_cc_src);
630
#endif
631
    tcg_gen_sub_tl(dst, dst, cpu_cc_src2);
632
633
634
635
    tcg_gen_mov_tl(cpu_cc_dst, dst);
    gen_cc_NZ_icc(cpu_cc_dst);
    gen_cc_C_sub_icc(cpu_cc_dst, cpu_cc_src);
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
636
#ifdef TARGET_SPARC64
637
638
639
    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);
640
#endif
641
642
}

643
static inline void gen_op_tsub_cc(TCGv dst, TCGv src1, TCGv src2)
644
{
645
    tcg_gen_mov_tl(cpu_cc_src, src1);
646
    tcg_gen_mov_tl(cpu_cc_src2, src2);
647
    tcg_gen_sub_tl(dst, src1, src2);
648
    tcg_gen_mov_tl(cpu_cc_dst, dst);
649
    gen_cc_clear_icc();
650
    gen_cc_NZ_icc(cpu_cc_dst);
651
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
652
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
653
    gen_cc_V_tag(cpu_cc_src, cpu_cc_src2);
654
655
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
656
    gen_cc_NZ_xcc(cpu_cc_dst);
657
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
658
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
659
#endif
660
661
}

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

681
static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
682
{
blueswir1's avatar
blueswir1 committed
683
    TCGv r_temp, r_temp2;
684
    int l1;
685
686
687

    l1 = gen_new_label();
    r_temp = tcg_temp_new(TCG_TYPE_TL);
blueswir1's avatar
blueswir1 committed
688
    r_temp2 = tcg_temp_new(TCG_TYPE_I32);
689
690
691
692
693

    /* old op:
    if (!(env->y & 1))
        T1 = 0;
    */
694
    tcg_gen_mov_tl(cpu_cc_src, src1);
blueswir1's avatar
blueswir1 committed
695
696
697
    tcg_gen_ld32u_tl(r_temp, cpu_env, offsetof(CPUSPARCState, y));
    tcg_gen_trunc_tl_i32(r_temp2, r_temp);
    tcg_gen_andi_i32(r_temp2, r_temp2, 0x1);
698
    tcg_gen_mov_tl(cpu_cc_src2, src2);
pbrook's avatar
pbrook committed
699
    tcg_gen_brcondi_i32(TCG_COND_NE, r_temp2, 0, l1);
700
    tcg_gen_movi_tl(cpu_cc_src2, 0);
701
    gen_set_label(l1);
702
703
704

    // b2 = T0 & 1;
    // env->y = (b2 << 31) | (env->y >> 1);
705
    tcg_gen_trunc_tl_i32(r_temp2, cpu_cc_src);
blueswir1's avatar
blueswir1 committed
706
707
    tcg_gen_andi_i32(r_temp2, r_temp2, 0x1);
    tcg_gen_shli_i32(r_temp2, r_temp2, 31);
blueswir1's avatar
blueswir1 committed
708
709
    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, y));
    tcg_gen_shri_i32(cpu_tmp32, cpu_tmp32, 1);
blueswir1's avatar
blueswir1 committed
710
    tcg_gen_or_i32(cpu_tmp32, cpu_tmp32, r_temp2);
blueswir1's avatar
blueswir1 committed
711
    tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, y));
712
713
714
715
716
717
718
719
720

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

    // T0 = (b1 << 31) | (T0 >> 1);
    // src1 = T0;
    tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
721
    tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
722
723
724
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);

    /* do addition and update flags */
725
    tcg_gen_add_tl(dst, cpu_cc_src, cpu_cc_src2);
726
    tcg_gen_mov_tl(cpu_cc_dst, dst);
727

728
    gen_cc_clear_icc();
729
730
731
    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);
732
733
}

734
static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
blueswir1's avatar
blueswir1 committed
735
736
737
738
739
740
{
    TCGv r_temp, r_temp2;

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

741
742
    tcg_gen_extu_tl_i64(r_temp, src2);
    tcg_gen_extu_tl_i64(r_temp2, src1);
blueswir1's avatar
blueswir1 committed
743
744
745
746
747
748
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);

    tcg_gen_shri_i64(r_temp, r_temp2, 32);
    tcg_gen_trunc_i64_i32(r_temp, r_temp);
    tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
#ifdef TARGET_SPARC64
749
    tcg_gen_mov_i64(dst, r_temp2);
blueswir1's avatar
blueswir1 committed
750
#else
751
    tcg_gen_trunc_i64_tl(dst, r_temp2);
blueswir1's avatar
blueswir1 committed
752
753
754
#endif
}

755
static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
blueswir1's avatar
blueswir1 committed
756
757
758
759
760
761
{
    TCGv r_temp, r_temp2;

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

762
763
    tcg_gen_ext_tl_i64(r_temp, src2);
    tcg_gen_ext_tl_i64(r_temp2, src1);
blueswir1's avatar
blueswir1 committed
764
765
766
767
768
769
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);

    tcg_gen_shri_i64(r_temp, r_temp2, 32);
    tcg_gen_trunc_i64_i32(r_temp, r_temp);
    tcg_gen_st_i32(r_temp, cpu_env, offsetof(CPUSPARCState, y));
#ifdef TARGET_SPARC64
770
    tcg_gen_mov_i64(dst, r_temp2);
blueswir1's avatar
blueswir1 committed
771
#else
772
    tcg_gen_trunc_i64_tl(dst, r_temp2);
blueswir1's avatar
blueswir1 committed
773
774
775
#endif
}

blueswir1's avatar
blueswir1 committed
776
#ifdef TARGET_SPARC64
blueswir1's avatar
blueswir1 committed
777
static inline void gen_trap_ifdivzero_tl(TCGv divisor)
blueswir1's avatar
blueswir1 committed
778
779
780
781
{
    int l1;

    l1 = gen_new_label();
pbrook's avatar
pbrook committed
782
    tcg_gen_brcondi_tl(TCG_COND_NE, divisor, 0, l1);
blueswir1's avatar
blueswir1 committed
783
    tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_DIV_ZERO));
blueswir1's avatar
blueswir1 committed
784
785
786
    gen_set_label(l1);
}

787
static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
blueswir1's avatar
blueswir1 committed
788
789
790
791
792
{
    int l1, l2;

    l1 = gen_new_label();
    l2 = gen_new_label();
793
794
    tcg_gen_mov_tl(cpu_cc_src, src1);
    tcg_gen_mov_tl(cpu_cc_src2, src2);
795
    gen_trap_ifdivzero_tl(src2);
pbrook's avatar
pbrook committed
796
797
    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);
798
    tcg_gen_movi_i64(dst, INT64_MIN);
blueswir1's avatar
blueswir1 committed
799
    tcg_gen_br(l2);
blueswir1's avatar
blueswir1 committed
800
    gen_set_label(l1);
801
    tcg_gen_div_i64(dst, cpu_cc_src, cpu_cc_src2);
blueswir1's avatar
blueswir1 committed
802
803
804
805
    gen_set_label(l2);
}
#endif

806
static inline void gen_op_div_cc(TCGv dst)
807
808
809
{
    int l1;

810
    tcg_gen_mov_tl(cpu_cc_dst, dst);
811
    gen_cc_clear_icc();
812
    gen_cc_NZ_icc(cpu_cc_dst);
813
    l1 = gen_new_label();
814
    tcg_gen_ld_tl(cpu_tmp0, cpu_env, offsetof(CPUSPARCState, cc_src2));
pbrook's avatar
pbrook committed
815
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
816
817
818
819
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
    gen_set_label(l1);
}

820
static inline void gen_op_logic_cc(TCGv dst)
821
{
822
823
    tcg_gen_mov_tl(cpu_cc_dst, dst);

824
    gen_cc_clear_icc();
825
    gen_cc_NZ_icc(cpu_cc_dst);
826
827
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
828
    gen_cc_NZ_xcc(cpu_cc_dst);
829
#endif
830
831
}

832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
// 1
static inline void gen_op_eval_ba(TCGv dst)
{
    tcg_gen_movi_tl(dst, 1);
}

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

// Z | (N ^ V)
static inline void gen_op_eval_ble(TCGv dst, TCGv src)
{
847
    gen_mov_reg_N(cpu_tmp0, src);
848
    gen_mov_reg_V(dst, src);
849
850
851
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
    gen_mov_reg_Z(cpu_tmp0, src);
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
852
853
854
855
856
}

// N ^ V
static inline void gen_op_eval_bl(TCGv dst, TCGv src)
{
857
    gen_mov_reg_V(cpu_tmp0, src);
858
    gen_mov_reg_N(dst, src);
859
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
860
861
862
863
864
}

// C | Z
static inline void gen_op_eval_bleu(TCGv dst, TCGv src)
{
865
    gen_mov_reg_Z(cpu_tmp0, src);
866
    gen_mov_reg_C(dst, src);
867
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
}

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

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

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

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

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

// !(Z | (N ^ V))
static inline void gen_op_eval_bg(TCGv dst, TCGv src)
{
904
    gen_mov_reg_N(cpu_tmp0, src);
905
    gen_mov_reg_V(dst, src);
906
907
908
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
    gen_mov_reg_Z(cpu_tmp0, src);
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
909
910
911
912
913
914
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !(N ^ V)
static inline void gen_op_eval_bge(TCGv dst, TCGv src)
{
915
    gen_mov_reg_V(cpu_tmp0, src);
916
    gen_mov_reg_N(dst, src);
917
    tcg_gen_xor_tl(dst