Statistics
| Branch: | Revision:

root / target-sparc / translate.c @ 1f587329

History | View | Annotate | Download (138.4 kB)

1
/*
2
   SPARC translation
3

4
   Copyright (C) 2003 Thomas M. Ogrisegg <tom@fnord.at>
5
   Copyright (C) 2003-2005 Fabrice Bellard
6

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

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

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

    
22
/*
23
   TODO-list:
24

25
   Rest of V9 instructions, VIS instructions
26
   NPC/PC static optimisations (use JUMP_TB when possible)
27
   Optimize synthetic instructions
28
*/
29

    
30
#include <stdarg.h>
31
#include <stdlib.h>
32
#include <stdio.h>
33
#include <string.h>
34
#include <inttypes.h>
35

    
36
#include "cpu.h"
37
#include "exec-all.h"
38
#include "disas.h"
39

    
40
#define DEBUG_DISAS
41

    
42
#define DYNAMIC_PC  1 /* dynamic pc value */
43
#define JUMP_PC     2 /* dynamic pc value which takes only two values
44
                         according to jump_pc[T2] */
45

    
46
typedef struct DisasContext {
47
    target_ulong pc;    /* current Program Counter: integer or DYNAMIC_PC */
48
    target_ulong npc;   /* next PC: integer or DYNAMIC_PC or JUMP_PC */
49
    target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */
50
    int is_br;
51
    int mem_idx;
52
    int fpu_enabled;
53
    struct TranslationBlock *tb;
54
} DisasContext;
55

    
56
typedef struct sparc_def_t sparc_def_t;
57

    
58
struct sparc_def_t {
59
    const unsigned char *name;
60
    target_ulong iu_version;
61
    uint32_t fpu_version;
62
    uint32_t mmu_version;
63
    uint32_t mmu_bm;
64
};
65

    
66
static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name);
67

    
68
static uint16_t *gen_opc_ptr;
69
static uint32_t *gen_opparam_ptr;
70
extern FILE *logfile;
71
extern int loglevel;
72

    
73
enum {
74
#define DEF(s,n,copy_size) INDEX_op_ ## s,
75
#include "opc.h"
76
#undef DEF
77
    NB_OPS
78
};
79

    
80
#include "gen-op.h"
81

    
82
// This function uses non-native bit order
83
#define GET_FIELD(X, FROM, TO) \
84
  ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
85

    
86
// This function uses the order in the manuals, i.e. bit 0 is 2^0
87
#define GET_FIELD_SP(X, FROM, TO) \
88
    GET_FIELD(X, 31 - (TO), 31 - (FROM))
89

    
90
#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
91
#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), ((b) - (a) + 1))
92

    
93
#ifdef TARGET_SPARC64
94
#define DFPREG(r) (((r & 1) << 5) | (r & 0x1e))
95
#define QFPREG(r) (((r & 1) << 5) | (r & 0x1c))
96
#else
97
#define DFPREG(r) (r & 0x1e)
98
#define QFPREG(r) (r & 0x1c)
99
#endif
100

    
101
#ifdef USE_DIRECT_JUMP
102
#define TBPARAM(x)
103
#else
104
#define TBPARAM(x) (long)(x)
105
#endif
106

    
107
static int sign_extend(int x, int len)
108
{
109
    len = 32 - len;
110
    return (x << len) >> len;
111
}
112

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

    
115
static void disas_sparc_insn(DisasContext * dc);
116

    
117
static GenOpFunc * const gen_op_movl_TN_reg[2][32] = {
118
    {
119
     gen_op_movl_g0_T0,
120
     gen_op_movl_g1_T0,
121
     gen_op_movl_g2_T0,
122
     gen_op_movl_g3_T0,
123
     gen_op_movl_g4_T0,
124
     gen_op_movl_g5_T0,
125
     gen_op_movl_g6_T0,
126
     gen_op_movl_g7_T0,
127
     gen_op_movl_o0_T0,
128
     gen_op_movl_o1_T0,
129
     gen_op_movl_o2_T0,
130
     gen_op_movl_o3_T0,
131
     gen_op_movl_o4_T0,
132
     gen_op_movl_o5_T0,
133
     gen_op_movl_o6_T0,
134
     gen_op_movl_o7_T0,
135
     gen_op_movl_l0_T0,
136
     gen_op_movl_l1_T0,
137
     gen_op_movl_l2_T0,
138
     gen_op_movl_l3_T0,
139
     gen_op_movl_l4_T0,
140
     gen_op_movl_l5_T0,
141
     gen_op_movl_l6_T0,
142
     gen_op_movl_l7_T0,
143
     gen_op_movl_i0_T0,
144
     gen_op_movl_i1_T0,
145
     gen_op_movl_i2_T0,
146
     gen_op_movl_i3_T0,
147
     gen_op_movl_i4_T0,
148
     gen_op_movl_i5_T0,
149
     gen_op_movl_i6_T0,
150
     gen_op_movl_i7_T0,
151
     },
152
    {
153
     gen_op_movl_g0_T1,
154
     gen_op_movl_g1_T1,
155
     gen_op_movl_g2_T1,
156
     gen_op_movl_g3_T1,
157
     gen_op_movl_g4_T1,
158
     gen_op_movl_g5_T1,
159
     gen_op_movl_g6_T1,
160
     gen_op_movl_g7_T1,
161
     gen_op_movl_o0_T1,
162
     gen_op_movl_o1_T1,
163
     gen_op_movl_o2_T1,
164
     gen_op_movl_o3_T1,
165
     gen_op_movl_o4_T1,
166
     gen_op_movl_o5_T1,
167
     gen_op_movl_o6_T1,
168
     gen_op_movl_o7_T1,
169
     gen_op_movl_l0_T1,
170
     gen_op_movl_l1_T1,
171
     gen_op_movl_l2_T1,
172
     gen_op_movl_l3_T1,
173
     gen_op_movl_l4_T1,
174
     gen_op_movl_l5_T1,
175
     gen_op_movl_l6_T1,
176
     gen_op_movl_l7_T1,
177
     gen_op_movl_i0_T1,
178
     gen_op_movl_i1_T1,
179
     gen_op_movl_i2_T1,
180
     gen_op_movl_i3_T1,
181
     gen_op_movl_i4_T1,
182
     gen_op_movl_i5_T1,
183
     gen_op_movl_i6_T1,
184
     gen_op_movl_i7_T1,
185
     }
186
};
187

    
188
static GenOpFunc * const gen_op_movl_reg_TN[3][32] = {
189
    {
190
     gen_op_movl_T0_g0,
191
     gen_op_movl_T0_g1,
192
     gen_op_movl_T0_g2,
193
     gen_op_movl_T0_g3,
194
     gen_op_movl_T0_g4,
195
     gen_op_movl_T0_g5,
196
     gen_op_movl_T0_g6,
197
     gen_op_movl_T0_g7,
198
     gen_op_movl_T0_o0,
199
     gen_op_movl_T0_o1,
200
     gen_op_movl_T0_o2,
201
     gen_op_movl_T0_o3,
202
     gen_op_movl_T0_o4,
203
     gen_op_movl_T0_o5,
204
     gen_op_movl_T0_o6,
205
     gen_op_movl_T0_o7,
206
     gen_op_movl_T0_l0,
207
     gen_op_movl_T0_l1,
208
     gen_op_movl_T0_l2,
209
     gen_op_movl_T0_l3,
210
     gen_op_movl_T0_l4,
211
     gen_op_movl_T0_l5,
212
     gen_op_movl_T0_l6,
213
     gen_op_movl_T0_l7,
214
     gen_op_movl_T0_i0,
215
     gen_op_movl_T0_i1,
216
     gen_op_movl_T0_i2,
217
     gen_op_movl_T0_i3,
218
     gen_op_movl_T0_i4,
219
     gen_op_movl_T0_i5,
220
     gen_op_movl_T0_i6,
221
     gen_op_movl_T0_i7,
222
     },
223
    {
224
     gen_op_movl_T1_g0,
225
     gen_op_movl_T1_g1,
226
     gen_op_movl_T1_g2,
227
     gen_op_movl_T1_g3,
228
     gen_op_movl_T1_g4,
229
     gen_op_movl_T1_g5,
230
     gen_op_movl_T1_g6,
231
     gen_op_movl_T1_g7,
232
     gen_op_movl_T1_o0,
233
     gen_op_movl_T1_o1,
234
     gen_op_movl_T1_o2,
235
     gen_op_movl_T1_o3,
236
     gen_op_movl_T1_o4,
237
     gen_op_movl_T1_o5,
238
     gen_op_movl_T1_o6,
239
     gen_op_movl_T1_o7,
240
     gen_op_movl_T1_l0,
241
     gen_op_movl_T1_l1,
242
     gen_op_movl_T1_l2,
243
     gen_op_movl_T1_l3,
244
     gen_op_movl_T1_l4,
245
     gen_op_movl_T1_l5,
246
     gen_op_movl_T1_l6,
247
     gen_op_movl_T1_l7,
248
     gen_op_movl_T1_i0,
249
     gen_op_movl_T1_i1,
250
     gen_op_movl_T1_i2,
251
     gen_op_movl_T1_i3,
252
     gen_op_movl_T1_i4,
253
     gen_op_movl_T1_i5,
254
     gen_op_movl_T1_i6,
255
     gen_op_movl_T1_i7,
256
     },
257
    {
258
     gen_op_movl_T2_g0,
259
     gen_op_movl_T2_g1,
260
     gen_op_movl_T2_g2,
261
     gen_op_movl_T2_g3,
262
     gen_op_movl_T2_g4,
263
     gen_op_movl_T2_g5,
264
     gen_op_movl_T2_g6,
265
     gen_op_movl_T2_g7,
266
     gen_op_movl_T2_o0,
267
     gen_op_movl_T2_o1,
268
     gen_op_movl_T2_o2,
269
     gen_op_movl_T2_o3,
270
     gen_op_movl_T2_o4,
271
     gen_op_movl_T2_o5,
272
     gen_op_movl_T2_o6,
273
     gen_op_movl_T2_o7,
274
     gen_op_movl_T2_l0,
275
     gen_op_movl_T2_l1,
276
     gen_op_movl_T2_l2,
277
     gen_op_movl_T2_l3,
278
     gen_op_movl_T2_l4,
279
     gen_op_movl_T2_l5,
280
     gen_op_movl_T2_l6,
281
     gen_op_movl_T2_l7,
282
     gen_op_movl_T2_i0,
283
     gen_op_movl_T2_i1,
284
     gen_op_movl_T2_i2,
285
     gen_op_movl_T2_i3,
286
     gen_op_movl_T2_i4,
287
     gen_op_movl_T2_i5,
288
     gen_op_movl_T2_i6,
289
     gen_op_movl_T2_i7,
290
     }
291
};
292

    
293
static GenOpFunc1 * const gen_op_movl_TN_im[3] = {
294
    gen_op_movl_T0_im,
295
    gen_op_movl_T1_im,
296
    gen_op_movl_T2_im
297
};
298

    
299
// Sign extending version
300
static GenOpFunc1 * const gen_op_movl_TN_sim[3] = {
301
    gen_op_movl_T0_sim,
302
    gen_op_movl_T1_sim,
303
    gen_op_movl_T2_sim
304
};
305

    
306
#ifdef TARGET_SPARC64
307
#define GEN32(func, NAME) \
308
static GenOpFunc * const NAME ## _table [64] = {                              \
309
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
310
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
311
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
312
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
313
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
314
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
315
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
316
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
317
NAME ## 32, 0, NAME ## 34, 0, NAME ## 36, 0, NAME ## 38, 0,                   \
318
NAME ## 40, 0, NAME ## 42, 0, NAME ## 44, 0, NAME ## 46, 0,                   \
319
NAME ## 48, 0, NAME ## 50, 0, NAME ## 52, 0, NAME ## 54, 0,                   \
320
NAME ## 56, 0, NAME ## 58, 0, NAME ## 60, 0, NAME ## 62, 0,                   \
321
};                                                                            \
322
static inline void func(int n)                                                \
323
{                                                                             \
324
    NAME ## _table[n]();                                                      \
325
}
326
#else
327
#define GEN32(func, NAME) \
328
static GenOpFunc *const NAME ## _table [32] = {                               \
329
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
330
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
331
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
332
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
333
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
334
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
335
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
336
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
337
};                                                                            \
338
static inline void func(int n)                                                \
339
{                                                                             \
340
    NAME ## _table[n]();                                                      \
341
}
342
#endif
343

    
344
/* floating point registers moves */
345
GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fprf);
346
GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fprf);
347
GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fprf);
348
GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fprf);
349

    
350
GEN32(gen_op_load_fpr_DT0, gen_op_load_fpr_DT0_fprf);
351
GEN32(gen_op_load_fpr_DT1, gen_op_load_fpr_DT1_fprf);
352
GEN32(gen_op_store_DT0_fpr, gen_op_store_DT0_fpr_fprf);
353
GEN32(gen_op_store_DT1_fpr, gen_op_store_DT1_fpr_fprf);
354

    
355
#if defined(CONFIG_USER_ONLY)
356
GEN32(gen_op_load_fpr_QT0, gen_op_load_fpr_QT0_fprf);
357
GEN32(gen_op_load_fpr_QT1, gen_op_load_fpr_QT1_fprf);
358
GEN32(gen_op_store_QT0_fpr, gen_op_store_QT0_fpr_fprf);
359
GEN32(gen_op_store_QT1_fpr, gen_op_store_QT1_fpr_fprf);
360
#endif
361

    
362
/* moves */
363
#ifdef CONFIG_USER_ONLY
364
#define supervisor(dc) 0
365
#ifdef TARGET_SPARC64
366
#define hypervisor(dc) 0
367
#endif
368
#define gen_op_ldst(name)        gen_op_##name##_raw()
369
#else
370
#define supervisor(dc) (dc->mem_idx >= 1)
371
#ifdef TARGET_SPARC64
372
#define hypervisor(dc) (dc->mem_idx == 2)
373
#define OP_LD_TABLE(width)                                              \
374
    static GenOpFunc * const gen_op_##width[] = {                       \
375
        &gen_op_##width##_user,                                         \
376
        &gen_op_##width##_kernel,                                       \
377
        &gen_op_##width##_hypv,                                         \
378
    };
379
#else
380
#define OP_LD_TABLE(width)                                              \
381
    static GenOpFunc * const gen_op_##width[] = {                       \
382
        &gen_op_##width##_user,                                         \
383
        &gen_op_##width##_kernel,                                       \
384
    };
385
#endif
386
#define gen_op_ldst(name)        (*gen_op_##name[dc->mem_idx])()
387
#endif
388

    
389
#ifndef CONFIG_USER_ONLY
390
OP_LD_TABLE(ld);
391
OP_LD_TABLE(st);
392
OP_LD_TABLE(ldub);
393
OP_LD_TABLE(lduh);
394
OP_LD_TABLE(ldsb);
395
OP_LD_TABLE(ldsh);
396
OP_LD_TABLE(stb);
397
OP_LD_TABLE(sth);
398
OP_LD_TABLE(std);
399
OP_LD_TABLE(ldstub);
400
OP_LD_TABLE(swap);
401
OP_LD_TABLE(ldd);
402
OP_LD_TABLE(stf);
403
OP_LD_TABLE(stdf);
404
OP_LD_TABLE(ldf);
405
OP_LD_TABLE(lddf);
406

    
407
#ifdef TARGET_SPARC64
408
OP_LD_TABLE(lduw);
409
OP_LD_TABLE(ldsw);
410
OP_LD_TABLE(ldx);
411
OP_LD_TABLE(stx);
412
#endif
413
#endif
414

    
415
/* asi moves */
416
#ifdef TARGET_SPARC64
417
static inline void gen_ld_asi(int insn, int size, int sign)
418
{
419
    int asi, offset;
420

    
421
    if (IS_IMM) {
422
        offset = GET_FIELD(insn, 25, 31);
423
        gen_op_ld_asi_reg(offset, size, sign);
424
    } else {
425
        asi = GET_FIELD(insn, 19, 26);
426
        gen_op_ld_asi(asi, size, sign);
427
    }
428
}
429

    
430
static inline void gen_st_asi(int insn, int size)
431
{
432
    int asi, offset;
433

    
434
    if (IS_IMM) {
435
        offset = GET_FIELD(insn, 25, 31);
436
        gen_op_st_asi_reg(offset, size);
437
    } else {
438
        asi = GET_FIELD(insn, 19, 26);
439
        gen_op_st_asi(asi, size);
440
    }
441
}
442

    
443
static inline void gen_ldf_asi(int insn, int size)
444
{
445
    int asi, offset, rd;
446

    
447
    rd = DFPREG(GET_FIELD(insn, 2, 6));
448
    if (IS_IMM) {
449
        offset = GET_FIELD(insn, 25, 31);
450
        gen_op_ldf_asi_reg(offset, size, rd);
451
    } else {
452
        asi = GET_FIELD(insn, 19, 26);
453
        gen_op_ldf_asi(asi, size, rd);
454
    }
455
}
456

    
457
static inline void gen_stf_asi(int insn, int size)
458
{
459
    int asi, offset, rd;
460

    
461
    rd = DFPREG(GET_FIELD(insn, 2, 6));
462
    if (IS_IMM) {
463
        offset = GET_FIELD(insn, 25, 31);
464
        gen_op_stf_asi_reg(offset, size, rd);
465
    } else {
466
        asi = GET_FIELD(insn, 19, 26);
467
        gen_op_stf_asi(asi, size, rd);
468
    }
469
}
470

    
471
static inline void gen_swap_asi(int insn)
472
{
473
    int asi, offset;
474

    
475
    if (IS_IMM) {
476
        offset = GET_FIELD(insn, 25, 31);
477
        gen_op_swap_asi_reg(offset);
478
    } else {
479
        asi = GET_FIELD(insn, 19, 26);
480
        gen_op_swap_asi(asi);
481
    }
482
}
483

    
484
static inline void gen_ldstub_asi(int insn)
485
{
486
    int asi, offset;
487

    
488
    if (IS_IMM) {
489
        offset = GET_FIELD(insn, 25, 31);
490
        gen_op_ldstub_asi_reg(offset);
491
    } else {
492
        asi = GET_FIELD(insn, 19, 26);
493
        gen_op_ldstub_asi(asi);
494
    }
495
}
496

    
497
static inline void gen_ldda_asi(int insn)
498
{
499
    int asi, offset;
500

    
501
    if (IS_IMM) {
502
        offset = GET_FIELD(insn, 25, 31);
503
        gen_op_ldda_asi_reg(offset);
504
    } else {
505
        asi = GET_FIELD(insn, 19, 26);
506
        gen_op_ldda_asi(asi);
507
    }
508
}
509

    
510
static inline void gen_stda_asi(int insn)
511
{
512
    int asi, offset;
513

    
514
    if (IS_IMM) {
515
        offset = GET_FIELD(insn, 25, 31);
516
        gen_op_stda_asi_reg(offset);
517
    } else {
518
        asi = GET_FIELD(insn, 19, 26);
519
        gen_op_stda_asi(asi);
520
    }
521
}
522

    
523
static inline void gen_cas_asi(int insn)
524
{
525
    int asi, offset;
526

    
527
    if (IS_IMM) {
528
        offset = GET_FIELD(insn, 25, 31);
529
        gen_op_cas_asi_reg(offset);
530
    } else {
531
        asi = GET_FIELD(insn, 19, 26);
532
        gen_op_cas_asi(asi);
533
    }
534
}
535

    
536
static inline void gen_casx_asi(int insn)
537
{
538
    int asi, offset;
539

    
540
    if (IS_IMM) {
541
        offset = GET_FIELD(insn, 25, 31);
542
        gen_op_casx_asi_reg(offset);
543
    } else {
544
        asi = GET_FIELD(insn, 19, 26);
545
        gen_op_casx_asi(asi);
546
    }
547
}
548

    
549
#elif !defined(CONFIG_USER_ONLY)
550

    
551
static inline void gen_ld_asi(int insn, int size, int sign)
552
{
553
    int asi;
554

    
555
    asi = GET_FIELD(insn, 19, 26);
556
    gen_op_ld_asi(asi, size, sign);
557
}
558

    
559
static inline void gen_st_asi(int insn, int size)
560
{
561
    int asi;
562

    
563
    asi = GET_FIELD(insn, 19, 26);
564
    gen_op_st_asi(asi, size);
565
}
566

    
567
static inline void gen_ldstub_asi(int insn)
568
{
569
    int asi;
570

    
571
    asi = GET_FIELD(insn, 19, 26);
572
    gen_op_ldstub_asi(asi);
573
}
574

    
575
static inline void gen_swap_asi(int insn)
576
{
577
    int asi;
578

    
579
    asi = GET_FIELD(insn, 19, 26);
580
    gen_op_swap_asi(asi);
581
}
582

    
583
static inline void gen_ldda_asi(int insn)
584
{
585
    int asi;
586

    
587
    asi = GET_FIELD(insn, 19, 26);
588
    gen_op_ld_asi(asi, 8, 0);
589
}
590

    
591
static inline void gen_stda_asi(int insn)
592
{
593
    int asi;
594

    
595
    asi = GET_FIELD(insn, 19, 26);
596
    gen_op_st_asi(asi, 8);
597
}
598
#endif
599

    
600
static inline void gen_movl_imm_TN(int reg, uint32_t imm)
601
{
602
    gen_op_movl_TN_im[reg](imm);
603
}
604

    
605
static inline void gen_movl_imm_T1(uint32_t val)
606
{
607
    gen_movl_imm_TN(1, val);
608
}
609

    
610
static inline void gen_movl_imm_T0(uint32_t val)
611
{
612
    gen_movl_imm_TN(0, val);
613
}
614

    
615
static inline void gen_movl_simm_TN(int reg, int32_t imm)
616
{
617
    gen_op_movl_TN_sim[reg](imm);
618
}
619

    
620
static inline void gen_movl_simm_T1(int32_t val)
621
{
622
    gen_movl_simm_TN(1, val);
623
}
624

    
625
static inline void gen_movl_simm_T0(int32_t val)
626
{
627
    gen_movl_simm_TN(0, val);
628
}
629

    
630
static inline void gen_movl_reg_TN(int reg, int t)
631
{
632
    if (reg)
633
        gen_op_movl_reg_TN[t][reg] ();
634
    else
635
        gen_movl_imm_TN(t, 0);
636
}
637

    
638
static inline void gen_movl_reg_T0(int reg)
639
{
640
    gen_movl_reg_TN(reg, 0);
641
}
642

    
643
static inline void gen_movl_reg_T1(int reg)
644
{
645
    gen_movl_reg_TN(reg, 1);
646
}
647

    
648
static inline void gen_movl_reg_T2(int reg)
649
{
650
    gen_movl_reg_TN(reg, 2);
651
}
652

    
653
static inline void gen_movl_TN_reg(int reg, int t)
654
{
655
    if (reg)
656
        gen_op_movl_TN_reg[t][reg] ();
657
}
658

    
659
static inline void gen_movl_T0_reg(int reg)
660
{
661
    gen_movl_TN_reg(reg, 0);
662
}
663

    
664
static inline void gen_movl_T1_reg(int reg)
665
{
666
    gen_movl_TN_reg(reg, 1);
667
}
668

    
669
static inline void gen_jmp_im(target_ulong pc)
670
{
671
#ifdef TARGET_SPARC64
672
    if (pc == (uint32_t)pc) {
673
        gen_op_jmp_im(pc);
674
    } else {
675
        gen_op_jmp_im64(pc >> 32, pc);
676
    }
677
#else
678
    gen_op_jmp_im(pc);
679
#endif
680
}
681

    
682
static inline void gen_movl_npc_im(target_ulong npc)
683
{
684
#ifdef TARGET_SPARC64
685
    if (npc == (uint32_t)npc) {
686
        gen_op_movl_npc_im(npc);
687
    } else {
688
        gen_op_movq_npc_im64(npc >> 32, npc);
689
    }
690
#else
691
    gen_op_movl_npc_im(npc);
692
#endif
693
}
694

    
695
static inline void gen_goto_tb(DisasContext *s, int tb_num,
696
                               target_ulong pc, target_ulong npc)
