Blame view

target-sparc/translate.c 188 KB
1
2
3
4
/*
   SPARC translation

   Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
bellard authored
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"
31
#include "helper.h"
bellard authored
32
#include "tcg-op.h"
33
pbrook authored
34
35
36
#define GEN_HELPER 1
#include "helper.h"
37
38
#define DEBUG_DISAS
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] */
43
/* global register indexes */
pbrook authored
44
static TCGv_ptr cpu_env, cpu_regwptr;
blueswir1 authored
45
static TCGv cpu_cc_src, cpu_cc_src2, cpu_cc_dst;
pbrook authored
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
pbrook authored
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;
pbrook authored
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
62
/* local register indexes (only used inside old micro ops) */
pbrook authored
63
64
65
static TCGv cpu_tmp0;
static TCGv_i32 cpu_tmp32;
static TCGv_i64 cpu_tmp64;
66
/* Floating point registers */
pbrook authored
67
static TCGv_i32 cpu_fpr[TARGET_FPREGS];
68
pbrook authored
69
70
#include "gen-icount.h"
71
typedef struct DisasContext {
blueswir1 authored
72
73
    target_ulong pc;    /* current Program Counter: integer or DYNAMIC_PC */
    target_ulong npc;   /* next PC: integer or DYNAMIC_PC or JUMP_PC */
74
    target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
75
    int is_br;
76
    int mem_idx;
77
    int fpu_enabled;
78
    int address_mask_32bit;
79
    struct TranslationBlock *tb;
80
    sparc_def_t *def;
81
82
} DisasContext;
bellard authored
83
// This function uses non-native bit order
84
85
86
#define GET_FIELD(X, FROM, TO) \
  ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
bellard authored
87
88
89
90
91
// 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 authored
92
#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
bellard authored
93
94

#ifdef TARGET_SPARC64
95
#define FFPREG(r) (r)
96
#define DFPREG(r) (((r & 1) << 5) | (r & 0x1e))
97
#define QFPREG(r) (((r & 1) << 5) | (r & 0x1c))
bellard authored
98
#else
99
#define FFPREG(r) (r)
100
#define DFPREG(r) (r & 0x1e)
101
#define QFPREG(r) (r & 0x1c)
bellard authored
102
103
#endif
104
105
106
#define UA2005_HTRAP_MASK 0xff
#define V8_TRAP_MASK 0x7f
bellard authored
107
108
109
110
111
112
static int sign_extend(int x, int len)
{
    len = 32 - len;
    return (x << len) >> len;
}
113
114
#define IS_IMM (insn & (1<<13))
115
116
117
/* floating point registers moves */
static void gen_op_load_fpr_DT0(unsigned int src)
{
118
    tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, dt0) +
blueswir1 authored
119
                   offsetof(CPU_DoubleU, l.upper));
120
    tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, dt0) +
blueswir1 authored
121
                   offsetof(CPU_DoubleU, l.lower));
122
123
124
125
}

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

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

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

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

static void gen_op_store_QT0_fpr(unsigned int dst)
{
166
    tcg_gen_ld_i32(cpu_fpr[dst], cpu_env, offsetof(CPUSPARCState, qt0) +
blueswir1 authored
167
                   offsetof(CPU_QuadU, l.upmost));
168
    tcg_gen_ld_i32(cpu_fpr[dst + 1], cpu_env, offsetof(CPUSPARCState, qt0) +
blueswir1 authored
169
                   offsetof(CPU_QuadU, l.upper));
170
    tcg_gen_ld_i32(cpu_fpr[dst + 2], cpu_env, offsetof(CPUSPARCState, qt0) +
blueswir1 authored
171
                   offsetof(CPU_QuadU, l.lower));
172
    tcg_gen_ld_i32(cpu_fpr[dst + 3], cpu_env, offsetof(CPUSPARCState, qt0) +
blueswir1 authored
173
                   offsetof(CPU_QuadU, l.lowest));
174
}
175
176
177
/* moves */
#ifdef CONFIG_USER_ONLY
bellard authored
178
#define supervisor(dc) 0
179
#ifdef TARGET_SPARC64
180
#define hypervisor(dc) 0
181
#endif
bellard authored
182
#else
blueswir1 authored
183
#define supervisor(dc) (dc->mem_idx >= 1)
184
185
#ifdef TARGET_SPARC64
#define hypervisor(dc) (dc->mem_idx == 2)
blueswir1 authored
186
#else
bellard authored
187
#endif
188
189
#endif
190
191
192
#ifdef TARGET_SPARC64
#ifndef TARGET_ABI32
#define AM_CHECK(dc) ((dc)->address_mask_32bit)
193
#else
194
195
#define AM_CHECK(dc) (1)
#endif
196
#endif
197
198
199
200
201
202
203
204
205
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
}
206
static inline void gen_movl_reg_TN(int reg, TCGv tn)
207
{
208
209
210
    if (reg == 0)
        tcg_gen_movi_tl(tn, 0);
    else if (reg < 8)
211
        tcg_gen_mov_tl(tn, cpu_gregs[reg]);
212
213
    else {
        tcg_gen_ld_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
214
215
216
    }
}
217
static inline void gen_movl_TN_reg(int reg, TCGv tn)
218
{
219
220
221
    if (reg == 0)
        return;
    else if (reg < 8)
222
        tcg_gen_mov_tl(cpu_gregs[reg], tn);
223
224
    else {
        tcg_gen_st_tl(tn, cpu_regwptr, (reg - 8) * sizeof(target_ulong));
225
226
227
    }
}
228
static inline void gen_goto_tb(DisasContext *s, int tb_num,
229
230
231
232
233
234
235
236
                               target_ulong pc, target_ulong npc)
{
    TranslationBlock *tb;

    tb = s->tb;
    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
        (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK))  {
        /* jump to same page: we can use a direct jump */
bellard authored
237
        tcg_gen_goto_tb(tb_num);
238
239
        tcg_gen_movi_tl(cpu_pc, pc);
        tcg_gen_movi_tl(cpu_npc, npc);
bellard authored
240
        tcg_gen_exit_tb((long)tb + tb_num);
241
242
    } else {
        /* jump to another page: currently not optimized */
243
244
        tcg_gen_movi_tl(cpu_pc, pc);
        tcg_gen_movi_tl(cpu_npc, npc);
bellard authored
245
        tcg_gen_exit_tb(0);
246
247
248
    }
}
249
// XXX suboptimal
pbrook authored
250
static inline void gen_mov_reg_N(TCGv reg, TCGv_i32 src)
251
{
252
    tcg_gen_extu_i32_tl(reg, src);
blueswir1 authored
253
    tcg_gen_shri_tl(reg, reg, PSR_NEG_SHIFT);
254
255
256
    tcg_gen_andi_tl(reg, reg, 0x1);
}
pbrook authored
257
static inline void gen_mov_reg_Z(TCGv reg, TCGv_i32 src)
258
{
259
    tcg_gen_extu_i32_tl(reg, src);
blueswir1 authored
260
    tcg_gen_shri_tl(reg, reg, PSR_ZERO_SHIFT);
261
262
263
    tcg_gen_andi_tl(reg, reg, 0x1);
}
pbrook authored
264
static inline void gen_mov_reg_V(TCGv reg, TCGv_i32 src)
265
{
266
    tcg_gen_extu_i32_tl(reg, src);
blueswir1 authored
267
    tcg_gen_shri_tl(reg, reg, PSR_OVF_SHIFT);
268
269
270
    tcg_gen_andi_tl(reg, reg, 0x1);
}
pbrook authored
271
static inline void gen_mov_reg_C(TCGv reg, TCGv_i32 src)
272
{
273
    tcg_gen_extu_i32_tl(reg, src);
blueswir1 authored
274
    tcg_gen_shri_tl(reg, reg, PSR_CARRY_SHIFT);
275
276
277
    tcg_gen_andi_tl(reg, reg, 0x1);
}
278
static inline void gen_cc_clear_icc(void)
279
280
{
    tcg_gen_movi_i32(cpu_psr, 0);
281
282
}
283
#ifdef TARGET_SPARC64
284
285
static inline void gen_cc_clear_xcc(void)
{
286
287
    tcg_gen_movi_i32(cpu_xcc, 0);
}
288
#endif
289
290
291
292
293
294
295

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

    l1 = gen_new_label();
    l2 = gen_new_label();
pbrook authored
303
    r_temp = tcg_temp_new();
304
    tcg_gen_andi_tl(r_temp, dst, 0xffffffffULL);
305
    tcg_gen_brcondi_tl(TCG_COND_NE, r_temp, 0, l1);
306
307
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_ZERO);
    gen_set_label(l1);
blueswir1 authored
308
    tcg_gen_ext32s_tl(r_temp, dst);
309
    tcg_gen_brcondi_tl(TCG_COND_GE, r_temp, 0, l2);
310
311
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_NEG);
    gen_set_label(l2);
blueswir1 authored
312
    tcg_temp_free(r_temp);
313
314
}
315
#ifdef TARGET_SPARC64
316
317
318
319
320
321
static inline void gen_cc_NZ_xcc(TCGv dst)
{
    int l1, l2;

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

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

    l1 = gen_new_label();
pbrook authored
341
342
    r_temp1 = tcg_temp_new();
    r_temp2 = tcg_temp_new();
343
344
345
    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);
346
347
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
    gen_set_label(l1);
348
349
    tcg_temp_free(r_temp1);
    tcg_temp_free(r_temp2);
350
351
}
352
#ifdef TARGET_SPARC64
353
354
355
static inline void gen_cc_C_add_xcc(TCGv dst, TCGv src1)
{
    int l1;
356
357
358
359
360
    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);
361
}
362
#endif
363
364
365
366
367

/* old op:
    if (((src1 ^ T1 ^ -1) & (src1 ^ T0)) & (1 << 31))
        env->psr |= PSR_OVF;
*/
368
static inline void gen_cc_V_add_icc(TCGv dst, TCGv src1, TCGv src2)
369
{
370
    TCGv r_temp;
371
pbrook authored
372
    r_temp = tcg_temp_new();
373
    tcg_gen_xor_tl(r_temp, src1, src2);
blueswir1 authored
374
    tcg_gen_not_tl(r_temp, r_temp);
375
376
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
377
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
blueswir1 authored
378
379
    tcg_gen_shri_tl(r_temp, r_temp, 31 - PSR_OVF_SHIFT);
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
blueswir1 authored
380
    tcg_temp_free(r_temp);
blueswir1 authored
381
    tcg_gen_or_i32(cpu_psr, cpu_psr, cpu_tmp32);
382
383
}
384
#ifdef TARGET_SPARC64
385
386
387
388
static inline void gen_cc_V_add_xcc(TCGv dst, TCGv src1, TCGv src2)
{
    TCGv r_temp;
pbrook authored
389
    r_temp = tcg_temp_new();
390
    tcg_gen_xor_tl(r_temp, src1, src2);
blueswir1 authored
391
    tcg_gen_not_tl(r_temp, r_temp);
392
393
394
    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 authored
395
396
    tcg_gen_shri_tl(r_temp, r_temp, 63 - PSR_OVF_SHIFT);
    tcg_gen_trunc_tl_i32(cpu_tmp32, r_temp);
blueswir1 authored
397
    tcg_temp_free(r_temp);
blueswir1 authored
398
    tcg_gen_or_i32(cpu_xcc, cpu_xcc, cpu_tmp32);
399
}
400
#endif
401
402
403

static inline void gen_add_tv(TCGv dst, TCGv src1, TCGv src2)
{
pbrook authored
404
405
    TCGv r_temp;
    TCGv_i32 r_const;
406
407
408
409
    int l1;

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

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

    l1 = gen_new_label();
429
430
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
431
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
432
433
434
435
436
437
438
    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;
pbrook authored
439
    TCGv_i32 r_const;
440
441

    l1 = gen_new_label();
442
443
    tcg_gen_or_tl(cpu_tmp0, src1, src2);
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x3);
444
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_tmp0, 0, l1);
blueswir1 authored
445
    r_const = tcg_const_i32(TT_TOVF);
pbrook authored
446
447
    gen_helper_raise_exception(r_const);
    tcg_temp_free_i32(r_const);
448
449
450
    gen_set_label(l1);
}
451
static inline void gen_op_add_cc(TCGv dst, TCGv src1, TCGv src2)
452
{
453
    tcg_gen_mov_tl(cpu_cc_src, src1);
454
    tcg_gen_mov_tl(cpu_cc_src2, src2);
455
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
456
    gen_cc_clear_icc();
457
458
459
    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);
460
461
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
462
463
464
    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);
465
#endif
466
    tcg_gen_mov_tl(dst, cpu_cc_dst);
467
468
}
469
static inline void gen_op_addx_cc(TCGv dst, TCGv src1, TCGv src2)
470
{
471
    tcg_gen_mov_tl(cpu_cc_src, src1);
472
    tcg_gen_mov_tl(cpu_cc_src2, src2);
473
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
474
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_tmp0);
475
    gen_cc_clear_icc();
476
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
477
478
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
479
    gen_cc_C_add_xcc(cpu_cc_dst, cpu_cc_src);
480
#endif
481
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_dst, cpu_cc_src2);
482
483
484
    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);
485
#ifdef TARGET_SPARC64
486
487
488
    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);
489
#endif
490
    tcg_gen_mov_tl(dst, cpu_cc_dst);
491
492
}
493
static inline void gen_op_tadd_cc(TCGv dst, TCGv src1, TCGv src2)
494
{
495
    tcg_gen_mov_tl(cpu_cc_src, src1);
496
    tcg_gen_mov_tl(cpu_cc_src2, src2);
497
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
498
    gen_cc_clear_icc();
499
500
501
    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);
502
    gen_cc_V_tag(cpu_cc_src, cpu_cc_src2);
503
504
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
505
506
507
    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);
508
#endif
509
    tcg_gen_mov_tl(dst, cpu_cc_dst);
510
511
}
512
static inline void gen_op_tadd_ccTV(TCGv dst, TCGv src1, TCGv src2)
513
{
514
    tcg_gen_mov_tl(cpu_cc_src, src1);
515
516
    tcg_gen_mov_tl(cpu_cc_src2, src2);
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
517
518
    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);
519
    gen_cc_clear_icc();
520
521
    gen_cc_NZ_icc(cpu_cc_dst);
    gen_cc_C_add_icc(cpu_cc_dst, cpu_cc_src);
522
523
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
524
525
526
    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);
527
#endif
528
    tcg_gen_mov_tl(dst, cpu_cc_dst);
529
530
531
532
533
534
}

/* old op:
    if (src1 < T1)
        env->psr |= PSR_CARRY;
*/
535
static inline void gen_cc_C_sub_icc(TCGv src1, TCGv src2)
536
{
537
    TCGv r_temp1, r_temp2;
538
539
540
    int l1;

    l1 = gen_new_label();
pbrook authored
541
542
    r_temp1 = tcg_temp_new();
    r_temp2 = tcg_temp_new();
543
544
545
    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);
546
547
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_CARRY);
    gen_set_label(l1);
blueswir1 authored
548
549
    tcg_temp_free(r_temp1);
    tcg_temp_free(r_temp2);
550
551
}
552
#ifdef TARGET_SPARC64
553
554
555
static inline void gen_cc_C_sub_xcc(TCGv src1, TCGv src2)
{
    int l1;
556
557
558
559
560
    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);
561
}
562
#endif
563
564
565
566
567

/* old op:
    if (((src1 ^ T1) & (src1 ^ T0)) & (1 << 31))
        env->psr |= PSR_OVF;
*/
568
static inline void gen_cc_V_sub_icc(TCGv dst, TCGv src1, TCGv src2)
569
{
570
    TCGv r_temp;
571
pbrook authored
572
    r_temp = tcg_temp_new();
573
    tcg_gen_xor_tl(r_temp, src1, src2);
574
575
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
576
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
blueswir1 authored
577
578
579
    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);
blueswir1 authored
580
    tcg_temp_free(r_temp);
581
582
}
583
#ifdef TARGET_SPARC64
584
585
586
587
static inline void gen_cc_V_sub_xcc(TCGv dst, TCGv src1, TCGv src2)
{
    TCGv r_temp;
pbrook authored
588
    r_temp = tcg_temp_new();
589
590
591
592
    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 authored
593
594
595
    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);
blueswir1 authored
596
    tcg_temp_free(r_temp);
597
}
598
#endif
599
600
601

static inline void gen_sub_tv(TCGv dst, TCGv src1, TCGv src2)
{
pbrook authored
602
603
    TCGv r_temp;
    TCGv_i32 r_const;
604
605
606
607
    int l1;

    l1 = gen_new_label();
pbrook authored
608
    r_temp = tcg_temp_new();
609
    tcg_gen_xor_tl(r_temp, src1, src2);
610
611
    tcg_gen_xor_tl(cpu_tmp0, src1, dst);
    tcg_gen_and_tl(r_temp, r_temp, cpu_tmp0);
612
    tcg_gen_andi_tl(r_temp, r_temp, (1ULL << 31));
613
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_temp, 0, l1);
blueswir1 authored
614
    r_const = tcg_const_i32(TT_TOVF);
pbrook authored
615
616
    gen_helper_raise_exception(r_const);
    tcg_temp_free_i32(r_const);
617
    gen_set_label(l1);
blueswir1 authored
618
    tcg_temp_free(r_temp);
619
620
}
621
static inline void gen_op_sub_cc(TCGv dst, TCGv src1, TCGv src2)
622
{
623
    tcg_gen_mov_tl(cpu_cc_src, src1);
624
    tcg_gen_mov_tl(cpu_cc_src2, src2);
625
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
626
    gen_cc_clear_icc();
627
    gen_cc_NZ_icc(cpu_cc_dst);
628
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
629
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
630
631
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
632
    gen_cc_NZ_xcc(cpu_cc_dst);
633
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
634
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
635
#endif
636
    tcg_gen_mov_tl(dst, cpu_cc_dst);
637
638
}
639
static inline void gen_op_subx_cc(TCGv dst, TCGv src1, TCGv src2)
640
{
641
    tcg_gen_mov_tl(cpu_cc_src, src1);
642
    tcg_gen_mov_tl(cpu_cc_src2, src2);
643
    gen_mov_reg_C(cpu_tmp0, cpu_psr);
644
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_tmp0);
645
    gen_cc_clear_icc();
646
    gen_cc_C_sub_icc(cpu_cc_dst, cpu_cc_src);
647
648
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
649
    gen_cc_C_sub_xcc(cpu_cc_dst, cpu_cc_src);
650
#endif
651
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_dst, cpu_cc_src2);
652
653
654
    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);
655
#ifdef TARGET_SPARC64
656
657
658
    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);
659
#endif
660
    tcg_gen_mov_tl(dst, cpu_cc_dst);
661
662
}
663
static inline void gen_op_tsub_cc(TCGv dst, TCGv src1, TCGv src2)
664
{
665
    tcg_gen_mov_tl(cpu_cc_src, src1);
666
    tcg_gen_mov_tl(cpu_cc_src2, src2);
667
    tcg_gen_sub_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
668
    gen_cc_clear_icc();
669
    gen_cc_NZ_icc(cpu_cc_dst);
670
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
671
    gen_cc_V_sub_icc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
672
    gen_cc_V_tag(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
    tcg_gen_mov_tl(dst, cpu_cc_dst);
680
681
}
682
static inline void gen_op_tsub_ccTV(TCGv dst, TCGv src1, TCGv src2)
683
{
684
    tcg_gen_mov_tl(cpu_cc_src, src1);
685
686
    tcg_gen_mov_tl(cpu_cc_src2, src2);
    gen_tag_tv(cpu_cc_src, cpu_cc_src2);
687
688
    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);
689
    gen_cc_clear_icc();
690
    gen_cc_NZ_icc(cpu_cc_dst);
691
    gen_cc_C_sub_icc(cpu_cc_src, cpu_cc_src2);
692
693
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
694
    gen_cc_NZ_xcc(cpu_cc_dst);
695
    gen_cc_C_sub_xcc(cpu_cc_src, cpu_cc_src2);
696
    gen_cc_V_sub_xcc(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
697
#endif
698
    tcg_gen_mov_tl(dst, cpu_cc_dst);
699
700
}
701
static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
702
{
703
    TCGv r_temp;
704
    int l1;
705
706

    l1 = gen_new_label();
pbrook authored
707
    r_temp = tcg_temp_new();
708
709
710
711
712

    /* old op:
    if (!(env->y & 1))
        T1 = 0;
    */
713
    tcg_gen_andi_tl(cpu_cc_src, src1, 0xffffffff);
714
    tcg_gen_andi_tl(r_temp, cpu_y, 0x1);
715
    tcg_gen_andi_tl(cpu_cc_src2, src2, 0xffffffff);
716
    tcg_gen_brcondi_tl(TCG_COND_NE, r_temp, 0, l1);
717
    tcg_gen_movi_tl(cpu_cc_src2, 0);
718
    gen_set_label(l1);
719
720
721

    // b2 = T0 & 1;
    // env->y = (b2 << 31) | (env->y >> 1);
722
723
    tcg_gen_andi_tl(r_temp, cpu_cc_src, 0x1);
    tcg_gen_shli_tl(r_temp, r_temp, 31);
724
    tcg_gen_shri_tl(cpu_tmp0, cpu_y, 1);
725
    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x7fffffff);
726
727
    tcg_gen_or_tl(cpu_tmp0, cpu_tmp0, r_temp);
    tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
728
729
730
731
732

    // 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);
blueswir1 authored
733
    tcg_temp_free(r_temp);
734
735
736
737

    // T0 = (b1 << 31) | (T0 >> 1);
    // src1 = T0;
    tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);
738
    tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
739
740
741
    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);

    /* do addition and update flags */
742
    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
743
744
    gen_cc_clear_icc();
745
746
747
    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);
748
    tcg_gen_mov_tl(dst, cpu_cc_dst);
749
750
}
751
static inline void gen_op_umul(TCGv dst, TCGv src1, TCGv src2)
752
{
pbrook authored
753
    TCGv_i64 r_temp, r_temp2;
754
pbrook authored
755
756
    r_temp = tcg_temp_new_i64();
    r_temp2 = tcg_temp_new_i64();
757
blueswir1 authored
758
759
    tcg_gen_extu_tl_i64(r_temp, src2);
    tcg_gen_extu_tl_i64(r_temp2, src1);
760
761
762
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);

    tcg_gen_shri_i64(r_temp, r_temp2, 32);
763
    tcg_gen_trunc_i64_tl(cpu_tmp0, r_temp);
pbrook authored
764
    tcg_temp_free_i64(r_temp);
765
    tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
766
#ifdef TARGET_SPARC64
767
    tcg_gen_mov_i64(dst, r_temp2);
768
#else
769
    tcg_gen_trunc_i64_tl(dst, r_temp2);
770
#endif
pbrook authored
771
    tcg_temp_free_i64(r_temp2);
