Revision f5ef6aac tcg/sparc/tcg-target.c

b/tcg/sparc/tcg-target.c
87 87
    TCG_REG_O1,
88 88
};
89 89

  
90
static inline int check_fit(tcg_target_long val, unsigned int bits)
91
{
92
    return ((val << ((sizeof(tcg_target_long) * 8 - bits))
93
             >> (sizeof(tcg_target_long) * 8 - bits)) == val);
94
}
95

  
90 96
static void patch_reloc(uint8_t *code_ptr, int type,
91 97
                        tcg_target_long value, tcg_target_long addend)
92 98
{
......
97 103
            tcg_abort();
98 104
        *(uint32_t *)code_ptr = value;
99 105
        break;
106
    case R_SPARC_WDISP22:
107
        value -= (long)code_ptr;
108
        value >>= 2;
109
        if (!check_fit(value, 22))
110
            tcg_abort();
111
        *(uint32_t *)code_ptr = ((*(uint32_t *)code_ptr) & ~0x3fffff) | value;
112
        break;
100 113
    default:
101 114
        tcg_abort();
102 115
    }
......
119 132
    case 'L': /* qemu_ld/st constraint */
120 133
        ct->ct |= TCG_CT_REG;
121 134
        tcg_regset_set32(ct->u.regs, 0, 0xffffffff);
135
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_I0);
136
        tcg_regset_reset_reg(ct->u.regs, TCG_REG_I1);
122 137
        break;
123 138
    case 'I':
124 139
        ct->ct |= TCG_CT_CONST_S11;
......
134 149
    return 0;
135 150
}
136 151

  
137
static inline int check_fit(tcg_target_long val, unsigned int bits)
138
{
139
    return ((val << ((sizeof(tcg_target_long) * 8 - bits))
140
             >> (sizeof(tcg_target_long) * 8 - bits)) == val);
141
}
142

  
143 152
/* test if a constant matches the constraint */
144 153
static inline int tcg_target_const_match(tcg_target_long val,
145 154
                                         const TCGArgConstraint *arg_ct)
......
192 201
#define ARITH_ANDCC (INSN_OP(2) | INSN_OP3(0x11))
193 202
#define ARITH_OR   (INSN_OP(2) | INSN_OP3(0x02))
194 203
#define ARITH_XOR  (INSN_OP(2) | INSN_OP3(0x03))
195
#define ARITH_SUB  (INSN_OP(2) | INSN_OP3(0x08))
196
#define ARITH_SUBCC (INSN_OP(2) | INSN_OP3(0x18))
204
#define ARITH_SUB  (INSN_OP(2) | INSN_OP3(0x04))
205
#define ARITH_SUBCC (INSN_OP(2) | INSN_OP3(0x14))
197 206
#define ARITH_ADDX (INSN_OP(2) | INSN_OP3(0x10))
198 207
#define ARITH_SUBX (INSN_OP(2) | INSN_OP3(0x0c))
199 208
#define ARITH_UMUL (INSN_OP(2) | INSN_OP3(0x0a))
......
333 342
    if (val != 0) {
334 343
        if (check_fit(val, 13))
335 344
            tcg_out_arithi(s, reg, reg, val, ARITH_ADD);
336
        else
337
            fprintf(stderr, "unimplemented addi %ld\n", (long)val);
345
        else {
346
            tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, val);
347
            tcg_out_arith(s, reg, reg, TCG_REG_I5, ARITH_ADD);
348
        }
338 349
    }
339 350
}
340 351

  
......
350 361

  
351 362
    if (l->has_value) {
352 363
        val = l->u.value - (tcg_target_long)s->code_ptr;
353
        tcg_out32(s, (INSN_OP(0) | opc | INSN_OP2(0x2)
364
        tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2)
354 365
                      | INSN_OFF22(l->u.value - (unsigned long)s->code_ptr)));
355
    } else
356
        fprintf(stderr, "unimplemented branch\n");
366
    } else {
367
        tcg_out_reloc(s, s->code_ptr, R_SPARC_WDISP22, label_index, 0);
368
        tcg_out32(s, (INSN_OP(0) | INSN_COND(opc, 0) | INSN_OP2(0x2) | 0));
369
    }
