Revision aaa9128a target-mips/translate.c

b/target-mips/translate.c
488 488
    tcg_gen_st_tl(cpu_T[0], r_tmp, sizeof(target_ulong) * reg);
489 489
}
490 490

  
491
/* Load immediates, zero being a special case. */
492
static inline void gen_op_set_T0(target_ulong arg)
493
{
494
    tcg_gen_movi_tl(cpu_T[0], arg);
495
}
496

  
497
static inline void gen_op_set_T1(target_ulong arg)
498
{
499
    tcg_gen_movi_tl(cpu_T[1], arg);
500
}
501

  
502
static inline void gen_op_reset_T0(void)
503
{
504
    tcg_gen_movi_tl(cpu_T[0], 0);
505
}
506

  
507
static inline void gen_op_reset_T1(void)
508
{
509
    tcg_gen_movi_tl(cpu_T[1], 0);
510
}
511

  
512
/* Moves to/from HI/LO registers. */
513
static inline void gen_op_load_HI(int reg)
514
{
515
    tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, HI[reg]));
516
}
517

  
518
static inline void gen_op_store_HI(int reg)
519
{
520
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, HI[reg]));
521
}
522

  
523
static inline void gen_op_load_LO(int reg)
524
{
525
    tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, LO[reg]));
526
}
527

  
528
static inline void gen_op_store_LO(int reg)
529
{
530
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, LO[reg]));
531
}
532

  
533

  
534
/* Floating point register moves. */
491 535
static const char *fregnames[] =
492 536
    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
493 537
      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
......
639 683
    }                                                                         \
640 684
} while (0)
641 685

  
642
#if defined(TARGET_MIPS64)
643
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
644
do {                                                                          \
645
    if (Imm == 0) {                                                           \
646
        glue(gen_op_reset_, Tn)();                                            \
647
    } else if ((int32_t)Imm == Imm) {                                         \
648
        glue(gen_op_set_, Tn)(Imm);                                           \
649
    } else {                                                                  \
650
        glue(gen_op_set64_, Tn)(((uint64_t)Imm) >> 32, (uint32_t)Imm);        \
651
    }                                                                         \
652
} while (0)
653
#else
654 686
#define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
655 687
do {                                                                          \
656 688
    if (Imm == 0) {                                                           \
......
659 691
        glue(gen_op_set_, Tn)(Imm);                                           \
660 692
    }                                                                         \
661 693
} while (0)
662
#endif
663 694

  
664 695
#define GEN_STORE_T0_REG(Rn)                                                  \
665 696
do {                                                                          \
......
759 790
    }