697
{
698
    TranslationBlock *tb;
699

    
700
    tb = s->tb;
701
    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
702
        (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK))  {
703
        /* jump to same page: we can use a direct jump */
704
        if (tb_num == 0)
705
            gen_op_goto_tb0(TBPARAM(tb));
706
        else
707
            gen_op_goto_tb1(TBPARAM(tb));
708
        gen_jmp_im(pc);
709
        gen_movl_npc_im(npc);
710
        gen_op_movl_T0_im((long)tb + tb_num);
711
        gen_op_exit_tb();
712
    } else {
713
        /* jump to another page: currently not optimized */
714
        gen_jmp_im(pc);
715
        gen_movl_npc_im(npc);
716
        gen_op_movl_T0_0();
717
        gen_op_exit_tb();
718
    }
719
}
720

    
721
static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
722
                               target_ulong pc2)
723
{
724
    int l1;
725

    
726
    l1 = gen_new_label();
727

    
728
    gen_op_jz_T2_label(l1);
729

    
730
    gen_goto_tb(dc, 0, pc1, pc1 + 4);
731

    
732
    gen_set_label(l1);
733
    gen_goto_tb(dc, 1, pc2, pc2 + 4);
734
}
735

    
736
static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,
737
                                target_ulong pc2)
738
{
739
    int l1;
740

    
741
    l1 = gen_new_label();
742

    
743
    gen_op_jz_T2_label(l1);
744

    
745
    gen_goto_tb(dc, 0, pc2, pc1);
746

    
747
    gen_set_label(l1);
748
    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
749
}
750

    
751
static inline void gen_branch(DisasContext *dc, target_ulong pc,
752
                              target_ulong npc)
753
{
754
    gen_goto_tb(dc, 0, pc, npc);
755
}
756

    
757
static inline void gen_generic_branch(target_ulong npc1, target_ulong npc2)
758
{
759
    int l1, l2;
760

    
761
    l1 = gen_new_label();
762
    l2 = gen_new_label();
763
    gen_op_jz_T2_label(l1);
764

    
765
    gen_movl_npc_im(npc1);
766
    gen_op_jmp_label(l2);
767

    
768
    gen_set_label(l1);
769
    gen_movl_npc_im(npc2);
770
    gen_set_label(l2);
771
}
772

    
773
/* call this function before using T2 as it may have been set for a jump */
774
static inline void flush_T2(DisasContext * dc)
775
{
776
    if (dc->npc == JUMP_PC) {
777
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
778
        dc->npc = DYNAMIC_PC;
779
    }
780
}
781

    
782
static inline void save_npc(DisasContext * dc)
783
{
784
    if (dc->npc == JUMP_PC) {
785
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
786
        dc->npc = DYNAMIC_PC;
787
    } else if (dc->npc != DYNAMIC_PC) {
788
        gen_movl_npc_im(dc->npc);
789
    }
790
}
791

    
792
static inline void save_state(DisasContext * dc)
793
{
794
    gen_jmp_im(dc->pc);
795
    save_npc(dc);
796
}
797

    
798
static inline void gen_mov_pc_npc(DisasContext * dc)
799
{
800
    if (dc->npc == JUMP_PC) {
801
        gen_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
802
        gen_op_mov_pc_npc();
803
        dc->pc = DYNAMIC_PC;
804
    } else if (dc->npc == DYNAMIC_PC) {
805
        gen_op_mov_pc_npc();
806
        dc->pc = DYNAMIC_PC;
807
    } else {
808
        dc->pc = dc->npc;
809
    }
810
}
811

    
812
static GenOpFunc * const gen_cond[2][16] = {
813
    {
814
        gen_op_eval_bn,
815
        gen_op_eval_be,
816
        gen_op_eval_ble,
817
        gen_op_eval_bl,
818
        gen_op_eval_bleu,
819
        gen_op_eval_bcs,
820
        gen_op_eval_bneg,
821
        gen_op_eval_bvs,
822
        gen_op_eval_ba,
823
        gen_op_eval_bne,
824
        gen_op_eval_bg,
825
        gen_op_eval_bge,
826
        gen_op_eval_bgu,
827
        gen_op_eval_bcc,
828
        gen_op_eval_bpos,
829
        gen_op_eval_bvc,
830
    },
831
    {
832
#ifdef TARGET_SPARC64
833
        gen_op_eval_bn,
834
        gen_op_eval_xbe,
835
        gen_op_eval_xble,
836
        gen_op_eval_xbl,
837
        gen_op_eval_xbleu,
838
        gen_op_eval_xbcs,
839
        gen_op_eval_xbneg,
840
        gen_op_eval_xbvs,
841
        gen_op_eval_ba,
842
        gen_op_eval_xbne,
843
        gen_op_eval_xbg,
844
        gen_op_eval_xbge,
845
        gen_op_eval_xbgu,
846
        gen_op_eval_xbcc,
847
        gen_op_eval_xbpos,
848
        gen_op_eval_xbvc,
849
#endif
850
    },
851
};
852

    
853
static GenOpFunc * const gen_fcond[4][16] = {
854
    {
855
        gen_op_eval_bn,
856
        gen_op_eval_fbne,
857
        gen_op_eval_fblg,
858
        gen_op_eval_fbul,
859
        gen_op_eval_fbl,
860
        gen_op_eval_fbug,
861
        gen_op_eval_fbg,
862
        gen_op_eval_fbu,
863
        gen_op_eval_ba,
864
        gen_op_eval_fbe,
865
        gen_op_eval_fbue,
866
        gen_op_eval_fbge,
867
        gen_op_eval_fbuge,
868
        gen_op_eval_fble,
869
        gen_op_eval_fbule,
870
        gen_op_eval_fbo,
871
    },
872
#ifdef TARGET_SPARC64
873
    {
874
        gen_op_eval_bn,
875
        gen_op_eval_fbne_fcc1,
876
        gen_op_eval_fblg_fcc1,
877
        gen_op_eval_fbul_fcc1,
878
        gen_op_eval_fbl_fcc1,
879
        gen_op_eval_fbug_fcc1,
880
        gen_op_eval_fbg_fcc1,
881
        gen_op_eval_fbu_fcc1,
882
        gen_op_eval_ba,
883
        gen_op_eval_fbe_fcc1,
884
        gen_op_eval_fbue_fcc1,
885
        gen_op_eval_fbge_fcc1,
886
        gen_op_eval_fbuge_fcc1,
887
        gen_op_eval_fble_fcc1,
888
        gen_op_eval_fbule_fcc1,
889
        gen_op_eval_fbo_fcc1,
890
    },
891
    {
892
        gen_op_eval_bn,
893
        gen_op_eval_fbne_fcc2,
894
        gen_op_eval_fblg_fcc2,
895
        gen_op_eval_fbul_fcc2,
896
        gen_op_eval_fbl_fcc2,
897
        gen_op_eval_fbug_fcc2,
898
        gen_op_eval_fbg_fcc2,
899
        gen_op_eval_fbu_fcc2,
900
        gen_op_eval_ba,
901
        gen_op_eval_fbe_fcc2,
902
        gen_op_eval_fbue_fcc2,
903
        gen_op_eval_fbge_fcc2,
904
        gen_op_eval_fbuge_fcc2,
905
        gen_op_eval_fble_fcc2,
906
        gen_op_eval_fbule_fcc2,
907
        gen_op_eval_fbo_fcc2,
908
    },
909
    {
910
        gen_op_eval_bn,
911
        gen_op_eval_fbne_fcc3,
912
        gen_op_eval_fblg_fcc3,
913
        gen_op_eval_fbul_fcc3,
914
        gen_op_eval_fbl_fcc3,
915
        gen_op_eval_fbug_fcc3,
916
        gen_op_eval_fbg_fcc3,
917
        gen_op_eval_fbu_fcc3,
918
        gen_op_eval_ba,
919
        gen_op_eval_fbe_fcc3,
920
        gen_op_eval_fbue_fcc3,
921
        gen_op_eval_fbge_fcc3,
922
        gen_op_eval_fbuge_fcc3,
923
        gen_op_eval_fble_fcc3,
924
        gen_op_eval_fbule_fcc3,
925
        gen_op_eval_fbo_fcc3,
926
    },
927
#else
928
    {}, {}, {},
929
#endif
930
};
931

    
932
#ifdef TARGET_SPARC64
933
static void gen_cond_reg(int cond)
934
{
935
        switch (cond) {
936
        case 0x1:
937
            gen_op_eval_brz();
938
            break;
939
        case 0x2:
940
            gen_op_eval_brlez();
941
            break;
942
        case 0x3:
943
            gen_op_eval_brlz();
944
            break;
945
        case 0x5:
946
            gen_op_eval_brnz();
947
            break;
948
        case 0x6:
949
            gen_op_eval_brgz();
950
            break;
951
        default:
952
        case 0x7:
953
            gen_op_eval_brgez();
954
            break;
955
        }
956
}
957
#endif
958

    
959
/* XXX: potentially incorrect if dynamic npc */
960
static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
961
{
962
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
963
    target_ulong target = dc->pc + offset;
964

    
965
    if (cond == 0x0) {
966
        /* unconditional not taken */
967
        if (a) {
968
            dc->pc = dc->npc + 4;
969
            dc->npc = dc->pc + 4;
970
        } else {
971
            dc->pc = dc->npc;
972
            dc->npc = dc->pc + 4;
973
        }
974
    } else if (cond == 0x8) {
975
        /* unconditional taken */
976
        if (a) {
977
            dc->pc = target;
978
            dc->npc = dc->pc + 4;
979
        } else {
980
            dc->pc = dc->npc;
981
            dc->npc = target;
982
        }
983
    } else {
984
        flush_T2(dc);
985
        gen_cond[cc][cond]();
986
        if (a) {
987
            gen_branch_a(dc, target, dc->npc);
988
            dc->is_br = 1;
989
        } else {
990
            dc->pc = dc->npc;
991
            dc->jump_pc[0] = target;
992
            dc->jump_pc[1] = dc->npc + 4;
993
            dc->npc = JUMP_PC;
994
        }
995
    }
996
}
997

    
998
/* XXX: potentially incorrect if dynamic npc */
999
static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
1000
{
1001
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
1002
    target_ulong target = dc->pc + offset;
1003

    
1004
    if (cond == 0x0) {
1005
        /* unconditional not taken */
1006
        if (a) {
1007
            dc->pc = dc->npc + 4;
1008
            dc->npc = dc->pc + 4;
1009
        } else {
1010
            dc->pc = dc->npc;
1011
            dc->npc = dc->pc + 4;
1012
        }
1013
    } else if (cond == 0x8) {
1014
        /* unconditional taken */
1015
        if (a) {
1016
            dc->pc = target;
1017
            dc->npc = dc->pc + 4;
1018
        } else {
1019
            dc->pc = dc->npc;
1020
            dc->npc = target;
1021
        }
1022
    } else {
1023
        flush_T2(dc);
1024
        gen_fcond[cc][cond]();
1025
        if (a) {
1026
            gen_branch_a(dc, target, dc->npc);
1027
            dc->is_br = 1;
1028
        } else {
1029
            dc->pc = dc->npc;
1030
            dc->jump_pc[0] = target;
1031
            dc->jump_pc[1] = dc->npc + 4;
1032
            dc->npc = JUMP_PC;
1033
        }
1034
    }
1035
}
1036

    
1037
#ifdef TARGET_SPARC64
1038
/* XXX: potentially incorrect if dynamic npc */
1039
static void do_branch_reg(DisasContext * dc, int32_t offset, uint32_t insn)
1040
{
1041
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
1042
    target_ulong target = dc->pc + offset;
1043

    
1044
    flush_T2(dc);
1045
    gen_cond_reg(cond);
1046
    if (a) {
1047
        gen_branch_a(dc, target, dc->npc);
1048
        dc->is_br = 1;
1049
    } else {
1050
        dc->pc = dc->npc;
1051
        dc->jump_pc[0] = target;
1052
        dc->jump_pc[1] = dc->npc + 4;
1053
        dc->npc = JUMP_PC;
1054
    }
1055
}
1056

    
1057
static GenOpFunc * const gen_fcmps[4] = {
1058
    gen_op_fcmps,
1059
    gen_op_fcmps_fcc1,
1060
    gen_op_fcmps_fcc2,
1061
    gen_op_fcmps_fcc3,
1062
};
1063

    
1064
static GenOpFunc * const gen_fcmpd[4] = {
1065
    gen_op_fcmpd,
1066
    gen_op_fcmpd_fcc1,
1067
    gen_op_fcmpd_fcc2,
1068
    gen_op_fcmpd_fcc3,
1069
};
1070

    
1071
#if defined(CONFIG_USER_ONLY)
1072
static GenOpFunc * const gen_fcmpq[4] = {
1073
    gen_op_fcmpq,
1074
    gen_op_fcmpq_fcc1,
1075
    gen_op_fcmpq_fcc2,
1076
    gen_op_fcmpq_fcc3,
1077
};
1078
#endif
1079

    
1080
static GenOpFunc * const gen_fcmpes[4] = {
1081
    gen_op_fcmpes,
1082
    gen_op_fcmpes_fcc1,
1083
    gen_op_fcmpes_fcc2,
1084
    gen_op_fcmpes_fcc3,
1085
};
1086

    
1087
static GenOpFunc * const gen_fcmped[4] = {
1088
    gen_op_fcmped,
1089
    gen_op_fcmped_fcc1,
1090
    gen_op_fcmped_fcc2,
1091
    gen_op_fcmped_fcc3,
1092
};
1093

    
1094
#if defined(CONFIG_USER_ONLY)
1095
static GenOpFunc * const gen_fcmpeq[4] = {
1096
    gen_op_fcmpeq,
1097
    gen_op_fcmpeq_fcc1,
1098
    gen_op_fcmpeq_fcc2,
1099
    gen_op_fcmpeq_fcc3,
1100
};
1101
#endif
1102
#endif
1103

    
1104
static int gen_trap_ifnofpu(DisasContext * dc)
1105
{
1106
#if !defined(CONFIG_USER_ONLY)
1107
    if (!dc->fpu_enabled) {
1108
        save_state(dc);
1109
        gen_op_exception(TT_NFPU_INSN);
1110
        dc->is_br = 1;
1111
        return 1;
1112
    }
1113
#endif
1114
    return 0;
1115
}
1116

    
1117
/* before an instruction, dc->pc must be static */
1118
static void disas_sparc_insn(DisasContext * dc)
1119
{
1120
    unsigned int insn, opc, rs1, rs2, rd;
1121

    
1122
    insn = ldl_code(dc->pc);
1123
    opc = GET_FIELD(insn, 0, 1);
1124

    
1125
    rd = GET_FIELD(insn, 2, 6);
1126
    switch (opc) {
1127
    case 0:                     /* branches/sethi */
1128
        {
1129
            unsigned int xop = GET_FIELD(insn, 7, 9);
1130
            int32_t target;
1131
            switch (xop) {
1132
#ifdef TARGET_SPARC64
1133
            case 0x1:           /* V9 BPcc */
1134
                {
1135
                    int cc;
1136

    
1137
                    target = GET_FIELD_SP(insn, 0, 18);
1138
                    target = sign_extend(target, 18);
1139
                    target <<= 2;
1140
                    cc = GET_FIELD_SP(insn, 20, 21);
1141
                    if (cc == 0)
1142
                        do_branch(dc, target, insn, 0);
1143
                    else if (cc == 2)
1144
                        do_branch(dc, target, insn, 1);
1145
                    else
1146
                        goto illegal_insn;
1147
                    goto jmp_insn;
1148
                }
1149
            case 0x3:           /* V9 BPr */
1150
                {
1151
                    target = GET_FIELD_SP(insn, 0, 13) |
1152
                        (GET_FIELD_SP(insn, 20, 21) << 14);
1153
                    target = sign_extend(target, 16);
1154
                    target <<= 2;
1155
                    rs1 = GET_FIELD(insn, 13, 17);
1156
                    gen_movl_reg_T0(rs1);
1157
                    do_branch_reg(dc, target, insn);
1158
                    goto jmp_insn;
1159
                }
1160
            case 0x5:           /* V9 FBPcc */
1161
                {
1162
                    int cc = GET_FIELD_SP(insn, 20, 21);
1163
                    if (gen_trap_ifnofpu(dc))
1164
                        goto jmp_insn;
1165
                    target = GET_FIELD_SP(insn, 0, 18);
1166
                    target = sign_extend(target, 19);
1167
                    target <<= 2;
1168
                    do_fbranch(dc, target, insn, cc);
1169
                    goto jmp_insn;
1170
                }
1171
#else
1172
            case 0x7:           /* CBN+x */
1173
                {
1174
                    goto ncp_insn;
1175
                }
1176
#endif
1177
            case 0x2:           /* BN+x */
1178
                {
1179
                    target = GET_FIELD(insn, 10, 31);
1180
                    target = sign_extend(target, 22);
1181
                    target <<= 2;
1182
                    do_branch(dc, target, insn, 0);
1183
                    goto jmp_insn;
1184
                }
1185
            case 0x6:           /* FBN+x */
1186
                {
1187
                    if (gen_trap_ifnofpu(dc))
1188
                        goto jmp_insn;
1189
                    target = GET_FIELD(insn, 10, 31);
1190
                    target = sign_extend(target, 22);
1191
                    target <<= 2;
1192
                    do_fbranch(dc, target, insn, 0);
1193
                    goto jmp_insn;
1194
                }
1195
            case 0x4:           /* SETHI */
1196
#define OPTIM
1197
#if defined(OPTIM)
1198
                if (rd) { // nop
1199
#endif
1200
                    uint32_t value = GET_FIELD(insn, 10, 31);
1201
                    gen_movl_imm_T0(value << 10);
1202
                    gen_movl_T0_reg(rd);
1203
#if defined(OPTIM)
1204
                }
1205
#endif
1206
                break;
1207
            case 0x0:           /* UNIMPL */
1208
            default:
1209
                goto illegal_insn;
1210
            }
1211
            break;
1212
        }
1213
        break;
1214
    case 1:
1215
        /*CALL*/ {
1216
            target_long target = GET_FIELDs(insn, 2, 31) << 2;
1217

    
1218
#ifdef TARGET_SPARC64
1219
            if (dc->pc == (uint32_t)dc->pc) {
1220
                gen_op_movl_T0_im(dc->pc);
1221
            } else {
1222
                gen_op_movq_T0_im64(dc->pc >> 32, dc->pc);
1223
            }
1224
#else
1225
            gen_op_movl_T0_im(dc->pc);
1226
#endif
1227
            gen_movl_T0_reg(15);
1228
            target += dc->pc;
1229
            gen_mov_pc_npc(dc);
1230
            dc->npc = target;
1231
        }
1232
        goto jmp_insn;
1233
    case 2:                     /* FPU & Logical Operations */
1234
        {
1235
            unsigned int xop = GET_FIELD(insn, 7, 12);
1236
            if (xop == 0x3a) {  /* generate trap */
1237
                int cond;
1238

    
1239
                rs1 = GET_FIELD(insn, 13, 17);
1240
                gen_movl_reg_T0(rs1);
1241
                if (IS_IMM) {
1242
                    rs2 = GET_FIELD(insn, 25, 31);
1243
#if defined(OPTIM)
1244
                    if (rs2 != 0) {
1245
#endif
1246
                        gen_movl_simm_T1(rs2);
1247
                        gen_op_add_T1_T0();
1248
#if defined(OPTIM)
1249
                    }
1250
#endif
1251
                } else {
1252
                    rs2 = GET_FIELD(insn, 27, 31);
1253
#if defined(OPTIM)
1254
                    if (rs2 != 0) {
1255
#endif
1256
                        gen_movl_reg_T1(rs2);
1257
                        gen_op_add_T1_T0();
1258
#if defined(OPTIM)
1259
                    }
1260
#endif
1261
                }
1262
                cond = GET_FIELD(insn, 3, 6);
1263
                if (cond == 0x8) {
1264
                    save_state(dc);
1265
                    gen_op_trap_T0();
1266
                } else if (cond != 0) {
1267
#ifdef TARGET_SPARC64
1268
                    /* V9 icc/xcc */
1269
                    int cc = GET_FIELD_SP(insn, 11, 12);
1270
                    flush_T2(dc);
1271
                    save_state(dc);
1272
                    if (cc == 0)
1273
                        gen_cond[0][cond]();
1274
                    else if (cc == 2)
1275
                        gen_cond[1][cond]();
1276
                    else
1277
                        goto illegal_insn;
1278
#else
1279
                    flush_T2(dc);
1280
                    save_state(dc);
1281
                    gen_cond[0][cond]();
1282
#endif
1283
                    gen_op_trapcc_T0();
1284
                }
1285
                gen_op_next_insn();
1286
                gen_op_movl_T0_0();
1287
                gen_op_exit_tb();
1288
                dc->is_br = 1;
1289
                goto jmp_insn;
1290
            } else if (xop == 0x28) {
1291
                rs1 = GET_FIELD(insn, 13, 17);
1292
                switch(rs1) {
1293
                case 0: /* rdy */
1294
#ifndef TARGET_SPARC64
1295
                case 0x01 ... 0x0e: /* undefined in the SPARCv8
1296
                                       manual, rdy on the microSPARC
1297
                                       II */
1298
                case 0x0f:          /* stbar in the SPARCv8 manual,
1299
                                       rdy on the microSPARC II */
1300
                case 0x10 ... 0x1f: /* implementation-dependent in the
1301
                                       SPARCv8 manual, rdy on the
1302
                                       microSPARC II */
1303
#endif
1304
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, y));
1305
                    gen_movl_T0_reg(rd);
1306
                    break;
1307
#ifdef TARGET_SPARC64
1308
                case 0x2: /* V9 rdccr */
1309
                    gen_op_rdccr();
1310
                    gen_movl_T0_reg(rd);
1311
                    break;
1312
                case 0x3: /* V9 rdasi */
1313
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, asi));
1314
                    gen_movl_T0_reg(rd);
1315
                    break;
1316
                case 0x4: /* V9 rdtick */
1317
                    gen_op_rdtick();
1318
                    gen_movl_T0_reg(rd);
1319
                    break;
1320
                case 0x5: /* V9 rdpc */
1321
                    if (dc->pc == (uint32_t)dc->pc) {
1322
                        gen_op_movl_T0_im(dc->pc);
1323
                    } else {
1324
                        gen_op_movq_T0_im64(dc->pc >> 32, dc->pc);
1325
                    }
1326
                    gen_movl_T0_reg(rd);
1327
                    break;
1328
                case 0x6: /* V9 rdfprs */
1329
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, fprs));
1330
                    gen_movl_T0_reg(rd);