357 370
}
358 371

  
359 372
static const uint8_t tcg_cond_to_bcond[10] = {
......
375 388
{
376 389
    if (const_arg2 && arg2 == 0)
377 390
        /* andcc r, r, %g0 */
378
        tcg_out_arithi(s, TCG_REG_G0, arg1, arg1, ARITH_ANDCC);
391
        tcg_out_arith(s, TCG_REG_G0, arg1, arg1, ARITH_ANDCC);
379 392
    else
380 393
        /* subcc r1, r2, %g0 */
381 394
        tcg_out_arith(s, TCG_REG_G0, arg1, arg2, ARITH_SUBCC);
......
393 406
    tcg_out_nop(s);
394 407
}
395 408

  
409
#if defined(CONFIG_SOFTMMU)
410
extern void __ldb_mmu(void);
411
extern void __ldw_mmu(void);
412
extern void __ldl_mmu(void);
413
extern void __ldq_mmu(void);
414

  
415
extern void __stb_mmu(void);
416
extern void __stw_mmu(void);
417
extern void __stl_mmu(void);
418
extern void __stq_mmu(void);
419

  
420

  
421
static void *qemu_ld_helpers[4] = {
422
    __ldb_mmu,
423
    __ldw_mmu,
424
    __ldl_mmu,
425
    __ldq_mmu,
426
};
427

  
428
static void *qemu_st_helpers[4] = {
429
    __stb_mmu,
430
    __stw_mmu,
431
    __stl_mmu,
432
    __stq_mmu,
433
};
434
#endif
435

  
436
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
437
                            int opc)
438
{
439
    int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap, ld_op;
440
#if defined(CONFIG_SOFTMMU)
441
    uint8_t *label1_ptr, *label2_ptr;
442
#endif
443

  
444
    data_reg = *args++;
445
    addr_reg = *args++;
446
    mem_index = *args;
447
    s_bits = opc & 3;
448

  
449
    r0 = TCG_REG_I0;
450
    r1 = TCG_REG_I1;
451

  
452
#if TARGET_LONG_BITS == 32
453
    ld_op = LDUW;
454
#else
455
    ld_op = LDX;
456
#endif
457

  
458
#if defined(CONFIG_SOFTMMU)
459
    /* srl addr_reg, x, r1 */
460
    tcg_out_arithi(s, r1, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS,
461
                   SHIFT_SRL);
462
    /* and addr_reg, x, r0 */
463
    tcg_out_arithi(s, r0, addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
464
                   ARITH_AND);
465

  
466
    /* and r1, x, r1 */
467
    tcg_out_arithi(s, r1, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS,
468
                   ARITH_AND);
469

  
470
    /* add r1, x, r1 */
471
    tcg_out_arithi(s, r1, r1, offsetof(CPUState, tlb_table[mem_index][0].addr_read),
472
                   ARITH_ADD);
473

  
474
    /* ld [env + r1], r1 */
475
    tcg_out_ldst(s, r1, TCG_AREG0, r1, ld_op);
476

  
477
    /* subcc r0, r1, %g0 */
478
    tcg_out_arith(s, TCG_REG_G0, r0, r1, ARITH_SUBCC);
479

  
480
    /* will become:
481
       be label1 */
482
    label1_ptr = s->code_ptr;
483
    tcg_out32(s, 0);
484

  
485
    /* mov (delay slot)*/
486
    tcg_out_mov(s, r0, addr_reg);
487

  
488
    /* XXX: move that code at the end of the TB */
489
    tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_ld_helpers[s_bits]
490
                           - (tcg_target_ulong)s->code_ptr) >> 2)
491
                         & 0x3fffffff));
492
    /* mov (delay slot)*/
493
    tcg_out_movi(s, TCG_TYPE_I32, r1, mem_index);
494

  
495
    switch(opc) {
496
    case 0 | 4:
497
        /* sll i0, 24/56, i0 */
498
        tcg_out_arithi(s, TCG_REG_I0, TCG_REG_I0,
499
                       sizeof(tcg_target_long) * 8 - 8, SHIFT_SLL);
500
        /* sra i0, 24/56, data_reg */
501
        tcg_out_arithi(s, data_reg, TCG_REG_I0,
502
                       sizeof(tcg_target_long) * 8 - 8, SHIFT_SRA);
503
        break;
504
    case 1 | 4:
505
        /* sll i0, 16/48, i0 */
506
        tcg_out_arithi(s, TCG_REG_I0, TCG_REG_I0,
507
                       sizeof(tcg_target_long) * 8 - 16, SHIFT_SLL);
508
        /* sra i0, 16/48, data_reg */
509
        tcg_out_arithi(s, data_reg, TCG_REG_I0,
510
                       sizeof(tcg_target_long) * 8 - 16, SHIFT_SRA);
511
        break;
512
    case 2 | 4:
513
        /* sll i0, 32, i0 */
514
        tcg_out_arithi(s, TCG_REG_I0, TCG_REG_I0, 32, SHIFT_SLL);
515
        /* sra i0, 32, data_reg */
516
        tcg_out_arithi(s, data_reg, TCG_REG_I0, 32, SHIFT_SRA);
517
        break;
518
    case 0:
519
    case 1:
520
    case 2:
521
    case 3:
522
    default:
523
        /* mov */
524
        tcg_out_mov(s, data_reg, TCG_REG_I0);
525
        break;
526
    }