772
773
}
774
static inline void gen_op_smul(TCGv dst, TCGv src1, TCGv src2)
775
{
pbrook authored
776
    TCGv_i64 r_temp, r_temp2;
777
pbrook authored
778
779
    r_temp = tcg_temp_new_i64();
    r_temp2 = tcg_temp_new_i64();
780
blueswir1 authored
781
782
    tcg_gen_ext_tl_i64(r_temp, src2);
    tcg_gen_ext_tl_i64(r_temp2, src1);
783
784
785
    tcg_gen_mul_i64(r_temp2, r_temp, r_temp2);

    tcg_gen_shri_i64(r_temp, r_temp2, 32);
786
    tcg_gen_trunc_i64_tl(cpu_tmp0, r_temp);
pbrook authored
787
    tcg_temp_free_i64(r_temp);
788
    tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
789
#ifdef TARGET_SPARC64
790
    tcg_gen_mov_i64(dst, r_temp2);
791
#else
792
    tcg_gen_trunc_i64_tl(dst, r_temp2);
793
#endif
pbrook authored
794
    tcg_temp_free_i64(r_temp2);
795
796
}
797
#ifdef TARGET_SPARC64
798
static inline void gen_trap_ifdivzero_tl(TCGv divisor)
799
{
pbrook authored
800
    TCGv_i32 r_const;
801
802
803
    int l1;

    l1 = gen_new_label();
804
    tcg_gen_brcondi_tl(TCG_COND_NE, divisor, 0, l1);
blueswir1 authored
805
    r_const = tcg_const_i32(TT_DIV_ZERO);
pbrook authored
806
807
    gen_helper_raise_exception(r_const);
    tcg_temp_free_i32(r_const);
808
809
810
    gen_set_label(l1);
}
811
static inline void gen_op_sdivx(TCGv dst, TCGv src1, TCGv src2)
812
813
814
815
816
{
    int l1, l2;

    l1 = gen_new_label();
    l2 = gen_new_label();
817
818
    tcg_gen_mov_tl(cpu_cc_src, src1);
    tcg_gen_mov_tl(cpu_cc_src2, src2);
819
    gen_trap_ifdivzero_tl(cpu_cc_src2);
820
821
    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);
822
    tcg_gen_movi_i64(dst, INT64_MIN);
823
    tcg_gen_br(l2);
824
    gen_set_label(l1);
825
    tcg_gen_div_i64(dst, cpu_cc_src, cpu_cc_src2);
826
827
828
829
    gen_set_label(l2);
}
#endif
830
static inline void gen_op_div_cc(TCGv dst)
831
832
833
{
    int l1;
834
    tcg_gen_mov_tl(cpu_cc_dst, dst);
835
    gen_cc_clear_icc();
836
    gen_cc_NZ_icc(cpu_cc_dst);
837
    l1 = gen_new_label();
838
    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_cc_src2, 0, l1);
839
840
841
842
    tcg_gen_ori_i32(cpu_psr, cpu_psr, PSR_OVF);
    gen_set_label(l1);
}
843
static inline void gen_op_logic_cc(TCGv dst)
844
{
845
846
    tcg_gen_mov_tl(cpu_cc_dst, dst);
847
    gen_cc_clear_icc();
848
    gen_cc_NZ_icc(cpu_cc_dst);
849
850
#ifdef TARGET_SPARC64
    gen_cc_clear_xcc();
851
    gen_cc_NZ_xcc(cpu_cc_dst);
852
#endif
853
854
}
855
856
857
858
859
860
861
// 1
static inline void gen_op_eval_ba(TCGv dst)
{
    tcg_gen_movi_tl(dst, 1);
}

// Z
pbrook authored
862
static inline void gen_op_eval_be(TCGv dst, TCGv_i32 src)
863
864
865
866
867
{
    gen_mov_reg_Z(dst, src);
}

// Z | (N ^ V)
pbrook authored
868
static inline void gen_op_eval_ble(TCGv dst, TCGv_i32 src)
869
{
870
    gen_mov_reg_N(cpu_tmp0, src);
871
    gen_mov_reg_V(dst, src);
872
873
874
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
    gen_mov_reg_Z(cpu_tmp0, src);
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
875
876
877
}

// N ^ V
pbrook authored
878
static inline void gen_op_eval_bl(TCGv dst, TCGv_i32 src)
879
{
880
    gen_mov_reg_V(cpu_tmp0, src);
881
    gen_mov_reg_N(dst, src);
882
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
883
884
885
}

// C | Z
pbrook authored
886
static inline void gen_op_eval_bleu(TCGv dst, TCGv_i32 src)
887
{
888
    gen_mov_reg_Z(cpu_tmp0, src);
889
    gen_mov_reg_C(dst, src);
890
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
891
892
893
}

// C
pbrook authored
894
static inline void gen_op_eval_bcs(TCGv dst, TCGv_i32 src)
895
896
897
898
899
{
    gen_mov_reg_C(dst, src);
}

// V
pbrook authored
900
static inline void gen_op_eval_bvs(TCGv dst, TCGv_i32 src)
901
902
903
904
905
906
907
908
909
910
911
{
    gen_mov_reg_V(dst, src);
}

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

// N
pbrook authored
912
static inline void gen_op_eval_bneg(TCGv dst, TCGv_i32 src)
913
914
915
916
917
{
    gen_mov_reg_N(dst, src);
}

// !Z
pbrook authored
918
static inline void gen_op_eval_bne(TCGv dst, TCGv_i32 src)
919
920
921
922
923
924
{
    gen_mov_reg_Z(dst, src);
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !(Z | (N ^ V))
pbrook authored
925
static inline void gen_op_eval_bg(TCGv dst, TCGv_i32 src)
926
{
927
    gen_mov_reg_N(cpu_tmp0, src);
928
    gen_mov_reg_V(dst, src);
929
930
931
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
    gen_mov_reg_Z(cpu_tmp0, src);
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
932
933
934
935
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !(N ^ V)
pbrook authored
936
static inline void gen_op_eval_bge(TCGv dst, TCGv_i32 src)
937
{
938
    gen_mov_reg_V(cpu_tmp0, src);
939
    gen_mov_reg_N(dst, src);
940
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
941
942
943
944
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !(C | Z)
pbrook authored
945
static inline void gen_op_eval_bgu(TCGv dst, TCGv_i32 src)
946
{
947
    gen_mov_reg_Z(cpu_tmp0, src);
948
    gen_mov_reg_C(dst, src);
949
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
950
951
952
953
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !C
pbrook authored
954
static inline void gen_op_eval_bcc(TCGv dst, TCGv_i32 src)
955
956
957
958
959
960
{
    gen_mov_reg_C(dst, src);
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !N
pbrook authored
961
static inline void gen_op_eval_bpos(TCGv dst, TCGv_i32 src)
962
963
964
965
966
967
{
    gen_mov_reg_N(dst, src);
    tcg_gen_xori_tl(dst, dst, 0x1);
}

// !V
pbrook authored
968
static inline void gen_op_eval_bvc(TCGv dst, TCGv_i32 src)
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
{
    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)
{
984
    tcg_gen_shri_tl(reg, src, FSR_FCC0_SHIFT + fcc_offset);
985
986
987
988
989
990
    tcg_gen_andi_tl(reg, reg, 0x1);
}

static inline void gen_mov_reg_FCC1(TCGv reg, TCGv src,
                                    unsigned int fcc_offset)
{
991
    tcg_gen_shri_tl(reg, src, FSR_FCC1_SHIFT + fcc_offset);
992
993
994
995
996
997
998
999
    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);
1000
1001
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
1002
1003
1004
1005
1006
1007
1008
}

// 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);
1009
1010
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
}

// 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);
1025
1026
1027
    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);
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
}

// 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);
1043
1044
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1045
1046
1047
1048
1049
1050
1051
}

// 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);
1052
1053
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1054
1055
1056
1057
1058
1059
1060
}

// 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);
1061
1062
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_or_tl(dst, dst, cpu_tmp0);
1063
1064
1065
1066
1067
1068
1069
1070
    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);
1071
1072
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_xor_tl(dst, dst, cpu_tmp0);
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
    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);
1089
1090
1091
    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);
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
    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);
1109
1110
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1111
1112
1113
1114
1115
1116
1117
1118
    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);
1119
1120
    gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset);
    tcg_gen_and_tl(dst, dst, cpu_tmp0);
1121
1122
1123
    tcg_gen_xori_tl(dst, dst, 0x1);
}
blueswir1 authored
1124
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
1125
                               target_ulong pc2, TCGv r_cond)
bellard authored
1126
1127
1128
1129
1130
{
    int l1;

    l1 = gen_new_label();
1131
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
bellard authored
1132
1133
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
bellard authored
1134
1135

    gen_set_label(l1);
1136
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
bellard authored
1137
1138
}
blueswir1 authored
1139
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
1140
                                target_ulong pc2, TCGv r_cond)
bellard authored
1141
1142
1143
1144
1145
{
    int l1;

    l1 = gen_new_label();
1146
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
bellard authored
1147
1148
    gen_goto_tb(dc, 0, pc2, pc1);
bellard authored
1149
1150

    gen_set_label(l1);
1151
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
bellard authored
1152
1153
}
1154
1155
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2,
                                      TCGv r_cond)
bellard authored
1156
1157
1158
1159
1160
{
    int l1, l2;

    l1 = gen_new_label();
    l2 = gen_new_label();
1161
1162
    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
bellard authored
1163
1164
    tcg_gen_movi_tl(cpu_npc, npc1);
1165
    tcg_gen_br(l2);
bellard authored
1166
1167

    gen_set_label(l1);
1168
    tcg_gen_movi_tl(cpu_npc, npc2);
bellard authored
1169
1170
1171
    gen_set_label(l2);
}
1172
1173
1174
/* 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)
bellard authored
1175
1176
{
    if (dc->npc == JUMP_PC) {
1177
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
bellard authored
1178
1179
1180
1181
        dc->npc = DYNAMIC_PC;
    }
}
1182
static inline void save_npc(DisasContext *dc, TCGv cond)
1183
1184
{
    if (dc->npc == JUMP_PC) {
1185
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1186
1187
        dc->npc = DYNAMIC_PC;
    } else if (dc->npc != DYNAMIC_PC) {
1188
        tcg_gen_movi_tl(cpu_npc, dc->npc);
1189
1190
1191
    }
}
1192
static inline void save_state(DisasContext *dc, TCGv cond)
1193
{
1194
    tcg_gen_movi_tl(cpu_pc, dc->pc);
1195
    save_npc(dc, cond);
1196
1197
}
1198
static inline void gen_mov_pc_npc(DisasContext *dc, TCGv cond)
bellard authored
1199
1200
{
    if (dc->npc == JUMP_PC) {
1201
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1], cond);
1202
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
bellard authored
1203
1204
        dc->pc = DYNAMIC_PC;
    } else if (dc->npc == DYNAMIC_PC) {
1205
        tcg_gen_mov_tl(cpu_pc, cpu_npc);
bellard authored
1206
1207
1208
1209
1210
1211
        dc->pc = DYNAMIC_PC;
    } else {
        dc->pc = dc->npc;
    }
}
1212
1213
static inline void gen_op_next_insn(void)
{
1214
1215
    tcg_gen_mov_tl(cpu_pc, cpu_npc);
    tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
1216
1217
}
1218
1219
static inline void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond)
{
pbrook authored
1220
    TCGv_i32 r_src;
bellard authored
1221
1222

#ifdef TARGET_SPARC64
1223
    if (cc)
1224
        r_src = cpu_xcc;
1225
    else
1226
        r_src = cpu_psr;
bellard authored
1227
#else
1228
    r_src = cpu_psr;
bellard authored
1229
#endif
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
    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;
    }
}
1281
1282
static inline void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
1283
{
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
    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:
blueswir1 authored
1307
        gen_op_eval_fbne(r_dst, cpu_fsr, offset);
1308
1309
        break;
    case 0x2:
blueswir1 authored
1310
        gen_op_eval_fblg(r_dst, cpu_fsr, offset);
1311
1312
        break;
    case 0x3:
blueswir1 authored
1313
        gen_op_eval_fbul(r_dst, cpu_fsr, offset);
1314
1315
        break;
    case 0x4:
blueswir1 authored
1316
        gen_op_eval_fbl(r_dst, cpu_fsr, offset);
1317
1318
        break;
    case 0x5:
blueswir1 authored
1319
        gen_op_eval_fbug(r_dst, cpu_fsr, offset);
1320
1321
        break;
    case 0x6:
blueswir1 authored
1322
        gen_op_eval_fbg(r_dst, cpu_fsr, offset);
1323
1324
        break;
    case 0x7:
blueswir1 authored
1325
        gen_op_eval_fbu(r_dst, cpu_fsr, offset);
1326
1327
1328
1329
1330
        break;
    case 0x8:
        gen_op_eval_ba(r_dst);
        break;
    case 0x9:
blueswir1 authored
1331
        gen_op_eval_fbe(r_dst, cpu_fsr, offset);
1332
1333
        break;
    case 0xa:
blueswir1 authored
1334
        gen_op_eval_fbue(r_dst, cpu_fsr, offset);
1335
1336
        break;
    case 0xb:
blueswir1 authored
1337
        gen_op_eval_fbge(r_dst, cpu_fsr, offset);
1338
1339
        break;
    case 0xc:
blueswir1 authored
1340
        gen_op_eval_fbuge(r_dst, cpu_fsr, offset);
1341
1342
        break;
    case 0xd:
blueswir1 authored
1343
        gen_op_eval_fble(r_dst, cpu_fsr, offset);
1344
1345
        break;
    case 0xe:
blueswir1 authored
1346
        gen_op_eval_fbule(r_dst, cpu_fsr, offset);
1347
1348
        break;
    case 0xf:
blueswir1 authored
1349
        gen_op_eval_fbo(r_dst, cpu_fsr, offset);
1350
1351
        break;
    }
1352
}
1353
1354
#ifdef TARGET_SPARC64
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
// 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,
};
1366
1367
static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
1368
1369
1370
1371
{
    int l1;

    l1 = gen_new_label();
1372
    tcg_gen_movi_tl(r_dst, 0);
1373
    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], r_src, 0, l1);
1374
1375
1376
    tcg_gen_movi_tl(r_dst, 1);
    gen_set_label(l1);
}
bellard authored
1377
#endif
1378
bellard authored
1379
/* XXX: potentially incorrect if dynamic npc */
1380
1381
static void do_branch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
                      TCGv r_cond)
1382
{
1383
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1384
    target_ulong target = dc->pc + offset;
1385
1386
    if (cond == 0x0) {
blueswir1 authored
1387
1388
1389
1390
1391
1392
1393
1394
        /* 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;
        }
1395
    } else if (cond == 0x8) {
blueswir1 authored
1396
1397
1398
1399
1400
1401
1402
1403
        /* unconditional taken */
        if (a) {
            dc->pc = target;
            dc->npc = dc->pc + 4;
        } else {
            dc->pc = dc->npc;
            dc->npc = target;
        }
1404
    } else {
1405
1406
        flush_cond(dc, r_cond);
        gen_cond(r_cond, cc, cond);
blueswir1 authored
1407
        if (a) {
1408
            gen_branch_a(dc, target, dc->npc, r_cond);
1409
            dc->is_br = 1;
blueswir1 authored
1410
        } else {
1411
            dc->pc = dc->npc;
1412
1413
1414
            dc->jump_pc[0] = target;
            dc->jump_pc[1] = dc->npc + 4;
            dc->npc = JUMP_PC;
blueswir1 authored
1415
        }
1416
    }
1417
1418
}
bellard authored
1419
/* XXX: potentially incorrect if dynamic npc */
1420
1421
static void do_fbranch(DisasContext *dc, int32_t offset, uint32_t insn, int cc,
                      TCGv r_cond)
1422
1423
{
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1424
1425
    target_ulong target = dc->pc + offset;
1426
    if (cond == 0x0) {
blueswir1 authored
1427
1428
1429
1430
1431
1432
1433
1434
        /* 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;
        }
1435
    } else if (cond == 0x8) {
blueswir1 authored
1436
1437
1438
1439
1440
1441
1442
1443
        /* unconditional taken */
        if (a) {
            dc->pc = target;
            dc->npc = dc->pc + 4;
        } else {
            dc->pc = dc->npc;
            dc->npc = target;
        }
1444
    } else {
1445
1446
        flush_cond(dc, r_cond);
        gen_fcond(r_cond, cc, cond);
blueswir1 authored
1447
        if (a) {
1448
            gen_branch_a(dc, target, dc->npc, r_cond);
1449
            dc->is_br = 1;
blueswir1 authored
1450
        } else {
1451
1452
1453
1454
            dc->pc = dc->npc;
            dc->jump_pc[0] = target;
            dc->jump_pc[1] = dc->npc + 4;
            dc->npc = JUMP_PC;
blueswir1 authored
1455
        }
1456
1457
1458
    }
}
bellard authored
1459
1460
#ifdef TARGET_SPARC64
/* XXX: potentially incorrect if dynamic npc */
1461
1462
static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn,
                          TCGv r_cond, TCGv r_reg)
1463
{
bellard authored
1464
1465
1466
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
    target_ulong target = dc->pc + offset;
1467
1468
    flush_cond(dc, r_cond);
    gen_cond_reg(r_cond, cond, r_reg);
bellard authored
1469
    if (a) {
1470
        gen_branch_a(dc, target, dc->npc, r_cond);
blueswir1 authored
1471
        dc->is_br = 1;
bellard authored
1472
    } else {
blueswir1 authored
1473
1474
1475
1476
        dc->pc = dc->npc;
        dc->jump_pc[0] = target;
        dc->jump_pc[1] = dc->npc + 4;
        dc->npc = JUMP_PC;
bellard authored
1477
    }
1478
1479
}
pbrook authored
1480
static inline void gen_op_fcmps(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
1481
{
1482
1483
    switch (fccno) {
    case 0:
pbrook authored
1484
        gen_helper_fcmps(r_rs1, r_rs2);
1485
1486
        break;
    case 1:
pbrook authored
1487
        gen_helper_fcmps_fcc1(r_rs1, r_rs2);
1488
1489
        break;
    case 2:
pbrook authored
1490
        gen_helper_fcmps_fcc2(r_rs1, r_rs2);
1491
1492
        break;
    case 3:
pbrook authored
1493
        gen_helper_fcmps_fcc3(r_rs1, r_rs2);
1494
1495
        break;
    }
1496
1497
1498
1499
}

static inline void gen_op_fcmpd(int fccno)
{
pbrook authored
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
    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;
    }
1514
1515
1516
1517
}

static inline void gen_op_fcmpq(int fccno)
{
pbrook authored
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
    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;
    }
1532
1533
}
pbrook authored
1534
static inline void gen_op_fcmpes(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2)
1535
{
1536
1537
    switch (fccno) {
    case 0:
pbrook authored
1538
        gen_helper_fcmpes(r_rs1, r_rs2);
1539
1540
        break;
    case 1:
pbrook authored
1541
        gen_helper_fcmpes_fcc1(r_rs1, r_rs2);
1542
1543
        break;
    case 2:
pbrook authored
1544
        gen_helper_fcmpes_fcc2(r_rs1, r_rs2);
1545
1546
        break;
    case 3:
pbrook authored
1547
        gen_helper_fcmpes_fcc3(r_rs1, r_rs2);
1548
1549
        break;
    }
1550
1551
1552
1553
}

static inline void gen_op_fcmped(int fccno)
{
pbrook authored
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
    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;
    }
1568
1569
1570
1571
}

static inline void gen_op_fcmpeq(int fccno)
{
pbrook authored
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
    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;
    }
1586
1587
1588
1589
}

#else
1590
static inline void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2)
1591
{
pbrook authored
1592
    gen_helper_fcmps(r_rs1, r_rs2);
1593
1594
1595
1596
}

static inline void gen_op_fcmpd(int fccno)
{
pbrook authored
1597
    gen_helper_fcmpd();
1598
1599
1600
1601
}

static inline void gen_op_fcmpq(int fccno)
{
pbrook authored
1602
    gen_helper_fcmpq();
1603
1604
}
1605
static inline void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2)
1606
{
pbrook authored
1607
    gen_helper_fcmpes(r_rs1, r_rs2);
1608
1609
1610
1611
}

static inline void gen_op_fcmped(int fccno)
{
pbrook authored
1612
    gen_helper_fcmped();
1613
1614
1615
1616
}

static inline void gen_op_fcmpeq(int fccno)
{
pbrook authored
1617
    gen_helper_fcmpeq();
1618
1619
1620
}
#endif
1621
1622
static inline void gen_op_fpexception_im(int fsr_flags)
{
pbrook authored
1623
    TCGv_i32 r_const;
blueswir1 authored
1624
1625
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_NMASK);
blueswir1 authored
1626
    tcg_gen_ori_tl(cpu_fsr, cpu_fsr, fsr_flags);
blueswir1 authored
1627
    r_const = tcg_const_i32(TT_FP_EXCP);
pbrook authored
1628
1629
    gen_helper_raise_exception(r_const);
    tcg_temp_free_i32(r_const);
1630
1631
}
1632
static int gen_trap_ifnofpu(DisasContext *dc, TCGv r_cond)
1633
1634
1635
{
#if !defined(CONFIG_USER_ONLY)
    if (!dc->fpu_enabled) {
pbrook authored
1636
        TCGv_i32 r_const;
blueswir1 authored
1637
1638
        save_state(dc, r_cond);
blueswir1 authored
1639
        r_const = tcg_const_i32(TT_NFPU_INSN);
pbrook authored
1640
1641
        gen_helper_raise_exception(r_const);
        tcg_temp_free_i32(r_const);
1642
1643
1644
1645
1646
1647
1648
        dc->is_br = 1;
        return 1;
    }
#endif
    return 0;
}
1649
1650
static inline void gen_op_clear_ieee_excp_and_FTT(void)
{
1651
    tcg_gen_andi_tl(cpu_fsr, cpu_fsr, FSR_FTT_CEXC_NMASK);
1652
1653
1654
1655
}

static inline void gen_clear_float_exceptions(void)
{
pbrook authored
1656
    gen_helper_clear_float_exceptions();
1657
1658
}
1659
1660
/* asi moves */
#ifdef TARGET_SPARC64
pbrook authored
1661
static inline TCGv_i32 gen_get_asi(int insn, TCGv r_addr)
1662
{
1663
    int asi;
pbrook authored
1664
    TCGv_i32 r_asi;
1665
1666

    if (IS_IMM) {
pbrook authored
1667
        r_asi = tcg_temp_new_i32();
1668
        tcg_gen_mov_i32(r_asi, cpu_asi);
1669
1670
    } else {
        asi = GET_FIELD(insn, 19, 26);
1671
        r_asi = tcg_const_i32(asi);
1672
    }
1673
1674
1675
    return r_asi;
}
blueswir1 authored
1676
1677
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
                              int sign)
1678
{
pbrook authored
1679
    TCGv_i32 r_asi, r_size, r_sign;
1680
1681
    r_asi = gen_get_asi(insn, addr);
blueswir1 authored
1682
1683
    r_size = tcg_const_i32(size);
    r_sign = tcg_const_i32(sign);
pbrook authored
1684
1685
1686
1687
    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);
