Revision 3475187d target-sparc/translate.c

b/target-sparc/translate.c
2 2
   SPARC translation
3 3

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

  
7 7
   This library is free software; you can redistribute it and/or
8 8
   modify it under the terms of the GNU Lesser General Public
......
22 22
/*
23 23
   TODO-list:
24 24

  
25
   Rest of V9 instructions, VIS instructions
25 26
   NPC/PC static optimisations (use JUMP_TB when possible)
26
   FPU-Instructions
27
   Privileged instructions
28
   Coprocessor-Instructions
29 27
   Optimize synthetic instructions
30
   Optional alignment and privileged instruction check
28
   Optional alignment check
29
   128-bit float
30
   Tagged add/sub
31 31
*/
32 32

  
33 33
#include <stdarg.h>
......
69 69

  
70 70
#include "gen-op.h"
71 71

  
72
// This function uses non-native bit order
72 73
#define GET_FIELD(X, FROM, TO) \
73 74
  ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1))
74 75

  
76
// This function uses the order in the manuals, i.e. bit 0 is 2^0
77
#define GET_FIELD_SP(X, FROM, TO) \
78
    GET_FIELD(X, 31 - (TO), 31 - (FROM))
79

  
80
#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
81
#define GET_FIELD_SPs(x,a,b) sign_extend (GET_FIELD_SP(x,a,b), 32 - ((b) - (a) + 1))
82

  
83
#ifdef TARGET_SPARC64
84
#define DFPREG(r) (((r & 1) << 6) | (r & 0x1e))
85
#else
86
#define DFPREG(r) (r)
87
#endif
88

  
89
static int sign_extend(int x, int len)
90
{
91
    len = 32 - len;
92
    return (x << len) >> len;
93
}
94

  
75 95
#define IS_IMM (insn & (1<<13))
76 96

  
77 97
static void disas_sparc_insn(DisasContext * dc);
......
258 278
    gen_op_movl_T2_im
259 279
};
260 280

  
281
// Sign extending version
282
static GenOpFunc1 * const gen_op_movl_TN_sim[3] = {
283
    gen_op_movl_T0_sim,
284
    gen_op_movl_T1_sim,
285
    gen_op_movl_T2_sim
286
};
287

  
288
#ifdef TARGET_SPARC64
289
#define GEN32(func, NAME) \
290
static GenOpFunc *NAME ## _table [64] = {                                     \
291
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
292
NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7,                                   \
293
NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11,                                 \
294
NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
295
NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
296
NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
297
NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
298
NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
299
NAME ## 32, 0, NAME ## 34, 0, NAME ## 36, 0, NAME ## 38, 0,                   \
300
NAME ## 40, 0, NAME ## 42, 0, NAME ## 44, 0, NAME ## 46, 0,                   \
301
NAME ## 48, 0, NAME ## 50, 0, NAME ## 52, 0, NAME ## 54, 0,                   \
302
NAME ## 56, 0, NAME ## 58, 0, NAME ## 60, 0, NAME ## 62, 0,                   \
303
};                                                                            \
304
static inline void func(int n)                                                \
305
{                                                                             \
306
    NAME ## _table[n]();                                                      \
307
}
308
#else
261 309
#define GEN32(func, NAME) \
262 310
static GenOpFunc *NAME ## _table [32] = {                                     \
263 311
NAME ## 0, NAME ## 1, NAME ## 2, NAME ## 3,                                   \
......
273 321
{                                                                             \
274 322
    NAME ## _table[n]();                                                      \
275 323
}
324
#endif
276 325

  
277 326
/* floating point registers moves */
278 327
GEN32(gen_op_load_fpr_FT0, gen_op_load_fpr_FT0_fprf);
279 328
GEN32(gen_op_load_fpr_FT1, gen_op_load_fpr_FT1_fprf);
280
GEN32(gen_op_load_fpr_FT2, gen_op_load_fpr_FT2_fprf);
281 329
GEN32(gen_op_store_FT0_fpr, gen_op_store_FT0_fpr_fprf);
282 330
GEN32(gen_op_store_FT1_fpr, gen_op_store_FT1_fpr_fprf);
283
GEN32(gen_op_store_FT2_fpr, gen_op_store_FT2_fpr_fprf);
284 331

  
285 332
GEN32(gen_op_load_fpr_DT0, gen_op_load_fpr_DT0_fprf);
286 333
GEN32(gen_op_load_fpr_DT1, gen_op_load_fpr_DT1_fprf);
287
GEN32(gen_op_load_fpr_DT2, gen_op_load_fpr_DT2_fprf);
288 334
GEN32(gen_op_store_DT0_fpr, gen_op_store_DT0_fpr_fprf);
289 335
GEN32(gen_op_store_DT1_fpr, gen_op_store_DT1_fpr_fprf);
290
GEN32(gen_op_store_DT2_fpr, gen_op_store_DT2_fpr_fprf);
291 336

  
337
#ifdef TARGET_SPARC64
338
// 'a' versions allowed to user depending on asi
339
#if defined(CONFIG_USER_ONLY)
340
#define supervisor(dc) 0
341
#define gen_op_ldst(name)        gen_op_##name##_raw()
342
#define OP_LD_TABLE(width)						\
343
    static void gen_op_##width##a(int insn, int is_ld, int size, int sign) \
344
    {									\
345
	int asi, offset;						\
346
									\
347
	if (IS_IMM) {							\
348
	    offset = GET_FIELD(insn, 25, 31);				\
349
	    if (is_ld)							\
350
		gen_op_ld_asi_reg(offset, size, sign);			\
351
	    else							\
352
		gen_op_st_asi_reg(offset, size, sign);			\
353
	    return;							\
354
	}								\
355
	asi = GET_FIELD(insn, 19, 26);					\
356
	switch (asi) {							\
357
	case 0x80: /* Primary address space */				\
358
	    gen_op_##width##_raw();					\
359
	    break;							\
360
	default:							\
361
            break;							\
362
	}								\
363
    }
364

  
365
#else
366
#define gen_op_ldst(name)        (*gen_op_##name[dc->mem_idx])()
367
#define OP_LD_TABLE(width)						\
368
    static GenOpFunc *gen_op_##width[] = {				\
369
	&gen_op_##width##_user,						\
370
	&gen_op_##width##_kernel,					\
371
    };									\
372
									\
373
    static void gen_op_##width##a(int insn, int is_ld, int size, int sign) \
374
    {									\
375
	int asi, offset;						\
376
									\
377
	if (IS_IMM) {							\
378
	    offset = GET_FIELD(insn, 25, 31);				\
379
	    if (is_ld)							\
380
		gen_op_ld_asi_reg(offset, size, sign);			\
381
	    else							\
382
		gen_op_st_asi_reg(offset, size, sign);			\
383
	    return;							\
384
	}								\
385
	asi = GET_FIELD(insn, 19, 26);					\
386
	if (is_ld)							\
387
	    gen_op_ld_asi(asi, size, sign);				\
388
	else								\
389
	    gen_op_st_asi(asi, size, sign);				\
390
    }