527

  
528
    /* will become:
529
       ba label2 */
530
    label2_ptr = s->code_ptr;
531
    tcg_out32(s, 0);
532

  
533
    /* label1: */
534
    *label1_ptr = (INSN_OP(0) | COND_A | INSN_OP2(0x2) |
535
                   INSN_OFF22((unsigned long)label1_ptr -
536
                              (unsigned long)s->code_ptr));
537

  
538
    /* ld [r1 + x], r1 */
539
    tcg_out_ldst(s, r1, r1, offsetof(CPUTLBEntry, addend) -
540
                 offsetof(CPUTLBEntry, addr_read), ld_op);
541
    /* add x(r1), r0 */
542
    tcg_out_arith(s, r0, r1, r0, ARITH_ADD);
543
#else
544
    r0 = addr_reg;
545
#endif
546

  
547
#ifdef TARGET_WORDS_BIGENDIAN
548
    bswap = 0;
549
#else
550
    bswap = 1;
551
#endif
552
    switch(opc) {
553
    case 0:
554
        /* ldub [r0], data_reg */
555
        tcg_out_ldst(s, data_reg, r0, 0, LDUB);
556
        break;
557
    case 0 | 4:
558
        /* ldsb [r0], data_reg */
559
        tcg_out_ldst(s, data_reg, r0, 0, LDSB);
560
        break;
561
    case 1:
562
        /* lduh [r0], data_reg */
563
        tcg_out_ldst(s, data_reg, r0, 0, LDUH);
564
        if (bswap) {
565
            fprintf(stderr, "unimplemented %s with bswap\n", __func__);
566
        }
567
        break;
568
    case 1 | 4:
569
        /* ldsh [r0], data_reg */
570
        tcg_out_ldst(s, data_reg, r0, 0, LDSH);
571
        if (bswap) {
572
            fprintf(stderr, "unimplemented %s with bswap\n", __func__);
573
        }
574
        break;
575
    case 2:
576
        /* lduw [r0], data_reg */
577
        tcg_out_ldst(s, data_reg, r0, 0, LDUW);
578
        if (bswap) {
579
            fprintf(stderr, "unimplemented %s with bswap\n", __func__);
580
        }
581
        break;
582
    case 2 | 4:
583
        /* ldsw [r0], data_reg */
584
        tcg_out_ldst(s, data_reg, r0, 0, LDSW);
585
        if (bswap) {
586
            fprintf(stderr, "unimplemented %s with bswap\n", __func__);
587
        }
588
        break;
589
    case 3:
590
        /* ldx [r0], data_reg */
591
        tcg_out_ldst(s, data_reg, r0, 0, LDX);
592
        if (bswap) {
593
            fprintf(stderr, "unimplemented %s with bswap\n", __func__);
594
        }
595
        break;
596
    default:
597
        tcg_abort();
598
    }
599

  
600
#if defined(CONFIG_SOFTMMU)
601
    /* label2: */
602
    *label2_ptr = (INSN_OP(0) | COND_A | INSN_OP2(0x2) |
603
                   INSN_OFF22((unsigned long)label2_ptr -
604
                              (unsigned long)s->code_ptr));
605
#endif
606
}
607

  
608
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
609
                            int opc)
610
{
611
    int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap, ld_op;
612
#if defined(CONFIG_SOFTMMU)
613
    uint8_t *label1_ptr, *label2_ptr;
614
#endif
615

  
616
    data_reg = *args++;
617
    addr_reg = *args++;
618
    mem_index = *args;
619

  
620
    s_bits = opc;
621

  
622
    r0 = TCG_REG_I5;
623
    r1 = TCG_REG_I4;
624

  
625
#if TARGET_LONG_BITS == 32
626
    ld_op = LDUW;
627
#else
628
    ld_op = LDX;
629
#endif
630

  
631
#if defined(CONFIG_SOFTMMU)
632
    /* srl addr_reg, x, r1 */
633
    tcg_out_arithi(s, r1, addr_reg, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS,
634
                   SHIFT_SRL);
635
    /* and addr_reg, x, r0 */
636
    tcg_out_arithi(s, r0, addr_reg, TARGET_PAGE_MASK | ((1 << s_bits) - 1),
637
                   ARITH_AND);
638

  
639
    /* and r1, x, r1 */
640
    tcg_out_arithi(s, r1, r1, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS,
641
                   ARITH_AND);
642

  
643
    /* add r1, x, r1 */
644
    tcg_out_arithi(s, r1, r1,
645
                   offsetof(CPUState, tlb_table[mem_index][0].addr_write),
646
                   ARITH_ADD);
647

  
648
    /* ld [env + r1], r1 */
649
    tcg_out_ldst(s, r1, TCG_AREG0, r1, ld_op);
650

  
651
    /* subcc r0, r1, %g0 */
652
    tcg_out_arith(s, TCG_REG_G0, r0, r1, ARITH_SUBCC);
653

  
654
    /* will become:
655
       be label1 */
656
    label1_ptr = s->code_ptr;
657
    tcg_out32(s, 0);
658
    /* mov (delay slot)*/
659
    tcg_out_mov(s, r0, addr_reg);
660

  
661
    switch(opc) {
662
    case 0 | 4:
663
        /* sll i0, 24/56, i0 */
664
        tcg_out_arithi(s, TCG_REG_I0, TCG_REG_I0,
665
                       sizeof(tcg_target_long) * 8 - 8, SHIFT_SLL);
666
        /* sra i0, 24/56, data_reg */
667
        tcg_out_arithi(s, data_reg, TCG_REG_I0,
668
                       sizeof(tcg_target_long) * 8 - 8, SHIFT_SRA);
669
        break;
670
    case 1 | 4:
671
        /* sll i0, 16/48, i0 */
672
        tcg_out_arithi(s, TCG_REG_I0, TCG_REG_I0,
673
                       sizeof(tcg_target_long) * 8 - 16, SHIFT_SLL);
674
        /* sra i0, 16/48, data_reg */
675
        tcg_out_arithi(s, data_reg, TCG_REG_I0,
676
                       sizeof(tcg_target_long) * 8 - 16, SHIFT_SRA);
677
        break;
678
    case 2 | 4:
679
        /* sll i0, 32, i0 */
680
        tcg_out_arithi(s, TCG_REG_I0, TCG_REG_I0, 32, SHIFT_SLL);
681
        /* sra i0, 32, data_reg */
682
        tcg_out_arithi(s, data_reg, TCG_REG_I0, 32, SHIFT_SRA);
683
        break;
684
    case 0:
685
    case 1:
686
    case 2:
687
    case 3:
688
    default:
689
        /* mov */
690
        tcg_out_mov(s, data_reg, TCG_REG_I0);
691
        break;
692
    }
693

  
694
    tcg_out32(s, CALL | ((((tcg_target_ulong)qemu_st_helpers[s_bits]
695
                           - (tcg_target_ulong)s->code_ptr) >> 2)
696
                         & 0x3fffffff));
697
    /* mov (delay slot)*/
698
    tcg_out_movi(s, TCG_TYPE_I32, r1, mem_index);
699

  
700
    /* will become:
701
       ba label2 */
702
    label2_ptr = s->code_ptr;
703
    tcg_out32(s, 0);
704

  
705
    /* label1: */
706
    *label1_ptr = (INSN_OP(0) | COND_A | INSN_OP2(0x2) |
707
                   INSN_OFF22((unsigned long)label1_ptr -
708
                              (unsigned long)s->code_ptr));
709

  
710
    /* ld [r1 + x], r1 */
711
    tcg_out_ldst(s, r1, r1, offsetof(CPUTLBEntry, addend) -
712
                 offsetof(CPUTLBEntry, addr_write), ld_op);
713
    /* add x(r1), r0 */
714
    tcg_out_arith(s, r0, r1, r0, ARITH_ADD);
715
#else
716
    r0 = addr_reg;
717
#endif
718

  
719
#ifdef TARGET_WORDS_BIGENDIAN
720
    bswap = 0;
721
#else
722
    bswap = 1;
723
#endif
724
    switch(opc) {
725
    case 0:
726
        /* stb data_reg, [r0] */
727
        tcg_out_ldst(s, data_reg, r0, 0, STB);
728
        break;
729
    case 1:
730
        if (bswap) {
731
            fprintf(stderr, "unimplemented %s with bswap\n", __func__);
732
        }
733
        /* sth data_reg, [r0] */
734
        tcg_out_ldst(s, data_reg, r0, 0, STH);
735
        break;
736
    case 2:
737
        if (bswap) {
738
            fprintf(stderr, "unimplemented %s with bswap\n", __func__);
739
        }
740
        /* stw data_reg, [r0] */
741
        tcg_out_ldst(s, data_reg, r0, 0, STW);
742
        break;
743
    case 3:
744
        if (bswap) {
745
            fprintf(stderr, "unimplemented %s with bswap\n", __func__);
746
        }
747
        /* stx data_reg, [r0] */
748
        tcg_out_ldst(s, data_reg, r0, 0, STX);
749
        break;
750
    default:
751
        tcg_abort();
752
    }
753

  
754
#if defined(CONFIG_SOFTMMU)
755
    /* label2: */
756
    *label2_ptr = (INSN_OP(0) | COND_A | INSN_OP2(0x2) |
757
                   INSN_OFF22((unsigned long)label2_ptr -
758
                              (unsigned long)s->code_ptr));
759
#endif
760
}
761

  
396 762
static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,
397 763
                              const int *const_args)
398 764
{
......
437 803
        }
438 804
        break;
439 805
    case INDEX_op_jmp:
440
        fprintf(stderr, "unimplemented jmp\n");
441
        break;
442 806
    case INDEX_op_br:
443
        fprintf(stderr, "unimplemented br\n");
807
        tcg_out_branch(s, COND_A, args[0]);
808
        tcg_out_nop(s);
444 809
        break;
445 810
    case INDEX_op_movi_i32:
446 811
        tcg_out_movi(s, TCG_TYPE_I32, args[0], (uint32_t)args[1]);
......
536 901
        break;
537 902

  
538 903
    case INDEX_op_qemu_ld8u:
539
        fprintf(stderr, "unimplemented qld\n");
904
        tcg_out_qemu_ld(s, args, 0);
540 905
        break;
541 906
    case INDEX_op_qemu_ld8s:
542
        fprintf(stderr, "unimplemented qld\n");
907
        tcg_out_qemu_ld(s, args, 0 | 4);
543 908
        break;
544 909
    case INDEX_op_qemu_ld16u:
545
        fprintf(stderr, "unimplemented qld\n");
910
        tcg_out_qemu_ld(s, args, 1);
546 911
        break;
547 912
    case INDEX_op_qemu_ld16s:
548
        fprintf(stderr, "unimplemented qld\n");
913
        tcg_out_qemu_ld(s, args, 1 | 4);
549 914
        break;
550 915
    case INDEX_op_qemu_ld32u:
551
        fprintf(stderr, "unimplemented qld\n");
916
        tcg_out_qemu_ld(s, args, 2);
552 917
        break;
553 918
    case INDEX_op_qemu_ld32s:
554
        fprintf(stderr, "unimplemented qld\n");
919
        tcg_out_qemu_ld(s, args, 2 | 4);
555 920
        break;
556 921
    case INDEX_op_qemu_st8:
557
        fprintf(stderr, "unimplemented qst\n");
922
        tcg_out_qemu_st(s, args, 0);
558 923
        break;
559 924
    case INDEX_op_qemu_st16:
560
        fprintf(stderr, "unimplemented qst\n");
925
        tcg_out_qemu_st(s, args, 1);
561 926
        break;
562 927
    case INDEX_op_qemu_st32:
563
        fprintf(stderr, "unimplemented qst\n");
928
        tcg_out_qemu_st(s, args, 2);
564 929
        break;
565 930

  
566 931
#if defined(__sparc_v9__) && !defined(__sparc_v8plus__)
......
596 961
        goto gen_arith32;
597 962

  
598 963
    case INDEX_op_brcond_i64:
599
        fprintf(stderr, "unimplemented brcond\n");
964
        tcg_out_brcond(s, args[2], args[0], args[1], const_args[1],
965
                       args[3]);
600 966
        break;
601 967
    case INDEX_op_qemu_ld64:
602
        fprintf(stderr, "unimplemented qld\n");
968
        tcg_out_qemu_ld(s, args, 3);
603 969
        break;
604 970
    case INDEX_op_qemu_st64:
605
        fprintf(stderr, "unimplemented qst\n");
971
        tcg_out_qemu_st(s, args, 3);
606 972
        break;
607 973

  
608 974
#endif

Also available in: Unified diff