1688
1689
}
1690
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1691
{
pbrook authored
1692
    TCGv_i32 r_asi, r_size;
1693
1694
    r_asi = gen_get_asi(insn, addr);
blueswir1 authored
1695
    r_size = tcg_const_i32(size);
pbrook authored
1696
1697
1698
    gen_helper_st_asi(addr, src, r_asi, r_size);
    tcg_temp_free_i32(r_size);
    tcg_temp_free_i32(r_asi);
1699
1700
}
1701
static inline void gen_ldf_asi(TCGv addr, int insn, int size, int rd)
1702
{
pbrook authored
1703
    TCGv_i32 r_asi, r_size, r_rd;
1704
1705
    r_asi = gen_get_asi(insn, addr);
blueswir1 authored
1706
1707
    r_size = tcg_const_i32(size);
    r_rd = tcg_const_i32(rd);
pbrook authored
1708
1709
1710
1711
    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);
1712
1713
}
1714
static inline void gen_stf_asi(TCGv addr, int insn, int size, int rd)
1715
{
pbrook authored
1716
    TCGv_i32 r_asi, r_size, r_rd;
1717
1718
    r_asi = gen_get_asi(insn, addr);
blueswir1 authored
1719
1720
    r_size = tcg_const_i32(size);
    r_rd = tcg_const_i32(rd);
pbrook authored
1721
1722
1723
1724
    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);
1725
1726
}
1727
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1728
{
pbrook authored
1729
    TCGv_i32 r_asi, r_size, r_sign;
1730
1731
    r_asi = gen_get_asi(insn, addr);
blueswir1 authored
1732
1733
    r_size = tcg_const_i32(4);
    r_sign = tcg_const_i32(0);
pbrook authored
1734
1735
1736
1737
1738
    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);
blueswir1 authored
1739
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1740
1741
}
1742
static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
1743
{
pbrook authored
1744
    TCGv_i32 r_asi, r_rd;
1745
1746
    r_asi = gen_get_asi(insn, addr);
1747
    r_rd = tcg_const_i32(rd);
pbrook authored
1748
1749
1750
    gen_helper_ldda_asi(addr, r_asi, r_rd);
    tcg_temp_free_i32(r_rd);
    tcg_temp_free_i32(r_asi);
1751
1752
}
1753
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1754
{
pbrook authored
1755
    TCGv_i32 r_asi, r_size;
1756
1757

    gen_movl_reg_TN(rd + 1, cpu_tmp0);
1758
    tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, hi);
1759
    r_asi = gen_get_asi(insn, addr);
blueswir1 authored
1760
    r_size = tcg_const_i32(8);
pbrook authored
1761
1762
1763
    gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
    tcg_temp_free_i32(r_size);
    tcg_temp_free_i32(r_asi);
1764
1765
}
blueswir1 authored
1766
1767
static inline void gen_cas_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
                               int rd)
1768
{
pbrook authored
1769
1770
    TCGv r_val1;
    TCGv_i32 r_asi;
1771
pbrook authored
1772
    r_val1 = tcg_temp_new();
1773
    gen_movl_reg_TN(rd, r_val1);
1774
    r_asi = gen_get_asi(insn, addr);
pbrook authored
1775
1776
    gen_helper_cas_asi(dst, addr, r_val1, val2, r_asi);
    tcg_temp_free_i32(r_asi);
blueswir1 authored
1777
    tcg_temp_free(r_val1);
1778
1779
}
blueswir1 authored
1780
1781
static inline void gen_casx_asi(TCGv dst, TCGv addr, TCGv val2, int insn,
                                int rd)
1782
{
pbrook authored
1783
    TCGv_i32 r_asi;
1784
1785
    gen_movl_reg_TN(rd, cpu_tmp64);
1786
    r_asi = gen_get_asi(insn, addr);
pbrook authored
1787
1788
    gen_helper_casx_asi(dst, addr, cpu_tmp64, val2, r_asi);
    tcg_temp_free_i32(r_asi);
1789
1790
1791
1792
}

#elif !defined(CONFIG_USER_ONLY)
blueswir1 authored
1793
1794
static inline void gen_ld_asi(TCGv dst, TCGv addr, int insn, int size,
                              int sign)
1795
{
pbrook authored
1796
    TCGv_i32 r_asi, r_size, r_sign;
1797
blueswir1 authored
1798
1799
1800
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(size);
    r_sign = tcg_const_i32(sign);
pbrook authored
1801
    gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
blueswir1 authored
1802
1803
1804
    tcg_temp_free(r_sign);
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
1805
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1806
1807
}
1808
static inline void gen_st_asi(TCGv src, TCGv addr, int insn, int size)
1809
{
pbrook authored
1810
    TCGv_i32 r_asi, r_size;
1811
1812
    tcg_gen_extu_tl_i64(cpu_tmp64, src);
blueswir1 authored
1813
1814
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(size);
pbrook authored
1815
    gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
blueswir1 authored
1816
1817
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
1818
1819
}
1820
static inline void gen_swap_asi(TCGv dst, TCGv addr, int insn)
1821
{
pbrook authored
1822
1823
    TCGv_i32 r_asi, r_size, r_sign;
    TCGv_i64 r_val;
1824
blueswir1 authored
1825
1826
1827
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(4);
    r_sign = tcg_const_i32(0);
pbrook authored
1828
    gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
blueswir1 authored
1829
    tcg_temp_free(r_sign);
pbrook authored
1830
1831
1832
1833
    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);
blueswir1 authored
1834
1835
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
blueswir1 authored
1836
    tcg_gen_trunc_i64_tl(dst, cpu_tmp64);
1837
1838
}
1839
static inline void gen_ldda_asi(TCGv hi, TCGv addr, int insn, int rd)
1840
{
pbrook authored
1841
    TCGv_i32 r_asi, r_size, r_sign;
1842
blueswir1 authored
1843
1844
1845
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(8);
    r_sign = tcg_const_i32(0);
pbrook authored
1846
    gen_helper_ld_asi(cpu_tmp64, addr, r_asi, r_size, r_sign);
blueswir1 authored
1847
1848
1849
    tcg_temp_free(r_sign);
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
1850
1851
    tcg_gen_trunc_i64_tl(cpu_tmp0, cpu_tmp64);
    gen_movl_TN_reg(rd + 1, cpu_tmp0);
1852
    tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
1853
    tcg_gen_trunc_i64_tl(hi, cpu_tmp64);
1854
    gen_movl_TN_reg(rd, hi);
1855
1856
}
1857
static inline void gen_stda_asi(TCGv hi, TCGv addr, int insn, int rd)
1858
{
pbrook authored
1859
    TCGv_i32 r_asi, r_size;
1860
1861

    gen_movl_reg_TN(rd + 1, cpu_tmp0);
1862
    tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, hi);
blueswir1 authored
1863
1864
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(8);
pbrook authored
1865
    gen_helper_st_asi(addr, cpu_tmp64, r_asi, r_size);
blueswir1 authored
1866
1867
    tcg_temp_free(r_size);
    tcg_temp_free(r_asi);
1868
1869
1870
1871
}
#endif

#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
1872
static inline void gen_ldstub_asi(TCGv dst, TCGv addr, int insn)
1873
{
pbrook authored
1874
1875
    TCGv_i64 r_val;
    TCGv_i32 r_asi, r_size;
1876
1877
    gen_ld_asi(dst, addr, insn, 1, 0);
1878
blueswir1 authored
1879
1880
1881
    r_val = tcg_const_i64(0xffULL);
    r_asi = tcg_const_i32(GET_FIELD(insn, 19, 26));
    r_size = tcg_const_i32(1);
pbrook authored
1882
1883
1884
1885
    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);
1886
1887
1888
}
#endif
1889
1890
1891
1892
1893
1894
1895
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)
1896
        r_rs1 = tcg_const_tl(0); // XXX how to free?
1897
    else if (rs1 < 8)
1898
        r_rs1 = cpu_gregs[rs1];
1899
1900
1901
1902
1903
    else
        tcg_gen_ld_tl(def, cpu_regwptr, (rs1 - 8) * sizeof(target_ulong));
    return r_rs1;
}
1904
1905
1906
1907
1908
1909
1910
static inline TCGv get_src2(unsigned int insn, TCGv def)
{
    TCGv r_rs2 = def;
    unsigned int rs2;

    if (IS_IMM) { /* immediate */
        rs2 = GET_FIELDs(insn, 19, 31);
blueswir1 authored
1911
        r_rs2 = tcg_const_tl((int)rs2); // XXX how to free?
1912
1913
1914
    } else { /* register */
        rs2 = GET_FIELD(insn, 27, 31);
        if (rs2 == 0)
blueswir1 authored
1915
            r_rs2 = tcg_const_tl(0); // XXX how to free?
1916
1917
1918
1919
1920
1921
1922
1923
        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;
}
1924
#define CHECK_IU_FEATURE(dc, FEATURE)                      \
1925
    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
1926
1927
        goto illegal_insn;
#define CHECK_FPU_FEATURE(dc, FEATURE)                     \
1928
    if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE))  \
1929
1930
        goto nfpu_insn;
bellard authored
1931
/* before an instruction, dc->pc must be static */
1932
1933
1934
static void disas_sparc_insn(DisasContext * dc)
{
    unsigned int insn, opc, rs1, rs2, rd;
1935
1936
    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
blueswir1 authored
1937
        tcg_gen_debug_insn_start(dc->pc);
bellard authored
1938
    insn = ldl_code(dc->pc);
1939
    opc = GET_FIELD(insn, 0, 1);
1940
1941
    rd = GET_FIELD(insn, 2, 6);
1942
pbrook authored
1943
1944
    cpu_src1 = tcg_temp_new(); // const
    cpu_src2 = tcg_temp_new(); // const
1945
1946
    switch (opc) {
blueswir1 authored
1947
1948
1949
1950
1951
    case 0:                     /* branches/sethi */
        {
            unsigned int xop = GET_FIELD(insn, 7, 9);
            int32_t target;
            switch (xop) {
bellard authored
1952
#ifdef TARGET_SPARC64
blueswir1 authored
1953
1954
1955
1956
1957
1958
1959
1960
1961
            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)
1962
                        do_branch(dc, target, insn, 0, cpu_cond);
blueswir1 authored
1963
                    else if (cc == 2)
1964
                        do_branch(dc, target, insn, 1, cpu_cond);
blueswir1 authored
1965
1966
1967
1968
1969
1970
1971
                    else
                        goto illegal_insn;
                    goto jmp_insn;
                }
            case 0x3:           /* V9 BPr */
                {
                    target = GET_FIELD_SP(insn, 0, 13) |
1972
                        (GET_FIELD_SP(insn, 20, 21) << 14);
blueswir1 authored
1973
1974
                    target = sign_extend(target, 16);
                    target <<= 2;
1975
                    cpu_src1 = get_src1(insn, cpu_src1);
1976
                    do_branch_reg(dc, target, insn, cpu_cond, cpu_src1);
blueswir1 authored
1977
1978
1979
1980
1981
                    goto jmp_insn;
                }
            case 0x5:           /* V9 FBPcc */
                {
                    int cc = GET_FIELD_SP(insn, 20, 21);
1982
                    if (gen_trap_ifnofpu(dc, cpu_cond))
1983
                        goto jmp_insn;
blueswir1 authored
1984
1985
1986
                    target = GET_FIELD_SP(insn, 0, 18);
                    target = sign_extend(target, 19);
                    target <<= 2;
1987
                    do_fbranch(dc, target, insn, cc, cpu_cond);
blueswir1 authored
1988
1989
                    goto jmp_insn;
                }
1990
#else
blueswir1 authored
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
            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;
2001
                    do_branch(dc, target, insn, 0, cpu_cond);
blueswir1 authored
2002
2003
2004
2005
                    goto jmp_insn;
                }
            case 0x6:           /* FBN+x */
                {
2006
                    if (gen_trap_ifnofpu(dc, cpu_cond))
2007
                        goto jmp_insn;
blueswir1 authored
2008
2009
2010
                    target = GET_FIELD(insn, 10, 31);
                    target = sign_extend(target, 22);
                    target <<= 2;
2011
                    do_fbranch(dc, target, insn, 0, cpu_cond);
blueswir1 authored
2012
2013
2014
2015
2016
                    goto jmp_insn;
                }
            case 0x4:           /* SETHI */
                if (rd) { // nop
                    uint32_t value = GET_FIELD(insn, 10, 31);
blueswir1 authored
2017
2018
2019
2020
2021
                    TCGv r_const;

                    r_const = tcg_const_tl(value << 10);
                    gen_movl_TN_reg(rd, r_const);
                    tcg_temp_free(r_const);
blueswir1 authored
2022
2023
2024
2025
                }
                break;
            case 0x0:           /* UNIMPL */
            default:
bellard authored
2026
                goto illegal_insn;
blueswir1 authored
2027
2028
2029
2030
            }
            break;
        }
        break;
2031
    case 1:
blueswir1 authored
2032
2033
        /*CALL*/ {
            target_long target = GET_FIELDs(insn, 2, 31) << 2;
blueswir1 authored
2034
            TCGv r_const;
2035
blueswir1 authored
2036
2037
2038
            r_const = tcg_const_tl(dc->pc);
            gen_movl_TN_reg(15, r_const);
            tcg_temp_free(r_const);
blueswir1 authored
2039
            target += dc->pc;
2040
            gen_mov_pc_npc(dc, cpu_cond);
blueswir1 authored
2041
2042
2043
2044
2045
2046
2047
            dc->npc = target;
        }
        goto jmp_insn;
    case 2:                     /* FPU & Logical Operations */
        {
            unsigned int xop = GET_FIELD(insn, 7, 12);
            if (xop == 0x3a) {  /* generate trap */
2048
                int cond;
bellard authored
2049
2050
                cpu_src1 = get_src1(insn, cpu_src1);
blueswir1 authored
2051
2052
                if (IS_IMM) {
                    rs2 = GET_FIELD(insn, 25, 31);
2053
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, rs2);
2054
2055
                } else {
                    rs2 = GET_FIELD(insn, 27, 31);
blueswir1 authored
2056
                    if (rs2 != 0) {
2057
2058
                        gen_movl_reg_TN(rs2, cpu_src2);
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
2059
2060
                    } else
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
2061
2062
2063
                }
                cond = GET_FIELD(insn, 3, 6);
                if (cond == 0x8) {
2064
                    save_state(dc, cpu_cond);
2065
2066
2067
2068
2069
2070
                    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);
pbrook authored
2071
2072
                    tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
                    gen_helper_raise_exception(cpu_tmp32);
2073
                } else if (cond != 0) {
pbrook authored
2074
                    TCGv r_cond = tcg_temp_new();
2075
                    int l1;
bellard authored
2076
#ifdef TARGET_SPARC64
blueswir1 authored
2077
2078
                    /* V9 icc/xcc */
                    int cc = GET_FIELD_SP(insn, 11, 12);
2079
2080
                    save_state(dc, cpu_cond);
blueswir1 authored
2081
                    if (cc == 0)
2082
                        gen_cond(r_cond, 0, cond);
blueswir1 authored
2083
                    else if (cc == 2)
2084
                        gen_cond(r_cond, 1, cond);
blueswir1 authored
2085
2086
                    else
                        goto illegal_insn;
bellard authored
2087
#else
2088
                    save_state(dc, cpu_cond);
2089
                    gen_cond(r_cond, 0, cond);
bellard authored
2090
#endif
2091
2092
2093
2094
2095
2096
2097
2098
2099
                    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);
pbrook authored
2100
2101
                    tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
                    gen_helper_raise_exception(cpu_tmp32);
2102
2103

                    gen_set_label(l1);
blueswir1 authored
2104
                    tcg_temp_free(r_cond);
2105
                }
2106
                gen_op_next_insn();
bellard authored
2107
                tcg_gen_exit_tb(0);
2108
2109
                dc->is_br = 1;
                goto jmp_insn;
2110
2111
2112
2113
            } else if (xop == 0x28) {
                rs1 = GET_FIELD(insn, 13, 17);
                switch(rs1) {
                case 0: /* rdy */
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
#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
2124
                    gen_movl_TN_reg(rd, cpu_y);
2125
                    break;
bellard authored
2126
#ifdef TARGET_SPARC64
blueswir1 authored
2127
                case 0x2: /* V9 rdccr */
pbrook authored
2128
                    gen_helper_rdccr(cpu_dst);
2129
                    gen_movl_TN_reg(rd, cpu_dst);
bellard authored
2130
                    break;
blueswir1 authored
2131
                case 0x3: /* V9 rdasi */
2132
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_asi);
2133
                    gen_movl_TN_reg(rd, cpu_dst);
bellard authored
2134
                    break;
blueswir1 authored
2135
                case 0x4: /* V9 rdtick */
2136
                    {
pbrook authored
2137
                        TCGv_ptr r_tickptr;
2138
pbrook authored
2139
                        r_tickptr = tcg_temp_new_ptr();
2140
2141
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                       offsetof(CPUState, tick));
pbrook authored
2142
2143
                        gen_helper_tick_get_count(cpu_dst, r_tickptr);
                        tcg_temp_free_ptr(r_tickptr);
2144
                        gen_movl_TN_reg(rd, cpu_dst);
2145
                    }
bellard authored
2146
                    break;
blueswir1 authored
2147
                case 0x5: /* V9 rdpc */
blueswir1 authored
2148
2149
2150
2151
2152
2153
2154
                    {
                        TCGv r_const;

                        r_const = tcg_const_tl(dc->pc);
                        gen_movl_TN_reg(rd, r_const);
                        tcg_temp_free(r_const);
                    }
blueswir1 authored
2155
2156
                    break;
                case 0x6: /* V9 rdfprs */
2157
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_fprs);
2158
                    gen_movl_TN_reg(rd, cpu_dst);
bellard authored
2159
                    break;
2160
2161
                case 0xf: /* V9 membar */
                    break; /* no effect */
blueswir1 authored
2162
                case 0x13: /* Graphics Status */
2163
                    if (gen_trap_ifnofpu(dc, cpu_cond))
bellard authored
2164
                        goto jmp_insn;
2165
                    gen_movl_TN_reg(rd, cpu_gsr);
bellard authored
2166
                    break;
2167
2168
2169
2170
                case 0x16: /* Softint */
                    tcg_gen_ext_i32_tl(cpu_dst, cpu_softint);
                    gen_movl_TN_reg(rd, cpu_dst);
                    break;
blueswir1 authored
2171
                case 0x17: /* Tick compare */
2172
                    gen_movl_TN_reg(rd, cpu_tick_cmpr);
bellard authored
2173
                    break;
blueswir1 authored
2174
                case 0x18: /* System tick */
2175
                    {
pbrook authored
2176
                        TCGv_ptr r_tickptr;
2177
pbrook authored
2178
                        r_tickptr = tcg_temp_new_ptr();
2179
2180
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                       offsetof(CPUState, stick));
pbrook authored
2181
2182
                        gen_helper_tick_get_count(cpu_dst, r_tickptr);
                        tcg_temp_free_ptr(r_tickptr);
2183
                        gen_movl_TN_reg(rd, cpu_dst);
2184
                    }
bellard authored
2185
                    break;
blueswir1 authored
2186
                case 0x19: /* System tick compare */
2187
                    gen_movl_TN_reg(rd, cpu_stick_cmpr);
bellard authored
2188
                    break;
blueswir1 authored
2189
2190
2191
2192
2193
                case 0x10: /* Performance Control */
                case 0x11: /* Performance Instrumentation Counter */
                case 0x12: /* Dispatch Control */
                case 0x14: /* Softint set, WO */
                case 0x15: /* Softint clear, WO */
bellard authored
2194
2195
#endif
                default:
2196
2197
                    goto illegal_insn;
                }
2198
#if !defined(CONFIG_USER_ONLY)
2199
            } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
bellard authored
2200
#ifndef TARGET_SPARC64
blueswir1 authored
2201
2202
                if (!supervisor(dc))
                    goto priv_insn;
pbrook authored
2203
                gen_helper_rdpsr(cpu_dst);
2204
#else
2205
                CHECK_IU_FEATURE(dc, HYPV);
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
                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
2217
                    tcg_gen_mov_tl(cpu_dst, cpu_hintp);
2218
2219
                    break;
                case 5: // htba
2220
                    tcg_gen_mov_tl(cpu_dst, cpu_htba);
2221
2222
                    break;
                case 6: // hver
2223
                    tcg_gen_mov_tl(cpu_dst, cpu_hver);
2224
2225
                    break;
                case 31: // hstick_cmpr
2226
                    tcg_gen_mov_tl(cpu_dst, cpu_hstick_cmpr);
2227
2228
2229
2230
2231
                    break;
                default:
                    goto illegal_insn;
                }
#endif
2232
                gen_movl_TN_reg(rd, cpu_dst);
2233
                break;
bellard authored
2234
            } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
blueswir1 authored
2235
2236
                if (!supervisor(dc))
                    goto priv_insn;
bellard authored
2237
2238
#ifdef TARGET_SPARC64
                rs1 = GET_FIELD(insn, 13, 17);
blueswir1 authored
2239
2240
                switch (rs1) {
                case 0: // tpc
2241
                    {
pbrook authored
2242
                        TCGv_ptr r_tsptr;
2243
pbrook authored
2244
                        r_tsptr = tcg_temp_new_ptr();
2245
2246
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                       offsetof(CPUState, tsptr));
pbrook authored
2247
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2248
                                      offsetof(trap_state, tpc));
pbrook authored
2249
                        tcg_temp_free_ptr(r_tsptr);
2250
                    }
blueswir1 authored
2251
2252
                    break;
                case 1: // tnpc
2253
                    {
pbrook authored
2254
                        TCGv_ptr r_tsptr;
2255
pbrook authored
2256
                        r_tsptr = tcg_temp_new_ptr();
2257
2258
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                       offsetof(CPUState, tsptr));
2259
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2260
                                      offsetof(trap_state, tnpc));
pbrook authored
2261
                        tcg_temp_free_ptr(r_tsptr);
2262
                    }
blueswir1 authored
2263
2264
                    break;
                case 2: // tstate
2265
                    {
pbrook authored
2266
                        TCGv_ptr r_tsptr;
2267
pbrook authored
2268
                        r_tsptr = tcg_temp_new_ptr();
2269
2270
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                       offsetof(CPUState, tsptr));
2271
                        tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
2272
                                      offsetof(trap_state, tstate));
pbrook authored
2273
                        tcg_temp_free_ptr(r_tsptr);
2274
                    }
blueswir1 authored
2275
2276
                    break;
                case 3: // tt
2277
                    {
pbrook authored
2278
                        TCGv_ptr r_tsptr;
2279
pbrook authored
2280
                        r_tsptr = tcg_temp_new_ptr();
2281
2282
                        tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                       offsetof(CPUState, tsptr));
pbrook authored
2283
                        tcg_gen_ld_i32(cpu_tmp32, r_tsptr,
2284
                                       offsetof(trap_state, tt));
pbrook authored
2285
2286
                        tcg_temp_free_ptr(r_tsptr);
                        tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2287
                    }
blueswir1 authored
2288
2289
                    break;
                case 4: // tick
2290
                    {
pbrook authored
2291
                        TCGv_ptr r_tickptr;
2292
pbrook authored
2293
                        r_tickptr = tcg_temp_new_ptr();
2294
2295
                        tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                       offsetof(CPUState, tick));
pbrook authored
2296
                        gen_helper_tick_get_count(cpu_tmp0, r_tickptr);
2297
                        gen_movl_TN_reg(rd, cpu_tmp0);
pbrook authored
2298
                        tcg_temp_free_ptr(r_tickptr);