1331
                    break;
1332
                case 0xf: /* V9 membar */
1333
                    break; /* no effect */
1334
                case 0x13: /* Graphics Status */
1335
                    if (gen_trap_ifnofpu(dc))
1336
                        goto jmp_insn;
1337
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, gsr));
1338
                    gen_movl_T0_reg(rd);
1339
                    break;
1340
                case 0x17: /* Tick compare */
1341
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, tick_cmpr));
1342
                    gen_movl_T0_reg(rd);
1343
                    break;
1344
                case 0x18: /* System tick */
1345
                    gen_op_rdstick();
1346
                    gen_movl_T0_reg(rd);
1347
                    break;
1348
                case 0x19: /* System tick compare */
1349
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, stick_cmpr));
1350
                    gen_movl_T0_reg(rd);
1351
                    break;
1352
                case 0x10: /* Performance Control */
1353
                case 0x11: /* Performance Instrumentation Counter */
1354
                case 0x12: /* Dispatch Control */
1355
                case 0x14: /* Softint set, WO */
1356
                case 0x15: /* Softint clear, WO */
1357
                case 0x16: /* Softint write */
1358
#endif
1359
                default:
1360
                    goto illegal_insn;
1361
                }
1362
#if !defined(CONFIG_USER_ONLY)
1363
            } else if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
1364
#ifndef TARGET_SPARC64
1365
                if (!supervisor(dc))
1366
                    goto priv_insn;
1367
                gen_op_rdpsr();
1368
#else
1369
                if (!hypervisor(dc))
1370
                    goto priv_insn;
1371
                rs1 = GET_FIELD(insn, 13, 17);
1372
                switch (rs1) {
1373
                case 0: // hpstate
1374
                    // gen_op_rdhpstate();
1375
                    break;
1376
                case 1: // htstate
1377
                    // gen_op_rdhtstate();
1378
                    break;
1379
                case 3: // hintp
1380
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, hintp));
1381
                    break;
1382
                case 5: // htba
1383
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, htba));
1384
                    break;
1385
                case 6: // hver
1386
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, hver));
1387
                    break;
1388
                case 31: // hstick_cmpr
1389
                    gen_op_movl_env_T0(offsetof(CPUSPARCState, hstick_cmpr));
1390
                    break;
1391
                default:
1392
                    goto illegal_insn;
1393
                }
1394
#endif
1395
                gen_movl_T0_reg(rd);
1396
                break;
1397
            } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
1398
                if (!supervisor(dc))
1399
                    goto priv_insn;
1400
#ifdef TARGET_SPARC64
1401
                rs1 = GET_FIELD(insn, 13, 17);
1402
                switch (rs1) {
1403
                case 0: // tpc
1404
                    gen_op_rdtpc();
1405
                    break;
1406
                case 1: // tnpc
1407
                    gen_op_rdtnpc();
1408
                    break;
1409
                case 2: // tstate
1410
                    gen_op_rdtstate();
1411
                    break;
1412
                case 3: // tt
1413
                    gen_op_rdtt();
1414
                    break;
1415
                case 4: // tick
1416
                    gen_op_rdtick();
1417
                    break;
1418
                case 5: // tba
1419
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
1420
                    break;
1421
                case 6: // pstate
1422
                    gen_op_rdpstate();
1423
                    break;
1424
                case 7: // tl
1425
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, tl));
1426
                    break;
1427
                case 8: // pil
1428
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, psrpil));
1429
                    break;
1430
                case 9: // cwp
1431
                    gen_op_rdcwp();
1432
                    break;
1433
                case 10: // cansave
1434
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, cansave));
1435
                    break;
1436
                case 11: // canrestore
1437
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, canrestore));
1438
                    break;
1439
                case 12: // cleanwin
1440
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, cleanwin));
1441
                    break;
1442
                case 13: // otherwin
1443
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, otherwin));
1444
                    break;
1445
                case 14: // wstate
1446
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, wstate));
1447
                    break;
1448
                case 16: // UA2005 gl
1449
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, gl));
1450
                    break;
1451
                case 26: // UA2005 strand status
1452
                    if (!hypervisor(dc))
1453
                        goto priv_insn;
1454
                    gen_op_movl_T0_env(offsetof(CPUSPARCState, ssr));
1455
                    break;
1456
                case 31: // ver
1457
                    gen_op_movtl_T0_env(offsetof(CPUSPARCState, version));
1458
                    break;
1459
                case 15: // fq
1460
                default:
1461
                    goto illegal_insn;
1462
                }
1463
#else
1464
                gen_op_movl_T0_env(offsetof(CPUSPARCState, wim));
1465
#endif
1466
                gen_movl_T0_reg(rd);
1467
                break;
1468
            } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
1469
#ifdef TARGET_SPARC64
1470
                gen_op_flushw();
1471
#else
1472
                if (!supervisor(dc))
1473
                    goto priv_insn;
1474
                gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
1475
                gen_movl_T0_reg(rd);
1476
#endif
1477
                break;
1478
#endif
1479
            } else if (xop == 0x34) {   /* FPU Operations */
1480
                if (gen_trap_ifnofpu(dc))
1481
                    goto jmp_insn;
1482
                gen_op_clear_ieee_excp_and_FTT();
1483
                rs1 = GET_FIELD(insn, 13, 17);
1484
                rs2 = GET_FIELD(insn, 27, 31);
1485
                xop = GET_FIELD(insn, 18, 26);
1486
                switch (xop) {
1487
                    case 0x1: /* fmovs */
1488
                        gen_op_load_fpr_FT0(rs2);
1489
                        gen_op_store_FT0_fpr(rd);
1490
                        break;
1491
                    case 0x5: /* fnegs */
1492
                        gen_op_load_fpr_FT1(rs2);
1493
                        gen_op_fnegs();
1494
                        gen_op_store_FT0_fpr(rd);
1495
                        break;
1496
                    case 0x9: /* fabss */
1497
                        gen_op_load_fpr_FT1(rs2);
1498
                        gen_op_fabss();
1499
                        gen_op_store_FT0_fpr(rd);
1500
                        break;
1501
                    case 0x29: /* fsqrts */
1502
                        gen_op_load_fpr_FT1(rs2);
1503
                        gen_op_fsqrts();
1504
                        gen_op_store_FT0_fpr(rd);
1505
                        break;
1506
                    case 0x2a: /* fsqrtd */
1507
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1508
                        gen_op_fsqrtd();
1509
                        gen_op_store_DT0_fpr(DFPREG(rd));
1510
                        break;
1511
                    case 0x2b: /* fsqrtq */
1512
#if defined(CONFIG_USER_ONLY)
1513
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1514
                        gen_op_fsqrtq();
1515
                        gen_op_store_QT0_fpr(QFPREG(rd));
1516
                        break;
1517
#else
1518
                        goto nfpu_insn;
1519
#endif
1520
                    case 0x41:
1521
                        gen_op_load_fpr_FT0(rs1);
1522
                        gen_op_load_fpr_FT1(rs2);
1523
                        gen_op_fadds();
1524
                        gen_op_store_FT0_fpr(rd);
1525
                        break;
1526
                    case 0x42:
1527
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1528
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1529
                        gen_op_faddd();
1530
                        gen_op_store_DT0_fpr(DFPREG(rd));
1531
                        break;
1532
                    case 0x43: /* faddq */
1533
#if defined(CONFIG_USER_ONLY)
1534
                        gen_op_load_fpr_QT0(QFPREG(rs1));
1535
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1536
                        gen_op_faddq();
1537
                        gen_op_store_QT0_fpr(QFPREG(rd));
1538
                        break;
1539
#else
1540
                        goto nfpu_insn;
1541
#endif
1542
                    case 0x45:
1543
                        gen_op_load_fpr_FT0(rs1);
1544
                        gen_op_load_fpr_FT1(rs2);
1545
                        gen_op_fsubs();
1546
                        gen_op_store_FT0_fpr(rd);
1547
                        break;
1548
                    case 0x46:
1549
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1550
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1551
                        gen_op_fsubd();
1552
                        gen_op_store_DT0_fpr(DFPREG(rd));
1553
                        break;
1554
                    case 0x47: /* fsubq */
1555
#if defined(CONFIG_USER_ONLY)
1556
                        gen_op_load_fpr_QT0(QFPREG(rs1));
1557
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1558
                        gen_op_fsubq();
1559
                        gen_op_store_QT0_fpr(QFPREG(rd));
1560
                        break;
1561
#else
1562
                        goto nfpu_insn;
1563
#endif
1564
                    case 0x49:
1565
                        gen_op_load_fpr_FT0(rs1);
1566
                        gen_op_load_fpr_FT1(rs2);
1567
                        gen_op_fmuls();
1568
                        gen_op_store_FT0_fpr(rd);
1569
                        break;
1570
                    case 0x4a:
1571
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1572
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1573
                        gen_op_fmuld();
1574
                        gen_op_store_DT0_fpr(rd);
1575
                        break;
1576
                    case 0x4b: /* fmulq */
1577
#if defined(CONFIG_USER_ONLY)
1578
                        gen_op_load_fpr_QT0(QFPREG(rs1));
1579
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1580
                        gen_op_fmulq();
1581
                        gen_op_store_QT0_fpr(QFPREG(rd));
1582
                        break;
1583
#else
1584
                        goto nfpu_insn;
1585
#endif
1586
                    case 0x4d:
1587
                        gen_op_load_fpr_FT0(rs1);
1588
                        gen_op_load_fpr_FT1(rs2);
1589
                        gen_op_fdivs();
1590
                        gen_op_store_FT0_fpr(rd);
1591
                        break;
1592
                    case 0x4e:
1593
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1594
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1595
                        gen_op_fdivd();
1596
                        gen_op_store_DT0_fpr(DFPREG(rd));
1597
                        break;
1598
                    case 0x4f: /* fdivq */
1599
#if defined(CONFIG_USER_ONLY)
1600
                        gen_op_load_fpr_QT0(QFPREG(rs1));
1601
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1602
                        gen_op_fdivq();
1603
                        gen_op_store_QT0_fpr(QFPREG(rd));
1604
                        break;
1605
#else
1606
                        goto nfpu_insn;
1607
#endif
1608
                    case 0x69:
1609
                        gen_op_load_fpr_FT0(rs1);
1610
                        gen_op_load_fpr_FT1(rs2);
1611
                        gen_op_fsmuld();
1612
                        gen_op_store_DT0_fpr(DFPREG(rd));
1613
                        break;
1614
                    case 0x6e: /* fdmulq */
1615
#if defined(CONFIG_USER_ONLY)
1616
                        gen_op_load_fpr_DT0(DFPREG(rs1));
1617
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1618
                        gen_op_fdmulq();
1619
                        gen_op_store_QT0_fpr(QFPREG(rd));
1620
                        break;
1621
#else
1622
                        goto nfpu_insn;
1623
#endif
1624
                    case 0xc4:
1625
                        gen_op_load_fpr_FT1(rs2);
1626
                        gen_op_fitos();
1627
                        gen_op_store_FT0_fpr(rd);
1628
                        break;
1629
                    case 0xc6:
1630
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1631
                        gen_op_fdtos();
1632
                        gen_op_store_FT0_fpr(rd);
1633
                        break;
1634
                    case 0xc7: /* fqtos */
1635
#if defined(CONFIG_USER_ONLY)
1636
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1637
                        gen_op_fqtos();
1638
                        gen_op_store_FT0_fpr(rd);
1639
                        break;
1640
#else
1641
                        goto nfpu_insn;
1642
#endif
1643
                    case 0xc8:
1644
                        gen_op_load_fpr_FT1(rs2);
1645
                        gen_op_fitod();
1646
                        gen_op_store_DT0_fpr(DFPREG(rd));
1647
                        break;
1648
                    case 0xc9:
1649
                        gen_op_load_fpr_FT1(rs2);
1650
                        gen_op_fstod();
1651
                        gen_op_store_DT0_fpr(DFPREG(rd));
1652
                        break;
1653
                    case 0xcb: /* fqtod */
1654
#if defined(CONFIG_USER_ONLY)
1655
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1656
                        gen_op_fqtod();
1657
                        gen_op_store_DT0_fpr(DFPREG(rd));
1658
                        break;
1659
#else
1660
                        goto nfpu_insn;
1661
#endif
1662
                    case 0xcc: /* fitoq */
1663
#if defined(CONFIG_USER_ONLY)
1664
                        gen_op_load_fpr_FT1(rs2);
1665
                        gen_op_fitoq();
1666
                        gen_op_store_QT0_fpr(QFPREG(rd));
1667
                        break;
1668
#else
1669
                        goto nfpu_insn;
1670
#endif
1671
                    case 0xcd: /* fstoq */
1672
#if defined(CONFIG_USER_ONLY)
1673
                        gen_op_load_fpr_FT1(rs2);
1674
                        gen_op_fstoq();
1675
                        gen_op_store_QT0_fpr(QFPREG(rd));
1676
                        break;
1677
#else
1678
                        goto nfpu_insn;
1679
#endif
1680
                    case 0xce: /* fdtoq */
1681
#if defined(CONFIG_USER_ONLY)
1682
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1683
                        gen_op_fdtoq();
1684
                        gen_op_store_QT0_fpr(QFPREG(rd));
1685
                        break;
1686
#else
1687
                        goto nfpu_insn;
1688
#endif
1689
                    case 0xd1:
1690
                        gen_op_load_fpr_FT1(rs2);
1691
                        gen_op_fstoi();
1692
                        gen_op_store_FT0_fpr(rd);
1693
                        break;
1694
                    case 0xd2:
1695
                        gen_op_load_fpr_DT1(rs2);
1696
                        gen_op_fdtoi();
1697
                        gen_op_store_FT0_fpr(rd);
1698
                        break;
1699
                    case 0xd3: /* fqtoi */
1700
#if defined(CONFIG_USER_ONLY)
1701
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1702
                        gen_op_fqtoi();
1703
                        gen_op_store_FT0_fpr(rd);
1704
                        break;
1705
#else
1706
                        goto nfpu_insn;
1707
#endif
1708
#ifdef TARGET_SPARC64
1709
                    case 0x2: /* V9 fmovd */
1710
                        gen_op_load_fpr_DT0(DFPREG(rs2));
1711
                        gen_op_store_DT0_fpr(DFPREG(rd));
1712
                        break;
1713
                    case 0x3: /* V9 fmovq */
1714
#if defined(CONFIG_USER_ONLY)
1715
                        gen_op_load_fpr_QT0(QFPREG(rs2));
1716
                        gen_op_store_QT0_fpr(QFPREG(rd));
1717
                        break;
1718
#else
1719
                        goto nfpu_insn;
1720
#endif
1721
                    case 0x6: /* V9 fnegd */
1722
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1723
                        gen_op_fnegd();
1724
                        gen_op_store_DT0_fpr(DFPREG(rd));
1725
                        break;
1726
                    case 0x7: /* V9 fnegq */
1727
#if defined(CONFIG_USER_ONLY)
1728
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1729
                        gen_op_fnegq();
1730
                        gen_op_store_QT0_fpr(QFPREG(rd));
1731
                        break;
1732
#else
1733
                        goto nfpu_insn;
1734
#endif
1735
                    case 0xa: /* V9 fabsd */
1736
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1737
                        gen_op_fabsd();
1738
                        gen_op_store_DT0_fpr(DFPREG(rd));
1739
                        break;
1740
                    case 0xb: /* V9 fabsq */
1741
#if defined(CONFIG_USER_ONLY)
1742
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1743
                        gen_op_fabsq();
1744
                        gen_op_store_QT0_fpr(QFPREG(rd));
1745
                        break;
1746
#else
1747
                        goto nfpu_insn;
1748
#endif
1749
                    case 0x81: /* V9 fstox */
1750
                        gen_op_load_fpr_FT1(rs2);
1751
                        gen_op_fstox();
1752
                        gen_op_store_DT0_fpr(DFPREG(rd));
1753
                        break;
1754
                    case 0x82: /* V9 fdtox */
1755
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1756
                        gen_op_fdtox();
1757
                        gen_op_store_DT0_fpr(DFPREG(rd));
1758
                        break;
1759
                    case 0x83: /* V9 fqtox */
1760
#if defined(CONFIG_USER_ONLY)
1761
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1762
                        gen_op_fqtox();
1763
                        gen_op_store_DT0_fpr(DFPREG(rd));
1764
                        break;
1765
#else
1766
                        goto nfpu_insn;
1767
#endif
1768
                    case 0x84: /* V9 fxtos */
1769
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1770
                        gen_op_fxtos();
1771
                        gen_op_store_FT0_fpr(rd);
1772
                        break;
1773
                    case 0x88: /* V9 fxtod */
1774
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1775
                        gen_op_fxtod();
1776
                        gen_op_store_DT0_fpr(DFPREG(rd));
1777
                        break;
1778
                    case 0x8c: /* V9 fxtoq */
1779
#if defined(CONFIG_USER_ONLY)
1780
                        gen_op_load_fpr_DT1(DFPREG(rs2));
1781
                        gen_op_fxtoq();
1782
                        gen_op_store_QT0_fpr(QFPREG(rd));
1783
                        break;
1784
#else
1785
                        goto nfpu_insn;
1786
#endif
1787
#endif
1788
                    default:
1789
                        goto illegal_insn;
1790
                }
1791
            } else if (xop == 0x35) {   /* FPU Operations */
1792
#ifdef TARGET_SPARC64
1793
                int cond;
1794
#endif
1795
                if (gen_trap_ifnofpu(dc))
1796
                    goto jmp_insn;
1797
                gen_op_clear_ieee_excp_and_FTT();
1798
                rs1 = GET_FIELD(insn, 13, 17);
1799
                rs2 = GET_FIELD(insn, 27, 31);
1800
                xop = GET_FIELD(insn, 18, 26);
1801
#ifdef TARGET_SPARC64
1802
                if ((xop & 0x11f) == 0x005) { // V9 fmovsr
1803
                    cond = GET_FIELD_SP(insn, 14, 17);
1804
                    gen_op_load_fpr_FT0(rd);
1805
                    gen_op_load_fpr_FT1(rs2);
1806
                    rs1 = GET_FIELD(insn, 13, 17);
1807
                    gen_movl_reg_T0(rs1);
1808
                    flush_T2(dc);
1809
                    gen_cond_reg(cond);
1810
                    gen_op_fmovs_cc();
1811
                    gen_op_store_FT0_fpr(rd);
1812
                    break;
1813
                } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
1814
                    cond = GET_FIELD_SP(insn, 14, 17);
1815
                    gen_op_load_fpr_DT0(rd);
1816
                    gen_op_load_fpr_DT1(rs2);
1817
                    flush_T2(dc);
1818
                    rs1 = GET_FIELD(insn, 13, 17);
1819
                    gen_movl_reg_T0(rs1);
1820
                    gen_cond_reg(cond);
1821
                    gen_op_fmovs_cc();
1822
                    gen_op_store_DT0_fpr(rd);
1823
                    break;
1824
                } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