391

  
392
#define supervisor(dc) (dc->mem_idx == 1)
393
#endif
394
#else
292 395
#if defined(CONFIG_USER_ONLY)
293 396
#define gen_op_ldst(name)        gen_op_##name##_raw()
294 397
#define OP_LD_TABLE(width)
......
330 433

  
331 434
#define supervisor(dc) (dc->mem_idx == 1)
332 435
#endif
436
#endif
333 437

  
334 438
OP_LD_TABLE(ld);
335 439
OP_LD_TABLE(st);
......
348 452
OP_LD_TABLE(ldf);
349 453
OP_LD_TABLE(lddf);
350 454

  
351
static inline void gen_movl_imm_TN(int reg, int imm)
455
#ifdef TARGET_SPARC64
456
OP_LD_TABLE(ldsw);
457
OP_LD_TABLE(ldx);
458
OP_LD_TABLE(stx);
459
OP_LD_TABLE(cas);
460
OP_LD_TABLE(casx);
461
#endif
462

  
463
static inline void gen_movl_imm_TN(int reg, uint32_t imm)
352 464
{
353 465
    gen_op_movl_TN_im[reg] (imm);
354 466
}
355 467

  
356
static inline void gen_movl_imm_T1(int val)
468
static inline void gen_movl_imm_T1(uint32_t val)
357 469
{
358 470
    gen_movl_imm_TN(1, val);
359 471
}
360 472

  
361
static inline void gen_movl_imm_T0(int val)
473
static inline void gen_movl_imm_T0(uint32_t val)
362 474
{
363 475
    gen_movl_imm_TN(0, val);
364 476
}
365 477

  
478
static inline void gen_movl_simm_TN(int reg, int32_t imm)
479
{
480
    gen_op_movl_TN_sim[reg](imm);
481
}
482

  
483
static inline void gen_movl_simm_T1(int32_t val)
484
{
485
    gen_movl_simm_TN(1, val);
486
}
487

  
488
static inline void gen_movl_simm_T0(int32_t val)
489
{
490
    gen_movl_simm_TN(0, val);
491
}
492

  
366 493
static inline void gen_movl_reg_TN(int reg, int t)
367 494
{
368 495
    if (reg)
......
411 538
    }
412 539
}
413 540

  
541
static inline void gen_jmp_im(target_ulong pc)
542
{
543
#ifdef TARGET_SPARC64
544
    if (pc == (uint32_t)pc) {
545
        gen_op_jmp_im(pc);
546
    } else {
547
        gen_op_jmp_im64(pc >> 32, pc);
548
    }
549
#else
550
    gen_op_jmp_im(pc);
551
#endif
552
}
553

  
554
static inline void gen_movl_npc_im(target_ulong npc)
555
{
556
#ifdef TARGET_SPARC64
557
    if (npc == (uint32_t)npc) {
558
        gen_op_movl_npc_im(npc);
559
    } else {
560
        gen_op_movq_npc_im64(npc >> 32, npc);
561
    }
562
#else
563
    gen_op_movl_npc_im(npc);
564
#endif
565
}
566

  
414 567
static inline void save_npc(DisasContext * dc)
415 568
{
416 569
    if (dc->npc == JUMP_PC) {
417 570
        gen_op_generic_branch(dc->jump_pc[0], dc->jump_pc[1]);
418 571
        dc->npc = DYNAMIC_PC;
419 572
    } else if (dc->npc != DYNAMIC_PC) {
420
        gen_op_movl_npc_im(dc->npc);
573
        gen_movl_npc_im(dc->npc);
421 574
    }
422 575
}
423 576

  
424 577
static inline void save_state(DisasContext * dc)
425 578
{
426
    gen_op_jmp_im(dc->pc);
579
    gen_jmp_im(dc->pc);
427 580
    save_npc(dc);
428 581
}
429 582

  
......
441 594
    }