2299
                    }
blueswir1 authored
2300
2301
                    break;
                case 5: // tba
2302
                    tcg_gen_mov_tl(cpu_tmp0, cpu_tbr);
blueswir1 authored
2303
2304
                    break;
                case 6: // pstate
blueswir1 authored
2305
2306
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, pstate));
2307
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
blueswir1 authored
2308
2309
                    break;
                case 7: // tl
blueswir1 authored
2310
2311
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, tl));
2312
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
blueswir1 authored
2313
2314
                    break;
                case 8: // pil
blueswir1 authored
2315
2316
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, psrpil));
2317
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
blueswir1 authored
2318
2319
                    break;
                case 9: // cwp
pbrook authored
2320
                    gen_helper_rdcwp(cpu_tmp0);
blueswir1 authored
2321
2322
                    break;
                case 10: // cansave
blueswir1 authored
2323
2324
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, cansave));
2325
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
blueswir1 authored
2326
2327
                    break;
                case 11: // canrestore
blueswir1 authored
2328
2329
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, canrestore));
2330
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
blueswir1 authored
2331
2332
                    break;
                case 12: // cleanwin
blueswir1 authored
2333
2334
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, cleanwin));
2335
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
blueswir1 authored
2336
2337
                    break;
                case 13: // otherwin
blueswir1 authored
2338
2339
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, otherwin));
2340
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
blueswir1 authored
2341
2342
                    break;
                case 14: // wstate
blueswir1 authored
2343
2344
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, wstate));
2345
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
blueswir1 authored
2346
                    break;
2347
                case 16: // UA2005 gl
2348
                    CHECK_IU_FEATURE(dc, GL);
blueswir1 authored
2349
2350
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env,
                                   offsetof(CPUSPARCState, gl));
2351
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_tmp32);
2352
2353
                    break;
                case 26: // UA2005 strand status
2354
                    CHECK_IU_FEATURE(dc, HYPV);
2355
2356
                    if (!hypervisor(dc))
                        goto priv_insn;
blueswir1 authored
2357
                    tcg_gen_mov_tl(cpu_tmp0, cpu_ssr);
2358
                    break;
blueswir1 authored
2359
                case 31: // ver
2360
                    tcg_gen_mov_tl(cpu_tmp0, cpu_ver);
blueswir1 authored
2361
2362
2363
2364
2365
                    break;
                case 15: // fq
                default:
                    goto illegal_insn;
                }
bellard authored
2366
#else
2367
                tcg_gen_ext_i32_tl(cpu_tmp0, cpu_wim);
bellard authored
2368
#endif
2369
                gen_movl_TN_reg(rd, cpu_tmp0);
2370
                break;
bellard authored
2371
2372
            } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
#ifdef TARGET_SPARC64
2373
                save_state(dc, cpu_cond);
pbrook authored
2374
                gen_helper_flushw();
bellard authored
2375
#else
blueswir1 authored
2376
2377
                if (!supervisor(dc))
                    goto priv_insn;
2378
                gen_movl_TN_reg(rd, cpu_tbr);
bellard authored
2379
#endif
2380
2381
                break;
#endif
blueswir1 authored
2382
            } else if (xop == 0x34) {   /* FPU Operations */
2383
                if (gen_trap_ifnofpu(dc, cpu_cond))
2384
                    goto jmp_insn;
blueswir1 authored
2385
                gen_op_clear_ieee_excp_and_FTT();
2386
                rs1 = GET_FIELD(insn, 13, 17);
blueswir1 authored
2387
2388
2389
2390
                rs2 = GET_FIELD(insn, 27, 31);
                xop = GET_FIELD(insn, 18, 26);
                switch (xop) {
                    case 0x1: /* fmovs */
2391
                        tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);
blueswir1 authored
2392
2393
                        break;
                    case 0x5: /* fnegs */
pbrook authored
2394
                        gen_helper_fnegs(cpu_fpr[rd], cpu_fpr[rs2]);
blueswir1 authored
2395
2396
                        break;
                    case 0x9: /* fabss */
pbrook authored
2397
                        gen_helper_fabss(cpu_fpr[rd], cpu_fpr[rs2]);
blueswir1 authored
2398
2399
                        break;
                    case 0x29: /* fsqrts */
2400
                        CHECK_FPU_FEATURE(dc, FSQRT);
2401
                        gen_clear_float_exceptions();
pbrook authored
2402
2403
                        gen_helper_fsqrts(cpu_tmp32, cpu_fpr[rs2]);
                        gen_helper_check_ieee_exceptions();
2404
                        tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
blueswir1 authored
2405
2406
                        break;
                    case 0x2a: /* fsqrtd */
2407
                        CHECK_FPU_FEATURE(dc, FSQRT);
blueswir1 authored
2408
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2409
                        gen_clear_float_exceptions();
pbrook authored
2410
2411
                        gen_helper_fsqrtd();
                        gen_helper_check_ieee_exceptions();
blueswir1 authored
2412
2413
2414
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x2b: /* fsqrtq */
2415
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2416
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2417
                        gen_clear_float_exceptions();
pbrook authored
2418
2419
                        gen_helper_fsqrtq();
                        gen_helper_check_ieee_exceptions();
2420
2421
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
2422
                    case 0x41: /* fadds */
2423
                        gen_clear_float_exceptions();
pbrook authored
2424
2425
2426
                        gen_helper_fadds(cpu_tmp32,
                                         cpu_fpr[rs1], cpu_fpr[rs2]);
                        gen_helper_check_ieee_exceptions();
2427
                        tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
blueswir1 authored
2428
2429
2430
2431
                        break;
                    case 0x42:
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2432
                        gen_clear_float_exceptions();
pbrook authored
2433
2434
                        gen_helper_faddd();
                        gen_helper_check_ieee_exceptions();
blueswir1 authored
2435
2436
2437
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x43: /* faddq */
2438
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2439
2440
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2441
                        gen_clear_float_exceptions();
pbrook authored
2442
2443
                        gen_helper_faddq();
                        gen_helper_check_ieee_exceptions();
2444
2445
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
2446
                    case 0x45: /* fsubs */
2447
                        gen_clear_float_exceptions();
pbrook authored
2448
2449
2450
                        gen_helper_fsubs(cpu_tmp32,
                                         cpu_fpr[rs1], cpu_fpr[rs2]);
                        gen_helper_check_ieee_exceptions();
2451
                        tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
blueswir1 authored
2452
2453
2454
2455
                        break;
                    case 0x46:
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2456
                        gen_clear_float_exceptions();
pbrook authored
2457
2458
                        gen_helper_fsubd();
                        gen_helper_check_ieee_exceptions();
blueswir1 authored
2459
2460
2461
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x47: /* fsubq */
2462
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2463
2464
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2465
                        gen_clear_float_exceptions();
pbrook authored
2466
2467
                        gen_helper_fsubq();
                        gen_helper_check_ieee_exceptions();
2468
2469
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
2470
2471
                    case 0x49: /* fmuls */
                        CHECK_FPU_FEATURE(dc, FMUL);
2472
                        gen_clear_float_exceptions();
pbrook authored
2473
2474
2475
                        gen_helper_fmuls(cpu_tmp32,
                                         cpu_fpr[rs1], cpu_fpr[rs2]);
                        gen_helper_check_ieee_exceptions();
2476
                        tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
blueswir1 authored
2477
                        break;
2478
2479
                    case 0x4a: /* fmuld */
                        CHECK_FPU_FEATURE(dc, FMUL);
blueswir1 authored
2480
2481
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2482
                        gen_clear_float_exceptions();
pbrook authored
2483
2484
                        gen_helper_fmuld();
                        gen_helper_check_ieee_exceptions();
2485
                        gen_op_store_DT0_fpr(DFPREG(rd));
blueswir1 authored
2486
2487
                        break;
                    case 0x4b: /* fmulq */
2488
2489
                        CHECK_FPU_FEATURE(dc, FLOAT128);
                        CHECK_FPU_FEATURE(dc, FMUL);
2490
2491
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2492
                        gen_clear_float_exceptions();
pbrook authored
2493
2494
                        gen_helper_fmulq();
                        gen_helper_check_ieee_exceptions();
2495
2496
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
2497
                    case 0x4d: /* fdivs */
2498
                        gen_clear_float_exceptions();
pbrook authored
2499
2500
2501
                        gen_helper_fdivs(cpu_tmp32,
                                         cpu_fpr[rs1], cpu_fpr[rs2]);
                        gen_helper_check_ieee_exceptions();
2502
                        tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
blueswir1 authored
2503
2504
2505
2506
                        break;
                    case 0x4e:
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2507
                        gen_clear_float_exceptions();
pbrook authored
2508
2509
                        gen_helper_fdivd();
                        gen_helper_check_ieee_exceptions();
blueswir1 authored
2510
2511
2512
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x4f: /* fdivq */
2513
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2514
2515
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2516
                        gen_clear_float_exceptions();
pbrook authored
2517
2518
                        gen_helper_fdivq();
                        gen_helper_check_ieee_exceptions();
2519
2520
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
2521
                    case 0x69: /* fsmuld */
2522
                        CHECK_FPU_FEATURE(dc, FSMULD);
2523
                        gen_clear_float_exceptions();
pbrook authored
2524
2525
                        gen_helper_fsmuld(cpu_fpr[rs1], cpu_fpr[rs2]);
                        gen_helper_check_ieee_exceptions();
blueswir1 authored
2526
2527
2528
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x6e: /* fdmulq */
2529
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2530
2531
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2532
                        gen_clear_float_exceptions();
pbrook authored
2533
2534
                        gen_helper_fdmulq();
                        gen_helper_check_ieee_exceptions();
2535
2536
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
2537
                    case 0xc4: /* fitos */
2538
                        gen_clear_float_exceptions();
pbrook authored
2539
2540
                        gen_helper_fitos(cpu_tmp32, cpu_fpr[rs2]);
                        gen_helper_check_ieee_exceptions();
2541
                        tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
blueswir1 authored
2542
                        break;
2543
                    case 0xc6: /* fdtos */
blueswir1 authored
2544
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2545
                        gen_clear_float_exceptions();
pbrook authored
2546
2547
                        gen_helper_fdtos(cpu_tmp32);
                        gen_helper_check_ieee_exceptions();
2548
                        tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
blueswir1 authored
2549
2550
                        break;
                    case 0xc7: /* fqtos */
2551
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2552
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2553
                        gen_clear_float_exceptions();
pbrook authored
2554
2555
                        gen_helper_fqtos(cpu_tmp32);
                        gen_helper_check_ieee_exceptions();
2556
                        tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2557
                        break;
2558
                    case 0xc8: /* fitod */
pbrook authored
2559
                        gen_helper_fitod(cpu_fpr[rs2]);
blueswir1 authored
2560
2561
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
2562
                    case 0xc9: /* fstod */
pbrook authored
2563
                        gen_helper_fstod(cpu_fpr[rs2]);
blueswir1 authored
2564
2565
2566
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0xcb: /* fqtod */
2567
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2568
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2569
                        gen_clear_float_exceptions();
pbrook authored
2570
2571
                        gen_helper_fqtod();
                        gen_helper_check_ieee_exceptions();
2572
2573
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
blueswir1 authored
2574
                    case 0xcc: /* fitoq */
2575
                        CHECK_FPU_FEATURE(dc, FLOAT128);
pbrook authored
2576
                        gen_helper_fitoq(cpu_fpr[rs2]);
2577
2578
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
blueswir1 authored
2579
                    case 0xcd: /* fstoq */
2580
                        CHECK_FPU_FEATURE(dc, FLOAT128);
pbrook authored
2581
                        gen_helper_fstoq(cpu_fpr[rs2]);
2582
2583
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
blueswir1 authored
2584
                    case 0xce: /* fdtoq */
2585
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2586
                        gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
2587
                        gen_helper_fdtoq();
2588
2589
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
2590
                    case 0xd1: /* fstoi */
2591
                        gen_clear_float_exceptions();
pbrook authored
2592
2593
                        gen_helper_fstoi(cpu_tmp32, cpu_fpr[rs2]);
                        gen_helper_check_ieee_exceptions();
2594
                        tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
blueswir1 authored
2595
                        break;
2596
                    case 0xd2: /* fdtoi */
2597
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2598
                        gen_clear_float_exceptions();
pbrook authored
2599
2600
                        gen_helper_fdtoi(cpu_tmp32);
                        gen_helper_check_ieee_exceptions();
2601
                        tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
blueswir1 authored
2602
2603
                        break;
                    case 0xd3: /* fqtoi */
2604
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2605
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2606
                        gen_clear_float_exceptions();
pbrook authored
2607
2608
                        gen_helper_fqtoi(cpu_tmp32);
                        gen_helper_check_ieee_exceptions();
2609
                        tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
2610
                        break;
bellard authored
2611
#ifdef TARGET_SPARC64
blueswir1 authored
2612
                    case 0x2: /* V9 fmovd */
2613
2614
2615
2616
                        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]);
blueswir1 authored
2617
                        break;
2618
                    case 0x3: /* V9 fmovq */
2619
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2620
2621
2622
2623
2624
2625
2626
2627
                        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]);
2628
                        break;
blueswir1 authored
2629
2630
                    case 0x6: /* V9 fnegd */
                        gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
2631
                        gen_helper_fnegd();
blueswir1 authored
2632
2633
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
2634
                    case 0x7: /* V9 fnegq */
2635
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2636
                        gen_op_load_fpr_QT1(QFPREG(rs2));
pbrook authored
2637
                        gen_helper_fnegq();
2638
2639
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
blueswir1 authored
2640
2641
                    case 0xa: /* V9 fabsd */
                        gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
2642
                        gen_helper_fabsd();
blueswir1 authored
2643
2644
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
2645
                    case 0xb: /* V9 fabsq */
2646
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2647
                        gen_op_load_fpr_QT1(QFPREG(rs2));
pbrook authored
2648
                        gen_helper_fabsq();
2649
2650
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
blueswir1 authored
2651
                    case 0x81: /* V9 fstox */
2652
                        gen_clear_float_exceptions();
pbrook authored
2653
2654
                        gen_helper_fstox(cpu_fpr[rs2]);
                        gen_helper_check_ieee_exceptions();
blueswir1 authored
2655
2656
2657
2658
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x82: /* V9 fdtox */
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2659
                        gen_clear_float_exceptions();
pbrook authored
2660
2661
                        gen_helper_fdtox();
                        gen_helper_check_ieee_exceptions();
blueswir1 authored
2662
2663
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
2664
                    case 0x83: /* V9 fqtox */
2665
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2666
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2667
                        gen_clear_float_exceptions();
pbrook authored
2668
2669
                        gen_helper_fqtox();
                        gen_helper_check_ieee_exceptions();
2670
2671
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
blueswir1 authored
2672
2673
                    case 0x84: /* V9 fxtos */
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2674
                        gen_clear_float_exceptions();
pbrook authored
2675
2676
                        gen_helper_fxtos(cpu_tmp32);
                        gen_helper_check_ieee_exceptions();
2677
                        tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32);
blueswir1 authored
2678
2679
2680
                        break;
                    case 0x88: /* V9 fxtod */
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2681
                        gen_clear_float_exceptions();
pbrook authored
2682
2683
                        gen_helper_fxtod();
                        gen_helper_check_ieee_exceptions();
blueswir1 authored
2684
2685
2686
                        gen_op_store_DT0_fpr(DFPREG(rd));
                        break;
                    case 0x8c: /* V9 fxtoq */
2687
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2688
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2689
                        gen_clear_float_exceptions();
pbrook authored
2690
2691
                        gen_helper_fxtoq();
                        gen_helper_check_ieee_exceptions();
2692
2693
2694
                        gen_op_store_QT0_fpr(QFPREG(rd));
                        break;
#endif
blueswir1 authored
2695
2696
2697
2698
                    default:
                        goto illegal_insn;
                }
            } else if (xop == 0x35) {   /* FPU Operations */
bellard authored
2699
#ifdef TARGET_SPARC64
blueswir1 authored
2700
                int cond;
bellard authored
2701
#endif
2702
                if (gen_trap_ifnofpu(dc, cpu_cond))
2703
                    goto jmp_insn;
blueswir1 authored
2704
                gen_op_clear_ieee_excp_and_FTT();
2705
                rs1 = GET_FIELD(insn, 13, 17);
blueswir1 authored
2706
2707
                rs2 = GET_FIELD(insn, 27, 31);
                xop = GET_FIELD(insn, 18, 26);
bellard authored
2708
#ifdef TARGET_SPARC64
blueswir1 authored
2709
                if ((xop & 0x11f) == 0x005) { // V9 fmovsr
blueswir1 authored
2710
2711
2712
                    int l1;

                    l1 = gen_new_label();
blueswir1 authored
2713
                    cond = GET_FIELD_SP(insn, 14, 17);
2714
                    cpu_src1 = get_src1(insn, cpu_src1);
2715
2716
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
                                       0, l1);
2717
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);
blueswir1 authored
2718
                    gen_set_label(l1);
blueswir1 authored
2719
2720
                    break;
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
blueswir1 authored
2721
2722
2723
                    int l1;

                    l1 = gen_new_label();
blueswir1 authored
2724
                    cond = GET_FIELD_SP(insn, 14, 17);
2725
                    cpu_src1 = get_src1(insn, cpu_src1);
2726
2727
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
                                       0, l1);
2728
2729
                    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]);
blueswir1 authored
2730
                    gen_set_label(l1);
blueswir1 authored
2731
2732
                    break;
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
blueswir1 authored
2733
2734
                    int l1;
2735
                    CHECK_FPU_FEATURE(dc, FLOAT128);
blueswir1 authored
2736
                    l1 = gen_new_label();
2737
                    cond = GET_FIELD_SP(insn, 14, 17);
2738
                    cpu_src1 = get_src1(insn, cpu_src1);
2739
2740
                    tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1,
                                       0, l1);
2741
2742
2743
2744
                    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]);
blueswir1 authored
2745
                    gen_set_label(l1);
2746
                    break;
blueswir1 authored
2747
2748
2749
                }
#endif
                switch (xop) {
bellard authored
2750
#ifdef TARGET_SPARC64
2751
#define FMOVSCC(fcc)                                                    \
2752
                    {                                                   \
2753
                        TCGv r_cond;                                    \
2754
2755
2756
                        int l1;                                         \
                                                                        \
                        l1 = gen_new_label();                           \
pbrook authored
2757
                        r_cond = tcg_temp_new();             \
2758
2759
                        cond = GET_FIELD_SP(insn, 14, 17);              \
                        gen_fcond(r_cond, fcc, cond);                   \
2760
2761
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
                                           0, l1);                      \
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
                        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();                           \
pbrook authored
2772
                        r_cond = tcg_temp_new();             \
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
                        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();                           \
pbrook authored
2790
                        r_cond = tcg_temp_new();             \
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
                        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]);      \
2803
                        gen_set_label(l1);                              \
blueswir1 authored
2804
                        tcg_temp_free(r_cond);                          \
2805
                    }
blueswir1 authored
2806
                    case 0x001: /* V9 fmovscc %fcc0 */
2807
                        FMOVSCC(0);
blueswir1 authored
2808
2809
                        break;
                    case 0x002: /* V9 fmovdcc %fcc0 */
2810
                        FMOVDCC(0);
blueswir1 authored
2811
2812
                        break;
                    case 0x003: /* V9 fmovqcc %fcc0 */
2813
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2814
                        FMOVQCC(0);
2815
                        break;
blueswir1 authored
2816
                    case 0x041: /* V9 fmovscc %fcc1 */
2817
                        FMOVSCC(1);
blueswir1 authored
2818
2819
                        break;
                    case 0x042: /* V9 fmovdcc %fcc1 */
2820
                        FMOVDCC(1);
blueswir1 authored
2821
2822
                        break;
                    case 0x043: /* V9 fmovqcc %fcc1 */
2823
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2824
                        FMOVQCC(1);
2825
                        break;
blueswir1 authored
2826
                    case 0x081: /* V9 fmovscc %fcc2 */
2827
                        FMOVSCC(2);
blueswir1 authored
2828
2829
                        break;
                    case 0x082: /* V9 fmovdcc %fcc2 */
2830
                        FMOVDCC(2);
blueswir1 authored
2831
2832
                        break;
                    case 0x083: /* V9 fmovqcc %fcc2 */
2833
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2834
                        FMOVQCC(2);
2835
                        break;
blueswir1 authored
2836
                    case 0x0c1: /* V9 fmovscc %fcc3 */
2837
                        FMOVSCC(3);
blueswir1 authored
2838
2839
                        break;
                    case 0x0c2: /* V9 fmovdcc %fcc3 */
2840
                        FMOVDCC(3);
blueswir1 authored
2841
2842
                        break;
                    case 0x0c3: /* V9 fmovqcc %fcc3 */
2843
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2844
                        FMOVQCC(3);
2845
                        break;
2846
2847
2848
#undef FMOVSCC
#undef FMOVDCC
#undef FMOVQCC
2849
2850
#define FMOVCC(size_FDQ, icc)                                           \
                    {                                                   \
2851
                        TCGv r_cond;                                    \
2852
2853
2854
                        int l1;                                         \
                                                                        \
                        l1 = gen_new_label();                           \
pbrook authored
2855
                        r_cond = tcg_temp_new();             \
2856
2857
                        cond = GET_FIELD_SP(insn, 14, 17);              \
                        gen_cond(r_cond, icc, cond);                    \
2858
2859
                        tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond,         \
                                           0, l1);                      \
blueswir1 authored
2860
2861
2862
2863
                        glue(glue(gen_op_load_fpr_, size_FDQ), T0)      \
                            (glue(size_FDQ, FPREG(rs2)));               \
                        glue(glue(gen_op_store_, size_FDQ), T0_fpr)     \
                            (glue(size_FDQ, FPREG(rd)));                \
2864
                        gen_set_label(l1);                              \
blueswir1 authored
2865
                        tcg_temp_free(r_cond);                          \
2866
                    }
2867
2868
2869
2870
2871
2872
#define FMOVSCC(icc)                                                    \
                    {                                                   \
                        TCGv r_cond;                                    \
                        int l1;                                         \
                                                                        \
                        l1 = gen_new_label();                           \
pbrook authored
2873
                        r_cond = tcg_temp_new();             \
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
                        cond = GET_FIELD_SP(insn, 14, 17);              \
                        gen_cond(r_cond, icc, cond);                    \
                        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();                           \
pbrook authored
2888
                        r_cond = tcg_temp_new();             \
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
                        cond = GET_FIELD_SP(insn, 14, 17);              \
                        gen_cond(r_cond, icc, 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(icc)                                                    \
                    {                                                   \
                        TCGv r_cond;                                    \
                        int l1;                                         \
                                                                        \
                        l1 = gen_new_label();                           \
pbrook authored
2906
                        r_cond = tcg_temp_new();             \
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
                        cond = GET_FIELD_SP(insn, 14, 17);              \
                        gen_cond(r_cond, icc, 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]);      \
                        gen_set_label(l1);                              \
                        tcg_temp_free(r_cond);                          \
                    }
2922
blueswir1 authored
2923
                    case 0x101: /* V9 fmovscc %icc */
2924
                        FMOVSCC(0);
blueswir1 authored
2925
2926
                        break;
                    case 0x102: /* V9 fmovdcc %icc */
2927
                        FMOVDCC(0);
blueswir1 authored
2928
                    case 0x103: /* V9 fmovqcc %icc */
2929
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2930
                        FMOVQCC(0);
2931
                        break;
blueswir1 authored
2932
                    case 0x181: /* V9 fmovscc %xcc */
2933
                        FMOVSCC(1);
blueswir1 authored
2934
2935
                        break;
                    case 0x182: /* V9 fmovdcc %xcc */
2936
                        FMOVDCC(1);
blueswir1 authored
2937
2938
                        break;
                    case 0x183: /* V9 fmovqcc %xcc */
2939
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2940
                        FMOVQCC(1);
2941
                        break;
2942
2943
2944
#undef FMOVSCC
#undef FMOVDCC
#undef FMOVQCC
2945
2946
#endif
                    case 0x51: /* fcmps, V9 %fcc */
2947
                        gen_op_fcmps(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]);