1825
#if defined(CONFIG_USER_ONLY)
1826
                    cond = GET_FIELD_SP(insn, 14, 17);
1827
                    gen_op_load_fpr_QT0(QFPREG(rd));
1828
                    gen_op_load_fpr_QT1(QFPREG(rs2));
1829
                    flush_T2(dc);
1830
                    rs1 = GET_FIELD(insn, 13, 17);
1831
                    gen_movl_reg_T0(rs1);
1832
                    gen_cond_reg(cond);
1833
                    gen_op_fmovq_cc();
1834
                    gen_op_store_QT0_fpr(QFPREG(rd));
1835
                    break;
1836
#else
1837
                    goto nfpu_insn;
1838
#endif
1839
                }
1840
#endif
1841
                switch (xop) {
1842
#ifdef TARGET_SPARC64
1843
                    case 0x001: /* V9 fmovscc %fcc0 */
1844
                        cond = GET_FIELD_SP(insn, 14, 17);
1845
                        gen_op_load_fpr_FT0(rd);
1846
                        gen_op_load_fpr_FT1(rs2);
1847
                        flush_T2(dc);
1848
                        gen_fcond[0][cond]();
1849
                        gen_op_fmovs_cc();
1850
                        gen_op_store_FT0_fpr(rd);
1851
                        break;
1852
                    case 0x002: /* V9 fmovdcc %fcc0 */
1853
                        cond = GET_FIELD_SP(insn, 14, 17);
1854
                        gen_op_load_fpr_DT0(rd);
1855
                        gen_op_load_fpr_DT1(rs2);
1856
                        flush_T2(dc);
1857
                        gen_fcond[0][cond]();
1858
                        gen_op_fmovd_cc();
1859
                        gen_op_store_DT0_fpr(rd);
1860
                        break;
1861
                    case 0x003: /* V9 fmovqcc %fcc0 */
1862
#if defined(CONFIG_USER_ONLY)
1863
                        cond = GET_FIELD_SP(insn, 14, 17);
1864
                        gen_op_load_fpr_QT0(QFPREG(rd));
1865
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1866
                        flush_T2(dc);
1867
                        gen_fcond[0][cond]();
1868
                        gen_op_fmovq_cc();
1869
                        gen_op_store_QT0_fpr(QFPREG(rd));
1870
                        break;
1871
#else
1872
                        goto nfpu_insn;
1873
#endif
1874
                    case 0x041: /* V9 fmovscc %fcc1 */
1875
                        cond = GET_FIELD_SP(insn, 14, 17);
1876
                        gen_op_load_fpr_FT0(rd);
1877
                        gen_op_load_fpr_FT1(rs2);
1878
                        flush_T2(dc);
1879
                        gen_fcond[1][cond]();
1880
                        gen_op_fmovs_cc();
1881
                        gen_op_store_FT0_fpr(rd);
1882
                        break;
1883
                    case 0x042: /* V9 fmovdcc %fcc1 */
1884
                        cond = GET_FIELD_SP(insn, 14, 17);
1885
                        gen_op_load_fpr_DT0(rd);
1886
                        gen_op_load_fpr_DT1(rs2);
1887
                        flush_T2(dc);
1888
                        gen_fcond[1][cond]();
1889
                        gen_op_fmovd_cc();
1890
                        gen_op_store_DT0_fpr(rd);
1891
                        break;
1892
                    case 0x043: /* V9 fmovqcc %fcc1 */
1893
#if defined(CONFIG_USER_ONLY)
1894
                        cond = GET_FIELD_SP(insn, 14, 17);
1895
                        gen_op_load_fpr_QT0(QFPREG(rd));
1896
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1897
                        flush_T2(dc);
1898
                        gen_fcond[1][cond]();
1899
                        gen_op_fmovq_cc();
1900
                        gen_op_store_QT0_fpr(QFPREG(rd));
1901
                        break;
1902
#else
1903
                        goto nfpu_insn;
1904
#endif
1905
                    case 0x081: /* V9 fmovscc %fcc2 */
1906
                        cond = GET_FIELD_SP(insn, 14, 17);
1907
                        gen_op_load_fpr_FT0(rd);
1908
                        gen_op_load_fpr_FT1(rs2);
1909
                        flush_T2(dc);
1910
                        gen_fcond[2][cond]();
1911
                        gen_op_fmovs_cc();
1912
                        gen_op_store_FT0_fpr(rd);
1913
                        break;
1914
                    case 0x082: /* V9 fmovdcc %fcc2 */
1915
                        cond = GET_FIELD_SP(insn, 14, 17);
1916
                        gen_op_load_fpr_DT0(rd);
1917
                        gen_op_load_fpr_DT1(rs2);
1918
                        flush_T2(dc);
1919
                        gen_fcond[2][cond]();
1920
                        gen_op_fmovd_cc();
1921
                        gen_op_store_DT0_fpr(rd);
1922
                        break;
1923
                    case 0x083: /* V9 fmovqcc %fcc2 */
1924
#if defined(CONFIG_USER_ONLY)
1925
                        cond = GET_FIELD_SP(insn, 14, 17);
1926
                        gen_op_load_fpr_QT0(rd);
1927
                        gen_op_load_fpr_QT1(rs2);
1928
                        flush_T2(dc);
1929
                        gen_fcond[2][cond]();
1930
                        gen_op_fmovq_cc();
1931
                        gen_op_store_QT0_fpr(rd);
1932
                        break;
1933
#else
1934
                        goto nfpu_insn;
1935
#endif
1936
                    case 0x0c1: /* V9 fmovscc %fcc3 */
1937
                        cond = GET_FIELD_SP(insn, 14, 17);
1938
                        gen_op_load_fpr_FT0(rd);
1939
                        gen_op_load_fpr_FT1(rs2);
1940
                        flush_T2(dc);
1941
                        gen_fcond[3][cond]();
1942
                        gen_op_fmovs_cc();
1943
                        gen_op_store_FT0_fpr(rd);
1944
                        break;
1945
                    case 0x0c2: /* V9 fmovdcc %fcc3 */
1946
                        cond = GET_FIELD_SP(insn, 14, 17);
1947
                        gen_op_load_fpr_DT0(rd);
1948
                        gen_op_load_fpr_DT1(rs2);
1949
                        flush_T2(dc);
1950
                        gen_fcond[3][cond]();
1951
                        gen_op_fmovd_cc();
1952
                        gen_op_store_DT0_fpr(rd);
1953
                        break;
1954
                    case 0x0c3: /* V9 fmovqcc %fcc3 */
1955
#if defined(CONFIG_USER_ONLY)
1956
                        cond = GET_FIELD_SP(insn, 14, 17);
1957
                        gen_op_load_fpr_QT0(QFPREG(rd));
1958
                        gen_op_load_fpr_QT1(QFPREG(rs2));
1959
                        flush_T2(dc);
1960
                        gen_fcond[3][cond]();
1961
                        gen_op_fmovq_cc();
1962
                        gen_op_store_QT0_fpr(QFPREG(rd));
1963
                        break;
1964
#else
1965
                        goto nfpu_insn;
1966
#endif
1967
                    case 0x101: /* V9 fmovscc %icc */
1968
                        cond = GET_FIELD_SP(insn, 14, 17);
1969
                        gen_op_load_fpr_FT0(rd);
1970
                        gen_op_load_fpr_FT1(rs2);
1971
                        flush_T2(dc);
1972
                        gen_cond[0][cond]();
1973
                        gen_op_fmovs_cc();
1974
                        gen_op_store_FT0_fpr(rd);
1975
                        break;
1976
                    case 0x102: /* V9 fmovdcc %icc */
1977
                        cond = GET_FIELD_SP(insn, 14, 17);
1978
                        gen_op_load_fpr_DT0(rd);
1979
                        gen_op_load_fpr_DT1(rs2);
1980
                        flush_T2(dc);
1981
                        gen_cond[0][cond]();
1982
                        gen_op_fmovd_cc();
1983
                        gen_op_store_DT0_fpr(rd);
1984
                        break;
1985
                    case 0x103: /* V9 fmovqcc %icc */
1986
#if defined(CONFIG_USER_ONLY)
1987
                        cond = GET_FIELD_SP(insn, 14, 17);
1988
                        gen_op_load_fpr_QT0(rd);
1989
                        gen_op_load_fpr_QT1(rs2);
1990
                        flush_T2(dc);
1991
                        gen_cond[0][cond]();
1992
                        gen_op_fmovq_cc();
1993
                        gen_op_store_QT0_fpr(rd);
1994
                        break;
1995
#else
1996
                        goto nfpu_insn;
1997
#endif
1998
                    case 0x181: /* V9 fmovscc %xcc */
1999
                        cond = GET_FIELD_SP(insn, 14, 17);
2000
                        gen_op_load_fpr_FT0(rd);
2001
                        gen_op_load_fpr_FT1(rs2);
2002
                        flush_T2(dc);
2003
                        gen_cond[1][cond]();
2004
                        gen_op_fmovs_cc();
2005
                        gen_op_store_FT0_fpr(rd);
2006
                        break;
2007
                    case 0x182: /* V9 fmovdcc %xcc */
2008
                        cond = GET_FIELD_SP(insn, 14, 17);
2009
                        gen_op_load_fpr_DT0(rd);
2010
                        gen_op_load_fpr_DT1(rs2);
2011
                        flush_T2(dc);
2012
                        gen_cond[1][cond]();
2013
                        gen_op_fmovd_cc();
2014
                        gen_op_store_DT0_fpr(rd);
2015
                        break;
2016
                    case 0x183: /* V9 fmovqcc %xcc */
2017
#if defined(CONFIG_USER_ONLY)
2018
                        cond = GET_FIELD_SP(insn, 14, 17);
2019
                        gen_op_load_fpr_QT0(rd);
2020
                        gen_op_load_fpr_QT1(rs2);
2021
                        flush_T2(dc);
2022
                        gen_cond[1][cond]();
2023
                        gen_op_fmovq_cc();
2024
                        gen_op_store_QT0_fpr(rd);
2025
                        break;
2026
#else
2027
                        goto nfpu_insn;
2028
#endif
2029
#endif
2030
                    case 0x51: /* fcmps, V9 %fcc */
2031
                        gen_op_load_fpr_FT0(rs1);
2032
                        gen_op_load_fpr_FT1(rs2);
2033
#ifdef TARGET_SPARC64
2034
                        gen_fcmps[rd & 3]();
2035
#else
2036
                        gen_op_fcmps();
2037
#endif
2038
                        break;
2039
                    case 0x52: /* fcmpd, V9 %fcc */
2040
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2041
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2042
#ifdef TARGET_SPARC64
2043
                        gen_fcmpd[rd & 3]();
2044
#else
2045
                        gen_op_fcmpd();
2046
#endif
2047
                        break;
2048
                    case 0x53: /* fcmpq, V9 %fcc */
2049
#if defined(CONFIG_USER_ONLY)
2050
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2051
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2052
#ifdef TARGET_SPARC64
2053
                        gen_fcmpq[rd & 3]();
2054
#else
2055
                        gen_op_fcmpq();
2056
#endif
2057
                        break;
2058
#else /* !defined(CONFIG_USER_ONLY) */
2059
                        goto nfpu_insn;
2060
#endif
2061
                    case 0x55: /* fcmpes, V9 %fcc */
2062
                        gen_op_load_fpr_FT0(rs1);
2063
                        gen_op_load_fpr_FT1(rs2);
2064
#ifdef TARGET_SPARC64
2065
                        gen_fcmpes[rd & 3]();
2066
#else
2067
                        gen_op_fcmpes();
2068
#endif
2069
                        break;
2070
                    case 0x56: /* fcmped, V9 %fcc */
2071
                        gen_op_load_fpr_DT0(DFPREG(rs1));
2072
                        gen_op_load_fpr_DT1(DFPREG(rs2));
2073
#ifdef TARGET_SPARC64
2074
                        gen_fcmped[rd & 3]();
2075
#else
2076
                        gen_op_fcmped();
2077
#endif
2078
                        break;
2079
                    case 0x57: /* fcmpeq, V9 %fcc */
2080
#if defined(CONFIG_USER_ONLY)
2081
                        gen_op_load_fpr_QT0(QFPREG(rs1));
2082
                        gen_op_load_fpr_QT1(QFPREG(rs2));
2083
#ifdef TARGET_SPARC64
2084
                        gen_fcmpeq[rd & 3]();
2085
#else
2086
                        gen_op_fcmpeq();
2087
#endif
2088
                        break;
2089
#else/* !defined(CONFIG_USER_ONLY) */
2090
                        goto nfpu_insn;
2091
#endif
2092
                    default:
2093
                        goto illegal_insn;
2094
                }