760 791
}
761 792

  
793
static always_inline void
794
generate_tcg_exception_err (DisasContext *ctx, int excp, int err)
795
{
796
    save_cpu_state(ctx, 1);
797
    if (err == 0)
798
        gen_op_raise_exception(excp);
799
    else
800
        gen_op_raise_exception_err(excp, err);
801
    gen_op_interrupt_restart();
802
    tcg_gen_exit_tb(0);
803
}
804

  
805
static always_inline void
806
generate_tcg_exception (DisasContext *ctx, int excp)
807
{
808
    generate_tcg_exception_err (ctx, excp, 0);
809
}
810

  
762 811
static always_inline void generate_exception_err (DisasContext *ctx, int excp, int err)
763 812
{
764 813
#if defined MIPS_DEBUG_DISAS
......
864 913
#endif
865 914

  
866 915
#if defined(TARGET_MIPS64)
867
OP_LD_TABLE(d);
868 916
OP_LD_TABLE(dl);
869 917
OP_LD_TABLE(dr);
870
OP_ST_TABLE(d);
871 918
OP_ST_TABLE(dl);
872 919
OP_ST_TABLE(dr);
873
OP_LD_TABLE(ld);
874
OP_ST_TABLE(cd);
875
OP_LD_TABLE(wu);
876 920
#endif
877
OP_LD_TABLE(w);
878 921
OP_LD_TABLE(wl);
879 922
OP_LD_TABLE(wr);
880
OP_ST_TABLE(w);
881 923
OP_ST_TABLE(wl);
882 924
OP_ST_TABLE(wr);
883
OP_LD_TABLE(h);
884
OP_LD_TABLE(hu);
885
OP_ST_TABLE(h);
886
OP_LD_TABLE(b);
887
OP_LD_TABLE(bu);
888
OP_ST_TABLE(b);
889
OP_LD_TABLE(l);
890
OP_ST_TABLE(c);
891 925
OP_LD_TABLE(wc1);
892 926
OP_ST_TABLE(wc1);
893 927
OP_LD_TABLE(dc1);
......
895 929
OP_LD_TABLE(uxc1);
896 930
OP_ST_TABLE(uxc1);
897 931

  
932
#define OP_LD(insn,fname)                                        \
933
void inline op_ldst_##insn(DisasContext *ctx)                    \
934
{                                                                \
935
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);      \
936
}
937
OP_LD(lb,ld8s);
938
OP_LD(lbu,ld8u);
939
OP_LD(lh,ld16s);
940
OP_LD(lhu,ld16u);
941
OP_LD(lw,ld32s);
942
#if defined(TARGET_MIPS64)
943
OP_LD(lwu,ld32u);
944
OP_LD(ld,ld64);
945
#endif
946
#undef OP_LD
947

  
948
#define OP_ST(insn,fname)                                        \
949
void inline op_ldst_##insn(DisasContext *ctx)                    \
950
{                                                                \
951
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);      \
952
}
953
OP_ST(sb,st8);
954
OP_ST(sh,st16);
955
OP_ST(sw,st32);
956
#if defined(TARGET_MIPS64)
957
OP_ST(sd,st64);
958
#endif
959
#undef OP_ST
960

  
961
#define OP_LD_ATOMIC(insn,fname)                                        \
962
void inline op_ldst_##insn(DisasContext *ctx)                           \
963
{                                                                       \
964
    tcg_gen_mov_tl(cpu_T[1], cpu_T[0]);                                 \
965
    tcg_gen_qemu_##fname(cpu_T[0], cpu_T[0], ctx->mem_idx);             \
966
    tcg_gen_st_tl(cpu_T[1], cpu_env, offsetof(CPUState, CP0_LLAddr));   \
967
}
968
OP_LD_ATOMIC(ll,ld32s);
969
#if defined(TARGET_MIPS64)
970
OP_LD_ATOMIC(lld,ld64);
971
#endif
972
#undef OP_LD_ATOMIC
973

  
974
#define OP_ST_ATOMIC(insn,fname,almask)                                 \
975
void inline op_ldst_##insn(DisasContext *ctx)                           \
976
{                                                                       \
977
    int r_tmp = tcg_temp_new(TCG_TYPE_TL);                              \
978
    int l1 = gen_new_label();                                           \
979
    int l2 = gen_new_label();                                           \
980
    int l3 = gen_new_label();                                           \
981
                                                                        \
982
    tcg_gen_andi_tl(r_tmp, cpu_T[0], almask);                           \
983
    tcg_gen_brcond_tl(TCG_COND_EQ, r_tmp, tcg_const_tl(0), l1);         \
984
    tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, CP0_BadVAddr)); \
985
    generate_tcg_exception(ctx, EXCP_AdES);                             \
986
    gen_set_label(l1);                                                  \
987
    tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr));      \
988
    tcg_gen_brcond_tl(TCG_COND_NE, cpu_T[0], r_tmp, l2);                \
989
    tcg_gen_qemu_##fname(cpu_T[1], cpu_T[0], ctx->mem_idx);             \
990
    tcg_gen_movi_tl(cpu_T[0], 1);                                       \
991
    tcg_gen_br(l3);                                                     \
992
    gen_set_label(l2);                                                  \
993
    tcg_gen_movi_tl(cpu_T[0], 0);                                       \
994
    gen_set_label(l3);                                                  \
995
}
996
OP_ST_ATOMIC(sc,st32,0x3);
997
#if defined(TARGET_MIPS64)
998
OP_ST_ATOMIC(scd,st64,0x7);
999
#endif
1000
#undef OP_ST_ATOMIC
1001

  
1002
void inline op_ldst_lwc1(DisasContext *ctx)
1003
{
1004
    op_ldst(lwc1);
1005
}
1006

  
1007
void inline op_ldst_ldc1(DisasContext *ctx)
1008
{
1009
    op_ldst(ldc1);
1010
}
1011

  
1012
void inline op_ldst_swc1(DisasContext *ctx)
1013
{
1014
    op_ldst(swc1);
1015
}
1016

  
1017
void inline op_ldst_sdc1(DisasContext *ctx)
1018
{
1019
    op_ldst(sdc1);
1020
}
1021

  
898 1022
/* Load and store */
899 1023
static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
900 1024
                      int base, int16_t offset)
......
915 1039
    switch (opc) {
916 1040
#if defined(TARGET_MIPS64)
917 1041
    case OPC_LWU:
918
        op_ldst(lwu);
1042
        op_ldst_lwu(ctx);
919 1043
        GEN_STORE_T0_REG(rt);
920 1044
        opn = "lwu";
921 1045
        break;
922 1046
    case OPC_LD:
923
        op_ldst(ld);
1047
        op_ldst_ld(ctx);
924 1048
        GEN_STORE_T0_REG(rt);
925 1049
        opn = "ld";
926 1050
        break;
927 1051
    case OPC_LLD:
928
        op_ldst(lld);
1052
        op_ldst_lld(ctx);
929 1053
        GEN_STORE_T0_REG(rt);
930 1054
        opn = "lld";
931 1055
        break;
932 1056
    case OPC_SD:
933 1057
        GEN_LOAD_REG_T1(rt);
934
        op_ldst(sd);
1058
        op_ldst_sd(ctx);
935 1059
        opn = "sd";
936 1060
        break;
937 1061
    case OPC_SCD:
938 1062
        save_cpu_state(ctx, 1);
939 1063
        GEN_LOAD_REG_T1(rt);
940
        op_ldst(scd);
1064
        op_ldst_scd(ctx);
941 1065
        GEN_STORE_T0_REG(rt);
942 1066
        opn = "scd";
943 1067
        break;
......
965 1089
        break;
966 1090
#endif
967 1091
    case OPC_LW:
968
        op_ldst(lw);
1092
        op_ldst_lw(ctx);
969 1093
        GEN_STORE_T0_REG(rt);
970 1094
        opn = "lw";
971 1095
        break;
972 1096
    case OPC_SW:
973 1097
        GEN_LOAD_REG_T1(rt);
974
        op_ldst(sw);
1098
        op_ldst_sw(ctx);
975 1099
        opn = "sw";
976 1100
        break;
977 1101
    case OPC_LH:
978
        op_ldst(lh);
1102
        op_ldst_lh(ctx);
979 1103
        GEN_STORE_T0_REG(rt);
980 1104
        opn = "lh";
981 1105
        break;
982 1106
    case OPC_SH:
983 1107
        GEN_LOAD_REG_T1(rt);
984
        op_ldst(sh);
1108
        op_ldst_sh(ctx);
985 1109
        opn = "sh";
986 1110
        break;
987 1111
    case OPC_LHU:
988
        op_ldst(lhu);
1112
        op_ldst_lhu(ctx);
989 1113
        GEN_STORE_T0_REG(rt);
990 1114
        opn = "lhu";
991 1115
        break;
992 1116
    case OPC_LB:
993
        op_ldst(lb);
1117
        op_ldst_lb(ctx);
994 1118
        GEN_STORE_T0_REG(rt);
995 1119
        opn = "lb";
996 1120
        break;
997 1121
    case OPC_SB:
998 1122
        GEN_LOAD_REG_T1(rt);
999
        op_ldst(sb);
1123
        op_ldst_sb(ctx);
1000 1124
        opn = "sb";
1001 1125
        break;
1002 1126
    case OPC_LBU:
1003
        op_ldst(lbu);
1127
        op_ldst_lbu(ctx);
1004 1128
        GEN_STORE_T0_REG(rt);
1005 1129
        opn = "lbu";
1006 1130
        break;
......
1027 1151
        opn = "swr";
1028 1152
        break;
1029 1153
    case OPC_LL:
1030
        op_ldst(ll);
1154
        op_ldst_ll(ctx);
1031 1155
        GEN_STORE_T0_REG(rt);
1032 1156
        opn = "ll";
1033 1157
        break;
1034 1158
    case OPC_SC:
1035 1159
        save_cpu_state(ctx, 1);
1036 1160
        GEN_LOAD_REG_T1(rt);
1037
        op_ldst(sc);
1161
        op_ldst_sc(ctx);
1038 1162
        GEN_STORE_T0_REG(rt);
1039 1163
        opn = "sc";
1040 1164
        break;
......
1065 1189
       memory access. */
1066 1190
    switch (opc) {
1067 1191
    case OPC_LWC1:
1068
        op_ldst(lwc1);
1192
        op_ldst_lwc1(ctx);
1069 1193
        GEN_STORE_FTN_FREG(ft, WT0);
1070 1194
        opn = "lwc1";
1071 1195
        break;
1072 1196
    case OPC_SWC1:
1073 1197
        GEN_LOAD_FREG_FTN(WT0, ft);
1074
        op_ldst(swc1);
1198
        op_ldst_swc1(ctx);
1075 1199
        opn = "swc1";
1076 1200
        break;
1077 1201
    case OPC_LDC1:
1078
        op_ldst(ldc1);
1202
        op_ldst_ldc1(ctx);
1079 1203
        GEN_STORE_FTN_FREG(ft, DT0);
1080 1204
        opn = "ldc1";
1081 1205
        break;
1082 1206
    case OPC_SDC1:
1083 1207
        GEN_LOAD_FREG_FTN(DT0, ft);
1084
        op_ldst(sdc1);
1208
        op_ldst_sdc1(ctx);
1085 1209
        opn = "sdc1";
1086 1210
        break;
1087 1211
    default:
......
5852 5976
    switch (opc) {
5853 5977
    case OPC_LWXC1:
5854 5978
        check_cop1x(ctx);
5855
        op_ldst(lwc1);
5979
        op_ldst_lwc1(ctx);
5856 5980
        GEN_STORE_FTN_FREG(fd, WT0);
5857 5981
        opn = "lwxc1";
5858 5982
        break;
5859 5983
    case OPC_LDXC1:
5860 5984
        check_cop1x(ctx);
5861 5985
        check_cp1_registers(ctx, fd);
5862
        op_ldst(ldc1);
5986
        op_ldst_ldc1(ctx);
5863 5987
        GEN_STORE_FTN_FREG(fd, DT0);
5864 5988
        opn = "ldxc1";
5865 5989
        break;
......
5872 5996
    case OPC_SWXC1:
5873 5997
        check_cop1x(ctx);
5874 5998
        GEN_LOAD_FREG_FTN(WT0, fs);
5875
        op_ldst(swc1);
5999
        op_ldst_swc1(ctx);
5876 6000
        opn = "swxc1";
5877 6001
        store = 1;
5878 6002
        break;
......
5880 6004
        check_cop1x(ctx);
5881 6005
        check_cp1_registers(ctx, fs);
5882 6006
        GEN_LOAD_FREG_FTN(DT0, fs);
5883
        op_ldst(sdc1);
6007
        op_ldst_sdc1(ctx);
5884 6008
        opn = "sdxc1";
5885 6009
        store = 1;
5886 6010
        break;

Also available in: Unified diff