blueswir1 authored
2948
                        break;
2949
                    case 0x52: /* fcmpd, V9 %fcc */
blueswir1 authored
2950
2951
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2952
                        gen_op_fcmpd(rd & 3);
blueswir1 authored
2953
                        break;
2954
                    case 0x53: /* fcmpq, V9 %fcc */
2955
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2956
2957
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2958
                        gen_op_fcmpq(rd & 3);
2959
                        break;
blueswir1 authored
2960
                    case 0x55: /* fcmpes, V9 %fcc */
2961
                        gen_op_fcmpes(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]);
blueswir1 authored
2962
2963
2964
2965
                        break;
                    case 0x56: /* fcmped, V9 %fcc */
                        gen_op_load_fpr_DT0(DFPREG(rs1));
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2966
                        gen_op_fcmped(rd & 3);
blueswir1 authored
2967
                        break;
2968
                    case 0x57: /* fcmpeq, V9 %fcc */
2969
                        CHECK_FPU_FEATURE(dc, FLOAT128);
2970
2971
                        gen_op_load_fpr_QT0(QFPREG(rs1));
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2972
                        gen_op_fcmpeq(rd & 3);
2973
                        break;
blueswir1 authored
2974
2975
2976
2977
2978
                    default:
                        goto illegal_insn;
                }
            } else if (xop == 0x2) {
                // clr/mov shortcut
bellard authored
2979
2980

                rs1 = GET_FIELD(insn, 13, 17);
blueswir1 authored
2981
                if (rs1 == 0) {
2982
                    // or %g0, x, y -> mov T0, x; mov y, T0
blueswir1 authored
2983
                    if (IS_IMM) {       /* immediate */
blueswir1 authored
2984
2985
                        TCGv r_const;
blueswir1 authored
2986
                        rs2 = GET_FIELDs(insn, 19, 31);
blueswir1 authored
2987
2988
2989
                        r_const = tcg_const_tl((int)rs2);
                        gen_movl_TN_reg(rd, r_const);
                        tcg_temp_free(r_const);
blueswir1 authored
2990
2991
                    } else {            /* register */
                        rs2 = GET_FIELD(insn, 27, 31);
2992
                        gen_movl_reg_TN(rs2, cpu_dst);
2993
                        gen_movl_TN_reg(rd, cpu_dst);
blueswir1 authored
2994
2995
                    }
                } else {
2996
                    cpu_src1 = get_src1(insn, cpu_src1);
blueswir1 authored
2997
2998
                    if (IS_IMM) {       /* immediate */
                        rs2 = GET_FIELDs(insn, 19, 31);
2999
                        tcg_gen_ori_tl(cpu_dst, cpu_src1, (int)rs2);
3000
                        gen_movl_TN_reg(rd, cpu_dst);
blueswir1 authored
3001
3002
3003
3004
                    } else {            /* register */
                        // or x, %g0, y -> mov T1, x; mov y, T1
                        rs2 = GET_FIELD(insn, 27, 31);
                        if (rs2 != 0) {
3005
3006
                            gen_movl_reg_TN(rs2, cpu_src2);
                            tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
3007
                            gen_movl_TN_reg(rd, cpu_dst);
3008
                        } else
3009
                            gen_movl_TN_reg(rd, cpu_src1);
blueswir1 authored
3010
3011
                    }
                }
bellard authored
3012
#ifdef TARGET_SPARC64
blueswir1 authored
3013
            } else if (xop == 0x25) { /* sll, V9 sllx */
3014
                cpu_src1 = get_src1(insn, cpu_src1);
blueswir1 authored
3015
                if (IS_IMM) {   /* immediate */
bellard authored
3016
                    rs2 = GET_FIELDs(insn, 20, 31);
3017
                    if (insn & (1 << 12)) {
3018
                        tcg_gen_shli_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
3019
                    } else {
blueswir1 authored
3020
                        tcg_gen_shli_i64(cpu_dst, cpu_src1, rs2 & 0x1f);
3021
                    }
blueswir1 authored
3022
                } else {                /* register */
bellard authored
3023
                    rs2 = GET_FIELD(insn, 27, 31);
3024
                    gen_movl_reg_TN(rs2, cpu_src2);
3025
                    if (insn & (1 << 12)) {
3026
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
3027
                    } else {
3028
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
3029
                    }
blueswir1 authored
3030
                    tcg_gen_shl_i64(cpu_dst, cpu_src1, cpu_tmp0);
bellard authored
3031
                }
3032
                gen_movl_TN_reg(rd, cpu_dst);
blueswir1 authored
3033
            } else if (xop == 0x26) { /* srl, V9 srlx */
3034
                cpu_src1 = get_src1(insn, cpu_src1);
blueswir1 authored
3035
                if (IS_IMM) {   /* immediate */
bellard authored
3036
                    rs2 = GET_FIELDs(insn, 20, 31);
3037
                    if (insn & (1 << 12)) {
3038
                        tcg_gen_shri_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
3039
                    } else {
3040
3041
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
                        tcg_gen_shri_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
3042
                    }
blueswir1 authored
3043
                } else {                /* register */
bellard authored
3044
                    rs2 = GET_FIELD(insn, 27, 31);
3045
                    gen_movl_reg_TN(rs2, cpu_src2);
3046
                    if (insn & (1 << 12)) {
3047
3048
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
                        tcg_gen_shr_i64(cpu_dst, cpu_src1, cpu_tmp0);
3049
                    } else {
3050
3051
3052
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
                        tcg_gen_shr_i64(cpu_dst, cpu_dst, cpu_tmp0);
3053
                    }
bellard authored
3054
                }
3055
                gen_movl_TN_reg(rd, cpu_dst);
blueswir1 authored
3056
            } else if (xop == 0x27) { /* sra, V9 srax */
3057
                cpu_src1 = get_src1(insn, cpu_src1);
blueswir1 authored
3058
                if (IS_IMM) {   /* immediate */
bellard authored
3059
                    rs2 = GET_FIELDs(insn, 20, 31);
3060
                    if (insn & (1 << 12)) {
3061
                        tcg_gen_sari_i64(cpu_dst, cpu_src1, rs2 & 0x3f);
3062
                    } else {
3063
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
blueswir1 authored
3064
                        tcg_gen_ext32s_i64(cpu_dst, cpu_dst);
3065
                        tcg_gen_sari_i64(cpu_dst, cpu_dst, rs2 & 0x1f);
3066
                    }
blueswir1 authored
3067
                } else {                /* register */
bellard authored
3068
                    rs2 = GET_FIELD(insn, 27, 31);
3069
                    gen_movl_reg_TN(rs2, cpu_src2);
3070
                    if (insn & (1 << 12)) {
3071
3072
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x3f);
                        tcg_gen_sar_i64(cpu_dst, cpu_src1, cpu_tmp0);
3073
                    } else {
3074
3075
                        tcg_gen_andi_i64(cpu_tmp0, cpu_src2, 0x1f);
                        tcg_gen_andi_i64(cpu_dst, cpu_src1, 0xffffffffULL);
blueswir1 authored
3076
                        tcg_gen_ext32s_i64(cpu_dst, cpu_dst);
3077
                        tcg_gen_sar_i64(cpu_dst, cpu_dst, cpu_tmp0);
3078
                    }
bellard authored
3079
                }
3080
                gen_movl_TN_reg(rd, cpu_dst);
bellard authored
3081
#endif
3082
            } else if (xop < 0x36) {
3083
                cpu_src1 = get_src1(insn, cpu_src1);
3084
                cpu_src2 = get_src2(insn, cpu_src2);
3085
3086
3087
3088
                if (xop < 0x20) {
                    switch (xop & ~0x10) {
                    case 0x0:
                        if (xop & 0x10)
3089
                            gen_op_add_cc(cpu_dst, cpu_src1, cpu_src2);
3090
                        else
3091
                            tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
3092
3093
                        break;
                    case 0x1:
3094
                        tcg_gen_and_tl(cpu_dst, cpu_src1, cpu_src2);
3095
                        if (xop & 0x10)
3096
                            gen_op_logic_cc(cpu_dst);
3097
3098
                        break;
                    case 0x2:
3099
                        tcg_gen_or_tl(cpu_dst, cpu_src1, cpu_src2);
blueswir1 authored
3100
                        if (xop & 0x10)
3101
                            gen_op_logic_cc(cpu_dst);
blueswir1 authored
3102
                        break;
3103
                    case 0x3:
3104
                        tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3105
                        if (xop & 0x10)
3106
                            gen_op_logic_cc(cpu_dst);
3107
3108
3109
                        break;
                    case 0x4:
                        if (xop & 0x10)
3110
                            gen_op_sub_cc(cpu_dst, cpu_src1, cpu_src2);
3111
                        else
3112
                            tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_src2);
3113
3114
                        break;
                    case 0x5:
3115
                        tcg_gen_andc_tl(cpu_dst, cpu_src1, cpu_src2);
3116
                        if (xop & 0x10)
3117
                            gen_op_logic_cc(cpu_dst);
3118
3119
                        break;
                    case 0x6:
3120
                        tcg_gen_orc_tl(cpu_dst, cpu_src1, cpu_src2);
3121
                        if (xop & 0x10)
3122
                            gen_op_logic_cc(cpu_dst);
3123
3124
                        break;
                    case 0x7:
blueswir1 authored
3125
                        tcg_gen_not_tl(cpu_tmp0, cpu_src2);
3126
                        tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_tmp0);
3127
                        if (xop & 0x10)
3128
                            gen_op_logic_cc(cpu_dst);
3129
3130
3131
                        break;
                    case 0x8:
                        if (xop & 0x10)
3132
                            gen_op_addx_cc(cpu_dst, cpu_src1, cpu_src2);
3133
                        else {
3134
                            gen_mov_reg_C(cpu_tmp0, cpu_psr);
3135
3136
                            tcg_gen_add_tl(cpu_tmp0, cpu_src2, cpu_tmp0);
                            tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_tmp0);
3137
                        }
3138
                        break;
3139
#ifdef TARGET_SPARC64
blueswir1 authored
3140
                    case 0x9: /* V9 mulx */
3141
                        tcg_gen_mul_i64(cpu_dst, cpu_src1, cpu_src2);
3142
3143
                        break;
#endif
3144
                    case 0xa:
3145
                        CHECK_IU_FEATURE(dc, MUL);
3146
                        gen_op_umul(cpu_dst, cpu_src1, cpu_src2);
3147
                        if (xop & 0x10)
3148
                            gen_op_logic_cc(cpu_dst);
3149
3150
                        break;
                    case 0xb:
3151
                        CHECK_IU_FEATURE(dc, MUL);
3152
                        gen_op_smul(cpu_dst, cpu_src1, cpu_src2);
3153
                        if (xop & 0x10)
3154
                            gen_op_logic_cc(cpu_dst);
3155
3156
3157
                        break;
                    case 0xc:
                        if (xop & 0x10)
3158
                            gen_op_subx_cc(cpu_dst, cpu_src1, cpu_src2);
3159
                        else {
3160
                            gen_mov_reg_C(cpu_tmp0, cpu_psr);
3161
3162
                            tcg_gen_add_tl(cpu_tmp0, cpu_src2, cpu_tmp0);
                            tcg_gen_sub_tl(cpu_dst, cpu_src1, cpu_tmp0);
3163
                        }
3164
                        break;
3165
#ifdef TARGET_SPARC64
blueswir1 authored
3166
                    case 0xd: /* V9 udivx */
3167
3168
3169
3170
                        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);
3171
3172
                        break;
#endif
3173
                    case 0xe:
3174
                        CHECK_IU_FEATURE(dc, DIV);
pbrook authored
3175
                        gen_helper_udiv(cpu_dst, cpu_src1, cpu_src2);
3176
                        if (xop & 0x10)
3177
                            gen_op_div_cc(cpu_dst);
3178
3179
                        break;
                    case 0xf:
3180
                        CHECK_IU_FEATURE(dc, DIV);
pbrook authored
3181
                        gen_helper_sdiv(cpu_dst, cpu_src1, cpu_src2);
3182
                        if (xop & 0x10)
3183
                            gen_op_div_cc(cpu_dst);
3184
3185
3186
3187
                        break;
                    default:
                        goto illegal_insn;
                    }
3188
                    gen_movl_TN_reg(rd, cpu_dst);
3189
3190
                } else {
                    switch (xop) {
blueswir1 authored
3191
                    case 0x20: /* taddcc */
3192
3193
                        gen_op_tadd_cc(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
blueswir1 authored
3194
3195
                        break;
                    case 0x21: /* tsubcc */
3196
3197
                        gen_op_tsub_cc(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
blueswir1 authored
3198
3199
                        break;
                    case 0x22: /* taddcctv */
3200
3201
3202
                        save_state(dc, cpu_cond);
                        gen_op_tadd_ccTV(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
blueswir1 authored
3203
3204
                        break;
                    case 0x23: /* tsubcctv */
3205
3206
3207
                        save_state(dc, cpu_cond);
                        gen_op_tsub_ccTV(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
blueswir1 authored
3208
                        break;
3209
                    case 0x24: /* mulscc */
3210
3211
                        gen_op_mulscc(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
3212
                        break;
bellard authored
3213
#ifndef TARGET_SPARC64
blueswir1 authored
3214
                    case 0x25:  /* sll */
3215
3216
3217
3218
3219
3220
3221
                        if (IS_IMM) { /* immediate */
                            rs2 = GET_FIELDs(insn, 20, 31);
                            tcg_gen_shli_tl(cpu_dst, cpu_src1, rs2 & 0x1f);
                        } else { /* register */
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
                            tcg_gen_shl_tl(cpu_dst, cpu_src1, cpu_tmp0);
                        }
3222
                        gen_movl_TN_reg(rd, cpu_dst);
3223
                        break;
bellard authored
3224
                    case 0x26:  /* srl */
3225
3226
3227
3228
3229
3230
3231
                        if (IS_IMM) { /* immediate */
                            rs2 = GET_FIELDs(insn, 20, 31);
                            tcg_gen_shri_tl(cpu_dst, cpu_src1, rs2 & 0x1f);
                        } else { /* register */
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
                            tcg_gen_shr_tl(cpu_dst, cpu_src1, cpu_tmp0);
                        }
3232
                        gen_movl_TN_reg(rd, cpu_dst);
3233
                        break;
bellard authored
3234
                    case 0x27:  /* sra */
3235
3236
3237
3238
3239
3240
3241
                        if (IS_IMM) { /* immediate */
                            rs2 = GET_FIELDs(insn, 20, 31);
                            tcg_gen_sari_tl(cpu_dst, cpu_src1, rs2 & 0x1f);
                        } else { /* register */
                            tcg_gen_andi_tl(cpu_tmp0, cpu_src2, 0x1f);
                            tcg_gen_sar_tl(cpu_dst, cpu_src1, cpu_tmp0);
                        }
3242
                        gen_movl_TN_reg(rd, cpu_dst);
3243
                        break;
bellard authored
3244
#endif
3245
3246
3247
                    case 0x30:
                        {
                            switch(rd) {
bellard authored
3248
                            case 0: /* wry */
3249
3250
                                tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
                                tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);
3251
                                break;
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
#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
blueswir1 authored
3263
                            case 0x2: /* V9 wrccr */
3264
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
pbrook authored
3265
                                gen_helper_wrccr(cpu_dst);
blueswir1 authored
3266
3267
                                break;
                            case 0x3: /* V9 wrasi */
3268
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3269
                                tcg_gen_trunc_tl_i32(cpu_asi, cpu_dst);
blueswir1 authored
3270
3271
                                break;
                            case 0x6: /* V9 wrfprs */
3272
                                tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
3273
                                tcg_gen_trunc_tl_i32(cpu_fprs, cpu_dst);
3274
                                save_state(dc, cpu_cond);
3275
                                gen_op_next_insn();
bellard authored
3276
                                tcg_gen_exit_tb(0);
3277
                                dc->is_br = 1;
blueswir1 authored
3278
3279
                                break;
                            case 0xf: /* V9 sir, nop if user */
bellard authored
3280
#if !defined(CONFIG_USER_ONLY)
blueswir1 authored
3281
                                if (supervisor(dc))
3282
                                    ; // XXX
bellard authored
3283
#endif
blueswir1 authored
3284
3285
                                break;
                            case 0x13: /* Graphics Status */
3286
                                if (gen_trap_ifnofpu(dc, cpu_cond))
bellard authored
3287
                                    goto jmp_insn;
3288
                                tcg_gen_xor_tl(cpu_gsr, cpu_src1, cpu_src2);
blueswir1 authored
3289
                                break;
3290
3291
3292
3293
                            case 0x14: /* Softint set */
                                if (!supervisor(dc))
                                    goto illegal_insn;
                                tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2);
pbrook authored
3294
                                gen_helper_set_softint(cpu_tmp64);
3295
3296
3297
3298
3299
                                break;
                            case 0x15: /* Softint clear */
                                if (!supervisor(dc))
                                    goto illegal_insn;
                                tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2);
pbrook authored
3300
                                gen_helper_clear_softint(cpu_tmp64);
3301
3302
3303
3304
3305
                                break;
                            case 0x16: /* Softint write */
                                if (!supervisor(dc))
                                    goto illegal_insn;
                                tcg_gen_xor_tl(cpu_tmp64, cpu_src1, cpu_src2);
pbrook authored
3306
                                gen_helper_write_softint(cpu_tmp64);
3307
                                break;
blueswir1 authored
3308
                            case 0x17: /* Tick compare */
bellard authored
3309
#if !defined(CONFIG_USER_ONLY)
blueswir1 authored
3310
3311
                                if (!supervisor(dc))
                                    goto illegal_insn;
bellard authored
3312
#endif
3313
                                {
pbrook authored
3314
                                    TCGv_ptr r_tickptr;
3315
3316
                                    tcg_gen_xor_tl(cpu_tick_cmpr, cpu_src1,
3317
                                                   cpu_src2);
pbrook authored
3318
                                    r_tickptr = tcg_temp_new_ptr();
3319
3320
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, tick));
pbrook authored
3321
3322
3323
                                    gen_helper_tick_set_limit(r_tickptr,
                                                              cpu_tick_cmpr);
                                    tcg_temp_free_ptr(r_tickptr);
3324
                                }
blueswir1 authored
3325
3326
                                break;
                            case 0x18: /* System tick */
bellard authored
3327
#if !defined(CONFIG_USER_ONLY)
blueswir1 authored
3328
3329
                                if (!supervisor(dc))
                                    goto illegal_insn;
bellard authored
3330
#endif
3331
                                {
pbrook authored
3332
                                    TCGv_ptr r_tickptr;
3333
3334
3335
                                    tcg_gen_xor_tl(cpu_dst, cpu_src1,
                                                   cpu_src2);
pbrook authored
3336
                                    r_tickptr = tcg_temp_new_ptr();
3337
3338
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, stick));
pbrook authored
3339
3340
3341
                                    gen_helper_tick_set_count(r_tickptr,
                                                              cpu_dst);
                                    tcg_temp_free_ptr(r_tickptr);
3342
                                }
blueswir1 authored
3343
3344
                                break;
                            case 0x19: /* System tick compare */
bellard authored
3345
#if !defined(CONFIG_USER_ONLY)
blueswir1 authored
3346
3347
                                if (!supervisor(dc))
                                    goto illegal_insn;
bellard authored
3348
#endif
3349
                                {
pbrook authored
3350
                                    TCGv_ptr r_tickptr;
3351
3352
                                    tcg_gen_xor_tl(cpu_stick_cmpr, cpu_src1,
3353
                                                   cpu_src2);
pbrook authored
3354
                                    r_tickptr = tcg_temp_new_ptr();
3355
3356
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, stick));
pbrook authored
3357
3358
3359
                                    gen_helper_tick_set_limit(r_tickptr,
                                                              cpu_stick_cmpr);
                                    tcg_temp_free_ptr(r_tickptr);
3360
                                }
blueswir1 authored
3361
                                break;
bellard authored
3362
blueswir1 authored
3363
                            case 0x10: /* Performance Control */
blueswir1 authored
3364
3365
                            case 0x11: /* Performance Instrumentation
                                          Counter */
blueswir1 authored
3366
                            case 0x12: /* Dispatch Control */
bellard authored
3367
#endif
bellard authored
3368
                            default:
3369
3370
3371
3372
                                goto illegal_insn;
                            }
                        }
                        break;
3373
#if !defined(CONFIG_USER_ONLY)
3374
                    case 0x31: /* wrpsr, V9 saved, restored */
3375
                        {
blueswir1 authored
3376
3377
                            if (!supervisor(dc))
                                goto priv_insn;
bellard authored
3378
#ifdef TARGET_SPARC64
blueswir1 authored
3379
3380
                            switch (rd) {
                            case 0:
pbrook authored
3381
                                gen_helper_saved();
blueswir1 authored
3382
3383
                                break;
                            case 1:
pbrook authored
3384
                                gen_helper_restored();
blueswir1 authored
3385
                                break;
3386
3387
3388
3389
3390
                            case 2: /* UA2005 allclean */
                            case 3: /* UA2005 otherw */
                            case 4: /* UA2005 normalw */
                            case 5: /* UA2005 invalw */
                                // XXX
blueswir1 authored
3391
                            default:
bellard authored
3392
3393
3394
                                goto illegal_insn;
                            }
#else
3395
                            tcg_gen_xor_tl(cpu_dst, cpu_src1, cpu_src2);
pbrook authored
3396
                            gen_helper_wrpsr(cpu_dst);
3397
                            save_state(dc, cpu_cond);
bellard authored
3398
                            gen_op_next_insn();
bellard authored
3399
                            tcg_gen_exit_tb(0);
blueswir1 authored
3400
                            dc->is_br = 1;
bellard authored
3401
#endif
3402
3403
                        }
                        break;
3404
                    case 0x32: /* wrwim, V9 wrpr */
3405
                        {
blueswir1 authored
3406
3407
                            if (!supervisor(dc))
                                goto priv_insn;
3408
                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
bellard authored
3409
#ifdef TARGET_SPARC64
blueswir1 authored
3410
3411
                            switch (rd) {
                            case 0: // tpc
3412
                                {
pbrook authored
3413
                                    TCGv_ptr r_tsptr;
3414
pbrook authored
3415
                                    r_tsptr = tcg_temp_new_ptr();
3416
3417
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                                   offsetof(CPUState, tsptr));
3418
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3419
                                                  offsetof(trap_state, tpc));
pbrook authored
3420
                                    tcg_temp_free_ptr(r_tsptr);
3421
                                }