442 595
}
443 596

  
444
static void gen_cond(int cond)
445
{
446
	switch (cond) {
447
	case 0x1:
448
	    gen_op_eval_be();
449
	    break;
450
	case 0x2:
451
	    gen_op_eval_ble();
452
	    break;
453
	case 0x3:
454
	    gen_op_eval_bl();
455
	    break;
456
	case 0x4:
457
	    gen_op_eval_bleu();
458
	    break;
459
	case 0x5:
460
	    gen_op_eval_bcs();
461
	    break;
462
	case 0x6:
463
	    gen_op_eval_bneg();
464
	    break;
465
	case 0x7:
466
	    gen_op_eval_bvs();
467
	    break;
468
	case 0x9:
469
	    gen_op_eval_bne();
470
	    break;
471
	case 0xa:
472
	    gen_op_eval_bg();
473
	    break;
474
	case 0xb:
475
	    gen_op_eval_bge();
476
	    break;
477
	case 0xc:
478
	    gen_op_eval_bgu();
479
	    break;
480
	case 0xd:
481
	    gen_op_eval_bcc();
482
	    break;
483
	case 0xe:
484
	    gen_op_eval_bpos();
485
	    break;
486
        default:
487
	case 0xf:
488
	    gen_op_eval_bvc();
489
	    break;
490
	}
491
}
597
static GenOpFunc * const gen_cond[2][16] = {
598
    {
599
	gen_op_eval_ba,
600
	gen_op_eval_be,
601
	gen_op_eval_ble,
602
	gen_op_eval_bl,
603
	gen_op_eval_bleu,
604
	gen_op_eval_bcs,
605
	gen_op_eval_bneg,
606
	gen_op_eval_bvs,
607
	gen_op_eval_bn,
608
	gen_op_eval_bne,
609
	gen_op_eval_bg,
610
	gen_op_eval_bge,
611
	gen_op_eval_bgu,
612
	gen_op_eval_bcc,
613
	gen_op_eval_bpos,
614
	gen_op_eval_bvc,
615
    },
616
    {
617
#ifdef TARGET_SPARC64
618
	gen_op_eval_ba,
619
	gen_op_eval_xbe,
620
	gen_op_eval_xble,
621
	gen_op_eval_xbl,
622
	gen_op_eval_xbleu,
623
	gen_op_eval_xbcs,
624
	gen_op_eval_xbneg,
625
	gen_op_eval_xbvs,
626
	gen_op_eval_bn,
627
	gen_op_eval_xbne,
628
	gen_op_eval_xbg,
629
	gen_op_eval_xbge,
630
	gen_op_eval_xbgu,
631
	gen_op_eval_xbcc,
632
	gen_op_eval_xbpos,
633
	gen_op_eval_xbvc,
634
#endif
635
    },
636
};
637

  
638
static GenOpFunc * const gen_fcond[4][16] = {
639
    {
640
	gen_op_eval_ba,
641
	gen_op_eval_fbne,
642
	gen_op_eval_fblg,
643
	gen_op_eval_fbul,
644
	gen_op_eval_fbl,
645
	gen_op_eval_fbug,
646
	gen_op_eval_fbg,
647
	gen_op_eval_fbu,
648
	gen_op_eval_bn,
649
	gen_op_eval_fbe,
650
	gen_op_eval_fbue,
651
	gen_op_eval_fbge,
652
	gen_op_eval_fbuge,
653
	gen_op_eval_fble,
654
	gen_op_eval_fbule,
655
	gen_op_eval_fbo,
656
    },
657
#ifdef TARGET_SPARC64
658
    {
659
	gen_op_eval_ba,
660
	gen_op_eval_fbne_fcc1,
661
	gen_op_eval_fblg_fcc1,
662
	gen_op_eval_fbul_fcc1,
663
	gen_op_eval_fbl_fcc1,
664
	gen_op_eval_fbug_fcc1,
665
	gen_op_eval_fbg_fcc1,
666
	gen_op_eval_fbu_fcc1,
667
	gen_op_eval_bn,
668
	gen_op_eval_fbe_fcc1,
669
	gen_op_eval_fbue_fcc1,
670
	gen_op_eval_fbge_fcc1,
671
	gen_op_eval_fbuge_fcc1,
672
	gen_op_eval_fble_fcc1,
673
	gen_op_eval_fbule_fcc1,
674
	gen_op_eval_fbo_fcc1,
675
    },
676
    {
677
	gen_op_eval_ba,
678
	gen_op_eval_fbne_fcc2,
679
	gen_op_eval_fblg_fcc2,
680
	gen_op_eval_fbul_fcc2,
681
	gen_op_eval_fbl_fcc2,
682
	gen_op_eval_fbug_fcc2,
683
	gen_op_eval_fbg_fcc2,
684
	gen_op_eval_fbu_fcc2,
685
	gen_op_eval_bn,
686
	gen_op_eval_fbe_fcc2,
687
	gen_op_eval_fbue_fcc2,
688
	gen_op_eval_fbge_fcc2,
689
	gen_op_eval_fbuge_fcc2,
690
	gen_op_eval_fble_fcc2,
691
	gen_op_eval_fbule_fcc2,
692
	gen_op_eval_fbo_fcc2,
693
    },
694
    {
695
	gen_op_eval_ba,
696
	gen_op_eval_fbne_fcc3,
697
	gen_op_eval_fblg_fcc3,
698
	gen_op_eval_fbul_fcc3,
699
	gen_op_eval_fbl_fcc3,
700
	gen_op_eval_fbug_fcc3,
701
	gen_op_eval_fbg_fcc3,
702
	gen_op_eval_fbu_fcc3,
703
	gen_op_eval_bn,
704
	gen_op_eval_fbe_fcc3,
705
	gen_op_eval_fbue_fcc3,
706
	gen_op_eval_fbge_fcc3,
707
	gen_op_eval_fbuge_fcc3,
708
	gen_op_eval_fble_fcc3,
709
	gen_op_eval_fbule_fcc3,
710
	gen_op_eval_fbo_fcc3,
711
    },
712
#else
713
    {}, {}, {},
714
#endif
715
};
492 716

  
493
static void gen_fcond(int cond)
717
#ifdef TARGET_SPARC64
718
static void gen_cond_reg(int cond)
494 719
{
495 720
	switch (cond) {
496 721
	case 0x1:
497
	    gen_op_eval_fbne();
722
	    gen_op_eval_brz();
498 723
	    break;
499 724
	case 0x2:
500
	    gen_op_eval_fblg();
725
	    gen_op_eval_brlez();
501 726
	    break;
502 727
	case 0x3:
503
	    gen_op_eval_fbul();
504
	    break;
505
	case 0x4:
506
	    gen_op_eval_fbl();
728
	    gen_op_eval_brlz();
507 729
	    break;
508 730
	case 0x5:
509
	    gen_op_eval_fbug();
731
	    gen_op_eval_brnz();
510 732
	    break;
511 733
	case 0x6:
512
	    gen_op_eval_fbg();
513
	    break;
514
	case 0x7:
515
	    gen_op_eval_fbu();
516
	    break;
517
	case 0x9:
518
	    gen_op_eval_fbe();
519
	    break;
520
	case 0xa:
521
	    gen_op_eval_fbue();
522
	    break;
523
	case 0xb:
524
	    gen_op_eval_fbge();
525
	    break;
526
	case 0xc:
527
	    gen_op_eval_fbuge();
528
	    break;
529
	case 0xd:
530
	    gen_op_eval_fble();
531
	    break;
532
	case 0xe:
533
	    gen_op_eval_fbule();
734
	    gen_op_eval_brgz();
534 735
	    break;
535 736
        default:
536
	case 0xf:
537
	    gen_op_eval_fbo();
737
	case 0x7:
738
	    gen_op_eval_brgez();
538 739
	    break;
539 740
	}
540 741
}
742
#endif
541 743

  
542 744
/* XXX: potentially incorrect if dynamic npc */
543
static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn)
745
static void do_branch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
544 746
{
545 747
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
546 748
    target_ulong target = dc->pc + offset;
547

  
749
	
548 750
    if (cond == 0x0) {
549 751
	/* unconditional not taken */
550 752
	if (a) {
......
565 767
	}
566 768
    } else {
567 769
        flush_T2(dc);
568
        gen_cond(cond);
770
        gen_cond[cc][cond]();
569 771
	if (a) {
570 772
	    gen_op_branch_a((long)dc->tb, target, dc->npc);
571 773
            dc->is_br = 1;
......
579 781
}
580 782

  
581 783
/* XXX: potentially incorrect if dynamic npc */
582
static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn)
784
static void do_fbranch(DisasContext * dc, int32_t offset, uint32_t insn, int cc)
583 785
{
584 786
    unsigned int cond = GET_FIELD(insn, 3, 6), a = (insn & (1 << 29));
585 787
    target_ulong target = dc->pc + offset;
......
604 806
	}
605 807
    } else {
606 808
        flush_T2(dc);
607
        gen_fcond(cond);
809
        gen_fcond[cc][cond]();
608 810
	if (a) {
609 811
	    gen_op_branch_a((long)dc->tb, target, dc->npc);
610 812
            dc->is_br = 1;
......
617 819
    }
618 820
}
619 821

  
620
#define GET_FIELDs(x,a,b) sign_extend (GET_FIELD(x,a,b), (b) - (a) + 1)
621

  
622
static int sign_extend(int x, int len)
822
#ifdef TARGET_SPARC64
823
/* XXX: potentially incorrect if dynamic npc */
824
static void do_branch_reg(DisasContext * dc, int32_t offset, uint32_t insn)
623 825
{
624
    len = 32 - len;
625
    return (x << len) >> len;
826
    unsigned int cond = GET_FIELD_SP(insn, 25, 27), a = (insn & (1 << 29));
827
    target_ulong target = dc->pc + offset;
828

  
829
    flush_T2(dc);
830
    gen_cond_reg(cond);
831
    if (a) {
832
	gen_op_branch_a((long)dc->tb, target, dc->npc);
833
	dc->is_br = 1;
834
    } else {
835
	dc->pc = dc->npc;
836
	dc->jump_pc[0] = target;
837
	dc->jump_pc[1] = dc->npc + 4;
838
	dc->npc = JUMP_PC;
839
    }
626 840
}
627 841

  
842
static GenOpFunc * const gen_fcmps[4] = {
843
    gen_op_fcmps,
844
    gen_op_fcmps_fcc1,
845
    gen_op_fcmps_fcc2,
846
    gen_op_fcmps_fcc3,
847
};
848

  
849
static GenOpFunc * const gen_fcmpd[4] = {
850
    gen_op_fcmpd,
851
    gen_op_fcmpd_fcc1,
852
    gen_op_fcmpd_fcc2,
853
    gen_op_fcmpd_fcc3,
854
};
855
#endif
856

  
628 857
/* before an instruction, dc->pc must be static */
629 858
static void disas_sparc_insn(DisasContext * dc)
630 859
{
......
639 868
	{
640 869
	    unsigned int xop = GET_FIELD(insn, 7, 9);
641 870
	    int32_t target;
642
	    target = GET_FIELD(insn, 10, 31);
643 871
	    switch (xop) {
644
	    case 0x0:		/* UNIMPL */
872
#ifdef TARGET_SPARC64
645 873
	    case 0x1:		/* V9 BPcc */
874
		{
875
		    int cc;
876

  
877
		    target = GET_FIELD_SP(insn, 0, 18);
878
		    target <<= 2;
879
		    target = sign_extend(target, 18);
880
		    cc = GET_FIELD_SP(insn, 20, 21);
881
		    if (cc == 0)
882
			do_branch(dc, target, insn, 0);
883
		    else if (cc == 2)
884
			do_branch(dc, target, insn, 1);
885
		    else
886
			goto illegal_insn;
887
		    goto jmp_insn;
888
		}
646 889
	    case 0x3:		/* V9 BPr */
890
		{
891
		    target = GET_FIELD_SP(insn, 0, 13) | 
892
			(GET_FIELD_SP(insn, 20, 21) >> 7);
893
		    target <<= 2;
894
		    target = sign_extend(target, 16);
895
		    rs1 = GET_FIELD(insn, 13, 17);
896
		    gen_movl_T0_reg(rs1);
897
		    do_branch_reg(dc, target, insn);
898
		    goto jmp_insn;
899
		}
647 900
	    case 0x5:		/* V9 FBPcc */
648
	    default:
649
                goto illegal_insn;
901
		{
902
		    int cc = GET_FIELD_SP(insn, 20, 21);
903
#if !defined(CONFIG_USER_ONLY)
904
		    gen_op_trap_ifnofpu();
905
#endif
906
		    target = GET_FIELD_SP(insn, 0, 18);
907
		    target <<= 2;
908
		    target = sign_extend(target, 19);
909
		    do_fbranch(dc, target, insn, cc);
910
		    goto jmp_insn;
911
		}
912
#endif
650 913
	    case 0x2:		/* BN+x */
651 914
		{
915
		    target = GET_FIELD(insn, 10, 31);
652 916
		    target <<= 2;
653 917
		    target = sign_extend(target, 22);
654
		    do_branch(dc, target, insn);
918
		    do_branch(dc, target, insn, 0);
655 919
		    goto jmp_insn;
656 920
		}
657 921
	    case 0x6:		/* FBN+x */
......
659 923
#if !defined(CONFIG_USER_ONLY)
660 924
		    gen_op_trap_ifnofpu();
661 925
#endif
926
		    target = GET_FIELD(insn, 10, 31);
662 927
		    target <<= 2;
663 928
		    target = sign_extend(target, 22);
664
		    do_fbranch(dc, target, insn);
929
		    do_fbranch(dc, target, insn, 0);
665 930
		    goto jmp_insn;
666 931
		}
667 932
	    case 0x4:		/* SETHI */
......
669 934
#if defined(OPTIM)
670 935
		if (rd) { // nop
671 936
#endif
672
		    gen_movl_imm_T0(target << 10);
937
		    uint32_t value = GET_FIELD(insn, 10, 31);
938
		    gen_movl_imm_T0(value << 10);
673 939
		    gen_movl_T0_reg(rd);
674 940
#if defined(OPTIM)
675 941
		}
676 942
#endif
677 943
		break;
944
	    case 0x0:		/* UNIMPL */
945
	    default:
946
                goto illegal_insn;
678 947
	    }
679 948
	    break;
680 949
	}