2095
#if defined(OPTIM)
2096
            } else if (xop == 0x2) {
2097
                // clr/mov shortcut
2098

    
2099
                rs1 = GET_FIELD(insn, 13, 17);
2100
                if (rs1 == 0) {
2101
                    // or %g0, x, y -> mov T1, x; mov y, T1
2102
                    if (IS_IMM) {       /* immediate */
2103
                        rs2 = GET_FIELDs(insn, 19, 31);
2104
                        gen_movl_simm_T1(rs2);
2105
                    } else {            /* register */
2106
                        rs2 = GET_FIELD(insn, 27, 31);
2107
                        gen_movl_reg_T1(rs2);
2108
                    }
2109
                    gen_movl_T1_reg(rd);
2110
                } else {
2111
                    gen_movl_reg_T0(rs1);
2112
                    if (IS_IMM) {       /* immediate */
2113
                        // or x, #0, y -> mov T1, x; mov y, T1
2114
                        rs2 = GET_FIELDs(insn, 19, 31);
2115
                        if (rs2 != 0) {
2116
                            gen_movl_simm_T1(rs2);
2117
                            gen_op_or_T1_T0();
2118
                        }
2119
                    } else {            /* register */
2120
                        // or x, %g0, y -> mov T1, x; mov y, T1
2121
                        rs2 = GET_FIELD(insn, 27, 31);
2122
                        if (rs2 != 0) {
2123
                            gen_movl_reg_T1(rs2);
2124
                            gen_op_or_T1_T0();
2125
                        }
2126
                    }
2127
                    gen_movl_T0_reg(rd);
2128
                }
2129
#endif
2130
#ifdef TARGET_SPARC64
2131
            } else if (xop == 0x25) { /* sll, V9 sllx */
2132
                rs1 = GET_FIELD(insn, 13, 17);
2133
                gen_movl_reg_T0(rs1);
2134
                if (IS_IMM) {   /* immediate */
2135
                    rs2 = GET_FIELDs(insn, 20, 31);
2136
                    gen_movl_simm_T1(rs2);
2137
                } else {                /* register */
2138
                    rs2 = GET_FIELD(insn, 27, 31);
2139
                    gen_movl_reg_T1(rs2);
2140
                }
2141
                if (insn & (1 << 12))
2142
                    gen_op_sllx();
2143
                else
2144
                    gen_op_sll();
2145
                gen_movl_T0_reg(rd);
2146
            } else if (xop == 0x26) { /* srl, V9 srlx */
2147
                rs1 = GET_FIELD(insn, 13, 17);
2148
                gen_movl_reg_T0(rs1);
2149
                if (IS_IMM) {   /* immediate */
2150
                    rs2 = GET_FIELDs(insn, 20, 31);
2151
                    gen_movl_simm_T1(rs2);
2152
                } else {                /* register */
2153
                    rs2 = GET_FIELD(insn, 27, 31);
2154
                    gen_movl_reg_T1(rs2);
2155
                }
2156
                if (insn & (1 << 12))
2157
                    gen_op_srlx();
2158
                else
2159
                    gen_op_srl();
2160
                gen_movl_T0_reg(rd);
2161
            } else if (xop == 0x27) { /* sra, V9 srax */
2162
                rs1 = GET_FIELD(insn, 13, 17);
2163
                gen_movl_reg_T0(rs1);
2164
                if (IS_IMM) {   /* immediate */
2165
                    rs2 = GET_FIELDs(insn, 20, 31);
2166
                    gen_movl_simm_T1(rs2);
2167
                } else {                /* register */
2168
                    rs2 = GET_FIELD(insn, 27, 31);
2169
                    gen_movl_reg_T1(rs2);
2170
                }
2171
                if (insn & (1 << 12))
2172
                    gen_op_srax();
2173
                else
2174
                    gen_op_sra();
2175
                gen_movl_T0_reg(rd);
2176
#endif
2177
            } else if (xop < 0x36) {
2178
                rs1 = GET_FIELD(insn, 13, 17);
2179
                gen_movl_reg_T0(rs1);
2180
                if (IS_IMM) {   /* immediate */
2181
                    rs2 = GET_FIELDs(insn, 19, 31);
2182
                    gen_movl_simm_T1(rs2);
2183
                } else {                /* register */
2184
                    rs2 = GET_FIELD(insn, 27, 31);
2185
                    gen_movl_reg_T1(rs2);
2186
                }
2187
                if (xop < 0x20) {
2188
                    switch (xop & ~0x10) {
2189
                    case 0x0:
2190
                        if (xop & 0x10)
2191
                            gen_op_add_T1_T0_cc();
2192
                        else
2193
                            gen_op_add_T1_T0();
2194
                        break;
2195
                    case 0x1:
2196
                        gen_op_and_T1_T0();
2197
                        if (xop & 0x10)
2198
                            gen_op_logic_T0_cc();
2199
                        break;
2200
                    case 0x2:
2201
                        gen_op_or_T1_T0();
2202
                        if (xop & 0x10)
2203
                            gen_op_logic_T0_cc();
2204
                        break;
2205
                    case 0x3:
2206
                        gen_op_xor_T1_T0();
2207
                        if (xop & 0x10)
2208
                            gen_op_logic_T0_cc();
2209
                        break;
2210
                    case 0x4:
2211
                        if (xop & 0x10)
2212
                            gen_op_sub_T1_T0_cc();
2213
                        else
2214
                            gen_op_sub_T1_T0();
2215
                        break;
2216
                    case 0x5:
2217
                        gen_op_andn_T1_T0();
2218
                        if (xop & 0x10)
2219
                            gen_op_logic_T0_cc();
2220
                        break;
2221
                    case 0x6:
2222
                        gen_op_orn_T1_T0();
2223
                        if (xop & 0x10)
2224
                            gen_op_logic_T0_cc();
2225
                        break;
2226
                    case 0x7:
2227
                        gen_op_xnor_T1_T0();
2228
                        if (xop & 0x10)
2229
                            gen_op_logic_T0_cc();
2230
                        break;
2231
                    case 0x8:
2232
                        if (xop & 0x10)
2233
                            gen_op_addx_T1_T0_cc();
2234
                        else
2235
                            gen_op_addx_T1_T0();
2236
                        break;
2237
#ifdef TARGET_SPARC64
2238
                    case 0x9: /* V9 mulx */
2239
                        gen_op_mulx_T1_T0();
2240
                        break;
2241
#endif
2242
                    case 0xa:
2243
                        gen_op_umul_T1_T0();
2244
                        if (xop & 0x10)
2245
                            gen_op_logic_T0_cc();
2246
                        break;
2247
                    case 0xb:
2248
                        gen_op_smul_T1_T0();
2249
                        if (xop & 0x10)
2250
                            gen_op_logic_T0_cc();
2251
                        break;
2252
                    case 0xc:
2253
                        if (xop & 0x10)
2254
                            gen_op_subx_T1_T0_cc();
2255
                        else
2256
                            gen_op_subx_T1_T0();
2257
                        break;
2258
#ifdef TARGET_SPARC64
2259
                    case 0xd: /* V9 udivx */
2260
                        gen_op_udivx_T1_T0();
2261
                        break;
2262
#endif
2263
                    case 0xe:
2264
                        gen_op_udiv_T1_T0();
2265
                        if (xop & 0x10)
2266
                            gen_op_div_cc();
2267
                        break;
2268
                    case 0xf:
2269
                        gen_op_sdiv_T1_T0();
2270
                        if (xop & 0x10)
2271
                            gen_op_div_cc();
2272
                        break;
2273
                    default:
2274
                        goto illegal_insn;
2275
                    }
2276
                    gen_movl_T0_reg(rd);
2277
                } else {
2278
                    switch (xop) {
2279
                    case 0x20: /* taddcc */
2280
                        gen_op_tadd_T1_T0_cc();
2281
                        gen_movl_T0_reg(rd);
2282
                        break;
2283
                    case 0x21: /* tsubcc */
2284
                        gen_op_tsub_T1_T0_cc();
2285
                        gen_movl_T0_reg(rd);
2286
                        break;
2287
                    case 0x22: /* taddcctv */
2288
                        save_state(dc);
2289
                        gen_op_tadd_T1_T0_ccTV();
2290
                        gen_movl_T0_reg(rd);
2291
                        break;
2292
                    case 0x23: /* tsubcctv */
2293
                        save_state(dc);
2294
                        gen_op_tsub_T1_T0_ccTV();
2295
                        gen_movl_T0_reg(rd);
2296
                        break;
2297
                    case 0x24: /* mulscc */
2298
                        gen_op_mulscc_T1_T0();
2299
                        gen_movl_T0_reg(rd);
2300
                        break;
2301
#ifndef TARGET_SPARC64
2302
                    case 0x25:  /* sll */
2303
                        gen_op_sll();
2304
                        gen_movl_T0_reg(rd);
2305
                        break;
2306
                    case 0x26:  /* srl */
2307
                        gen_op_srl();
2308
                        gen_movl_T0_reg(rd);
2309
                        break;
2310
                    case 0x27:  /* sra */
2311
                        gen_op_sra();
2312
                        gen_movl_T0_reg(rd);
2313
                        break;
2314
#endif
2315
                    case 0x30:
2316
                        {
2317
                            switch(rd) {
2318
                            case 0: /* wry */
2319
                                gen_op_xor_T1_T0();
2320
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, y));
2321
                                break;
2322
#ifndef TARGET_SPARC64
2323
                            case 0x01 ... 0x0f: /* undefined in the
2324
                                                   SPARCv8 manual, nop
2325
                                                   on the microSPARC
2326
                                                   II */
2327
                            case 0x10 ... 0x1f: /* implementation-dependent
2328
                                                   in the SPARCv8
2329
                                                   manual, nop on the
2330
                                                   microSPARC II */
2331
                                break;
2332
#else
2333
                            case 0x2: /* V9 wrccr */
2334
                                gen_op_xor_T1_T0();
2335
                                gen_op_wrccr();
2336
                                break;
2337
                            case 0x3: /* V9 wrasi */
2338
                                gen_op_xor_T1_T0();
2339
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, asi));
2340
                                break;
2341
                            case 0x6: /* V9 wrfprs */
2342
                                gen_op_xor_T1_T0();
2343
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, fprs));
2344
                                save_state(dc);
2345
                                gen_op_next_insn();
2346
                                gen_op_movl_T0_0();
2347
                                gen_op_exit_tb();
2348
                                dc->is_br = 1;
2349
                                break;
2350
                            case 0xf: /* V9 sir, nop if user */
2351
#if !defined(CONFIG_USER_ONLY)
2352
                                if (supervisor(dc))
2353
                                    gen_op_sir();
2354
#endif
2355
                                break;
2356
                            case 0x13: /* Graphics Status */
2357
                                if (gen_trap_ifnofpu(dc))
2358
                                    goto jmp_insn;
2359
                                gen_op_xor_T1_T0();
2360
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, gsr));
2361
                                break;
2362
                            case 0x17: /* Tick compare */
2363
#if !defined(CONFIG_USER_ONLY)
2364
                                if (!supervisor(dc))
2365
                                    goto illegal_insn;
2366
#endif
2367
                                gen_op_xor_T1_T0();
2368
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, tick_cmpr));
2369
                                gen_op_wrtick_cmpr();
2370
                                break;
2371
                            case 0x18: /* System tick */
2372
#if !defined(CONFIG_USER_ONLY)
2373
                                if (!supervisor(dc))
2374
                                    goto illegal_insn;
2375
#endif
2376
                                gen_op_xor_T1_T0();
2377
                                gen_op_wrstick();
2378
                                break;
2379
                            case 0x19: /* System tick compare */
2380
#if !defined(CONFIG_USER_ONLY)
2381
                                if (!supervisor(dc))
2382
                                    goto illegal_insn;
2383
#endif
2384
                                gen_op_xor_T1_T0();
2385
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, stick_cmpr));
2386
                                gen_op_wrstick_cmpr();
2387
                                break;
2388

    
2389
                            case 0x10: /* Performance Control */
2390
                            case 0x11: /* Performance Instrumentation Counter */
2391
                            case 0x12: /* Dispatch Control */
2392
                            case 0x14: /* Softint set */
2393
                            case 0x15: /* Softint clear */
2394
                            case 0x16: /* Softint write */
2395
#endif
2396
                            default:
2397
                                goto illegal_insn;
2398
                            }
2399
                        }
2400
                        break;
2401
#if !defined(CONFIG_USER_ONLY)
2402
                    case 0x31: /* wrpsr, V9 saved, restored */
2403
                        {
2404
                            if (!supervisor(dc))
2405
                                goto priv_insn;
2406
#ifdef TARGET_SPARC64
2407
                            switch (rd) {
2408
                            case 0:
2409
                                gen_op_saved();
2410
                                break;
2411
                            case 1:
2412
                                gen_op_restored();
2413
                                break;
2414
                            case 2: /* UA2005 allclean */
2415
                            case 3: /* UA2005 otherw */
2416
                            case 4: /* UA2005 normalw */
2417
                            case 5: /* UA2005 invalw */
2418
                                // XXX
2419
                            default:
2420
                                goto illegal_insn;
2421
                            }
2422
#else
2423
                            gen_op_xor_T1_T0();
2424
                            gen_op_wrpsr();
2425
                            save_state(dc);
2426
                            gen_op_next_insn();
2427
                            gen_op_movl_T0_0();
2428
                            gen_op_exit_tb();
2429
                            dc->is_br = 1;
2430
#endif
2431
                        }
2432
                        break;
2433
                    case 0x32: /* wrwim, V9 wrpr */
2434
                        {
2435
                            if (!supervisor(dc))
2436
                                goto priv_insn;
2437
                            gen_op_xor_T1_T0();
2438
#ifdef TARGET_SPARC64
2439
                            switch (rd) {
2440
                            case 0: // tpc
2441
                                gen_op_wrtpc();
2442
                                break;
2443
                            case 1: // tnpc
2444
                                gen_op_wrtnpc();
2445
                                break;
2446
                            case 2: // tstate
2447
                                gen_op_wrtstate();
2448
                                break;
2449
                            case 3: // tt
2450
                                gen_op_wrtt();
2451
                                break;
2452
                            case 4: // tick
2453
                                gen_op_wrtick();
2454
                                break;
2455
                            case 5: // tba
2456
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
2457
                                break;
2458
                            case 6: // pstate
2459
                                gen_op_wrpstate();
2460
                                save_state(dc);
2461
                                gen_op_next_insn();
2462
                                gen_op_movl_T0_0();
2463
                                gen_op_exit_tb();
2464
                                dc->is_br = 1;
2465
                                break;
2466
                            case 7: // tl
2467
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, tl));
2468
                                break;
2469
                            case 8: // pil
2470
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, psrpil));
2471
                                break;
2472
                            case 9: // cwp
2473
                                gen_op_wrcwp();
2474
                                break;
2475
                            case 10: // cansave
2476
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, cansave));
2477
                                break;
2478
                            case 11: // canrestore
2479
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, canrestore));
2480
                                break;
2481
                            case 12: // cleanwin
2482
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, cleanwin));
2483
                                break;
2484
                            case 13: // otherwin
2485
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, otherwin));
2486
                                break;
2487
                            case 14: // wstate
2488
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, wstate));
2489
                                break;
2490
                            case 16: // UA2005 gl
2491
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, gl));
2492
                                break;
2493
                            case 26: // UA2005 strand status
2494
                                if (!hypervisor(dc))
2495
                                    goto priv_insn;
2496
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, ssr));
2497
                                break;
2498
                            default:
2499
                                goto illegal_insn;
2500
                            }
2501
#else
2502
                            gen_op_wrwim();
2503
#endif
2504
                        }
2505
                        break;
2506
                    case 0x33: /* wrtbr, UA2005 wrhpr */
2507
                        {
2508
#ifndef TARGET_SPARC64
2509
                            if (!supervisor(dc))
2510
                                goto priv_insn;
2511
                            gen_op_xor_T1_T0();
2512
                            gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
2513
#else
2514
                            if (!hypervisor(dc))
2515
                                goto priv_insn;
2516
                            gen_op_xor_T1_T0();
2517
                            switch (rd) {
2518
                            case 0: // hpstate
2519
                                // XXX gen_op_wrhpstate();
2520
                                save_state(dc);
2521
                                gen_op_next_insn();
2522
                                gen_op_movl_T0_0();
2523
                                gen_op_exit_tb();
2524
                                dc->is_br = 1;
2525
                                break;
2526
                            case 1: // htstate
2527
                                // XXX gen_op_wrhtstate();
2528
                                break;
2529
                            case 3: // hintp
2530
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, hintp));
2531
                                break;
2532
                            case 5: // htba
2533
                                gen_op_movl_env_T0(offsetof(CPUSPARCState, htba));
2534
                                break;
2535
                            case 31: // hstick_cmpr
2536
                                gen_op_movtl_env_T0(offsetof(CPUSPARCState, hstick_cmpr));
2537
                                gen_op_wrhstick_cmpr();
2538
                                break;
2539
                            case 6: // hver readonly
2540
                            default:
2541
                                goto illegal_insn;
2542
                            }
2543
#endif
2544
                        }
2545
                        break;
2546
#endif
2547
#ifdef TARGET_SPARC64
2548
                    case 0x2c: /* V9 movcc */
2549
                        {
2550
                            int cc = GET_FIELD_SP(insn, 11, 12);
2551
                            int cond = GET_FIELD_SP(insn, 14, 17);
2552
                            if (IS_IMM) {       /* immediate */
2553
                                rs2 = GET_FIELD_SPs(insn, 0, 10);
2554
                                gen_movl_simm_T1(rs2);
2555
                            }
2556
                            else {
2557
                                rs2 = GET_FIELD_SP(insn, 0, 4);
2558
                                gen_movl_reg_T1(rs2);
2559
                            }
2560
                            gen_movl_reg_T0(rd);
2561
                            flush_T2(dc);
2562
                            if (insn & (1 << 18)) {
2563
                                if (cc == 0)
2564
                                    gen_cond[0][cond]();
2565
                                else if (cc == 2)
2566
                                    gen_cond[1][cond]();
2567
                                else
2568
                                    goto illegal_insn;
2569
                            } else {
2570
                                gen_fcond[cc][cond]();
2571
                            }
2572
                            gen_op_mov_cc();
2573
                            gen_movl_T0_reg(rd);
2574
                            break;
2575
                        }
2576
                    case 0x2d: /* V9 sdivx */
2577
                        gen_op_sdivx_T1_T0();
2578
                        gen_movl_T0_reg(rd);
2579
                        break;
2580
                    case 0x2e: /* V9 popc */
2581
                        {
2582
                            if (IS_IMM) {       /* immediate */
2583
                                rs2 = GET_FIELD_SPs(insn, 0, 12);
2584
                                gen_movl_simm_T1(rs2);
2585
                                // XXX optimize: popc(constant)
2586
                            }
2587
                            else {
2588
                                rs2 = GET_FIELD_SP(insn, 0, 4);
2589
                                gen_movl_reg_T1(rs2);
2590
                            }
2591
                            gen_op_popc();
2592
                            gen_movl_T0_reg(rd);
2593
                        }
2594
                    case 0x2f: /* V9 movr */
2595
                        {
2596
                            int cond = GET_FIELD_SP(insn, 10, 12);
2597
                            rs1 = GET_FIELD(insn, 13, 17);
2598
                            flush_T2(dc);
2599
                            gen_movl_reg_T0(rs1);
2600
                            gen_cond_reg(cond);
2601
                            if (IS_IMM) {       /* immediate */
2602
                                rs2 = GET_FIELD_SPs(insn, 0, 9);
2603
                                gen_movl_simm_T1(rs2);
2604
                            }
2605
                            else {
2606
                                rs2 = GET_FIELD_SP(insn, 0, 4);
2607
                                gen_movl_reg_T1(rs2);
2608
                            }
2609
                            gen_movl_reg_T0(rd);
2610
                            gen_op_mov_cc();
2611
                            gen_movl_T0_reg(rd);
2612
                            break;
2613
                        }
2614
#endif
2615
                    default:
2616
                        goto illegal_insn;
2617
                    }
2618
                }
2619
            } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
2620
#ifdef TARGET_SPARC64
2621
                int opf = GET_FIELD_SP(insn, 5, 13);
2622
                rs1 = GET_FIELD(insn, 13, 17);
2623
                rs2 = GET_FIELD(insn, 27, 31);
2624
                if (gen_trap_ifnofpu(dc))
2625
                    goto jmp_insn;