blueswir1 authored
3422
3423
                                break;
                            case 1: // tnpc
3424
                                {
pbrook authored
3425
                                    TCGv_ptr r_tsptr;
3426
pbrook authored
3427
                                    r_tsptr = tcg_temp_new_ptr();
3428
3429
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                                   offsetof(CPUState, tsptr));
3430
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
3431
                                                  offsetof(trap_state, tnpc));
pbrook authored
3432
                                    tcg_temp_free_ptr(r_tsptr);
3433
                                }
blueswir1 authored
3434
3435
                                break;
                            case 2: // tstate
3436
                                {
pbrook authored
3437
                                    TCGv_ptr r_tsptr;
3438
pbrook authored
3439
                                    r_tsptr = tcg_temp_new_ptr();
3440
3441
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                                   offsetof(CPUState, tsptr));
3442
                                    tcg_gen_st_tl(cpu_tmp0, r_tsptr,
blueswir1 authored
3443
3444
                                                  offsetof(trap_state,
                                                           tstate));
pbrook authored
3445
                                    tcg_temp_free_ptr(r_tsptr);
3446
                                }
blueswir1 authored
3447
3448
                                break;
                            case 3: // tt
3449
                                {
pbrook authored
3450
                                    TCGv_ptr r_tsptr;
3451
pbrook authored
3452
                                    r_tsptr = tcg_temp_new_ptr();
3453
3454
                                    tcg_gen_ld_ptr(r_tsptr, cpu_env,
                                                   offsetof(CPUState, tsptr));
blueswir1 authored
3455
3456
                                    tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
                                    tcg_gen_st_i32(cpu_tmp32, r_tsptr,
3457
                                                   offsetof(trap_state, tt));
pbrook authored
3458
                                    tcg_temp_free_ptr(r_tsptr);
3459
                                }
blueswir1 authored
3460
3461
                                break;
                            case 4: // tick
3462
                                {
pbrook authored
3463
                                    TCGv_ptr r_tickptr;
3464
pbrook authored
3465
                                    r_tickptr = tcg_temp_new_ptr();
3466
3467
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, tick));
pbrook authored
3468
3469
3470
                                    gen_helper_tick_set_count(r_tickptr,
                                                              cpu_tmp0);
                                    tcg_temp_free_ptr(r_tickptr);
3471
                                }
blueswir1 authored
3472
3473
                                break;
                            case 5: // tba
3474
                                tcg_gen_mov_tl(cpu_tbr, cpu_tmp0);
blueswir1 authored
3475
3476
                                break;
                            case 6: // pstate
3477
                                save_state(dc, cpu_cond);
pbrook authored
3478
                                gen_helper_wrpstate(cpu_tmp0);
3479
                                gen_op_next_insn();
bellard authored
3480
                                tcg_gen_exit_tb(0);
3481
                                dc->is_br = 1;
blueswir1 authored
3482
3483
                                break;
                            case 7: // tl
3484
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
blueswir1 authored
3485
3486
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState, tl));
blueswir1 authored
3487
3488
                                break;
                            case 8: // pil
3489
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
blueswir1 authored
3490
3491
3492
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState,
                                                        psrpil));
blueswir1 authored
3493
3494
                                break;
                            case 9: // cwp
pbrook authored
3495
                                gen_helper_wrcwp(cpu_tmp0);
blueswir1 authored
3496
3497
                                break;
                            case 10: // cansave
3498
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
blueswir1 authored
3499
3500
3501
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState,
                                                        cansave));
blueswir1 authored
3502
3503
                                break;
                            case 11: // canrestore
3504
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
blueswir1 authored
3505
3506
3507
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState,
                                                        canrestore));
blueswir1 authored
3508
3509
                                break;
                            case 12: // cleanwin
3510
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
blueswir1 authored
3511
3512
3513
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState,
                                                        cleanwin));
blueswir1 authored
3514
3515
                                break;
                            case 13: // otherwin
3516
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
blueswir1 authored
3517
3518
3519
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState,
                                                        otherwin));
blueswir1 authored
3520
3521
                                break;
                            case 14: // wstate
3522
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
blueswir1 authored
3523
3524
3525
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState,
                                                        wstate));
blueswir1 authored
3526
                                break;
3527
                            case 16: // UA2005 gl
3528
                                CHECK_IU_FEATURE(dc, GL);
3529
                                tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
blueswir1 authored
3530
3531
                                tcg_gen_st_i32(cpu_tmp32, cpu_env,
                                               offsetof(CPUSPARCState, gl));
3532
3533
                                break;
                            case 26: // UA2005 strand status
3534
                                CHECK_IU_FEATURE(dc, HYPV);
3535
3536
                                if (!hypervisor(dc))
                                    goto priv_insn;
blueswir1 authored
3537
                                tcg_gen_mov_tl(cpu_ssr, cpu_tmp0);
3538
                                break;
blueswir1 authored
3539
3540
3541
                            default:
                                goto illegal_insn;
                            }
bellard authored
3542
#else
3543
                            tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
3544
3545
3546
                            if (dc->def->nwindows != 32)
                                tcg_gen_andi_tl(cpu_tmp32, cpu_tmp32,
                                                (1 << dc->def->nwindows) - 1);
3547
                            tcg_gen_mov_i32(cpu_wim, cpu_tmp32);
bellard authored
3548
#endif
3549
3550
                        }
                        break;
3551
                    case 0x33: /* wrtbr, UA2005 wrhpr */
3552
                        {
3553
#ifndef TARGET_SPARC64
blueswir1 authored
3554
3555
                            if (!supervisor(dc))
                                goto priv_insn;
3556
                            tcg_gen_xor_tl(cpu_tbr, cpu_src1, cpu_src2);
3557
#else
3558
                            CHECK_IU_FEATURE(dc, HYPV);
3559
3560
                            if (!hypervisor(dc))
                                goto priv_insn;
3561
                            tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
3562
3563
3564
                            switch (rd) {
                            case 0: // hpstate
                                // XXX gen_op_wrhpstate();
3565
                                save_state(dc, cpu_cond);
3566
                                gen_op_next_insn();
bellard authored
3567
                                tcg_gen_exit_tb(0);
3568
3569
3570
3571
3572
3573
                                dc->is_br = 1;
                                break;
                            case 1: // htstate
                                // XXX gen_op_wrhtstate();
                                break;
                            case 3: // hintp
3574
                                tcg_gen_mov_tl(cpu_hintp, cpu_tmp0);
3575
3576
                                break;
                            case 5: // htba
3577
                                tcg_gen_mov_tl(cpu_htba, cpu_tmp0);
3578
3579
                                break;
                            case 31: // hstick_cmpr
3580
                                {
pbrook authored
3581
                                    TCGv_ptr r_tickptr;
3582
3583
                                    tcg_gen_mov_tl(cpu_hstick_cmpr, cpu_tmp0);
pbrook authored
3584
                                    r_tickptr = tcg_temp_new_ptr();
3585
3586
                                    tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                   offsetof(CPUState, hstick));
pbrook authored
3587
3588
3589
                                    gen_helper_tick_set_limit(r_tickptr,
                                                              cpu_hstick_cmpr);
                                    tcg_temp_free_ptr(r_tickptr);
3590
                                }
3591
3592
3593
3594
3595
3596
                                break;
                            case 6: // hver readonly
                            default:
                                goto illegal_insn;
                            }
#endif
3597
3598
3599
                        }
                        break;
#endif
bellard authored
3600
#ifdef TARGET_SPARC64
blueswir1 authored
3601
3602
3603
3604
                    case 0x2c: /* V9 movcc */
                        {
                            int cc = GET_FIELD_SP(insn, 11, 12);
                            int cond = GET_FIELD_SP(insn, 14, 17);
3605
                            TCGv r_cond;
3606
3607
                            int l1;
pbrook authored
3608
                            r_cond = tcg_temp_new();
blueswir1 authored
3609
3610
                            if (insn & (1 << 18)) {
                                if (cc == 0)
3611
                                    gen_cond(r_cond, 0, cond);
blueswir1 authored
3612
                                else if (cc == 2)
3613
                                    gen_cond(r_cond, 1, cond);
blueswir1 authored
3614
3615
3616
                                else
                                    goto illegal_insn;
                            } else {
3617
                                gen_fcond(r_cond, cc, cond);
blueswir1 authored
3618
                            }
3619
3620
3621

                            l1 = gen_new_label();
3622
                            tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);
3623
                            if (IS_IMM) {       /* immediate */
blueswir1 authored
3624
3625
                                TCGv r_const;
3626
                                rs2 = GET_FIELD_SPs(insn, 0, 10);
blueswir1 authored
3627
3628
3629
                                r_const = tcg_const_tl((int)rs2);
                                gen_movl_TN_reg(rd, r_const);
                                tcg_temp_free(r_const);
3630
3631
                            } else {
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3632
3633
                                gen_movl_reg_TN(rs2, cpu_tmp0);
                                gen_movl_TN_reg(rd, cpu_tmp0);
3634
3635
                            }
                            gen_set_label(l1);
blueswir1 authored
3636
                            tcg_temp_free(r_cond);
blueswir1 authored
3637
3638
3639
                            break;
                        }
                    case 0x2d: /* V9 sdivx */
3640
3641
                        gen_op_sdivx(cpu_dst, cpu_src1, cpu_src2);
                        gen_movl_TN_reg(rd, cpu_dst);
blueswir1 authored
3642
3643
3644
                        break;
                    case 0x2e: /* V9 popc */
                        {
3645
                            cpu_src2 = get_src2(insn, cpu_src2);
pbrook authored
3646
                            gen_helper_popc(cpu_dst, cpu_src2);
3647
                            gen_movl_TN_reg(rd, cpu_dst);
blueswir1 authored
3648
3649
3650
3651
                        }
                    case 0x2f: /* V9 movr */
                        {
                            int cond = GET_FIELD_SP(insn, 10, 12);
3652
3653
                            int l1;
3654
                            cpu_src1 = get_src1(insn, cpu_src1);
3655
3656
3657

                            l1 = gen_new_label();
3658
3659
                            tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond],
                                              cpu_src1, 0, l1);
blueswir1 authored
3660
                            if (IS_IMM) {       /* immediate */
blueswir1 authored
3661
3662
                                TCGv r_const;
blueswir1 authored
3663
                                rs2 = GET_FIELD_SPs(insn, 0, 9);
blueswir1 authored
3664
3665
3666
                                r_const = tcg_const_tl((int)rs2);
                                gen_movl_TN_reg(rd, r_const);
                                tcg_temp_free(r_const);
3667
                            } else {
blueswir1 authored
3668
                                rs2 = GET_FIELD_SP(insn, 0, 4);
3669
3670
                                gen_movl_reg_TN(rs2, cpu_tmp0);
                                gen_movl_TN_reg(rd, cpu_tmp0);
blueswir1 authored
3671
                            }
3672
                            gen_set_label(l1);
blueswir1 authored
3673
3674
3675
3676
3677
3678
3679
                            break;
                        }
#endif
                    default:
                        goto illegal_insn;
                    }
                }
3680
3681
3682
3683
3684
            } 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);
3685
                if (gen_trap_ifnofpu(dc, cpu_cond))
3686
                    goto jmp_insn;
3687
3688

                switch (opf) {
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
                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 */
3704
                    CHECK_FPU_FEATURE(dc, VIS1);
3705
                    cpu_src1 = get_src1(insn, cpu_src1);
3706
                    gen_movl_reg_TN(rs2, cpu_src2);
pbrook authored
3707
                    gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
3708
                    gen_movl_TN_reg(rd, cpu_dst);
3709
3710
                    break;
                case 0x012: /* VIS I array16 */
3711
                    CHECK_FPU_FEATURE(dc, VIS1);
3712
                    cpu_src1 = get_src1(insn, cpu_src1);
3713
                    gen_movl_reg_TN(rs2, cpu_src2);
pbrook authored
3714
                    gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
3715
3716
                    tcg_gen_shli_i64(cpu_dst, cpu_dst, 1);
                    gen_movl_TN_reg(rd, cpu_dst);
3717
3718
                    break;
                case 0x014: /* VIS I array32 */
3719
                    CHECK_FPU_FEATURE(dc, VIS1);
3720
                    cpu_src1 = get_src1(insn, cpu_src1);
3721
                    gen_movl_reg_TN(rs2, cpu_src2);
pbrook authored
3722
                    gen_helper_array8(cpu_dst, cpu_src1, cpu_src2);
3723
3724
                    tcg_gen_shli_i64(cpu_dst, cpu_dst, 2);
                    gen_movl_TN_reg(rd, cpu_dst);
3725
                    break;
3726
                case 0x018: /* VIS I alignaddr */
3727
                    CHECK_FPU_FEATURE(dc, VIS1);
3728
                    cpu_src1 = get_src1(insn, cpu_src1);
3729
                    gen_movl_reg_TN(rs2, cpu_src2);
pbrook authored
3730
                    gen_helper_alignaddr(cpu_dst, cpu_src1, cpu_src2);
3731
                    gen_movl_TN_reg(rd, cpu_dst);
3732
                    break;
3733
                case 0x019: /* VIS II bmask */
3734
3735
                case 0x01a: /* VIS I alignaddrl */
                    // XXX
3736
3737
                    goto illegal_insn;
                case 0x020: /* VIS I fcmple16 */
3738
                    CHECK_FPU_FEATURE(dc, VIS1);
3739
3740
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
3741
                    gen_helper_fcmple16();
3742
                    gen_op_store_DT0_fpr(DFPREG(rd));
3743
3744
                    break;
                case 0x022: /* VIS I fcmpne16 */
3745
                    CHECK_FPU_FEATURE(dc, VIS1);
3746
3747
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
3748
                    gen_helper_fcmpne16();
3749
                    gen_op_store_DT0_fpr(DFPREG(rd));
3750
                    break;
3751
                case 0x024: /* VIS I fcmple32 */
3752
                    CHECK_FPU_FEATURE(dc, VIS1);
3753
3754
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
3755
                    gen_helper_fcmple32();
3756
                    gen_op_store_DT0_fpr(DFPREG(rd));
3757
3758
                    break;
                case 0x026: /* VIS I fcmpne32 */
3759
                    CHECK_FPU_FEATURE(dc, VIS1);
3760
3761
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
3762
                    gen_helper_fcmpne32();
3763
                    gen_op_store_DT0_fpr(DFPREG(rd));
3764
3765
                    break;
                case 0x028: /* VIS I fcmpgt16 */
3766
                    CHECK_FPU_FEATURE(dc, VIS1);
3767
3768
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
3769
                    gen_helper_fcmpgt16();
3770
                    gen_op_store_DT0_fpr(DFPREG(rd));
3771
3772
                    break;
                case 0x02a: /* VIS I fcmpeq16 */
3773
                    CHECK_FPU_FEATURE(dc, VIS1);
3774
3775
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
3776
                    gen_helper_fcmpeq16();
3777
                    gen_op_store_DT0_fpr(DFPREG(rd));
3778
3779
                    break;
                case 0x02c: /* VIS I fcmpgt32 */
3780
                    CHECK_FPU_FEATURE(dc, VIS1);
3781
3782
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
3783
                    gen_helper_fcmpgt32();
3784
                    gen_op_store_DT0_fpr(DFPREG(rd));
3785
3786
                    break;
                case 0x02e: /* VIS I fcmpeq32 */
3787
                    CHECK_FPU_FEATURE(dc, VIS1);
3788
3789
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
3790
                    gen_helper_fcmpeq32();
3791
                    gen_op_store_DT0_fpr(DFPREG(rd));
3792
3793
                    break;
                case 0x031: /* VIS I fmul8x16 */
3794
                    CHECK_FPU_FEATURE(dc, VIS1);
3795
3796
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
3797
                    gen_helper_fmul8x16();
3798
                    gen_op_store_DT0_fpr(DFPREG(rd));
3799
3800
                    break;
                case 0x033: /* VIS I fmul8x16au */
3801
                    CHECK_FPU_FEATURE(dc, VIS1);
3802
3803
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
3804
                    gen_helper_fmul8x16au();
3805
                    gen_op_store_DT0_fpr(DFPREG(rd));
3806
3807
                    break;
                case 0x035: /* VIS I fmul8x16al */
3808
                    CHECK_FPU_FEATURE(dc, VIS1);
3809
3810
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
3811
                    gen_helper_fmul8x16al();
3812
                    gen_op_store_DT0_fpr(DFPREG(rd));
3813
3814
                    break;
                case 0x036: /* VIS I fmul8sux16 */
3815
                    CHECK_FPU_FEATURE(dc, VIS1);
3816
3817
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
3818
                    gen_helper_fmul8sux16();
3819
                    gen_op_store_DT0_fpr(DFPREG(rd));
3820
3821
                    break;
                case 0x037: /* VIS I fmul8ulx16 */
3822
                    CHECK_FPU_FEATURE(dc, VIS1);
3823
3824
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
3825
                    gen_helper_fmul8ulx16();
3826
                    gen_op_store_DT0_fpr(DFPREG(rd));
3827
3828
                    break;
                case 0x038: /* VIS I fmuld8sux16 */
3829
                    CHECK_FPU_FEATURE(dc, VIS1);
3830
3831
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
3832
                    gen_helper_fmuld8sux16();
3833
                    gen_op_store_DT0_fpr(DFPREG(rd));
3834
3835
                    break;
                case 0x039: /* VIS I fmuld8ulx16 */
3836
                    CHECK_FPU_FEATURE(dc, VIS1);
3837
3838
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
3839
                    gen_helper_fmuld8ulx16();
3840
                    gen_op_store_DT0_fpr(DFPREG(rd));
3841
3842
3843
3844
3845
3846
3847
                    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;
3848
                case 0x048: /* VIS I faligndata */
3849
                    CHECK_FPU_FEATURE(dc, VIS1);
3850
3851
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
3852
                    gen_helper_faligndata();
3853
                    gen_op_store_DT0_fpr(DFPREG(rd));
3854
                    break;
3855
                case 0x04b: /* VIS I fpmerge */
3856
                    CHECK_FPU_FEATURE(dc, VIS1);
3857
3858
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
3859
                    gen_helper_fpmerge();
3860
                    gen_op_store_DT0_fpr(DFPREG(rd));
3861
3862
3863
3864
3865
                    break;
                case 0x04c: /* VIS II bshuffle */
                    // XXX
                    goto illegal_insn;
                case 0x04d: /* VIS I fexpand */
3866
                    CHECK_FPU_FEATURE(dc, VIS1);
3867
3868
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
3869
                    gen_helper_fexpand();
3870
                    gen_op_store_DT0_fpr(DFPREG(rd));
3871
3872
                    break;
                case 0x050: /* VIS I fpadd16 */
3873
                    CHECK_FPU_FEATURE(dc, VIS1);
3874
3875
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
3876
                    gen_helper_fpadd16();
3877
                    gen_op_store_DT0_fpr(DFPREG(rd));
3878
3879
                    break;
                case 0x051: /* VIS I fpadd16s */
3880
                    CHECK_FPU_FEATURE(dc, VIS1);
pbrook authored
3881
3882
                    gen_helper_fpadd16s(cpu_fpr[rd],
                                        cpu_fpr[rs1], cpu_fpr[rs2]);
3883
3884
                    break;
                case 0x052: /* VIS I fpadd32 */
3885
                    CHECK_FPU_FEATURE(dc, VIS1);
3886
3887
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
3888
                    gen_helper_fpadd32();
3889
                    gen_op_store_DT0_fpr(DFPREG(rd));
3890
3891
                    break;
                case 0x053: /* VIS I fpadd32s */
3892
                    CHECK_FPU_FEATURE(dc, VIS1);
pbrook authored
3893
3894
                    gen_helper_fpadd32s(cpu_fpr[rd],
                                        cpu_fpr[rs1], cpu_fpr[rs2]);
3895
3896
                    break;
                case 0x054: /* VIS I fpsub16 */
3897
                    CHECK_FPU_FEATURE(dc, VIS1);
3898
3899
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
3900
                    gen_helper_fpsub16();
3901
                    gen_op_store_DT0_fpr(DFPREG(rd));
3902
3903
                    break;
                case 0x055: /* VIS I fpsub16s */
3904
                    CHECK_FPU_FEATURE(dc, VIS1);
pbrook authored
3905
3906
                    gen_helper_fpsub16s(cpu_fpr[rd],
                                        cpu_fpr[rs1], cpu_fpr[rs2]);
3907
3908
                    break;
                case 0x056: /* VIS I fpsub32 */
3909
                    CHECK_FPU_FEATURE(dc, VIS1);
3910
3911
                    gen_op_load_fpr_DT0(DFPREG(rs1));
                    gen_op_load_fpr_DT1(DFPREG(rs2));
pbrook authored
3912
                    gen_helper_fpsub32();
3913
                    gen_op_store_DT0_fpr(DFPREG(rd));
3914
3915
                    break;
                case 0x057: /* VIS I fpsub32s */
3916
                    CHECK_FPU_FEATURE(dc, VIS1);
pbrook authored
3917
3918
                    gen_helper_fpsub32s(cpu_fpr[rd],
                                        cpu_fpr[rs1], cpu_fpr[rs2]);
3919
                    break;
3920
                case 0x060: /* VIS I fzero */
3921
                    CHECK_FPU_FEATURE(dc, VIS1);
3922
3923
                    tcg_gen_movi_i32(cpu_fpr[DFPREG(rd)], 0);
                    tcg_gen_movi_i32(cpu_fpr[DFPREG(rd) + 1], 0);
3924
3925
                    break;
                case 0x061: /* VIS I fzeros */
3926
                    CHECK_FPU_FEATURE(dc, VIS1);
3927
                    tcg_gen_movi_i32(cpu_fpr[rd], 0);
3928
                    break;
3929
                case 0x062: /* VIS I fnor */
3930
                    CHECK_FPU_FEATURE(dc, VIS1);
3931
3932
3933
3934
                    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]);
3935
3936
                    break;
                case 0x063: /* VIS I fnors */
3937
                    CHECK_FPU_FEATURE(dc, VIS1);
3938
                    tcg_gen_nor_i32(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
3939
3940
                    break;
                case 0x064: /* VIS I fandnot2 */
3941
                    CHECK_FPU_FEATURE(dc, VIS1);
3942
3943
3944
3945
3946
                    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]);
3947
3948
                    break;
                case 0x065: /* VIS I fandnot2s */
3949
                    CHECK_FPU_FEATURE(dc, VIS1);
3950
                    tcg_gen_andc_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
3951
3952
                    break;
                case 0x066: /* VIS I fnot2 */
3953
                    CHECK_FPU_FEATURE(dc, VIS1);
blueswir1 authored
3954
3955
3956
                    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]);
3957
3958
                    break;
                case 0x067: /* VIS I fnot2s */
3959
                    CHECK_FPU_FEATURE(dc, VIS1);
blueswir1 authored
3960
                    tcg_gen_not_i32(cpu_fpr[rd], cpu_fpr[rs2]);
3961
3962
                    break;
                case 0x068: /* VIS I fandnot1 */