......
695 964
	    unsigned int xop = GET_FIELD(insn, 7, 12);
696 965
	    if (xop == 0x3a) {	/* generate trap */
697 966
                int cond;
967

  
698 968
                rs1 = GET_FIELD(insn, 13, 17);
699 969
                gen_movl_reg_T0(rs1);
700 970
		if (IS_IMM) {
......
702 972
#if defined(OPTIM)
703 973
		    if (rs2 != 0) {
704 974
#endif
705
			gen_movl_imm_T1(rs2);
975
			gen_movl_simm_T1(rs2);
706 976
			gen_op_add_T1_T0();
707 977
#if defined(OPTIM)
708 978
		    }
......
719 989
#endif
720 990
                }
721 991
                save_state(dc);
722
		/* V9 icc/xcc */
723 992
                cond = GET_FIELD(insn, 3, 6);
724 993
                if (cond == 0x8) {
725 994
                    gen_op_trap_T0();
726 995
                    dc->is_br = 1;
727 996
                    goto jmp_insn;
728 997
                } else if (cond != 0) {
729
		    gen_cond(cond);
998
#ifdef TARGET_SPARC64
999
		    /* V9 icc/xcc */
1000
		    int cc = GET_FIELD_SP(insn, 11, 12);
1001
		    if (cc == 0)
1002
			gen_cond[0][cond]();
1003
		    else if (cc == 2)
1004
			gen_cond[1][cond]();
1005
		    else
1006
			goto illegal_insn;
1007
#else
1008
		    gen_cond[0][cond]();
1009
#endif
730 1010
                    gen_op_trapcc_T0();
731 1011
                }
732 1012
            } else if (xop == 0x28) {
733 1013
                rs1 = GET_FIELD(insn, 13, 17);
734 1014
                switch(rs1) {
735 1015
                case 0: /* rdy */
736
                    gen_op_rdy();
1016
		    gen_op_movtl_T0_env(offsetof(CPUSPARCState, y));
737 1017
                    gen_movl_T0_reg(rd);
738 1018
                    break;
739 1019
                case 15: /* stbar / V9 membar */
740 1020
		    break; /* no effect? */
741
                default:
1021
#ifdef TARGET_SPARC64
742 1022
		case 0x2: /* V9 rdccr */
1023
                    gen_op_rdccr();
1024
                    gen_movl_T0_reg(rd);
1025
                    break;
743 1026
		case 0x3: /* V9 rdasi */
1027
		    gen_op_movl_T0_env(offsetof(CPUSPARCState, asi));
1028
                    gen_movl_T0_reg(rd);
1029
                    break;
744 1030
		case 0x4: /* V9 rdtick */
1031
                    gen_op_rdtick();
1032
                    gen_movl_T0_reg(rd);
1033
                    break;
745 1034
		case 0x5: /* V9 rdpc */
1035
		    gen_op_movl_T0_im(dc->pc);
1036
		    gen_movl_T0_reg(rd);
1037
		    break;
746 1038
		case 0x6: /* V9 rdfprs */
1039
		    gen_op_movl_T0_env(offsetof(CPUSPARCState, fprs));
1040
                    gen_movl_T0_reg(rd);
1041
                    break;
1042
#endif
1043
                default:
747 1044
                    goto illegal_insn;
748 1045
                }
749 1046
#if !defined(CONFIG_USER_ONLY)
750
            } else if (xop == 0x29) {
1047
#ifndef TARGET_SPARC64
1048
            } else if (xop == 0x29) { /* rdpsr / V9 unimp */
751 1049
		if (!supervisor(dc))
752 1050
		    goto priv_insn;
753 1051
                gen_op_rdpsr();
754 1052
                gen_movl_T0_reg(rd);
755 1053
                break;
756
            } else if (xop == 0x2a) {
1054
#endif
1055
            } else if (xop == 0x2a) { /* rdwim / V9 rdpr */
757 1056
		if (!supervisor(dc))
758 1057
		    goto priv_insn;
759
                gen_op_rdwim();
1058
#ifdef TARGET_SPARC64
1059
                rs1 = GET_FIELD(insn, 13, 17);
1060
		switch (rs1) {
1061
		case 0: // tpc
1062
		    gen_op_rdtpc();
1063
		    break;
1064
		case 1: // tnpc
1065
		    gen_op_rdtnpc();
1066
		    break;
1067
		case 2: // tstate
1068
		    gen_op_rdtstate();
1069
		    break;
1070
		case 3: // tt
1071
		    gen_op_rdtt();
1072
		    break;
1073
		case 4: // tick
1074
		    gen_op_rdtick();
1075
		    break;
1076
		case 5: // tba
1077
		    gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
1078
		    break;
1079
		case 6: // pstate
1080
		    gen_op_rdpstate();
1081
		    break;
1082
		case 7: // tl
1083
		    gen_op_movl_T0_env(offsetof(CPUSPARCState, tl));
1084
		    break;
1085
		case 8: // pil
1086
		    gen_op_movl_T0_env(offsetof(CPUSPARCState, psrpil));
1087
		    break;
1088
		case 9: // cwp
1089
		    gen_op_rdcwp();
1090
		    break;
1091
		case 10: // cansave
1092
		    gen_op_movl_T0_env(offsetof(CPUSPARCState, cansave));
1093
		    break;
1094
		case 11: // canrestore
1095
		    gen_op_movl_T0_env(offsetof(CPUSPARCState, canrestore));
1096
		    break;
1097
		case 12: // cleanwin
1098
		    gen_op_movl_T0_env(offsetof(CPUSPARCState, cleanwin));
1099
		    break;
1100
		case 13: // otherwin
1101
		    gen_op_movl_T0_env(offsetof(CPUSPARCState, otherwin));
1102
		    break;
1103
		case 14: // wstate
1104
		    gen_op_movl_T0_env(offsetof(CPUSPARCState, wstate));
1105
		    break;
1106
		case 31: // ver
1107
		    gen_op_movtl_T0_env(offsetof(CPUSPARCState, version));
1108
		    break;
1109
		case 15: // fq
1110
		default:
1111
		    goto illegal_insn;
1112
		}
1113
#else
1114
		gen_op_movl_T0_env(offsetof(CPUSPARCState, wim));
1115
#endif
760 1116
                gen_movl_T0_reg(rd);
761 1117
                break;
762
            } else if (xop == 0x2b) {
1118
            } else if (xop == 0x2b) { /* rdtbr / V9 flushw */
1119
#ifdef TARGET_SPARC64
1120
		gen_op_flushw();
1121
#else
763 1122
		if (!supervisor(dc))
764 1123
		    goto priv_insn;
765
                gen_op_rdtbr();
1124
		gen_op_movtl_T0_env(offsetof(CPUSPARCState, tbr));
766 1125
                gen_movl_T0_reg(rd);
1126
#endif
767 1127
                break;
768 1128
#endif
769 1129
	    } else if (xop == 0x34) {	/* FPU Operations */
......
794 1154
			gen_op_store_FT0_fpr(rd);
795 1155
			break;
796 1156
		    case 0x2a: /* fsqrtd */
797
                	gen_op_load_fpr_DT1(rs2);
1157
                	gen_op_load_fpr_DT1(DFPREG(rs2));
798 1158
			gen_op_fsqrtd();
799
			gen_op_store_DT0_fpr(rd);
1159
			gen_op_store_DT0_fpr(DFPREG(rd));
800 1160
			break;
801 1161
		    case 0x2b: /* fsqrtq */
802 1162
		        goto nfpu_insn;
......
807 1167
			gen_op_store_FT0_fpr(rd);
808 1168
			break;
809 1169
		    case 0x42:
810
                	gen_op_load_fpr_DT0(rs1);
811
                	gen_op_load_fpr_DT1(rs2);
1170
                	gen_op_load_fpr_DT0(DFPREG(rs1));
1171
                	gen_op_load_fpr_DT1(DFPREG(rs2));
812 1172
			gen_op_faddd();
813
			gen_op_store_DT0_fpr(rd);
1173
			gen_op_store_DT0_fpr(DFPREG(rd));
814 1174
			break;
815 1175
		    case 0x43: /* faddq */
816 1176
		        goto nfpu_insn;
......
821 1181
			gen_op_store_FT0_fpr(rd);
822 1182
			break;
823 1183
		    case 0x46:
824
                	gen_op_load_fpr_DT0(rs1);
825
                	gen_op_load_fpr_DT1(rs2);
1184
                	gen_op_load_fpr_DT0(DFPREG(rs1));
1185
                	gen_op_load_fpr_DT1(DFPREG(rs2));
826 1186
			gen_op_fsubd();
827
			gen_op_store_DT0_fpr(rd);
1187
			gen_op_store_DT0_fpr(DFPREG(rd));
828 1188
			break;
829 1189
		    case 0x47: /* fsubq */
830 1190
		        goto nfpu_insn;
......
835 1195
			gen_op_store_FT0_fpr(rd);
836 1196
			break;
837 1197
		    case 0x4a:
838
                	gen_op_load_fpr_DT0(rs1);
839
                	gen_op_load_fpr_DT1(rs2);
1198
                	gen_op_load_fpr_DT0(DFPREG(rs1));
1199
                	gen_op_load_fpr_DT1(DFPREG(rs2));
840 1200
			gen_op_fmuld();
841 1201
			gen_op_store_DT0_fpr(rd);
842 1202
			break;
......
849 1209
			gen_op_store_FT0_fpr(rd);
850 1210
			break;
851 1211
		    case 0x4e:
852
                	gen_op_load_fpr_DT0(rs1);
853
                	gen_op_load_fpr_DT1(rs2);
1212
                	gen_op_load_fpr_DT0(DFPREG(rs1));
1213
			gen_op_load_fpr_DT1(DFPREG(rs2));
854 1214
			gen_op_fdivd();
855
			gen_op_store_DT0_fpr(rd);
1215
			gen_op_store_DT0_fpr(DFPREG(rd));
856 1216
			break;
857 1217
		    case 0x4f: /* fdivq */
858 1218
		        goto nfpu_insn;
......
860 1220
                	gen_op_load_fpr_FT0(rs1);
861 1221
                	gen_op_load_fpr_FT1(rs2);
862 1222
			gen_op_fsmuld();
863
			gen_op_store_DT0_fpr(rd);
1223
			gen_op_store_DT0_fpr(DFPREG(rd));
864 1224
			break;
865 1225
		    case 0x6e: /* fdmulq */
866 1226
		        goto nfpu_insn;
......
870 1230
			gen_op_store_FT0_fpr(rd);
871 1231
			break;
872 1232
		    case 0xc6:
873
                	gen_op_load_fpr_DT1(rs2);
1233
                	gen_op_load_fpr_DT1(DFPREG(rs2));
874 1234
			gen_op_fdtos();
875 1235
			gen_op_store_FT0_fpr(rd);
876 1236
			break;
......
879 1239
		    case 0xc8:
880 1240
                	gen_op_load_fpr_FT1(rs2);
881 1241
			gen_op_fitod();
882
			gen_op_store_DT0_fpr(rd);
1242
			gen_op_store_DT0_fpr(DFPREG(rd));
883 1243
			break;
884 1244
		    case 0xc9:
885 1245
                	gen_op_load_fpr_FT1(rs2);
886 1246
			gen_op_fstod();
887
			gen_op_store_DT0_fpr(rd);
1247
			gen_op_store_DT0_fpr(DFPREG(rd));
888 1248
			break;
889 1249
		    case 0xcb: /* fqtod */
890 1250
		        goto nfpu_insn;
......
906 1266
			break;
907 1267
		    case 0xd3: /* fqtoi */
908 1268
		        goto nfpu_insn;
909
		    default:
1269
#ifdef TARGET_SPARC64
910 1270
		    case 0x2: /* V9 fmovd */
1271
                	gen_op_load_fpr_DT0(DFPREG(rs2));
1272
			gen_op_store_DT0_fpr(DFPREG(rd));
1273
			break;
911 1274
		    case 0x6: /* V9 fnegd */
1275
                	gen_op_load_fpr_DT1(DFPREG(rs2));
1276
			gen_op_fnegd();
1277
			gen_op_store_DT0_fpr(DFPREG(rd));
1278
			break;
912 1279
		    case 0xa: /* V9 fabsd */
1280
                	gen_op_load_fpr_DT1(DFPREG(rs2));
1281
			gen_op_fabsd();
1282
			gen_op_store_DT0_fpr(DFPREG(rd));
1283
			break;
913 1284
		    case 0x81: /* V9 fstox */
1285
                	gen_op_load_fpr_FT1(rs2);
1286
			gen_op_fstox();
1287
			gen_op_store_DT0_fpr(DFPREG(rd));
1288
			break;
914 1289
		    case 0x82: /* V9 fdtox */
1290
                	gen_op_load_fpr_DT1(DFPREG(rs2));
1291
			gen_op_fdtox();
1292
			gen_op_store_DT0_fpr(DFPREG(rd));
1293
			break;
915 1294
		    case 0x84: /* V9 fxtos */
1295
                	gen_op_load_fpr_DT1(DFPREG(rs2));
1296
			gen_op_fxtos();
1297
			gen_op_store_FT0_fpr(rd);
1298
			break;
916 1299
		    case 0x88: /* V9 fxtod */
917

  
1300
                	gen_op_load_fpr_DT1(DFPREG(rs2));
1301
			gen_op_fxtod();
1302
			gen_op_store_DT0_fpr(DFPREG(rd));
1303
			break;
918 1304
		    case 0x3: /* V9 fmovq */
919 1305
		    case 0x7: /* V9 fnegq */
920 1306
		    case 0xb: /* V9 fabsq */
921 1307
		    case 0x83: /* V9 fqtox */
922 1308
		    case 0x8c: /* V9 fxtoq */
1309
		        goto nfpu_insn;
1310
#endif
1311
		    default:
923 1312
                	goto illegal_insn;
924 1313
		}