2626

    
2627
                switch (opf) {
2628
                case 0x000: /* VIS I edge8cc */
2629
                case 0x001: /* VIS II edge8n */
2630
                case 0x002: /* VIS I edge8lcc */
2631
                case 0x003: /* VIS II edge8ln */
2632
                case 0x004: /* VIS I edge16cc */
2633
                case 0x005: /* VIS II edge16n */
2634
                case 0x006: /* VIS I edge16lcc */
2635
                case 0x007: /* VIS II edge16ln */
2636
                case 0x008: /* VIS I edge32cc */
2637
                case 0x009: /* VIS II edge32n */
2638
                case 0x00a: /* VIS I edge32lcc */
2639
                case 0x00b: /* VIS II edge32ln */
2640
                    // XXX
2641
                    goto illegal_insn;
2642
                case 0x010: /* VIS I array8 */
2643
                    gen_movl_reg_T0(rs1);
2644
                    gen_movl_reg_T1(rs2);
2645
                    gen_op_array8();
2646
                    gen_movl_T0_reg(rd);
2647
                    break;
2648
                case 0x012: /* VIS I array16 */
2649
                    gen_movl_reg_T0(rs1);
2650
                    gen_movl_reg_T1(rs2);
2651
                    gen_op_array16();
2652
                    gen_movl_T0_reg(rd);
2653
                    break;
2654
                case 0x014: /* VIS I array32 */
2655
                    gen_movl_reg_T0(rs1);
2656
                    gen_movl_reg_T1(rs2);
2657
                    gen_op_array32();
2658
                    gen_movl_T0_reg(rd);
2659
                    break;
2660
                case 0x018: /* VIS I alignaddr */
2661
                    gen_movl_reg_T0(rs1);
2662
                    gen_movl_reg_T1(rs2);
2663
                    gen_op_alignaddr();
2664
                    gen_movl_T0_reg(rd);
2665
                    break;
2666
                case 0x019: /* VIS II bmask */
2667
                case 0x01a: /* VIS I alignaddrl */
2668
                    // XXX
2669
                    goto illegal_insn;
2670
                case 0x020: /* VIS I fcmple16 */
2671
                    gen_op_load_fpr_DT0(rs1);
2672
                    gen_op_load_fpr_DT1(rs2);
2673
                    gen_op_fcmple16();
2674
                    gen_op_store_DT0_fpr(rd);
2675
                    break;
2676
                case 0x022: /* VIS I fcmpne16 */
2677
                    gen_op_load_fpr_DT0(rs1);
2678
                    gen_op_load_fpr_DT1(rs2);
2679
                    gen_op_fcmpne16();
2680
                    gen_op_store_DT0_fpr(rd);
2681
                    break;
2682
                case 0x024: /* VIS I fcmple32 */
2683
                    gen_op_load_fpr_DT0(rs1);
2684
                    gen_op_load_fpr_DT1(rs2);
2685
                    gen_op_fcmple32();
2686
                    gen_op_store_DT0_fpr(rd);
2687
                    break;
2688
                case 0x026: /* VIS I fcmpne32 */
2689
                    gen_op_load_fpr_DT0(rs1);
2690
                    gen_op_load_fpr_DT1(rs2);
2691
                    gen_op_fcmpne32();
2692
                    gen_op_store_DT0_fpr(rd);
2693
                    break;
2694
                case 0x028: /* VIS I fcmpgt16 */
2695
                    gen_op_load_fpr_DT0(rs1);
2696
                    gen_op_load_fpr_DT1(rs2);
2697
                    gen_op_fcmpgt16();
2698
                    gen_op_store_DT0_fpr(rd);
2699
                    break;
2700
                case 0x02a: /* VIS I fcmpeq16 */
2701
                    gen_op_load_fpr_DT0(rs1);
2702
                    gen_op_load_fpr_DT1(rs2);
2703
                    gen_op_fcmpeq16();
2704
                    gen_op_store_DT0_fpr(rd);
2705
                    break;
2706
                case 0x02c: /* VIS I fcmpgt32 */
2707
                    gen_op_load_fpr_DT0(rs1);
2708
                    gen_op_load_fpr_DT1(rs2);
2709
                    gen_op_fcmpgt32();
2710
                    gen_op_store_DT0_fpr(rd);
2711
                    break;
2712
                case 0x02e: /* VIS I fcmpeq32 */
2713
                    gen_op_load_fpr_DT0(rs1);
2714
                    gen_op_load_fpr_DT1(rs2);
2715
                    gen_op_fcmpeq32();
2716
                    gen_op_store_DT0_fpr(rd);
2717
                    break;
2718
                case 0x031: /* VIS I fmul8x16 */
2719
                    gen_op_load_fpr_DT0(rs1);
2720
                    gen_op_load_fpr_DT1(rs2);
2721
                    gen_op_fmul8x16();
2722
                    gen_op_store_DT0_fpr(rd);
2723
                    break;
2724
                case 0x033: /* VIS I fmul8x16au */
2725
                    gen_op_load_fpr_DT0(rs1);
2726
                    gen_op_load_fpr_DT1(rs2);
2727
                    gen_op_fmul8x16au();
2728
                    gen_op_store_DT0_fpr(rd);
2729
                    break;
2730
                case 0x035: /* VIS I fmul8x16al */
2731
                    gen_op_load_fpr_DT0(rs1);
2732
                    gen_op_load_fpr_DT1(rs2);
2733
                    gen_op_fmul8x16al();
2734
                    gen_op_store_DT0_fpr(rd);
2735
                    break;
2736
                case 0x036: /* VIS I fmul8sux16 */
2737
                    gen_op_load_fpr_DT0(rs1);
2738
                    gen_op_load_fpr_DT1(rs2);
2739
                    gen_op_fmul8sux16();
2740
                    gen_op_store_DT0_fpr(rd);
2741
                    break;
2742
                case 0x037: /* VIS I fmul8ulx16 */
2743
                    gen_op_load_fpr_DT0(rs1);
2744
                    gen_op_load_fpr_DT1(rs2);
2745
                    gen_op_fmul8ulx16();
2746
                    gen_op_store_DT0_fpr(rd);
2747
                    break;
2748
                case 0x038: /* VIS I fmuld8sux16 */
2749
                    gen_op_load_fpr_DT0(rs1);
2750
                    gen_op_load_fpr_DT1(rs2);
2751
                    gen_op_fmuld8sux16();
2752
                    gen_op_store_DT0_fpr(rd);
2753
                    break;
2754
                case 0x039: /* VIS I fmuld8ulx16 */
2755
                    gen_op_load_fpr_DT0(rs1);
2756
                    gen_op_load_fpr_DT1(rs2);
2757
                    gen_op_fmuld8ulx16();
2758
                    gen_op_store_DT0_fpr(rd);
2759
                    break;
2760
                case 0x03a: /* VIS I fpack32 */
2761
                case 0x03b: /* VIS I fpack16 */
2762
                case 0x03d: /* VIS I fpackfix */
2763
                case 0x03e: /* VIS I pdist */
2764
                    // XXX
2765
                    goto illegal_insn;
2766
                case 0x048: /* VIS I faligndata */
2767
                    gen_op_load_fpr_DT0(rs1);
2768
                    gen_op_load_fpr_DT1(rs2);
2769
                    gen_op_faligndata();
2770
                    gen_op_store_DT0_fpr(rd);
2771
                    break;
2772
                case 0x04b: /* VIS I fpmerge */
2773
                    gen_op_load_fpr_DT0(rs1);
2774
                    gen_op_load_fpr_DT1(rs2);
2775
                    gen_op_fpmerge();
2776
                    gen_op_store_DT0_fpr(rd);
2777
                    break;
2778
                case 0x04c: /* VIS II bshuffle */
2779
                    // XXX
2780
                    goto illegal_insn;
2781
                case 0x04d: /* VIS I fexpand */
2782
                    gen_op_load_fpr_DT0(rs1);
2783
                    gen_op_load_fpr_DT1(rs2);
2784
                    gen_op_fexpand();
2785
                    gen_op_store_DT0_fpr(rd);
2786
                    break;
2787
                case 0x050: /* VIS I fpadd16 */
2788
                    gen_op_load_fpr_DT0(rs1);
2789
                    gen_op_load_fpr_DT1(rs2);
2790
                    gen_op_fpadd16();
2791
                    gen_op_store_DT0_fpr(rd);
2792
                    break;
2793
                case 0x051: /* VIS I fpadd16s */
2794
                    gen_op_load_fpr_FT0(rs1);
2795
                    gen_op_load_fpr_FT1(rs2);
2796
                    gen_op_fpadd16s();
2797
                    gen_op_store_FT0_fpr(rd);
2798
                    break;
2799
                case 0x052: /* VIS I fpadd32 */
2800
                    gen_op_load_fpr_DT0(rs1);
2801
                    gen_op_load_fpr_DT1(rs2);
2802
                    gen_op_fpadd32();
2803
                    gen_op_store_DT0_fpr(rd);
2804
                    break;
2805
                case 0x053: /* VIS I fpadd32s */
2806
                    gen_op_load_fpr_FT0(rs1);
2807
                    gen_op_load_fpr_FT1(rs2);
2808
                    gen_op_fpadd32s();
2809
                    gen_op_store_FT0_fpr(rd);
2810
                    break;
2811
                case 0x054: /* VIS I fpsub16 */
2812
                    gen_op_load_fpr_DT0(rs1);
2813
                    gen_op_load_fpr_DT1(rs2);
2814
                    gen_op_fpsub16();
2815
                    gen_op_store_DT0_fpr(rd);
2816
                    break;
2817
                case 0x055: /* VIS I fpsub16s */
2818
                    gen_op_load_fpr_FT0(rs1);
2819
                    gen_op_load_fpr_FT1(rs2);
2820
                    gen_op_fpsub16s();
2821
                    gen_op_store_FT0_fpr(rd);
2822
                    break;
2823
                case 0x056: /* VIS I fpsub32 */
2824
                    gen_op_load_fpr_DT0(rs1);
2825
                    gen_op_load_fpr_DT1(rs2);
2826
                    gen_op_fpadd32();
2827
                    gen_op_store_DT0_fpr(rd);
2828
                    break;
2829
                case 0x057: /* VIS I fpsub32s */
2830
                    gen_op_load_fpr_FT0(rs1);
2831
                    gen_op_load_fpr_FT1(rs2);
2832
                    gen_op_fpsub32s();
2833
                    gen_op_store_FT0_fpr(rd);
2834
                    break;
2835
                case 0x060: /* VIS I fzero */
2836
                    gen_op_movl_DT0_0();
2837
                    gen_op_store_DT0_fpr(rd);
2838
                    break;
2839
                case 0x061: /* VIS I fzeros */
2840
                    gen_op_movl_FT0_0();
2841
                    gen_op_store_FT0_fpr(rd);
2842
                    break;
2843
                case 0x062: /* VIS I fnor */
2844
                    gen_op_load_fpr_DT0(rs1);
2845
                    gen_op_load_fpr_DT1(rs2);
2846
                    gen_op_fnor();
2847
                    gen_op_store_DT0_fpr(rd);
2848
                    break;
2849
                case 0x063: /* VIS I fnors */
2850
                    gen_op_load_fpr_FT0(rs1);
2851
                    gen_op_load_fpr_FT1(rs2);
2852
                    gen_op_fnors();
2853
                    gen_op_store_FT0_fpr(rd);
2854
                    break;
2855
                case 0x064: /* VIS I fandnot2 */
2856
                    gen_op_load_fpr_DT1(rs1);
2857
                    gen_op_load_fpr_DT0(rs2);
2858
                    gen_op_fandnot();
2859
                    gen_op_store_DT0_fpr(rd);
2860
                    break;
2861
                case 0x065: /* VIS I fandnot2s */
2862
                    gen_op_load_fpr_FT1(rs1);
2863
                    gen_op_load_fpr_FT0(rs2);
2864
                    gen_op_fandnots();
2865
                    gen_op_store_FT0_fpr(rd);
2866
                    break;
2867
                case 0x066: /* VIS I fnot2 */
2868
                    gen_op_load_fpr_DT1(rs2);
2869
                    gen_op_fnot();
2870
                    gen_op_store_DT0_fpr(rd);
2871
                    break;
2872
                case 0x067: /* VIS I fnot2s */
2873
                    gen_op_load_fpr_FT1(rs2);
2874
                    gen_op_fnot();
2875
                    gen_op_store_FT0_fpr(rd);
2876
                    break;
2877
                case 0x068: /* VIS I fandnot1 */
2878
                    gen_op_load_fpr_DT0(rs1);
2879
                    gen_op_load_fpr_DT1(rs2);
2880
                    gen_op_fandnot();
2881
                    gen_op_store_DT0_fpr(rd);
2882
                    break;
2883
                case 0x069: /* VIS I fandnot1s */
2884
                    gen_op_load_fpr_FT0(rs1);
2885
                    gen_op_load_fpr_FT1(rs2);
2886
                    gen_op_fandnots();
2887
                    gen_op_store_FT0_fpr(rd);
2888
                    break;
2889
                case 0x06a: /* VIS I fnot1 */
2890
                    gen_op_load_fpr_DT1(rs1);
2891
                    gen_op_fnot();
2892
                    gen_op_store_DT0_fpr(rd);
2893
                    break;
2894
                case 0x06b: /* VIS I fnot1s */
2895
                    gen_op_load_fpr_FT1(rs1);
2896
                    gen_op_fnot();
2897
                    gen_op_store_FT0_fpr(rd);
2898
                    break;
2899
                case 0x06c: /* VIS I fxor */
2900
                    gen_op_load_fpr_DT0(rs1);
2901
                    gen_op_load_fpr_DT1(rs2);
2902
                    gen_op_fxor();
2903
                    gen_op_store_DT0_fpr(rd);
2904
                    break;
2905
                case 0x06d: /* VIS I fxors */
2906
                    gen_op_load_fpr_FT0(rs1);
2907
                    gen_op_load_fpr_FT1(rs2);
2908
                    gen_op_fxors();
2909
                    gen_op_store_FT0_fpr(rd);
2910
                    break;
2911
                case 0x06e: /* VIS I fnand */
2912
                    gen_op_load_fpr_DT0(rs1);
2913
                    gen_op_load_fpr_DT1(rs2);
2914
                    gen_op_fnand();
2915
                    gen_op_store_DT0_fpr(rd);
2916
                    break;
2917
                case 0x06f: /* VIS I fnands */
2918
                    gen_op_load_fpr_FT0(rs1);
2919
                    gen_op_load_fpr_FT1(rs2);
2920
                    gen_op_fnands();
2921
                    gen_op_store_FT0_fpr(rd);
2922
                    break;
2923
                case 0x070: /* VIS I fand */
2924
                    gen_op_load_fpr_DT0(rs1);
2925
                    gen_op_load_fpr_DT1(rs2);
2926
                    gen_op_fand();
2927
                    gen_op_store_DT0_fpr(rd);
2928
                    break;
2929
                case 0x071: /* VIS I fands */
2930
                    gen_op_load_fpr_FT0(rs1);
2931
                    gen_op_load_fpr_FT1(rs2);
2932
                    gen_op_fands();
2933
                    gen_op_store_FT0_fpr(rd);
2934
                    break;
2935
                case 0x072: /* VIS I fxnor */
2936
                    gen_op_load_fpr_DT0(rs1);
2937
                    gen_op_load_fpr_DT1(rs2);
2938
                    gen_op_fxnor();
2939
                    gen_op_store_DT0_fpr(rd);
2940
                    break;
2941
                case 0x073: /* VIS I fxnors */
2942
                    gen_op_load_fpr_FT0(rs1);
2943
                    gen_op_load_fpr_FT1(rs2);
2944
                    gen_op_fxnors();
2945
                    gen_op_store_FT0_fpr(rd);
2946
                    break;
2947
                case 0x074: /* VIS I fsrc1 */
2948
                    gen_op_load_fpr_DT0(rs1);
2949
                    gen_op_store_DT0_fpr(rd);
2950
                    break;
2951
                case 0x075: /* VIS I fsrc1s */
2952
                    gen_op_load_fpr_FT0(rs1);
2953
                    gen_op_store_FT0_fpr(rd);
2954
                    break;
2955
                case 0x076: /* VIS I fornot2 */
2956
                    gen_op_load_fpr_DT1(rs1);
2957
                    gen_op_load_fpr_DT0(rs2);
2958
                    gen_op_fornot();
2959
                    gen_op_store_DT0_fpr(rd);
2960
                    break;
2961
                case 0x077: /* VIS I fornot2s */
2962
                    gen_op_load_fpr_FT1(rs1);
2963
                    gen_op_load_fpr_FT0(rs2);
2964
                    gen_op_fornots();
2965
                    gen_op_store_FT0_fpr(rd);
2966
                    break;
2967
                case 0x078: /* VIS I fsrc2 */
2968
                    gen_op_load_fpr_DT0(rs2);
2969
                    gen_op_store_DT0_fpr(rd);
2970
                    break;
2971
                case 0x079: /* VIS I fsrc2s */
2972
                    gen_op_load_fpr_FT0(rs2);
2973
                    gen_op_store_FT0_fpr(rd);
2974
                    break;
2975
                case 0x07a: /* VIS I fornot1 */
2976
                    gen_op_load_fpr_DT0(rs1);
2977
                    gen_op_load_fpr_DT1(rs2);
2978
                    gen_op_fornot();
2979
                    gen_op_store_DT0_fpr(rd);
2980
                    break;
2981
                case 0x07b: /* VIS I fornot1s */
2982
                    gen_op_load_fpr_FT0(rs1);
2983
                    gen_op_load_fpr_FT1(rs2);
2984
                    gen_op_fornots();
2985
                    gen_op_store_FT0_fpr(rd);
2986
                    break;
2987
                case 0x07c: /* VIS I for */
2988
                    gen_op_load_fpr_DT0(rs1);
2989
                    gen_op_load_fpr_DT1(rs2);
2990
                    gen_op_for();
2991
                    gen_op_store_DT0_fpr(rd);
2992
                    break;
2993
                case 0x07d: /* VIS I fors */
2994
                    gen_op_load_fpr_FT0(rs1);
2995
                    gen_op_load_fpr_FT1(rs2);
2996
                    gen_op_fors();
2997
                    gen_op_store_FT0_fpr(rd);
2998
                    break;
2999
                case 0x07e: /* VIS I fone */
3000
                    gen_op_movl_DT0_1();
3001
                    gen_op_store_DT0_fpr(rd);
3002
                    break;
3003
                case 0x07f: /* VIS I fones */
3004
                    gen_op_movl_FT0_1();
3005
                    gen_op_store_FT0_fpr(rd);
3006
                    break;
3007
                case 0x080: /* VIS I shutdown */
3008
                case 0x081: /* VIS II siam */
3009
                    // XXX
3010
                    goto illegal_insn;
3011
                default:
3012
                    goto illegal_insn;
3013
                }
3014
#else
3015
                goto ncp_insn;
3016
#endif
3017
            } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
3018
#ifdef TARGET_SPARC64
3019
                goto illegal_insn;
3020
#else
3021
                goto ncp_insn;
3022
#endif
3023
#ifdef TARGET_SPARC64
3024
            } else if (xop == 0x39) { /* V9 return */
3025
                rs1 = GET_FIELD(insn, 13, 17);
3026
                save_state(dc);
3027
                gen_movl_reg_T0(rs1);
3028
                if (IS_IMM) {   /* immediate */
3029
                    rs2 = GET_FIELDs(insn, 19, 31);
3030
#if defined(OPTIM)
3031
                    if (rs2) {
3032
#endif
3033
                        gen_movl_simm_T1(rs2);
3034
                        gen_op_add_T1_T0();
3035
#if defined(OPTIM)
3036
                    }
3037
#endif
3038
                } else {                /* register */
3039
                    rs2 = GET_FIELD(insn, 27, 31);
3040
#if defined(OPTIM)
3041
                    if (rs2) {
3042
#endif
3043
                        gen_movl_reg_T1(rs2);
3044
                        gen_op_add_T1_T0();
3045
#if defined(OPTIM)
3046
                    }
3047
#endif
3048
                }
3049
                gen_op_restore();
3050
                gen_mov_pc_npc(dc);
3051
                gen_op_check_align_T0_3();
3052
                gen_op_movl_npc_T0();
3053
                dc->npc = DYNAMIC_PC;
3054
                goto jmp_insn;
3055
#endif
3056
            } else {
3057
                rs1 = GET_FIELD(insn, 13, 17);
3058
                gen_movl_reg_T0(rs1);
3059
                if (IS_IMM) {   /* immediate */
3060
                    rs2 = GET_FIELDs(insn, 19, 31);
3061
#if defined(OPTIM)
3062
                    if (rs2) {
3063
#endif
3064
                        gen_movl_simm_T1(rs2);
3065
                        gen_op_add_T1_T0();
3066
#if defined(OPTIM)
3067
                    }
3068
#endif
3069
                } else {                /* register */
3070
                    rs2 = GET_FIELD(insn, 27, 31);
3071
#if defined(OPTIM)
3072
                    if (rs2) {
3073
#endif
3074
                        gen_movl_reg_T1(rs2);
3075
                        gen_op_add_T1_T0();
3076
#if defined(OPTIM)
3077
                    }
3078
#endif
3079
                }
3080
                switch (xop) {
3081
                case 0x38:      /* jmpl */
3082
                    {
3083
                        if (rd != 0) {
3084
#ifdef TARGET_SPARC64
3085
                            if (dc->pc == (uint32_t)dc->pc) {
3086
                                gen_op_movl_T1_im(dc->pc);
3087
                            } else {
3088
                                gen_op_movq_T1_im64(dc->pc >> 32, dc->pc);
3089
                            }
3090
#else
3091
                            gen_op_movl_T1_im(dc->pc);
3092
#endif
3093
                            gen_movl_T1_reg(rd);
3094
                        }
3095
                        gen_mov_pc_npc(dc);
3096
                        gen_op_check_align_T0_3();
3097
                        gen_op_movl_npc_T0();
3098
                        dc->npc = DYNAMIC_PC;
3099
                    }
3100
                    goto jmp_insn;
3101
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
3102
                case 0x39:      /* rett, V9 return */
3103
                    {
3104
                        if (!supervisor(dc))
3105
                            goto priv_insn;
3106
                        gen_mov_pc_npc(dc);
3107
                        gen_op_check_align_T0_3();
3108
                        gen_op_movl_npc_T0();
3109
                        dc->npc = DYNAMIC_PC;
3110
                        gen_op_rett();
3111
                    }
3112
                    goto jmp_insn;
3113
#endif
3114
                case 0x3b: /* flush */
3115
                    gen_op_flush_T0();
3116
                    break;
3117
                case 0x3c:      /* save */
3118
                    save_state(dc);
3119
                    gen_op_save();
3120
                    gen_movl_T0_reg(rd);
3121
                    break;
3122
                case 0x3d:      /* restore */
3123
                    save_state(dc);
3124
                    gen_op_restore();
3125
                    gen_movl_T0_reg(rd);
3126
                    break;
3127
#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
3128
                case 0x3e:      /* V9 done/retry */
3129
                    {
3130
                        switch (rd) {
3131
                        case 0:
3132
                            if (!supervisor(dc))
3133
                                goto priv_insn;
3134
                            dc->npc = DYNAMIC_PC;
3135
                            dc->pc = DYNAMIC_PC;
3136
                            gen_op_done();
3137
                            goto jmp_insn;
3138
                        case 1:
3139
                            if (!supervisor(dc))
3140
                                goto priv_insn;
3141
                            dc->npc = DYNAMIC_PC;
3142
                            dc->pc = DYNAMIC_PC;
3143
                            gen_op_retry();
3144
                            goto jmp_insn;
3145
                        default:
3146
                            goto illegal_insn;
3147
                        }
3148
                    }
3149
                    break;
3150
#endif
3151
                default:
3152
                    goto illegal_insn;
3153
                }
3154
            }
3155
            break;
3156
        }
3157
        break;
3158
    case 3:                     /* load/store instructions */
3159
        {
3160
            unsigned int xop = GET_FIELD(insn, 7, 12);
3161
            rs1 = GET_FIELD(insn, 13, 17);
3162
            save_state(dc);
3163
            gen_movl_reg_T0(rs1);
3164
            if (xop == 0x3c || xop == 0x3e)
3165
            {
3166
                rs2 = GET_FIELD(insn, 27, 31);
3167
                gen_movl_reg_T1(rs2);
3168
            }
3169
            else if (IS_IMM) {       /* immediate */
3170
                rs2 = GET_FIELDs(insn, 19, 31);
3171
#if defined(OPTIM)
3172
                if (rs2 != 0) {
3173
#endif
3174
                    gen_movl_simm_T1(rs2);
3175
                    gen_op_add_T1_T0();
3176
#if defined(OPTIM)
3177
                }
3178
#endif
3179
            } else {            /* register */
3180
                rs2 = GET_FIELD(insn, 27, 31);
3181
#if defined(OPTIM)
3182
                if (rs2 != 0) {
3183
#endif
3184
                    gen_movl_reg_T1(rs2);
3185
                    gen_op_add_T1_T0();
3186
#if defined(OPTIM)
3187
                }
3188
#endif
3189
            }
3190
            if (xop < 4 || (xop > 7 && xop < 0x14 && xop != 0x0e) ||
3191
                (xop > 0x17 && xop <= 0x1d ) ||
3192
                (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
3193
                switch (xop) {
3194
                case 0x0:       /* load word */
3195
                    gen_op_check_align_T0_3();
3196
#ifndef TARGET_SPARC64
3197
                    gen_op_ldst(ld);
3198
#else
3199
                    gen_op_ldst(lduw);
3200
#endif
3201
                    break;
3202
                case 0x1:       /* load unsigned byte */
3203
                    gen_op_ldst(ldub);
3204
                    break;
3205
                case 0x2:       /* load unsigned halfword */
3206
                    gen_op_check_align_T0_1();
3207
                    gen_op_ldst(lduh);
3208
                    break;
3209
                case 0x3:       /* load double word */
3210
                    if (rd & 1)
3211
                        goto illegal_insn;
3212
                    gen_op_check_align_T0_7();
3213
                    gen_op_ldst(ldd);
3214
                    gen_movl_T0_reg(rd + 1);
3215
                    break;
3216
                case 0x9:       /* load signed byte */
3217
                    gen_op_ldst(ldsb);
3218
                    break;
3219
                case 0xa:       /* load signed halfword */
3220
                    gen_op_check_align_T0_1();
3221
                    gen_op_ldst(ldsh);
3222
                    break;
3223
                case 0xd:       /* ldstub -- XXX: should be atomically */
3224
                    gen_op_ldst(ldstub);
3225
                    break;
3226
                case 0x0f:      /* swap register with memory. Also atomically */
3227
                    gen_op_check_align_T0_3();
3228
                    gen_movl_reg_T1(rd);
3229
                    gen_op_ldst(swap);
3230
                    break;
3231
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
3232
                case 0x10:      /* load word alternate */
3233
#ifndef TARGET_SPARC64
3234
                    if (IS_IMM)
3235
                        goto illegal_insn;
3236
                    if (!supervisor(dc))
3237
                        goto priv_insn;
3238
#endif
3239
                    gen_op_check_align_T0_3();
3240
                    gen_ld_asi(insn, 4, 0);
3241
                    break;
3242
                case 0x11:      /* load unsigned byte alternate */
3243
#ifndef TARGET_SPARC64
3244
                    if (IS_IMM)
3245
                        goto illegal_insn;
3246
                    if (!supervisor(dc))
3247
                        goto priv_insn;
3248
#endif
3249
                    gen_ld_asi(insn, 1, 0);
3250
                    break;
3251
                case 0x12:      /* load unsigned halfword alternate */
3252
#ifndef TARGET_SPARC64
3253
                    if (IS_IMM)
3254
                        goto illegal_insn;
3255
                    if (!supervisor(dc))
3256
                        goto priv_insn;
3257
#endif
3258
                    gen_op_check_align_T0_1();
3259
                    gen_ld_asi(insn, 2, 0);
3260
                    break;
3261
                case 0x13:      /* load double word alternate */
3262
#ifndef TARGET_SPARC64
3263
                    if (IS_IMM)
3264
                        goto illegal_insn;
3265
                    if (!supervisor(dc))
3266
                        goto priv_insn;
3267
#endif
3268
                    if (rd & 1)
3269
                        goto illegal_insn;
3270
                    gen_op_check_align_T0_7();
3271
                    gen_ldda_asi(insn);
3272
                    gen_movl_T0_reg(rd + 1);
3273
                    break;
3274
                case 0x19:      /* load signed byte alternate */
3275
#ifndef TARGET_SPARC64
3276
                    if (IS_IMM)
3277
                        goto illegal_insn;
3278
                    if (!supervisor(dc))
3279
                        goto priv_insn;
3280
#endif
3281
                    gen_ld_asi(insn, 1, 1);
3282
                    break;
3283
                case 0x1a:      /* load signed halfword alternate */
3284
#ifndef TARGET_SPARC64
3285
                    if (IS_IMM)
3286
                        goto illegal_insn;
3287
                    if (!supervisor(dc))
3288
                        goto priv_insn;
3289
#endif
3290
                    gen_op_check_align_T0_1();
3291
                    gen_ld_asi(insn, 2, 1);
3292
                    break;
3293
                case 0x1d:      /* ldstuba -- XXX: should be atomically */
3294
#ifndef TARGET_SPARC64
3295
                    if (IS_IMM)
3296
                        goto illegal_insn;
3297
                    if (!supervisor(dc))
3298
                        goto priv_insn;
3299
#endif
3300
                    gen_ldstub_asi(insn);
3301
                    break;
3302
                case 0x1f:      /* swap reg with alt. memory. Also atomically */
3303
#ifndef TARGET_SPARC64
3304
                    if (IS_IMM)
3305
                        goto illegal_insn;
3306
                    if (!supervisor(dc))
3307
                        goto priv_insn;
3308
#endif
3309
                    gen_op_check_align_T0_3();
3310
                    gen_movl_reg_T1(rd);
3311
                    gen_swap_asi(insn);
3312
                    break;
3313

    
3314
#ifndef TARGET_SPARC64
3315
                case 0x30: /* ldc */
3316
                case 0x31: /* ldcsr */
3317
                case 0x33: /* lddc */
3318
                    goto ncp_insn;
3319
#endif
3320
#endif
3321
#ifdef TARGET_SPARC64
3322
                case 0x08: /* V9 ldsw */
3323
                    gen_op_check_align_T0_3();
3324
                    gen_op_ldst(ldsw);
3325
                    break;
3326
                case 0x0b: /* V9 ldx */
3327
                    gen_op_check_align_T0_7();
3328
                    gen_op_ldst(ldx);
3329
                    break;
3330
                case 0x18: /* V9 ldswa */
3331
                    gen_op_check_align_T0_3();
3332
                    gen_ld_asi(insn, 4, 1);
3333
                    break;
3334
                case 0x1b: /* V9 ldxa */
3335
                    gen_op_check_align_T0_7();
3336
                    gen_ld_asi(insn, 8, 0);
3337
                    break;
3338
                case 0x2d: /* V9 prefetch, no effect */
3339
                    goto skip_move;
3340
                case 0x30: /* V9 ldfa */
3341
                    gen_op_check_align_T0_3();
3342
                    gen_ldf_asi(insn, 4);
3343
                    goto skip_move;
3344
                case 0x33: /* V9 lddfa */
3345
                    gen_op_check_align_T0_3();
3346
                    gen_ldf_asi(insn, 8);
3347
                    goto skip_move;
3348
                case 0x3d: /* V9 prefetcha, no effect */
3349
                    goto skip_move;
3350
                case 0x32: /* V9 ldqfa */
3351
#if defined(CONFIG_USER_ONLY)
3352
                    gen_op_check_align_T0_3();
3353
                    gen_ldf_asi(insn, 16);
3354
                    goto skip_move;
3355
#else
3356
                    goto nfpu_insn;
3357
#endif
3358
#endif
3359
                default:
3360
                    goto illegal_insn;
3361
                }
3362
                gen_movl_T1_reg(rd);
3363
#ifdef TARGET_SPARC64
3364
            skip_move: ;
3365
#endif
3366
            } else if (xop >= 0x20 && xop < 0x24) {
3367
                if (gen_trap_ifnofpu(dc))
3368
                    goto jmp_insn;
3369
                switch (xop) {
3370
                case 0x20:      /* load fpreg */
3371
                    gen_op_check_align_T0_3();
3372
                    gen_op_ldst(ldf);
3373
                    gen_op_store_FT0_fpr(rd);
3374
                    break;
3375
                case 0x21:      /* load fsr */
3376
                    gen_op_check_align_T0_3();
3377
                    gen_op_ldst(ldf);
3378
                    gen_op_ldfsr();
3379
                    break;
3380
                case 0x22:      /* load quad fpreg */
3381
#if defined(CONFIG_USER_ONLY)
3382
                    gen_op_check_align_T0_7();
3383
                    gen_op_ldst(ldqf);
3384
                    gen_op_store_QT0_fpr(QFPREG(rd));
3385
                    break;
3386
#else
3387
                    goto nfpu_insn;
3388
#endif
3389
                case 0x23:      /* load double fpreg */
3390
                    gen_op_check_align_T0_7();
3391
                    gen_op_ldst(lddf);
3392
                    gen_op_store_DT0_fpr(DFPREG(rd));
3393
                    break;
3394
                default:
3395
                    goto illegal_insn;
3396
                }
3397
            } else if (xop < 8 || (xop >= 0x14 && xop < 0x18) || \
3398
                       xop == 0xe || xop == 0x1e) {
3399
                gen_movl_reg_T1(rd);
3400
                switch (xop) {
3401
                case 0x4:
3402
                    gen_op_check_align_T0_3();
3403
                    gen_op_ldst(st);
3404
                    break;
3405
                case 0x5:
3406
                    gen_op_ldst(stb);
3407
                    break;
3408
                case 0x6:
3409
                    gen_op_check_align_T0_1();
3410
                    gen_op_ldst(sth);
3411
                    break;
3412
                case 0x7:
3413
                    if (rd & 1)
3414
                        goto illegal_insn;
3415
                    gen_op_check_align_T0_7();
3416
                    flush_T2(dc);
3417
                    gen_movl_reg_T2(rd + 1);
3418
                    gen_op_ldst(std);
3419
                    break;
3420
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
3421
                case 0x14:
3422
#ifndef TARGET_SPARC64
3423
                    if (IS_IMM)
3424
                        goto illegal_insn;
3425
                    if (!supervisor(dc))
3426
                        goto priv_insn;
3427
#endif
3428
                    gen_op_check_align_T0_3();
3429
                    gen_st_asi(insn, 4);
3430
                    break;
3431
                case 0x15:
3432
#ifndef TARGET_SPARC64
3433
                    if (IS_IMM)
3434
                        goto illegal_insn;
3435
                    if (!supervisor(dc))
3436
                        goto priv_insn;
3437
#endif
3438
                    gen_st_asi(insn, 1);
3439
                    break;
3440
                case 0x16:
3441
#ifndef TARGET_SPARC64
3442
                    if (IS_IMM)
3443
                        goto illegal_insn;
3444
                    if (!supervisor(dc))
3445
                        goto priv_insn;
3446
#endif
3447
                    gen_op_check_align_T0_1();
3448
                    gen_st_asi(insn, 2);
3449
                    break;
3450
                case 0x17:
3451
#ifndef TARGET_SPARC64
3452
                    if (IS_IMM)
3453
                        goto illegal_insn;
3454
                    if (!supervisor(dc))
3455
                        goto priv_insn;
3456
#endif
3457
                    if (rd & 1)
3458
                        goto illegal_insn;
3459
                    gen_op_check_align_T0_7();
3460
                    flush_T2(dc);
3461
                    gen_movl_reg_T2(rd + 1);
3462
                    gen_stda_asi(insn);
3463
                    break;
3464
#endif
3465
#ifdef TARGET_SPARC64
3466
                case 0x0e: /* V9 stx */
3467
                    gen_op_check_align_T0_7();
3468
                    gen_op_ldst(stx);
3469
                    break;
3470
                case 0x1e: /* V9 stxa */
3471
                    gen_op_check_align_T0_7();
3472
                    gen_st_asi(insn, 8);
3473
                    break;
3474
#endif
3475
                default:
3476
                    goto illegal_insn;
3477
                }
3478
            } else if (xop > 0x23 && xop < 0x28) {
3479
                if (gen_trap_ifnofpu(dc))
3480
                    goto jmp_insn;
3481
                switch (xop) {
3482
                case 0x24:
3483
                    gen_op_check_align_T0_3();
3484
                    gen_op_load_fpr_FT0(rd);
3485
                    gen_op_ldst(stf);
3486
                    break;
3487
                case 0x25: /* stfsr, V9 stxfsr */
3488
#ifdef CONFIG_USER_ONLY
3489
                    gen_op_check_align_T0_3();
3490
#endif
3491
                    gen_op_stfsr();
3492
                    gen_op_ldst(stf);
3493
                    break;
3494
                case 0x26:
3495
#ifdef TARGET_SPARC64
3496
#if defined(CONFIG_USER_ONLY)
3497
                    /* V9 stqf, store quad fpreg */
3498
                    gen_op_check_align_T0_7();
3499
                    gen_op_load_fpr_QT0(QFPREG(rd));
3500
                    gen_op_ldst(stqf);
3501
                    break;
3502
#else
3503
                    goto nfpu_insn;
3504
#endif
3505
#else /* !TARGET_SPARC64 */
3506
                    /* stdfq, store floating point queue */
3507
#if defined(CONFIG_USER_ONLY)
3508
                    goto illegal_insn;
3509
#else
3510
                    if (!supervisor(dc))
3511
                        goto priv_insn;
3512
                    if (gen_trap_ifnofpu(dc))
3513
                        goto jmp_insn;
3514
                    goto nfq_insn;
3515
#endif
3516
#endif
3517
                case 0x27:
3518
                    gen_op_check_align_T0_7();
3519
                    gen_op_load_fpr_DT0(DFPREG(rd));
3520
                    gen_op_ldst(stdf);
3521
                    break;
3522
                default:
3523
                    goto illegal_insn;
3524
                }
3525
            } else if (xop > 0x33 && xop < 0x3f) {
3526
                switch (xop) {
3527
#ifdef TARGET_SPARC64
3528
                case 0x34: /* V9 stfa */
3529
                    gen_op_check_align_T0_3();
3530
                    gen_op_load_fpr_FT0(rd);
3531
                    gen_stf_asi(insn, 4);
3532
                    break;
3533
                case 0x36: /* V9 stqfa */
3534
#if defined(CONFIG_USER_ONLY)
3535
                    gen_op_check_align_T0_7();
3536
                    gen_op_load_fpr_QT0(QFPREG(rd));
3537
                    gen_stf_asi(insn, 16);
3538
                    break;
3539
#else
3540
                    goto nfpu_insn;
3541
#endif
3542
                case 0x37: /* V9 stdfa */
3543
                    gen_op_check_align_T0_3();
3544
                    gen_op_load_fpr_DT0(DFPREG(rd));
3545
                    gen_stf_asi(insn, 8);
3546
                    break;
3547
                case 0x3c: /* V9 casa */
3548
                    gen_op_check_align_T0_3();
3549
                    flush_T2(dc);
3550
                    gen_movl_reg_T2(rd);
3551
                    gen_cas_asi(insn);
3552
                    gen_movl_T1_reg(rd);
3553
                    break;
3554
                case 0x3e: /* V9 casxa */
3555
                    gen_op_check_align_T0_7();
3556
                    flush_T2(dc);
3557
                    gen_movl_reg_T2(rd);
3558
                    gen_casx_asi(insn);
3559
                    gen_movl_T1_reg(rd);
3560
                    break;
3561
#else
3562
                case 0x34: /* stc */
3563
                case 0x35: /* stcsr */
3564
                case 0x36: /* stdcq */
3565
                case 0x37: /* stdc */
3566
                    goto ncp_insn;
3567
#endif
3568
                default:
3569
                    goto illegal_insn;
3570
                }
3571
            }
3572
            else
3573
                goto illegal_insn;
3574
        }
3575
        break;
3576
    }
3577
    /* default case for non jump instructions */
3578
    if (dc->npc == DYNAMIC_PC) {
3579
        dc->pc = DYNAMIC_PC;
3580
        gen_op_next_insn();
3581
    } else if (dc->npc == JUMP_PC) {
3582
        /* we can do a static jump */
3583
        gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1]);
3584
        dc->is_br = 1;
3585
    } else {
3586
        dc->pc = dc->npc;
3587
        dc->npc = dc->npc + 4;
3588
    }
3589
 jmp_insn:
3590
    return;
3591
 illegal_insn:
3592
    save_state(dc);
3593
    gen_op_exception(TT_ILL_INSN);
3594
    dc->is_br = 1;
3595
    return;
3596
#if !defined(CONFIG_USER_ONLY)
3597
 priv_insn:
3598
    save_state(dc);
3599
    gen_op_exception(TT_PRIV_INSN);
3600
    dc->is_br = 1;
3601
    return;
3602
 nfpu_insn:
3603
    save_state(dc);
3604
    gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
3605
    dc->is_br = 1;
3606
    return;
3607
#ifndef TARGET_SPARC64
3608
 nfq_insn:
3609
    save_state(dc);
3610
    gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
3611
    dc->is_br = 1;