3963
                    CHECK_FPU_FEATURE(dc, VIS1);
3964
3965
3966
3967
3968
                    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]);
3969
3970
                    break;
                case 0x069: /* VIS I fandnot1s */
3971
                    CHECK_FPU_FEATURE(dc, VIS1);
3972
                    tcg_gen_andc_i32(cpu_fpr[rd], cpu_fpr[rs2], cpu_fpr[rs1]);
3973
3974
                    break;
                case 0x06a: /* VIS I fnot1 */
3975
                    CHECK_FPU_FEATURE(dc, VIS1);
blueswir1 authored
3976
3977
3978
                    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]);
3979
3980
                    break;
                case 0x06b: /* VIS I fnot1s */
3981
                    CHECK_FPU_FEATURE(dc, VIS1);
blueswir1 authored
3982
                    tcg_gen_not_i32(cpu_fpr[rd], cpu_fpr[rs1]);
3983
3984
                    break;
                case 0x06c: /* VIS I fxor */
3985
                    CHECK_FPU_FEATURE(dc, VIS1);
3986
3987
3988
3989
3990
                    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]);
3991
3992
                    break;
                case 0x06d: /* VIS I fxors */
3993
                    CHECK_FPU_FEATURE(dc, VIS1);
3994
                    tcg_gen_xor_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
3995
3996
                    break;
                case 0x06e: /* VIS I fnand */
3997
                    CHECK_FPU_FEATURE(dc, VIS1);
3998
3999
4000
4001
                    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]);
4002
4003
                    break;
                case 0x06f: /* VIS I fnands */
4004
                    CHECK_FPU_FEATURE(dc, VIS1);
4005
                    tcg_gen_nand_i32(cpu_tmp32, cpu_fpr[rs1], cpu_fpr[rs2]);
4006
4007
                    break;
                case 0x070: /* VIS I fand */
4008
                    CHECK_FPU_FEATURE(dc, VIS1);
4009
4010
4011
4012
4013
                    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]);
4014
4015
                    break;
                case 0x071: /* VIS I fands */
4016
                    CHECK_FPU_FEATURE(dc, VIS1);
4017
                    tcg_gen_and_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
4018
4019
                    break;
                case 0x072: /* VIS I fxnor */
4020
                    CHECK_FPU_FEATURE(dc, VIS1);
4021
4022
4023
4024
4025
4026
                    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]);
4027
4028
                    break;
                case 0x073: /* VIS I fxnors */
4029
                    CHECK_FPU_FEATURE(dc, VIS1);
4030
4031
                    tcg_gen_xori_i32(cpu_tmp32, cpu_fpr[rs2], -1);
                    tcg_gen_xor_i32(cpu_fpr[rd], cpu_tmp32, cpu_fpr[rs1]);
4032
                    break;
4033
                case 0x074: /* VIS I fsrc1 */
4034
                    CHECK_FPU_FEATURE(dc, VIS1);
4035
4036
4037
                    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]);
4038
4039
                    break;
                case 0x075: /* VIS I fsrc1s */
4040
                    CHECK_FPU_FEATURE(dc, VIS1);
4041
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs1]);
4042
                    break;
4043
                case 0x076: /* VIS I fornot2 */
4044
                    CHECK_FPU_FEATURE(dc, VIS1);
4045
4046
4047
4048
4049
                    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]);
4050
4051
                    break;
                case 0x077: /* VIS I fornot2s */
4052
                    CHECK_FPU_FEATURE(dc, VIS1);
4053
                    tcg_gen_orc_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
4054
                    break;
4055
                case 0x078: /* VIS I fsrc2 */
4056
                    CHECK_FPU_FEATURE(dc, VIS1);
4057
4058
                    gen_op_load_fpr_DT0(DFPREG(rs2));
                    gen_op_store_DT0_fpr(DFPREG(rd));
4059
4060
                    break;
                case 0x079: /* VIS I fsrc2s */
4061
                    CHECK_FPU_FEATURE(dc, VIS1);
4062
                    tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]);
4063
                    break;
4064
                case 0x07a: /* VIS I fornot1 */
4065
                    CHECK_FPU_FEATURE(dc, VIS1);
4066
4067
4068
4069
4070
                    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]);
4071
4072
                    break;
                case 0x07b: /* VIS I fornot1s */
4073
                    CHECK_FPU_FEATURE(dc, VIS1);
4074
                    tcg_gen_orc_i32(cpu_fpr[rd], cpu_fpr[rs2], cpu_fpr[rs1]);
4075
4076
                    break;
                case 0x07c: /* VIS I for */
4077
                    CHECK_FPU_FEATURE(dc, VIS1);
4078
4079
4080
4081
4082
                    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]);
4083
4084
                    break;
                case 0x07d: /* VIS I fors */
4085
                    CHECK_FPU_FEATURE(dc, VIS1);
4086
                    tcg_gen_or_i32(cpu_fpr[rd], cpu_fpr[rs1], cpu_fpr[rs2]);
4087
                    break;
4088
                case 0x07e: /* VIS I fone */
4089
                    CHECK_FPU_FEATURE(dc, VIS1);
4090
4091
                    tcg_gen_movi_i32(cpu_fpr[DFPREG(rd)], -1);
                    tcg_gen_movi_i32(cpu_fpr[DFPREG(rd) + 1], -1);
4092
4093
                    break;
                case 0x07f: /* VIS I fones */
4094
                    CHECK_FPU_FEATURE(dc, VIS1);
4095
                    tcg_gen_movi_i32(cpu_fpr[rd], -1);
4096
                    break;
4097
4098
4099
4100
                case 0x080: /* VIS I shutdown */
                case 0x081: /* VIS II siam */
                    // XXX
                    goto illegal_insn;
4101
4102
4103
4104
                default:
                    goto illegal_insn;
                }
#else
blueswir1 authored
4105
                goto ncp_insn;
4106
4107
#endif
            } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
4108
#ifdef TARGET_SPARC64
blueswir1 authored
4109
                goto illegal_insn;
4110
#else
blueswir1 authored
4111
                goto ncp_insn;
4112
#endif
bellard authored
4113
#ifdef TARGET_SPARC64
blueswir1 authored
4114
            } else if (xop == 0x39) { /* V9 return */
pbrook authored
4115
                TCGv_i32 r_const;
blueswir1 authored
4116
4117
                save_state(dc, cpu_cond);
4118
                cpu_src1 = get_src1(insn, cpu_src1);
blueswir1 authored
4119
4120
                if (IS_IMM) {   /* immediate */
                    rs2 = GET_FIELDs(insn, 19, 31);
4121
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, (int)rs2);
blueswir1 authored
4122
                } else {                /* register */
bellard authored
4123
                    rs2 = GET_FIELD(insn, 27, 31);
blueswir1 authored
4124
                    if (rs2) {
4125
4126
                        gen_movl_reg_TN(rs2, cpu_src2);
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
4127
4128
                    } else
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
bellard authored
4129
                }
pbrook authored
4130
                gen_helper_restore();
4131
                gen_mov_pc_npc(dc, cpu_cond);
blueswir1 authored
4132
                r_const = tcg_const_i32(3);
pbrook authored
4133
4134
                gen_helper_check_align(cpu_dst, r_const);
                tcg_temp_free_i32(r_const);
4135
                tcg_gen_mov_tl(cpu_npc, cpu_dst);
blueswir1 authored
4136
4137
                dc->npc = DYNAMIC_PC;
                goto jmp_insn;
bellard authored
4138
#endif
blueswir1 authored
4139
            } else {
4140
                cpu_src1 = get_src1(insn, cpu_src1);
blueswir1 authored
4141
4142
                if (IS_IMM) {   /* immediate */
                    rs2 = GET_FIELDs(insn, 19, 31);
4143
                    tcg_gen_addi_tl(cpu_dst, cpu_src1, (int)rs2);
blueswir1 authored
4144
                } else {                /* register */
bellard authored
4145
                    rs2 = GET_FIELD(insn, 27, 31);
blueswir1 authored
4146
                    if (rs2) {
4147
4148
                        gen_movl_reg_TN(rs2, cpu_src2);
                        tcg_gen_add_tl(cpu_dst, cpu_src1, cpu_src2);
4149
4150
                    } else
                        tcg_gen_mov_tl(cpu_dst, cpu_src1);
4151
                }
blueswir1 authored
4152
4153
4154
                switch (xop) {
                case 0x38:      /* jmpl */
                    {
pbrook authored
4155
4156
                        TCGv r_pc;
                        TCGv_i32 r_const;
blueswir1 authored
4157
pbrook authored
4158
4159
4160
                        r_pc = tcg_const_tl(dc->pc);
                        gen_movl_TN_reg(rd, r_pc);
                        tcg_temp_free(r_pc);
4161
                        gen_mov_pc_npc(dc, cpu_cond);
blueswir1 authored
4162
                        r_const = tcg_const_i32(3);
pbrook authored
4163
4164
                        gen_helper_check_align(cpu_dst, r_const);
                        tcg_temp_free_i32(r_const);
4165
                        tcg_gen_mov_tl(cpu_npc, cpu_dst);
blueswir1 authored
4166
4167
4168
                        dc->npc = DYNAMIC_PC;
                    }
                    goto jmp_insn;
bellard authored
4169
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
blueswir1 authored
4170
4171
                case 0x39:      /* rett, V9 return */
                    {
pbrook authored
4172
                        TCGv_i32 r_const;
blueswir1 authored
4173
blueswir1 authored
4174
4175
                        if (!supervisor(dc))
                            goto priv_insn;
4176
                        gen_mov_pc_npc(dc, cpu_cond);
blueswir1 authored
4177
                        r_const = tcg_const_i32(3);
pbrook authored
4178
4179
                        gen_helper_check_align(cpu_dst, r_const);
                        tcg_temp_free_i32(r_const);
4180
                        tcg_gen_mov_tl(cpu_npc, cpu_dst);
blueswir1 authored
4181
                        dc->npc = DYNAMIC_PC;
pbrook authored
4182
                        gen_helper_rett();
blueswir1 authored
4183
4184
4185
4186
                    }
                    goto jmp_insn;
#endif
                case 0x3b: /* flush */
4187
                    if (!((dc)->def->features & CPU_FEATURE_FLUSH))
4188
                        goto unimp_flush;
pbrook authored
4189
                    gen_helper_flush(cpu_dst);
blueswir1 authored
4190
4191
                    break;
                case 0x3c:      /* save */
4192
                    save_state(dc, cpu_cond);
pbrook authored
4193
                    gen_helper_save();
4194
                    gen_movl_TN_reg(rd, cpu_dst);
blueswir1 authored
4195
4196
                    break;
                case 0x3d:      /* restore */
4197
                    save_state(dc, cpu_cond);
pbrook authored
4198
                    gen_helper_restore();
4199
                    gen_movl_TN_reg(rd, cpu_dst);
blueswir1 authored
4200
                    break;
bellard authored
4201
#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
blueswir1 authored
4202
4203
4204
4205
4206
4207
4208
4209
                case 0x3e:      /* V9 done/retry */
                    {
                        switch (rd) {
                        case 0:
                            if (!supervisor(dc))
                                goto priv_insn;
                            dc->npc = DYNAMIC_PC;
                            dc->pc = DYNAMIC_PC;
pbrook authored
4210
                            gen_helper_done();
blueswir1 authored
4211
4212
4213
4214
4215
4216
                            goto jmp_insn;
                        case 1:
                            if (!supervisor(dc))
                                goto priv_insn;
                            dc->npc = DYNAMIC_PC;
                            dc->pc = DYNAMIC_PC;
pbrook authored
4217
                            gen_helper_retry();
blueswir1 authored
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
                            goto jmp_insn;
                        default:
                            goto illegal_insn;
                        }
                    }
                    break;
#endif
                default:
                    goto illegal_insn;
                }
4228
            }
blueswir1 authored
4229
4230
4231
4232
4233
4234
            break;
        }
        break;
    case 3:                     /* load/store instructions */
        {
            unsigned int xop = GET_FIELD(insn, 7, 12);
4235
4236

            cpu_src1 = get_src1(insn, cpu_src1);
blueswir1 authored
4237
            if (xop == 0x3c || xop == 0x3e) { // V9 casa/casxa
4238
                rs2 = GET_FIELD(insn, 27, 31);
4239
                gen_movl_reg_TN(rs2, cpu_src2);
blueswir1 authored
4240
4241
                tcg_gen_mov_tl(cpu_addr, cpu_src1);
            } else if (IS_IMM) {     /* immediate */
blueswir1 authored
4242
                rs2 = GET_FIELDs(insn, 19, 31);
4243
                tcg_gen_addi_tl(cpu_addr, cpu_src1, (int)rs2);
blueswir1 authored
4244
4245
4246
            } else {            /* register */
                rs2 = GET_FIELD(insn, 27, 31);
                if (rs2 != 0) {
4247
4248
                    gen_movl_reg_TN(rs2, cpu_src2);
                    tcg_gen_add_tl(cpu_addr, cpu_src1, cpu_src2);
4249
4250
                } else
                    tcg_gen_mov_tl(cpu_addr, cpu_src1);
blueswir1 authored
4251
            }
blueswir1 authored
4252
4253
4254
            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
                (xop > 0x17 && xop <= 0x1d ) ||
                (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
blueswir1 authored
4255
                switch (xop) {
4256
                case 0x0:       /* load unsigned word */
4257
                    gen_address_mask(dc, cpu_addr);
4258
                    tcg_gen_qemu_ld32u(cpu_val, cpu_addr, dc->mem_idx);
blueswir1 authored
4259
4260
                    break;
                case 0x1:       /* load unsigned byte */
4261
                    gen_address_mask(dc, cpu_addr);
4262
                    tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx);
blueswir1 authored
4263
4264
                    break;
                case 0x2:       /* load unsigned halfword */
4265
                    gen_address_mask(dc, cpu_addr);
4266
                    tcg_gen_qemu_ld16u(cpu_val, cpu_addr, dc->mem_idx);
blueswir1 authored
4267
4268
4269
                    break;
                case 0x3:       /* load double word */
                    if (rd & 1)
4270
                        goto illegal_insn;
4271
                    else {
pbrook authored
4272
                        TCGv_i32 r_const;
blueswir1 authored
4273
4274
                        save_state(dc, cpu_cond);
blueswir1 authored
4275
                        r_const = tcg_const_i32(7);
pbrook authored
4276
4277
                        gen_helper_check_align(cpu_addr, r_const); // XXX remove
                        tcg_temp_free_i32(r_const);
4278
                        gen_address_mask(dc, cpu_addr);
4279
                        tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
4280
4281
4282
                        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);
4283
                        tcg_gen_shri_i64(cpu_tmp64, cpu_tmp64, 32);
4284
4285
                        tcg_gen_trunc_i64_tl(cpu_val, cpu_tmp64);
                        tcg_gen_andi_tl(cpu_val, cpu_val, 0xffffffffULL);
4286
                    }
blueswir1 authored
4287
4288
                    break;
                case 0x9:       /* load signed byte */
4289
                    gen_address_mask(dc, cpu_addr);
4290
                    tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
blueswir1 authored
4291
4292
                    break;
                case 0xa:       /* load signed halfword */
4293
                    gen_address_mask(dc, cpu_addr);
4294
                    tcg_gen_qemu_ld16s(cpu_val, cpu_addr, dc->mem_idx);
blueswir1 authored
4295
4296
                    break;
                case 0xd:       /* ldstub -- XXX: should be atomically */
blueswir1 authored
4297
4298
4299
                    {
                        TCGv r_const;
4300
                        gen_address_mask(dc, cpu_addr);
blueswir1 authored
4301
4302
4303
4304
4305
                        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);
                    }
blueswir1 authored
4306
                    break;
blueswir1 authored
4307
4308
                case 0x0f:      /* swap register with memory. Also
                                   atomically */
4309
                    CHECK_IU_FEATURE(dc, SWAP);
4310
                    gen_movl_reg_TN(rd, cpu_val);
4311
                    gen_address_mask(dc, cpu_addr);
blueswir1 authored
4312
                    tcg_gen_qemu_ld32u(cpu_tmp0, cpu_addr, dc->mem_idx);
4313
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
blueswir1 authored
4314
                    tcg_gen_mov_tl(cpu_val, cpu_tmp0);
blueswir1 authored
4315
                    break;
bellard authored
4316
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
blueswir1 authored
4317
                case 0x10:      /* load word alternate */
bellard authored
4318
#ifndef TARGET_SPARC64
blueswir1 authored
4319
4320
4321
4322
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
blueswir1 authored
4323
#endif
4324
                    save_state(dc, cpu_cond);
4325
                    gen_ld_asi(cpu_val, cpu_addr, insn, 4, 0);
blueswir1 authored
4326
4327
                    break;
                case 0x11:      /* load unsigned byte alternate */
bellard authored
4328
#ifndef TARGET_SPARC64
blueswir1 authored
4329
4330
4331
4332
4333
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
#endif
4334
                    save_state(dc, cpu_cond);
4335
                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 0);
blueswir1 authored
4336
4337
                    break;
                case 0x12:      /* load unsigned halfword alternate */
bellard authored
4338
#ifndef TARGET_SPARC64
blueswir1 authored
4339
4340
4341
4342
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
blueswir1 authored
4343
#endif
4344
                    save_state(dc, cpu_cond);
4345
                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 0);
blueswir1 authored
4346
4347
                    break;
                case 0x13:      /* load double word alternate */
bellard authored
4348
#ifndef TARGET_SPARC64
blueswir1 authored
4349
4350
4351
4352
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
bellard authored
4353
#endif
blueswir1 authored
4354
                    if (rd & 1)
4355
                        goto illegal_insn;
4356
                    save_state(dc, cpu_cond);
4357
4358
                    gen_ldda_asi(cpu_val, cpu_addr, insn, rd);
                    goto skip_move;
blueswir1 authored
4359
                case 0x19:      /* load signed byte alternate */
bellard authored
4360
#ifndef TARGET_SPARC64
blueswir1 authored
4361
4362
4363
4364
4365
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
#endif
4366
                    save_state(dc, cpu_cond);
4367
                    gen_ld_asi(cpu_val, cpu_addr, insn, 1, 1);
blueswir1 authored
4368
4369
                    break;
                case 0x1a:      /* load signed halfword alternate */
bellard authored
4370
#ifndef TARGET_SPARC64
blueswir1 authored
4371
4372
4373
4374
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
blueswir1 authored
4375
#endif
4376
                    save_state(dc, cpu_cond);
4377
                    gen_ld_asi(cpu_val, cpu_addr, insn, 2, 1);
blueswir1 authored
4378
4379
                    break;
                case 0x1d:      /* ldstuba -- XXX: should be atomically */
bellard authored
4380
#ifndef TARGET_SPARC64
blueswir1 authored
4381
4382
4383
4384
4385
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
#endif
4386
                    save_state(dc, cpu_cond);
4387
                    gen_ldstub_asi(cpu_val, cpu_addr, insn);
blueswir1 authored
4388
                    break;
blueswir1 authored
4389
4390
                case 0x1f:      /* swap reg with alt. memory. Also
                                   atomically */
4391
                    CHECK_IU_FEATURE(dc, SWAP);
bellard authored
4392
#ifndef TARGET_SPARC64
blueswir1 authored
4393
4394
4395
4396
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
blueswir1 authored
4397
#endif
4398
                    save_state(dc, cpu_cond);
4399
4400
                    gen_movl_reg_TN(rd, cpu_val);
                    gen_swap_asi(cpu_val, cpu_addr, insn);
blueswir1 authored
4401
                    break;
bellard authored
4402
4403

#ifndef TARGET_SPARC64
blueswir1 authored
4404
4405
4406
4407
                case 0x30: /* ldc */
                case 0x31: /* ldcsr */
                case 0x33: /* lddc */
                    goto ncp_insn;
bellard authored
4408
4409
4410
#endif
#endif
#ifdef TARGET_SPARC64
blueswir1 authored
4411
                case 0x08: /* V9 ldsw */
4412
                    gen_address_mask(dc, cpu_addr);
4413
                    tcg_gen_qemu_ld32s(cpu_val, cpu_addr, dc->mem_idx);
blueswir1 authored
4414
4415
                    break;
                case 0x0b: /* V9 ldx */
4416
                    gen_address_mask(dc, cpu_addr);
4417
                    tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx);
blueswir1 authored
4418
4419
                    break;
                case 0x18: /* V9 ldswa */
4420
                    save_state(dc, cpu_cond);
4421
                    gen_ld_asi(cpu_val, cpu_addr, insn, 4, 1);
blueswir1 authored
4422
4423
                    break;
                case 0x1b: /* V9 ldxa */
4424
                    save_state(dc, cpu_cond);
4425
                    gen_ld_asi(cpu_val, cpu_addr, insn, 8, 0);
blueswir1 authored
4426
4427
4428
4429
                    break;
                case 0x2d: /* V9 prefetch, no effect */
                    goto skip_move;
                case 0x30: /* V9 ldfa */
4430
                    save_state(dc, cpu_cond);
4431
                    gen_ldf_asi(cpu_addr, insn, 4, rd);
4432
                    goto skip_move;
blueswir1 authored
4433
                case 0x33: /* V9 lddfa */
4434
                    save_state(dc, cpu_cond);
4435
                    gen_ldf_asi(cpu_addr, insn, 8, DFPREG(rd));
4436
                    goto skip_move;
blueswir1 authored
4437
4438
4439
                case 0x3d: /* V9 prefetcha, no effect */
                    goto skip_move;
                case 0x32: /* V9 ldqfa */
4440
                    CHECK_FPU_FEATURE(dc, FLOAT128);
4441
                    save_state(dc, cpu_cond);
4442
                    gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd));
4443
4444
                    goto skip_move;
#endif
blueswir1 authored
4445
4446
4447
                default:
                    goto illegal_insn;
                }
4448
                gen_movl_TN_reg(rd, cpu_val);
4449
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
blueswir1 authored
4450
            skip_move: ;
bellard authored
4451
#endif
blueswir1 authored
4452
            } else if (xop >= 0x20 && xop < 0x24) {
4453
                if (gen_trap_ifnofpu(dc, cpu_cond))
4454
                    goto jmp_insn;
4455
                save_state(dc, cpu_cond);
blueswir1 authored
4456
4457
                switch (xop) {
                case 0x20:      /* load fpreg */
4458
                    gen_address_mask(dc, cpu_addr);
blueswir1 authored
4459
4460
                    tcg_gen_qemu_ld32u(cpu_tmp0, cpu_addr, dc->mem_idx);
                    tcg_gen_trunc_tl_i32(cpu_fpr[rd], cpu_tmp0);
blueswir1 authored
4461
                    break;
4462
4463
                case 0x21:      /* ldfsr, V9 ldxfsr */
#ifdef TARGET_SPARC64
4464
                    gen_address_mask(dc, cpu_addr);
4465
4466
                    if (rd == 1) {
                        tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx);
pbrook authored
4467
                        gen_helper_ldxfsr(cpu_tmp64);
4468
4469
4470
4471
                    } else
#else
                    {
                        tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx);
pbrook authored
4472
                        gen_helper_ldfsr(cpu_tmp32);
4473
4474
                    }