925 1314
	    } else if (xop == 0x35) {	/* FPU Operations */
1315
#ifdef TARGET_SPARC64
1316
		int cond;
1317
#endif
926 1318
#if !defined(CONFIG_USER_ONLY)
927 1319
		gen_op_trap_ifnofpu();
928 1320
#endif
929 1321
                rs1 = GET_FIELD(insn, 13, 17);
930 1322
	        rs2 = GET_FIELD(insn, 27, 31);
931 1323
	        xop = GET_FIELD(insn, 18, 26);
932
		/* V9 fmovscc: x5, cond = x >> 1 */
933
		/* V9 fmovdcc: x6, cond = x >> 1 */
934

  
935
		/* V9 fmovqcc: x7, cond = x >> 1 */
1324
#ifdef TARGET_SPARC64
1325
		if ((xop & 0x11f) == 0x005) { // V9 fmovsr
1326
		    cond = GET_FIELD_SP(insn, 14, 17);
1327
		    gen_op_load_fpr_FT0(rd);
1328
		    gen_op_load_fpr_FT1(rs2);
1329
		    rs1 = GET_FIELD(insn, 13, 17);
1330
		    gen_movl_reg_T0(rs1);
1331
		    flush_T2(dc);
1332
		    gen_cond_reg(cond);
1333
		    gen_op_fmovs_cc();
1334
		    gen_op_store_FT0_fpr(rd);
1335
		    break;
1336
		} else if ((xop & 0x11f) == 0x006) { // V9 fmovdr
1337
		    cond = GET_FIELD_SP(insn, 14, 17);
1338
		    gen_op_load_fpr_DT0(rd);
1339
		    gen_op_load_fpr_DT1(rs2);
1340
		    flush_T2(dc);
1341
		    rs1 = GET_FIELD(insn, 13, 17);
1342
		    gen_movl_reg_T0(rs1);
1343
		    gen_cond_reg(cond);
1344
		    gen_op_fmovs_cc();
1345
		    gen_op_store_DT0_fpr(rd);
1346
		    break;
1347
		} else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
1348
		    goto nfpu_insn;
1349
		}