3612
    return;
3613
#endif
3614
#endif
3615
#ifndef TARGET_SPARC64
3616
 ncp_insn:
3617
    save_state(dc);
3618
    gen_op_exception(TT_NCP_INSN);
3619
    dc->is_br = 1;
3620
    return;
3621
#endif
3622
}
3623

    
3624
static inline int gen_intermediate_code_internal(TranslationBlock * tb,
3625
                                                 int spc, CPUSPARCState *env)
3626
{
3627
    target_ulong pc_start, last_pc;
3628
    uint16_t *gen_opc_end;
3629
    DisasContext dc1, *dc = &dc1;
3630
    int j, lj = -1;
3631

    
3632
    memset(dc, 0, sizeof(DisasContext));
3633
    dc->tb = tb;
3634
    pc_start = tb->pc;
3635
    dc->pc = pc_start;
3636
    last_pc = dc->pc;
3637
    dc->npc = (target_ulong) tb->cs_base;
3638
    dc->mem_idx = cpu_mmu_index(env);
3639
    dc->fpu_enabled = cpu_fpu_enabled(env);
3640
    gen_opc_ptr = gen_opc_buf;
3641
    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
3642
    gen_opparam_ptr = gen_opparam_buf;
3643
    nb_gen_labels = 0;
3644

    
3645
    do {
3646
        if (env->nb_breakpoints > 0) {
3647
            for(j = 0; j < env->nb_breakpoints; j++) {
3648
                if (env->breakpoints[j] == dc->pc) {
3649
                    if (dc->pc != pc_start)
3650
                        save_state(dc);
3651
                    gen_op_debug();
3652
                    gen_op_movl_T0_0();
3653
                    gen_op_exit_tb();
3654
                    dc->is_br = 1;
3655
                    goto exit_gen_loop;
3656
                }
3657
            }
3658
        }
3659
        if (spc) {
3660
            if (loglevel > 0)
3661
                fprintf(logfile, "Search PC...\n");
3662
            j = gen_opc_ptr - gen_opc_buf;
3663
            if (lj < j) {
3664
                lj++;
3665
                while (lj < j)
3666
                    gen_opc_instr_start[lj++] = 0;
3667
                gen_opc_pc[lj] = dc->pc;
3668
                gen_opc_npc[lj] = dc->npc;
3669
                gen_opc_instr_start[lj] = 1;
3670
            }
3671
        }
3672
        last_pc = dc->pc;
3673
        disas_sparc_insn(dc);
3674

    
3675
        if (dc->is_br)
3676
            break;
3677
        /* if the next PC is different, we abort now */
3678
        if (dc->pc != (last_pc + 4))
3679
            break;
3680
        /* if we reach a page boundary, we stop generation so that the
3681
           PC of a TT_TFAULT exception is always in the right page */
3682
        if ((dc->pc & (TARGET_PAGE_SIZE - 1)) == 0)
3683
            break;
3684
        /* if single step mode, we generate only one instruction and
3685
           generate an exception */
3686
        if (env->singlestep_enabled) {
3687
            gen_jmp_im(dc->pc);
3688
            gen_op_movl_T0_0();
3689
            gen_op_exit_tb();
3690
            break;
3691
        }
3692
    } while ((gen_opc_ptr < gen_opc_end) &&
3693
             (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
3694

    
3695
 exit_gen_loop:
3696
    if (!dc->is_br) {
3697
        if (dc->pc != DYNAMIC_PC &&
3698
            (dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
3699
            /* static PC and NPC: we can use direct chaining */
3700
            gen_branch(dc, dc->pc, dc->npc);
3701
        } else {
3702
            if (dc->pc != DYNAMIC_PC)
3703
                gen_jmp_im(dc->pc);
3704
            save_npc(dc);
3705
            gen_op_movl_T0_0();
3706
            gen_op_exit_tb();
3707
        }
3708
    }
3709
    *gen_opc_ptr = INDEX_op_end;
3710
    if (spc) {
3711
        j = gen_opc_ptr - gen_opc_buf;
3712
        lj++;
3713
        while (lj <= j)
3714
            gen_opc_instr_start[lj++] = 0;
3715
#if 0
3716
        if (loglevel > 0) {
3717
            page_dump(logfile);
3718
        }
3719
#endif
3720
        gen_opc_jump_pc[0] = dc->jump_pc[0];
3721
        gen_opc_jump_pc[1] = dc->jump_pc[1];
3722
    } else {
3723
        tb->size = last_pc + 4 - pc_start;
3724
    }
3725
#ifdef DEBUG_DISAS
3726
    if (loglevel & CPU_LOG_TB_IN_ASM) {
3727
        fprintf(logfile, "--------------\n");
3728
        fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
3729
        target_disas(logfile, pc_start, last_pc + 4 - pc_start, 0);
3730
        fprintf(logfile, "\n");
3731
        if (loglevel & CPU_LOG_TB_OP) {
3732
            fprintf(logfile, "OP:\n");
3733
            dump_ops(gen_opc_buf, gen_opparam_buf);
3734
            fprintf(logfile, "\n");
3735
        }
3736
    }
3737
#endif
3738
    return 0;
3739
}
3740

    
3741
int gen_intermediate_code(CPUSPARCState * env, TranslationBlock * tb)
3742
{
3743
    return gen_intermediate_code_internal(tb, 0, env);
3744
}
3745

    
3746
int gen_intermediate_code_pc(CPUSPARCState * env, TranslationBlock * tb)
3747
{
3748
    return gen_intermediate_code_internal(tb, 1, env);
3749
}
3750

    
3751
extern int ram_size;
3752

    
3753
void cpu_reset(CPUSPARCState *env)
3754
{
3755
    tlb_flush(env, 1);
3756
    env->cwp = 0;
3757
    env->wim = 1;
3758
    env->regwptr = env->regbase + (env->cwp * 16);
3759
#if defined(CONFIG_USER_ONLY)
3760
    env->user_mode_only = 1;
3761
#ifdef TARGET_SPARC64
3762
    env->cleanwin = NWINDOWS - 2;
3763
    env->cansave = NWINDOWS - 2;
3764
    env->pstate = PS_RMO | PS_PEF | PS_IE;
3765
    env->asi = 0x82; // Primary no-fault
3766
#endif
3767
#else
3768
    env->psret = 0;
3769
    env->psrs = 1;
3770
    env->psrps = 1;
3771
#ifdef TARGET_SPARC64
3772
    env->pstate = PS_PRIV;
3773
    env->hpstate = HS_PRIV;
3774
    env->pc = 0x1fff0000000ULL;
3775
#else
3776
    env->pc = 0;
3777
    env->mmuregs[0] &= ~(MMU_E | MMU_NF);
3778
    env->mmuregs[0] |= env->mmu_bm;
3779
#endif
3780
    env->npc = env->pc + 4;
3781
#endif
3782
}
3783

    
3784
CPUSPARCState *cpu_sparc_init(const char *cpu_model)
3785
{
3786
    CPUSPARCState *env;
3787
    const sparc_def_t *def;
3788

    
3789
    def = cpu_sparc_find_by_name(cpu_model);
3790
    if (!def)
3791
        return NULL;
3792

    
3793
    env = qemu_mallocz(sizeof(CPUSPARCState));
3794
    if (!env)
3795
        return NULL;
3796
    cpu_exec_init(env);
3797
    env->version = def->iu_version;
3798
    env->fsr = def->fpu_version;
3799
#if !defined(TARGET_SPARC64)
3800
    env->mmu_bm = def->mmu_bm;
3801
    env->mmuregs[0] |= def->mmu_version;
3802
    cpu_sparc_set_id(env, 0);
3803
#endif
3804
    cpu_reset(env);
3805
    
3806
    return env;
3807
}
3808

    
3809
void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
3810
{
3811
#if !defined(TARGET_SPARC64)
3812
    env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
3813
#endif
3814
}
3815

    
3816
static const sparc_def_t sparc_defs[] = {
3817
#ifdef TARGET_SPARC64
3818
    {
3819
        .name = "Fujitsu Sparc64",
3820
        .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)
3821
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3822
        .fpu_version = 0x00000000,
3823
        .mmu_version = 0,
3824
    },
3825
    {
3826
        .name = "Fujitsu Sparc64 III",
3827
        .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)
3828
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3829
        .fpu_version = 0x00000000,
3830
        .mmu_version = 0,
3831
    },
3832
    {
3833
        .name = "Fujitsu Sparc64 IV",
3834
        .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)
3835
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3836
        .fpu_version = 0x00000000,
3837
        .mmu_version = 0,
3838
    },
3839
    {
3840
        .name = "Fujitsu Sparc64 V",
3841
        .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)
3842
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3843
        .fpu_version = 0x00000000,
3844
        .mmu_version = 0,
3845
    },
3846
    {
3847
        .name = "TI UltraSparc I",
3848
        .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)
3849
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3850
        .fpu_version = 0x00000000,
3851
        .mmu_version = 0,
3852
    },
3853
    {
3854
        .name = "TI UltraSparc II",
3855
        .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)
3856
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3857
        .fpu_version = 0x00000000,
3858
        .mmu_version = 0,
3859
    },
3860
    {
3861
        .name = "TI UltraSparc IIi",
3862
        .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)
3863
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3864
        .fpu_version = 0x00000000,
3865
        .mmu_version = 0,
3866
    },
3867
    {
3868
        .name = "TI UltraSparc IIe",
3869
        .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)
3870
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3871
        .fpu_version = 0x00000000,
3872
        .mmu_version = 0,
3873
    },
3874
    {
3875
        .name = "Sun UltraSparc III",
3876
        .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)
3877
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3878
        .fpu_version = 0x00000000,
3879
        .mmu_version = 0,
3880
    },
3881
    {
3882
        .name = "Sun UltraSparc III Cu",
3883
        .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)
3884
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3885
        .fpu_version = 0x00000000,
3886
        .mmu_version = 0,
3887
    },
3888
    {
3889
        .name = "Sun UltraSparc IIIi",
3890
        .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)
3891
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3892
        .fpu_version = 0x00000000,
3893
        .mmu_version = 0,
3894
    },
3895
    {
3896
        .name = "Sun UltraSparc IV",
3897
        .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)
3898
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3899
        .fpu_version = 0x00000000,
3900
        .mmu_version = 0,
3901
    },
3902
    {
3903
        .name = "Sun UltraSparc IV+",
3904
        .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)
3905
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3906
        .fpu_version = 0x00000000,
3907
        .mmu_version = 0,
3908
    },
3909
    {
3910
        .name = "Sun UltraSparc IIIi+",
3911
        .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)
3912
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3913
        .fpu_version = 0x00000000,
3914
        .mmu_version = 0,
3915
    },
3916
    {
3917
        .name = "NEC UltraSparc I",
3918
        .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)
3919
                       | (MAXTL << 8) | (NWINDOWS - 1)),
3920
        .fpu_version = 0x00000000,
3921
        .mmu_version = 0,
3922
    },
3923
#else
3924
    {
3925
        .name = "Fujitsu MB86900",
3926
        .iu_version = 0x00 << 24, /* Impl 0, ver 0 */
3927
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
3928
        .mmu_version = 0x00 << 24, /* Impl 0, ver 0 */
3929
        .mmu_bm = 0x00004000,
3930
    },
3931
    {
3932
        .name = "Fujitsu MB86904",
3933
        .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
3934
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
3935
        .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
3936
        .mmu_bm = 0x00004000,
3937
    },
3938
    {
3939
        .name = "Fujitsu MB86907",
3940
        .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
3941
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
3942
        .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
3943
        .mmu_bm = 0x00004000,
3944
    },
3945
    {
3946
        .name = "LSI L64811",
3947
        .iu_version = 0x10 << 24, /* Impl 1, ver 0 */
3948
        .fpu_version = 1 << 17, /* FPU version 1 (LSI L64814) */
3949
        .mmu_version = 0x10 << 24,
3950
        .mmu_bm = 0x00004000,
3951
    },
3952
    {
3953
        .name = "Cypress CY7C601",
3954
        .iu_version = 0x11 << 24, /* Impl 1, ver 1 */
3955
        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
3956
        .mmu_version = 0x10 << 24,
3957
        .mmu_bm = 0x00004000,
3958
    },
3959
    {
3960
        .name = "Cypress CY7C611",
3961
        .iu_version = 0x13 << 24, /* Impl 1, ver 3 */
3962
        .fpu_version = 3 << 17, /* FPU version 3 (Cypress CY7C602) */
3963
        .mmu_version = 0x10 << 24,
3964
        .mmu_bm = 0x00004000,
3965
    },
3966
    {
3967
        .name = "TI SuperSparc II",
3968
        .iu_version = 0x40000000,
3969
        .fpu_version = 0 << 17,
3970
        .mmu_version = 0x04000000,
3971
        .mmu_bm = 0x00002000,
3972
    },
3973
    {
3974
        .name = "TI MicroSparc I",
3975
        .iu_version = 0x41000000,
3976
        .fpu_version = 4 << 17,
3977
        .mmu_version = 0x41000000,
3978
        .mmu_bm = 0x00004000,
3979
    },
3980
    {
3981
        .name = "TI MicroSparc II",
3982
        .iu_version = 0x42000000,
3983
        .fpu_version = 4 << 17,
3984
        .mmu_version = 0x02000000,
3985
        .mmu_bm = 0x00004000,
3986
    },
3987
    {
3988
        .name = "TI MicroSparc IIep",
3989
        .iu_version = 0x42000000,
3990
        .fpu_version = 4 << 17,
3991
        .mmu_version = 0x04000000,
3992
        .mmu_bm = 0x00004000,
3993
    },
3994
    {
3995
        .name = "TI SuperSparc 51",
3996
        .iu_version = 0x43000000,
3997
        .fpu_version = 0 << 17,
3998
        .mmu_version = 0x04000000,
3999
        .mmu_bm = 0x00002000,
4000
    },
4001
    {
4002
        .name = "TI SuperSparc 61",
4003
        .iu_version = 0x44000000,
4004
        .fpu_version = 0 << 17,
4005
        .mmu_version = 0x04000000,
4006
        .mmu_bm = 0x00002000,
4007
    },
4008
    {
4009
        .name = "Ross RT625",
4010
        .iu_version = 0x1e000000,
4011
        .fpu_version = 1 << 17,
4012
        .mmu_version = 0x1e000000,
4013
        .mmu_bm = 0x00004000,
4014
    },
4015
    {
4016
        .name = "Ross RT620",
4017
        .iu_version = 0x1f000000,
4018
        .fpu_version = 1 << 17,
4019
        .mmu_version = 0x1f000000,
4020
        .mmu_bm = 0x00004000,
4021
    },
4022
    {
4023
        .name = "BIT B5010",
4024
        .iu_version = 0x20000000,
4025
        .fpu_version = 0 << 17, /* B5010/B5110/B5120/B5210 */
4026
        .mmu_version = 0x20000000,
4027
        .mmu_bm = 0x00004000,
4028
    },
4029
    {
4030
        .name = "Matsushita MN10501",
4031
        .iu_version = 0x50000000,
4032
        .fpu_version = 0 << 17,
4033
        .mmu_version = 0x50000000,
4034
        .mmu_bm = 0x00004000,
4035
    },
4036
    {
4037
        .name = "Weitek W8601",
4038
        .iu_version = 0x90 << 24, /* Impl 9, ver 0 */
4039
        .fpu_version = 3 << 17, /* FPU version 3 (Weitek WTL3170/2) */
4040
        .mmu_version = 0x10 << 24,
4041
        .mmu_bm = 0x00004000,
4042
    },
4043
    {
4044
        .name = "LEON2",
4045
        .iu_version = 0xf2000000,
4046
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
4047
        .mmu_version = 0xf2000000,
4048
        .mmu_bm = 0x00004000,
4049
    },
4050
    {
4051
        .name = "LEON3",
4052
        .iu_version = 0xf3000000,
4053
        .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
4054
        .mmu_version = 0xf3000000,
4055
        .mmu_bm = 0x00004000,
4056
    },
4057
#endif
4058
};
4059

    
4060
static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name)
4061
{
4062
    unsigned int i;
4063

    
4064
    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
4065
        if (strcasecmp(name, sparc_defs[i].name) == 0) {
4066
            return &sparc_defs[i];
4067
        }
4068
    }
4069
    return NULL;
4070
}
4071

    
4072
void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
4073
{
4074
    unsigned int i;
4075

    
4076
    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
4077
        (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x\n",
4078
                       sparc_defs[i].name,
4079
                       sparc_defs[i].iu_version,
4080
                       sparc_defs[i].fpu_version,
4081
                       sparc_defs[i].mmu_version);
4082
    }
4083
}
4084

    
4085
#define GET_FLAG(a,b) ((env->psr & a)?b:'-')
4086

    
4087
void cpu_dump_state(CPUState *env, FILE *f,
4088
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
4089
                    int flags)
4090
{
4091
    int i, x;
4092

    
4093
    cpu_fprintf(f, "pc: " TARGET_FMT_lx "  npc: " TARGET_FMT_lx "\n", env->pc, env->npc);
4094
    cpu_fprintf(f, "General Registers:\n");
4095
    for (i = 0; i < 4; i++)
4096
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
4097
    cpu_fprintf(f, "\n");
4098
    for (; i < 8; i++)
4099
        cpu_fprintf(f, "%%g%c: " TARGET_FMT_lx "\t", i + '0', env->gregs[i]);
4100
    cpu_fprintf(f, "\nCurrent Register Window:\n");
4101
    for (x = 0; x < 3; x++) {
4102
        for (i = 0; i < 4; i++)
4103
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
4104
                    (x == 0 ? 'o' : (x == 1 ? 'l' : 'i')), i,
4105
                    env->regwptr[i + x * 8]);
4106
        cpu_fprintf(f, "\n");
4107
        for (; i < 8; i++)
4108
            cpu_fprintf(f, "%%%c%d: " TARGET_FMT_lx "\t",
4109
                    (x == 0 ? 'o' : x == 1 ? 'l' : 'i'), i,
4110
                    env->regwptr[i + x * 8]);
4111
        cpu_fprintf(f, "\n");
4112
    }
4113
    cpu_fprintf(f, "\nFloating Point Registers:\n");
4114
    for (i = 0; i < 32; i++) {
4115
        if ((i & 3) == 0)
4116
            cpu_fprintf(f, "%%f%02d:", i);
4117
        cpu_fprintf(f, " %016lf", env->fpr[i]);
4118
        if ((i & 3) == 3)
4119
            cpu_fprintf(f, "\n");
4120
    }
4121
#ifdef TARGET_SPARC64
4122
    cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d fprs: %d\n",
4123
                env->pstate, GET_CCR(env), env->asi, env->tl, env->fprs);
4124
    cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d cleanwin %d cwp %d\n",
4125
                env->cansave, env->canrestore, env->otherwin, env->wstate,
4126
                env->cleanwin, NWINDOWS - 1 - env->cwp);
4127
#else
4128
    cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n", GET_PSR(env),
4129
            GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
4130
            GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
4131
            env->psrs?'S':'-', env->psrps?'P':'-',
4132
            env->psret?'E':'-', env->wim);
4133
#endif
4134
    cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env));
4135
}
4136

    
4137
#if defined(CONFIG_USER_ONLY)
4138
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
4139
{
4140
    return addr;
4141
}
4142

    
4143
#else
4144
extern int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
4145
                                 int *access_index, target_ulong address, int rw,
4146
                                 int mmu_idx);
4147

    
4148
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
4149
{
4150
    target_phys_addr_t phys_addr;
4151
    int prot, access_index;
4152

    
4153
    if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 2, 0) != 0)
4154
        if (get_physical_address(env, &phys_addr, &prot, &access_index, addr, 0, 0) != 0)
4155
            return -1;
4156
    if (cpu_get_physical_page_desc(phys_addr) == IO_MEM_UNASSIGNED)
4157
        return -1;
4158
    return phys_addr;
4159
}
4160
#endif
4161

    
4162
void helper_flush(target_ulong addr)
4163
{
4164
    addr &= ~7;
4165
    tb_invalidate_page_range(addr, addr + 8);
4166
}