#endif
blueswir1 authored
4475
4476
                    break;
                case 0x22:      /* load quad fpreg */
blueswir1 authored
4477
                    {
pbrook authored
4478
                        TCGv_i32 r_const;
blueswir1 authored
4479
4480
4481

                        CHECK_FPU_FEATURE(dc, FLOAT128);
                        r_const = tcg_const_i32(dc->mem_idx);
pbrook authored
4482
4483
                        gen_helper_ldqf(cpu_addr, r_const);
                        tcg_temp_free_i32(r_const);
blueswir1 authored
4484
4485
                        gen_op_store_QT0_fpr(QFPREG(rd));
                    }
4486
                    break;
blueswir1 authored
4487
                case 0x23:      /* load double fpreg */
blueswir1 authored
4488
                    {
pbrook authored
4489
                        TCGv_i32 r_const;
blueswir1 authored
4490
4491

                        r_const = tcg_const_i32(dc->mem_idx);
pbrook authored
4492
4493
                        gen_helper_lddf(cpu_addr, r_const);
                        tcg_temp_free_i32(r_const);
blueswir1 authored
4494
4495
                        gen_op_store_DT0_fpr(DFPREG(rd));
                    }
blueswir1 authored
4496
4497
4498
4499
4500
4501
                    break;
                default:
                    goto illegal_insn;
                }
            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) || \
                       xop == 0xe || xop == 0x1e) {
4502
                gen_movl_reg_TN(rd, cpu_val);
blueswir1 authored
4503
                switch (xop) {
4504
                case 0x4: /* store word */
4505
                    gen_address_mask(dc, cpu_addr);
4506
                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
blueswir1 authored
4507
                    break;
4508
                case 0x5: /* store byte */
4509
                    gen_address_mask(dc, cpu_addr);
4510
                    tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx);
blueswir1 authored
4511
                    break;
4512
                case 0x6: /* store halfword */
4513
                    gen_address_mask(dc, cpu_addr);
4514
                    tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx);
blueswir1 authored
4515
                    break;
4516
                case 0x7: /* store double word */
blueswir1 authored
4517
                    if (rd & 1)
4518
                        goto illegal_insn;
4519
                    else {
pbrook authored
4520
                        TCGv_i32 r_const;
4521
4522
                        save_state(dc, cpu_cond);
4523
                        gen_address_mask(dc, cpu_addr);
blueswir1 authored
4524
                        r_const = tcg_const_i32(7);
pbrook authored
4525
4526
                        gen_helper_check_align(cpu_addr, r_const); // XXX remove
                        tcg_temp_free_i32(r_const);
4527
                        gen_movl_reg_TN(rd + 1, cpu_tmp0);
4528
                        tcg_gen_concat_tl_i64(cpu_tmp64, cpu_tmp0, cpu_val);
4529
                        tcg_gen_qemu_st64(cpu_tmp64, cpu_addr, dc->mem_idx);
4530
                    }
blueswir1 authored
4531
                    break;
bellard authored
4532
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
4533
                case 0x14: /* store word alternate */
bellard authored
4534
#ifndef TARGET_SPARC64
blueswir1 authored
4535
4536
4537
4538
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
bellard authored
4539
#endif
4540
                    save_state(dc, cpu_cond);
4541
                    gen_st_asi(cpu_val, cpu_addr, insn, 4);
4542
                    break;
4543
                case 0x15: /* store byte alternate */
bellard authored
4544
#ifndef TARGET_SPARC64
blueswir1 authored
4545
4546
4547
4548
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
bellard authored
4549
#endif
4550
                    save_state(dc, cpu_cond);
4551
                    gen_st_asi(cpu_val, cpu_addr, insn, 1);
4552
                    break;
4553
                case 0x16: /* store halfword alternate */
bellard authored
4554
#ifndef TARGET_SPARC64
blueswir1 authored
4555
4556
4557
4558
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
bellard authored
4559
#endif
4560
                    save_state(dc, cpu_cond);
4561
                    gen_st_asi(cpu_val, cpu_addr, insn, 2);
4562
                    break;
4563
                case 0x17: /* store double word alternate */
bellard authored
4564
#ifndef TARGET_SPARC64
blueswir1 authored
4565
4566
4567
4568
                    if (IS_IMM)
                        goto illegal_insn;
                    if (!supervisor(dc))
                        goto priv_insn;
bellard authored
4569
#endif
blueswir1 authored
4570
                    if (rd & 1)
4571
                        goto illegal_insn;
4572
                    else {
4573
                        save_state(dc, cpu_cond);
4574
                        gen_stda_asi(cpu_val, cpu_addr, insn, rd);
4575
                    }
4576
                    break;
bellard authored
4577
#endif
bellard authored
4578
#ifdef TARGET_SPARC64
blueswir1 authored
4579
                case 0x0e: /* V9 stx */
4580
                    gen_address_mask(dc, cpu_addr);
4581
                    tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx);
blueswir1 authored
4582
4583
                    break;
                case 0x1e: /* V9 stxa */
4584
                    save_state(dc, cpu_cond);
4585
                    gen_st_asi(cpu_val, cpu_addr, insn, 8);
blueswir1 authored
4586
                    break;
bellard authored
4587
#endif
blueswir1 authored
4588
4589
4590
4591
                default:
                    goto illegal_insn;
                }
            } else if (xop > 0x23 && xop < 0x28) {
4592
                if (gen_trap_ifnofpu(dc, cpu_cond))
4593
                    goto jmp_insn;
4594
                save_state(dc, cpu_cond);
blueswir1 authored
4595
                switch (xop) {
4596
                case 0x24: /* store fpreg */
4597
                    gen_address_mask(dc, cpu_addr);
blueswir1 authored
4598
4599
                    tcg_gen_ext_i32_tl(cpu_tmp0, cpu_fpr[rd]);
                    tcg_gen_qemu_st32(cpu_tmp0, cpu_addr, dc->mem_idx);
blueswir1 authored
4600
4601
                    break;
                case 0x25: /* stfsr, V9 stxfsr */
4602
#ifdef TARGET_SPARC64
4603
                    gen_address_mask(dc, cpu_addr);
4604
4605
4606
                    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);
blueswir1 authored
4607
4608
                    else
                        tcg_gen_qemu_st32(cpu_tmp64, cpu_addr, dc->mem_idx);
4609
4610
#else
                    tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUState, fsr));
4611
                    tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx);
4612
#endif
blueswir1 authored
4613
                    break;
4614
4615
4616
                case 0x26:
#ifdef TARGET_SPARC64
                    /* V9 stqf, store quad fpreg */
blueswir1 authored
4617
                    {
pbrook authored
4618
                        TCGv_i32 r_const;
blueswir1 authored
4619
4620
4621
4622

                        CHECK_FPU_FEATURE(dc, FLOAT128);
                        gen_op_load_fpr_QT0(QFPREG(rd));
                        r_const = tcg_const_i32(dc->mem_idx);
pbrook authored
4623
4624
                        gen_helper_stqf(cpu_addr, r_const);
                        tcg_temp_free_i32(r_const);
blueswir1 authored
4625
                    }
4626
4627
4628
4629
4630
4631
                    break;
#else /* !TARGET_SPARC64 */
                    /* stdfq, store floating point queue */
#if defined(CONFIG_USER_ONLY)
                    goto illegal_insn;
#else
blueswir1 authored
4632
4633
                    if (!supervisor(dc))
                        goto priv_insn;
4634
                    if (gen_trap_ifnofpu(dc, cpu_cond))
blueswir1 authored
4635
4636
4637
                        goto jmp_insn;
                    goto nfq_insn;
#endif
4638
#endif
4639
                case 0x27: /* store double fpreg */
blueswir1 authored
4640
                    {
pbrook authored
4641
                        TCGv_i32 r_const;
blueswir1 authored
4642
4643
4644

                        gen_op_load_fpr_DT0(DFPREG(rd));
                        r_const = tcg_const_i32(dc->mem_idx);
pbrook authored
4645
4646
                        gen_helper_stdf(cpu_addr, r_const);
                        tcg_temp_free_i32(r_const);
blueswir1 authored
4647
                    }
blueswir1 authored
4648
4649
4650
4651
4652
                    break;
                default:
                    goto illegal_insn;
                }
            } else if (xop > 0x33 && xop < 0x3f) {
4653
                save_state(dc, cpu_cond);
blueswir1 authored
4654
                switch (xop) {
4655
#ifdef TARGET_SPARC64
blueswir1 authored
4656
                case 0x34: /* V9 stfa */
4657
                    gen_stf_asi(cpu_addr, insn, 4, rd);
blueswir1 authored
4658
                    break;
4659
                case 0x36: /* V9 stqfa */
blueswir1 authored
4660
                    {
pbrook authored
4661
                        TCGv_i32 r_const;
blueswir1 authored
4662
4663
4664

                        CHECK_FPU_FEATURE(dc, FLOAT128);
                        r_const = tcg_const_i32(7);
pbrook authored
4665
4666
                        gen_helper_check_align(cpu_addr, r_const);
                        tcg_temp_free_i32(r_const);
blueswir1 authored
4667
4668
4669
                        gen_op_load_fpr_QT0(QFPREG(rd));
                        gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd));
                    }
4670
                    break;
blueswir1 authored
4671
                case 0x37: /* V9 stdfa */
4672
                    gen_op_load_fpr_DT0(DFPREG(rd));
4673
                    gen_stf_asi(cpu_addr, insn, 8, DFPREG(rd));
blueswir1 authored
4674
4675
                    break;
                case 0x3c: /* V9 casa */
blueswir1 authored
4676
                    gen_cas_asi(cpu_val, cpu_addr, cpu_src2, insn, rd);
4677
                    gen_movl_TN_reg(rd, cpu_val);
blueswir1 authored
4678
4679
                    break;
                case 0x3e: /* V9 casxa */
blueswir1 authored
4680
                    gen_casx_asi(cpu_val, cpu_addr, cpu_src2, insn, rd);
4681
                    gen_movl_TN_reg(rd, cpu_val);
blueswir1 authored
4682
                    break;
4683
#else
blueswir1 authored
4684
4685
4686
4687
4688
4689
4690
4691
4692
                case 0x34: /* stc */
                case 0x35: /* stcsr */
                case 0x36: /* stdcq */
                case 0x37: /* stdc */
                    goto ncp_insn;
#endif
                default:
                    goto illegal_insn;
                }
4693
            }
blueswir1 authored
4694
4695
4696
4697
            else
                goto illegal_insn;
        }
        break;
4698
4699
    }
    /* default case for non jump instructions */
4700
    if (dc->npc == DYNAMIC_PC) {
blueswir1 authored
4701
4702
        dc->pc = DYNAMIC_PC;
        gen_op_next_insn();
4703
4704
    } else if (dc->npc == JUMP_PC) {
        /* we can do a static jump */
4705
        gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1], cpu_cond);
4706
4707
        dc->is_br = 1;
    } else {
blueswir1 authored
4708
4709
        dc->pc = dc->npc;
        dc->npc = dc->npc + 4;
4710
    }
bellard authored
4711
 jmp_insn:
4712
4713
    return;
 illegal_insn:
blueswir1 authored
4714
    {
pbrook authored
4715
        TCGv_i32 r_const;
blueswir1 authored
4716
4717
4718

        save_state(dc, cpu_cond);
        r_const = tcg_const_i32(TT_ILL_INSN);
pbrook authored
4719
4720
        gen_helper_raise_exception(r_const);
        tcg_temp_free_i32(r_const);
blueswir1 authored
4721
4722
        dc->is_br = 1;
    }
4723
    return;
4724
 unimp_flush:
blueswir1 authored
4725
    {
pbrook authored
4726
        TCGv_i32 r_const;
blueswir1 authored
4727
4728
4729

        save_state(dc, cpu_cond);
        r_const = tcg_const_i32(TT_UNIMP_FLUSH);
pbrook authored
4730
4731
        gen_helper_raise_exception(r_const);
        tcg_temp_free_i32(r_const);
blueswir1 authored
4732
4733
        dc->is_br = 1;
    }
4734
    return;
bellard authored
4735
#if !defined(CONFIG_USER_ONLY)
4736
 priv_insn:
blueswir1 authored
4737
    {
pbrook authored
4738
        TCGv_i32 r_const;
blueswir1 authored
4739
4740
4741

        save_state(dc, cpu_cond);
        r_const = tcg_const_i32(TT_PRIV_INSN);
pbrook authored
4742
4743
        gen_helper_raise_exception(r_const);
        tcg_temp_free_i32(r_const);
blueswir1 authored
4744
4745
        dc->is_br = 1;
    }
bellard authored
4746
    return;
4747
#endif
bellard authored
4748
 nfpu_insn:
4749
    save_state(dc, cpu_cond);
bellard authored
4750
4751
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
    dc->is_br = 1;
4752
    return;
4753
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
4754
 nfq_insn:
4755
    save_state(dc, cpu_cond);
4756
4757
4758
4759
    gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
    dc->is_br = 1;
    return;
#endif
4760
4761
#ifndef TARGET_SPARC64
 ncp_insn:
blueswir1 authored
4762
4763
4764
4765
4766
    {
        TCGv r_const;

        save_state(dc, cpu_cond);
        r_const = tcg_const_i32(TT_NCP_INSN);
pbrook authored
4767
        gen_helper_raise_exception(r_const);
blueswir1 authored
4768
4769
4770
        tcg_temp_free(r_const);
        dc->is_br = 1;
    }
4771
4772
    return;
#endif
4773
4774
}
4775
4776
static inline void gen_intermediate_code_internal(TranslationBlock * tb,
                                                  int spc, CPUSPARCState *env)
4777
{
4778
    target_ulong pc_start, last_pc;
4779
4780
    uint16_t *gen_opc_end;
    DisasContext dc1, *dc = &dc1;
4781
    CPUBreakpoint *bp;
4782
    int j, lj = -1;
pbrook authored
4783
4784
    int num_insns;
    int max_insns;
4785
4786
4787

    memset(dc, 0, sizeof(DisasContext));
    dc->tb = tb;
4788
    pc_start = tb->pc;
4789
    dc->pc = pc_start;
bellard authored
4790
    last_pc = dc->pc;
4791
    dc->npc = (target_ulong) tb->cs_base;
blueswir1 authored
4792
    dc->mem_idx = cpu_mmu_index(env);
4793
4794
    dc->def = env->def;
    if ((dc->def->features & CPU_FEATURE_FLOAT))
4795
        dc->fpu_enabled = cpu_fpu_enabled(env);
4796
    else
4797
        dc->fpu_enabled = 0;
4798
4799
4800
#ifdef TARGET_SPARC64
    dc->address_mask_32bit = env->pstate & PS_AM;
#endif
4801
4802
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
pbrook authored
4803
4804
4805
    cpu_tmp0 = tcg_temp_new();
    cpu_tmp32 = tcg_temp_new_i32();
    cpu_tmp64 = tcg_temp_new_i64();
blueswir1 authored
4806
pbrook authored
4807
    cpu_dst = tcg_temp_local_new();
blueswir1 authored
4808
4809

    // loads and stores
pbrook authored
4810
4811
    cpu_val = tcg_temp_local_new();
    cpu_addr = tcg_temp_local_new();
4812
pbrook authored
4813
4814
4815
4816
4817
    num_insns = 0;
    max_insns = tb->cflags & CF_COUNT_MASK;
    if (max_insns == 0)
        max_insns = CF_COUNT_MASK;
    gen_icount_start();
4818
    do {
4819
4820
        if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
            TAILQ_FOREACH(bp, &env->breakpoints, entry) {
4821
                if (bp->pc == dc->pc) {
blueswir1 authored
4822
                    if (dc->pc != pc_start)
4823
                        save_state(dc, cpu_cond);
pbrook authored
4824
                    gen_helper_debug();
bellard authored
4825
                    tcg_gen_exit_tb(0);
blueswir1 authored
4826
                    dc->is_br = 1;
bellard authored
4827
                    goto exit_gen_loop;
4828
4829
4830
4831
                }
            }
        }
        if (spc) {
4832
            qemu_log("Search PC...\n");
4833
4834
4835
4836
4837
4838
4839
4840
            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;
pbrook authored
4841
                gen_opc_icount[lj] = num_insns;
4842
4843
            }
        }
pbrook authored
4844
4845
        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
            gen_io_start();
blueswir1 authored
4846
4847
        last_pc = dc->pc;
        disas_sparc_insn(dc);
pbrook authored
4848
        num_insns++;
blueswir1 authored
4849
4850
4851
4852
4853
4854

        if (dc->is_br)
            break;
        /* if the next PC is different, we abort now */
        if (dc->pc != (last_pc + 4))
            break;
4855
4856
4857
4858
        /* 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;
bellard authored
4859
4860
4861
        /* if single step mode, we generate only one instruction and
           generate an exception */
        if (env->singlestep_enabled) {
4862
            tcg_gen_movi_tl(cpu_pc, dc->pc);
bellard authored
4863
            tcg_gen_exit_tb(0);
bellard authored
4864
4865
            break;
        }
4866
    } while ((gen_opc_ptr < gen_opc_end) &&
pbrook authored
4867
4868
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32) &&
             num_insns < max_insns);
bellard authored
4869
4870

 exit_gen_loop:
blueswir1 authored
4871
    tcg_temp_free(cpu_addr);
blueswir1 authored
4872
    tcg_temp_free(cpu_val);
blueswir1 authored
4873
    tcg_temp_free(cpu_dst);
pbrook authored
4874
4875
    tcg_temp_free_i64(cpu_tmp64);
    tcg_temp_free_i32(cpu_tmp32);
blueswir1 authored
4876
    tcg_temp_free(cpu_tmp0);
pbrook authored
4877
4878
    if (tb->cflags & CF_LAST_IO)
        gen_io_end();
4879
    if (!dc->is_br) {
4880
        if (dc->pc != DYNAMIC_PC &&
4881
4882
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
            /* static PC and NPC: we can use direct chaining */
4883
            gen_goto_tb(dc, 0, dc->pc, dc->npc);
4884
4885
        } else {
            if (dc->pc != DYNAMIC_PC)
4886
                tcg_gen_movi_tl(cpu_pc, dc->pc);
4887
            save_npc(dc, cpu_cond);
bellard authored
4888
            tcg_gen_exit_tb(0);
4889
4890
        }
    }
pbrook authored
4891
    gen_icount_end(tb, num_insns);
4892
    *gen_opc_ptr = INDEX_op_end;
4893
4894
4895
4896
4897
4898
    if (spc) {
        j = gen_opc_ptr - gen_opc_buf;
        lj++;
        while (lj <= j)
            gen_opc_instr_start[lj++] = 0;
#if 0
4899
        log_page_dump();
4900
#endif
4901
4902
        gen_opc_jump_pc[0] = dc->jump_pc[0];
        gen_opc_jump_pc[1] = dc->jump_pc[1];
4903
    } else {
bellard authored
4904
        tb->size = last_pc + 4 - pc_start;
pbrook authored
4905
        tb->icount = num_insns;
4906
    }
4907
#ifdef DEBUG_DISAS
4908
    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
4909
4910
4911
4912
        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");
4913
    }
4914
4915
4916
#endif
}
4917
void gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
4918
{
4919
    gen_intermediate_code_internal(tb, 0, env);
4920
4921
}
4922
void gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
4923
{
4924
    gen_intermediate_code_internal(tb, 1, env);
4925
4926
}
4927
void gen_intermediate_code_init(CPUSPARCState *env)
bellard authored
4928
{
4929
    unsigned int i;
4930
    static int inited;
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
    static const char * const gregnames[8] = {
        NULL, // g0 not used
        "g1",
        "g2",
        "g3",
        "g4",
        "g5",
        "g6",
        "g7",
    };
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
    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",
    };
4951
4952
4953
4954
4955
    /* init various static tables */
    if (!inited) {
        inited = 1;
pbrook authored
4956
4957
4958
4959
        cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
        cpu_regwptr = tcg_global_mem_new_ptr(TCG_AREG0,
                                             offsetof(CPUState, regwptr),
                                             "regwptr");
4960
#ifdef TARGET_SPARC64
pbrook authored
4961
4962
4963
4964
4965
4966
4967
        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),
4968
                                     "gsr");
pbrook authored
4969
        cpu_tick_cmpr = tcg_global_mem_new(TCG_AREG0,
4970
4971
                                           offsetof(CPUState, tick_cmpr),
                                           "tick_cmpr");
pbrook authored
4972
        cpu_stick_cmpr = tcg_global_mem_new(TCG_AREG0,
4973
4974
                                            offsetof(CPUState, stick_cmpr),
                                            "stick_cmpr");
pbrook authored
4975
        cpu_hstick_cmpr = tcg_global_mem_new(TCG_AREG0,
4976
4977
                                             offsetof(CPUState, hstick_cmpr),
                                             "hstick_cmpr");
pbrook authored
4978
        cpu_hintp = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, hintp),
4979
                                       "hintp");
pbrook authored
4980
4981
4982
4983
4984
        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,
4985
                                     offsetof(CPUState, ssr), "ssr");
pbrook authored
4986
        cpu_ver = tcg_global_mem_new(TCG_AREG0,
4987
                                     offsetof(CPUState, version), "ver");
pbrook authored
4988
4989
4990
        cpu_softint = tcg_global_mem_new_i32(TCG_AREG0,
                                             offsetof(CPUState, softint),
                                             "softint");
4991
#else
pbrook authored
4992
        cpu_wim = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, wim),
4993
                                     "wim");
4994
#endif
pbrook authored
4995
        cpu_cond = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cond),
blueswir1 authored
4996
                                      "cond");
pbrook authored
4997
        cpu_cc_src = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_src),
4998
                                        "cc_src");
pbrook authored
4999
        cpu_cc_src2 = tcg_global_mem_new(TCG_AREG0,
5000
5001
                                         offsetof(CPUState, cc_src2),
                                         "cc_src2");
pbrook authored
5002
        cpu_cc_dst = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, cc_dst),
5003
                                        "cc_dst");
pbrook authored
5004
5005
5006
        cpu_psr = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, psr),
                                         "psr");
        cpu_fsr = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, fsr),
blueswir1 authored
5007
                                     "fsr");
pbrook authored
5008
        cpu_pc = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, pc),
5009
                                    "pc");
pbrook authored
5010
5011
5012
        cpu_npc = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, npc),
                                     "npc");
        cpu_y = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, y), "y");
5013
#ifndef CONFIG_USER_ONLY
pbrook authored
5014
        cpu_tbr = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, tbr),
5015
5016
                                     "tbr");
#endif
5017
        for (i = 1; i < 8; i++)
pbrook authored
5018
            cpu_gregs[i] = tcg_global_mem_new(TCG_AREG0,
5019
5020
                                              offsetof(CPUState, gregs[i]),
                                              gregnames[i]);
5021
        for (i = 0; i < TARGET_FPREGS; i++)
pbrook authored
5022
5023
5024
            cpu_fpr[i] = tcg_global_mem_new_i32(TCG_AREG0,
                                                offsetof(CPUState, fpr[i]),
                                                fregnames[i]);
5025
blueswir1 authored
5026
5027
        /* register helpers */
pbrook authored
5028
#define GEN_HELPER 2
blueswir1 authored
5029
#include "helper.h"
5030
    }
bellard authored
5031
}
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051

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