1350
#endif
936 1351
		switch (xop) {
937
		    case 0x51:
1352
#ifdef TARGET_SPARC64
1353
		    case 0x001: /* V9 fmovscc %fcc0 */
1354
			cond = GET_FIELD_SP(insn, 14, 17);
1355
                	gen_op_load_fpr_FT0(rd);
1356
                	gen_op_load_fpr_FT1(rs2);
1357
			flush_T2(dc);
1358
			gen_fcond[0][cond]();
1359
			gen_op_fmovs_cc();
1360
			gen_op_store_FT0_fpr(rd);
1361
			break;
1362
		    case 0x002: /* V9 fmovdcc %fcc0 */
1363
			cond = GET_FIELD_SP(insn, 14, 17);
1364
                	gen_op_load_fpr_DT0(rd);
1365
                	gen_op_load_fpr_DT1(rs2);
1366
			flush_T2(dc);
1367
			gen_fcond[0][cond]();
1368
			gen_op_fmovd_cc();
1369
			gen_op_store_DT0_fpr(rd);
1370
			break;
1371
		    case 0x003: /* V9 fmovqcc %fcc0 */
1372
		        goto nfpu_insn;
1373
		    case 0x041: /* V9 fmovscc %fcc1 */
1374
			cond = GET_FIELD_SP(insn, 14, 17);
1375
                	gen_op_load_fpr_FT0(rd);
1376
                	gen_op_load_fpr_FT1(rs2);
1377
			flush_T2(dc);
1378
			gen_fcond[1][cond]();
1379
			gen_op_fmovs_cc();
1380
			gen_op_store_FT0_fpr(rd);
1381
			break;
1382
		    case 0x042: /* V9 fmovdcc %fcc1 */
1383
			cond = GET_FIELD_SP(insn, 14, 17);
1384
                	gen_op_load_fpr_DT0(rd);
1385
                	gen_op_load_fpr_DT1(rs2);
1386
			flush_T2(dc);
1387
			gen_fcond[1][cond]();
1388
			gen_op_fmovd_cc();
1389
			gen_op_store_DT0_fpr(rd);
1390
			break;
1391
		    case 0x043: /* V9 fmovqcc %fcc1 */
1392
		        goto nfpu_insn;
1393
		    case 0x081: /* V9 fmovscc %fcc2 */
1394
			cond = GET_FIELD_SP(insn, 14, 17);
1395
                	gen_op_load_fpr_FT0(rd);
1396
                	gen_op_load_fpr_FT1(rs2);
1397
			flush_T2(dc);
1398
			gen_fcond[2][cond]();
1399
			gen_op_fmovs_cc();
1400
			gen_op_store_FT0_fpr(rd);
1401
			break;
1402
		    case 0x082: /* V9 fmovdcc %fcc2 */
1403
			cond = GET_FIELD_SP(insn, 14, 17);
1404
                	gen_op_load_fpr_DT0(rd);
1405
                	gen_op_load_fpr_DT1(rs2);
1406
			flush_T2(dc);
1407
			gen_fcond[2][cond]();
1408
			gen_op_fmovd_cc();
1409
			gen_op_store_DT0_fpr(rd);
1410
			break;
1411
		    case 0x083: /* V9 fmovqcc %fcc2 */
1412
		        goto nfpu_insn;
1413
		    case 0x0c1: /* V9 fmovscc %fcc3 */
1414
			cond = GET_FIELD_SP(insn, 14, 17);
1415
                	gen_op_load_fpr_FT0(rd);
1416
                	gen_op_load_fpr_FT1(rs2);
1417
			flush_T2(dc);
1418
			gen_fcond[3][cond]();
1419
			gen_op_fmovs_cc();
1420
			gen_op_store_FT0_fpr(rd);
1421
			break;
1422
		    case 0x0c2: /* V9 fmovdcc %fcc3 */
1423
			cond = GET_FIELD_SP(insn, 14, 17);
1424
                	gen_op_load_fpr_DT0(rd);
1425
                	gen_op_load_fpr_DT1(rs2);
1426
			flush_T2(dc);
1427
			gen_fcond[3][cond]();
1428
			gen_op_fmovd_cc();
1429
			gen_op_store_DT0_fpr(rd);
1430
			break;
1431
		    case 0x0c3: /* V9 fmovqcc %fcc3 */
1432
		        goto nfpu_insn;
1433
		    case 0x101: /* V9 fmovscc %icc */
1434
			cond = GET_FIELD_SP(insn, 14, 17);
1435
                	gen_op_load_fpr_FT0(rd);
1436
                	gen_op_load_fpr_FT1(rs2);
1437
			flush_T2(dc);
1438
			gen_cond[0][cond]();
1439
			gen_op_fmovs_cc();
1440
			gen_op_store_FT0_fpr(rd);
1441
			break;
1442
		    case 0x102: /* V9 fmovdcc %icc */
1443
			cond = GET_FIELD_SP(insn, 14, 17);
1444
                	gen_op_load_fpr_DT0(rd);
1445
                	gen_op_load_fpr_DT1(rs2);
1446
			flush_T2(dc);
1447
			gen_cond[0][cond]();
1448
			gen_op_fmovd_cc();
1449
			gen_op_store_DT0_fpr(rd);
1450
			break;
1451
		    case 0x103: /* V9 fmovqcc %icc */
1452
		        goto nfpu_insn;
1453
		    case 0x181: /* V9 fmovscc %xcc */
1454
			cond = GET_FIELD_SP(insn, 14, 17);
1455
                	gen_op_load_fpr_FT0(rd);
1456
                	gen_op_load_fpr_FT1(rs2);
1457
			flush_T2(dc);
1458
			gen_cond[1][cond]();
1459
			gen_op_fmovs_cc();
1460
			gen_op_store_FT0_fpr(rd);
1461
			break;
1462
		    case 0x182: /* V9 fmovdcc %xcc */
1463
			cond = GET_FIELD_SP(insn, 14, 17);
1464
                	gen_op_load_fpr_DT0(rd);
1465
                	gen_op_load_fpr_DT1(rs2);
1466
			flush_T2(dc);
1467
			gen_cond[1][cond]();
1468
			gen_op_fmovd_cc();
1469
			gen_op_store_DT0_fpr(rd);
1470
			break;
1471
		    case 0x183: /* V9 fmovqcc %xcc */
1472
		        goto nfpu_insn;
1473
#endif
1474
		    case 0x51: /* V9 %fcc */
938 1475
                	gen_op_load_fpr_FT0(rs1);
939 1476
                	gen_op_load_fpr_FT1(rs2);
1477
#ifdef TARGET_SPARC64
1478
			gen_fcmps[rd & 3]();
1479
#else
940 1480
			gen_op_fcmps();
1481
#endif
941 1482
			break;
942
		    case 0x52:
943
                	gen_op_load_fpr_DT0(rs1);
944
                	gen_op_load_fpr_DT1(rs2);
1483
		    case 0x52: /* V9 %fcc */
1484
                	gen_op_load_fpr_DT0(DFPREG(rs1));
1485
                	gen_op_load_fpr_DT1(DFPREG(rs2));
1486
#ifdef TARGET_SPARC64
1487
			gen_fcmpd[rd & 3]();
1488
#else
945 1489
			gen_op_fcmpd();
1490
#endif
946 1491
			break;
947 1492
		    case 0x53: /* fcmpq */
948 1493
		        goto nfpu_insn;
949
		    case 0x55: /* fcmpes */
1494
		    case 0x55: /* fcmpes, V9 %fcc */
950 1495
                	gen_op_load_fpr_FT0(rs1);
951 1496
                	gen_op_load_fpr_FT1(rs2);
1497
#ifdef TARGET_SPARC64
1498
			gen_fcmps[rd & 3]();
1499
#else
952 1500
			gen_op_fcmps(); /* XXX should trap if qNaN or sNaN  */
1501
#endif
953 1502
			break;
954
		    case 0x56: /* fcmped */
955
                	gen_op_load_fpr_DT0(rs1);
956
                	gen_op_load_fpr_DT1(rs2);
1503
		    case 0x56: /* fcmped, V9 %fcc */
1504
                	gen_op_load_fpr_DT0(DFPREG(rs1));
1505
                	gen_op_load_fpr_DT1(DFPREG(rs2));
1506
#ifdef TARGET_SPARC64
1507
			gen_fcmpd[rd & 3]();
1508
#else
957 1509
			gen_op_fcmpd(); /* XXX should trap if qNaN or sNaN  */
1510
#endif
958 1511
			break;
959 1512
		    case 0x57: /* fcmpeq */
960 1513
		        goto nfpu_insn;
......
970 1523
		    // or %g0, x, y -> mov T1, x; mov y, T1
971 1524
		    if (IS_IMM) {	/* immediate */
972 1525
			rs2 = GET_FIELDs(insn, 19, 31);
973
			gen_movl_imm_T1(rs2);
1526
			gen_movl_simm_T1(rs2);
974 1527
		    } else {		/* register */
975 1528
			rs2 = GET_FIELD(insn, 27, 31);
976 1529
			gen_movl_reg_T1(rs2);
......
982 1535
			// or x, #0, y -> mov T1, x; mov y, T1
983 1536
			rs2 = GET_FIELDs(insn, 19, 31);
984 1537
			if (rs2 != 0) {
985
			    gen_movl_imm_T1(rs2);
1538
			    gen_movl_simm_T1(rs2);
986 1539
			    gen_op_or_T1_T0();
987 1540
			}
988 1541
		    } else {		/* register */
......
1001 1554
		gen_movl_reg_T0(rs1);
1002 1555
		if (IS_IMM) {	/* immediate */
1003 1556
                    rs2 = GET_FIELDs(insn, 19, 31);
1004
                    gen_movl_imm_T1(rs2);
1557
                    gen_movl_simm_T1(rs2);
1005 1558
                } else {		/* register */
1006 1559
                    rs2 = GET_FIELD(insn, 27, 31);
1007 1560
                    gen_movl_reg_T1(rs2);
......
1083 1636
                            gen_op_div_cc();
1084 1637
                        break;
1085 1638
                    default:
1086
		    case 0x9: /* V9 mulx */
1087
		    case 0xd: /* V9 udivx */
1088 1639
                        goto illegal_insn;
1089 1640
                    }
1090 1641
		    gen_movl_T0_reg(rd);
1091 1642
                } else {
1092 1643
                    switch (xop) {
1644
#ifdef TARGET_SPARC64
1645
		    case 0x9: /* V9 mulx */
1646
                        gen_op_mulx_T1_T0();
1647
			gen_movl_T0_reg(rd);
1648
                        break;
1649
		    case 0xd: /* V9 udivx */
1650
                        gen_op_udivx_T1_T0();
1651
			gen_movl_T0_reg(rd);
1652
                        break;
1653
#endif
1093 1654
		    case 0x20: /* taddcc */
1094 1655
		    case 0x21: /* tsubcc */
1095 1656
		    case 0x22: /* taddcctv */
......
1099 1660
                        gen_op_mulscc_T1_T0();
1100 1661
                        gen_movl_T0_reg(rd);
1101 1662
                        break;
1102
                    case 0x25:	/* sll, V9 sllx */
1103
                        gen_op_sll();
1663
                    case 0x25:	/* sll, V9 sllx ( == sll) */
1664
			gen_op_sll();
1104 1665
                        gen_movl_T0_reg(rd);
1105 1666
                        break;
1106 1667
                    case 0x26:  /* srl, V9 srlx */
1107
                        gen_op_srl();
1668
#ifdef TARGET_SPARC64
1669
			if (insn & (1 << 12))
1670
			    gen_op_srlx();
1671
			else
1672
			    gen_op_srl();
1673
#else
1674
			gen_op_srl();
1675
#endif
1108 1676
                        gen_movl_T0_reg(rd);
1109 1677
                        break;
1110 1678
                    case 0x27:  /* sra, V9 srax */
1111
                        gen_op_sra();
1679
#ifdef TARGET_SPARC64
1680
			if (insn & (1 << 12))
1681
			    gen_op_srax();
1682
			else
1683
			    gen_op_sra();
1684
#else
1685
			gen_op_sra();
1686
#endif
1112 1687
                        gen_movl_T0_reg(rd);
1113 1688
                        break;
1114 1689
                    case 0x30:
1115 1690
                        {
1116
                            gen_op_xor_T1_T0();
1117 1691
                            switch(rd) {
1118
                            case 0:
1119
                                gen_op_wry();
1692
                            case 0: /* wry */
1693
				gen_op_xor_T1_T0();
1694
				gen_op_movtl_env_T0(offsetof(CPUSPARCState, y));
1120 1695
                                break;
1121
                            default:
1696
#ifdef TARGET_SPARC64
1122 1697
			    case 0x2: /* V9 wrccr */
1698
                                gen_op_wrccr();
1699
				break;
1123 1700
			    case 0x3: /* V9 wrasi */
1701
				gen_op_movl_env_T0(offsetof(CPUSPARCState, asi));
1702
				break;
1124 1703
			    case 0x6: /* V9 wrfprs */
1125
			    case 0xf: /* V9 sir */
1704
				gen_op_movl_env_T0(offsetof(CPUSPARCState, fprs));
1705
				break;
1706
			    case 0xf: /* V9 sir, nop if user */
1707
#if !defined(CONFIG_USER_ONLY)
1708
				if (supervisor(dc))
1709
				    gen_op_sir();
1710
#endif
1711
				break;
1712
#endif
1713
			    case 0x10: /* Performance Control */
1714
			    case 0x11: /* Performance Instrumentation Counter */
1715
			    case 0x12: /* Dispatch Control */
1716
			    case 0x13: /* Graphics Status */
1717
			    case 0x14: /* Softint set */
1718
			    case 0x15: /* Softint clear */
1719
			    case 0x16: /* Softint write */
1720
			    case 0x17: /* Tick compare */
1721
			    case 0x18: /* System tick */
1722
			    case 0x19: /* System tick compare */
1723
                            default:
1126 1724
                                goto illegal_insn;
1127 1725
                            }
1128 1726
                        }
......
1132 1730
                        {
1133 1731
			    if (!supervisor(dc))
1134 1732
				goto priv_insn;
1733
#ifdef TARGET_SPARC64
1734
			    switch (rd) {
1735
			    case 0:
1736
				gen_op_saved();
1737
				break;
1738
			    case 1:
1739
				gen_op_restored();
1740
				break;
1741
			    default:
1742
                                goto illegal_insn;
1743
                            }
1744
#else
1135 1745
                            gen_op_xor_T1_T0();
1136 1746
                            gen_op_wrpsr();
1747
#endif
1137 1748
                        }
1138 1749
                        break;
1139 1750
                    case 0x32: /* wrwim, V9 wrpr */
......
1141 1752
			    if (!supervisor(dc))
1142 1753
				goto priv_insn;
1143 1754
                            gen_op_xor_T1_T0();
1144
                            gen_op_wrwim();
1755
#ifdef TARGET_SPARC64
1756
			    switch (rd) {
1757
			    case 0: // tpc
1758
				gen_op_wrtpc();
1759
				break;
1760
			    case 1: // tnpc
1761
				gen_op_wrtnpc();
1762
				break;
1763
			    case 2: // tstate
1764
				gen_op_wrtstate();
1765
				break;
1766
			    case 3: // tt
1767
				gen_op_wrtt();
1768
				break;
1769
			    case 4: // tick
1770
				gen_op_wrtick();
1771
				break;
1772
			    case 5: // tba
1773
				gen_op_movl_env_T0(offsetof(CPUSPARCState, tbr));
1774
				break;
1775
			    case 6: // pstate
1776
				gen_op_wrpstate();
1777
				break;
1778
			    case 7: // tl
1779
				gen_op_movl_env_T0(offsetof(CPUSPARCState, tl));
1780
				break;
1781
			    case 8: // pil
1782
				gen_op_movl_env_T0(offsetof(CPUSPARCState, psrpil));
1783
				break;
1784
			    case 9: // cwp
1785
				gen_op_wrcwp();
1786
				break;
1787
			    case 10: // cansave
1788
				gen_op_movl_env_T0(offsetof(CPUSPARCState, cansave));
1789
				break;
1790
			    case 11: // canrestore
1791
				gen_op_movl_env_T0(offsetof(CPUSPARCState, canrestore));
1792
				break;
1793
			    case 12: // cleanwin
1794
				gen_op_movl_env_T0(offsetof(CPUSPARCState, cleanwin));
1795
				break;
1796
			    case 13: // otherwin
1797
				gen_op_movl_env_T0(offsetof(CPUSPARCState, otherwin));
1798
				break;
1799
			    case 14: // wstate
1800
				gen_op_movl_env_T0(offsetof(CPUSPARCState, wstate));
1801
				break;
1802
			    default:
1803
				goto illegal_insn;
1804
			    }
1805
#else
1806
			    gen_op_movl_env_T0(offsetof(CPUSPARCState, wim));
1807
#endif
1145 1808
                        }
1146 1809
                        break;
1147
                    case 0x33:
1810
#ifndef TARGET_SPARC64
1811
                    case 0x33: /* wrtbr, V9 unimp */
1148 1812
                        {
1149 1813
			    if (!supervisor(dc))
1150 1814
				goto priv_insn;
1151 1815
                            gen_op_xor_T1_T0();
1152
                            gen_op_wrtbr();
1816
			    gen_op_movtl_env_T0(offsetof(CPUSPARCState, tbr));
1153 1817
                        }
1154 1818
                        break;
1155 1819
#endif
1156
		    default:
1157
		    case 0x2a: /* V9 rdpr */
1158
		    case 0x2b: /* V9 flushw */
1820
#endif
1821
#ifdef TARGET_SPARC64
1159 1822
		    case 0x2c: /* V9 movcc */
1823
			{
1824
			    int cc = GET_FIELD_SP(insn, 11, 12);
1825
			    int cond = GET_FIELD_SP(insn, 14, 17);
1826
			    if (IS_IMM) {	/* immediate */
1827
				rs2 = GET_FIELD_SPs(insn, 0, 10);
1828
				gen_movl_simm_T1(rs2);
1829
			    }
1830
			    else {
1831
				rs2 = GET_FIELD_SP(insn, 0, 4);
1832
				gen_movl_reg_T1(rs2);
1833
			    }
1834
			    gen_movl_reg_T0(rd);
1835
			    flush_T2(dc);
1836
			    if (insn & (1 << 18)) {
1837
				if (cc == 0)
1838
				    gen_cond[0][cond]();
1839
				else if (cc == 2)
1840
				    gen_cond[1][cond]();
1841
				else
1842
				    goto illegal_insn;
1843
			    } else {
1844
				gen_fcond[cc][cond]();
1845
			    }
1846
			    gen_op_mov_cc();
1847
			    gen_movl_T0_reg(rd);
1848
			    break;
1849
			}
1160 1850
		    case 0x2d: /* V9 sdivx */
1851
                        gen_op_sdivx_T1_T0();
1852
			gen_movl_T0_reg(rd);
1853
                        break;
1161 1854
		    case 0x2e: /* V9 popc */
1855
			{
1856
			    if (IS_IMM) {	/* immediate */
1857
				rs2 = GET_FIELD_SPs(insn, 0, 12);
1858
				gen_movl_simm_T1(rs2);
1859
				// XXX optimize: popc(constant)
1860
			    }
1861
			    else {
1862
				rs2 = GET_FIELD_SP(insn, 0, 4);
1863
				gen_movl_reg_T1(rs2);
1864
			    }
1865
			    gen_op_popc();
1866
			    gen_movl_T0_reg(rd);
1867
			}
1162 1868
		    case 0x2f: /* V9 movr */
1869
			{
1870
			    int cond = GET_FIELD_SP(insn, 10, 12);
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff