Revision d66c7132 target-mips/translate.c
b/target-mips/translate.c | ||
---|---|---|
932 | 932 |
#define OP_ST_ATOMIC(insn,fname,almask) \ |
933 | 933 |
static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx) \ |
934 | 934 |
{ \ |
935 |
TCGv r_tmp = tcg_temp_local_new(); \
|
|
935 |
TCGv r_tmp = tcg_temp_new(); \
|
|
936 | 936 |
int l1 = gen_new_label(); \ |
937 | 937 |
int l2 = gen_new_label(); \ |
938 | 938 |
int l3 = gen_new_label(); \ |
... | ... | |
944 | 944 |
gen_set_label(l1); \ |
945 | 945 |
tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr)); \ |
946 | 946 |
tcg_gen_brcond_tl(TCG_COND_NE, t0, r_tmp, l2); \ |
947 |
tcg_temp_free(r_tmp); \ |
|
947 | 948 |
tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx); \ |
948 | 949 |
tcg_gen_movi_tl(t0, 1); \ |
949 | 950 |
tcg_gen_br(l3); \ |
950 | 951 |
gen_set_label(l2); \ |
951 | 952 |
tcg_gen_movi_tl(t0, 0); \ |
952 | 953 |
gen_set_label(l3); \ |
953 |
tcg_temp_free(r_tmp); \ |
|
954 | 954 |
} |
955 | 955 |
OP_ST_ATOMIC(sc,st32,0x3); |
956 | 956 |
#if defined(TARGET_MIPS64) |
... | ... | |
963 | 963 |
int base, int16_t offset) |
964 | 964 |
{ |
965 | 965 |
const char *opn = "ldst"; |
966 |
TCGv t0 = tcg_temp_local_new();
|
|
967 |
TCGv t1 = tcg_temp_local_new();
|
|
966 |
TCGv t0 = tcg_temp_new(); |
|
967 |
TCGv t1 = tcg_temp_new(); |
|
968 | 968 |
|
969 | 969 |
if (base == 0) { |
970 | 970 |
tcg_gen_movi_tl(t0, offset); |
... | ... | |
979 | 979 |
switch (opc) { |
980 | 980 |
#if defined(TARGET_MIPS64) |
981 | 981 |
case OPC_LWU: |
982 |
save_cpu_state(ctx, 0); |
|
982 | 983 |
op_ldst_lwu(t0, ctx); |
983 | 984 |
gen_store_gpr(t0, rt); |
984 | 985 |
opn = "lwu"; |
985 | 986 |
break; |
986 | 987 |
case OPC_LD: |
988 |
save_cpu_state(ctx, 0); |
|
987 | 989 |
op_ldst_ld(t0, ctx); |
988 | 990 |
gen_store_gpr(t0, rt); |
989 | 991 |
opn = "ld"; |
990 | 992 |
break; |
991 | 993 |
case OPC_LLD: |
994 |
save_cpu_state(ctx, 0); |
|
992 | 995 |
op_ldst_lld(t0, t1, ctx); |
993 | 996 |
gen_store_gpr(t0, rt); |
994 | 997 |
opn = "lld"; |
995 | 998 |
break; |
996 | 999 |
case OPC_SD: |
1000 |
save_cpu_state(ctx, 0); |
|
997 | 1001 |
gen_load_gpr(t1, rt); |
998 | 1002 |
op_ldst_sd(t0, t1, ctx); |
999 | 1003 |
opn = "sd"; |
1000 | 1004 |
break; |
1001 |
case OPC_SCD: |
|
1002 |
save_cpu_state(ctx, 1); |
|
1003 |
gen_load_gpr(t1, rt); |
|
1004 |
op_ldst_scd(t0, t1, ctx); |
|
1005 |
gen_store_gpr(t0, rt); |
|
1006 |
opn = "scd"; |
|
1007 |
break; |
|
1008 | 1005 |
case OPC_LDL: |
1009 | 1006 |
save_cpu_state(ctx, 1); |
1010 | 1007 |
gen_load_gpr(t1, rt); |
... | ... | |
1033 | 1030 |
break; |
1034 | 1031 |
#endif |
1035 | 1032 |
case OPC_LW: |
1033 |
save_cpu_state(ctx, 0); |
|
1036 | 1034 |
op_ldst_lw(t0, ctx); |
1037 | 1035 |
gen_store_gpr(t0, rt); |
1038 | 1036 |
opn = "lw"; |
1039 | 1037 |
break; |
1040 | 1038 |
case OPC_SW: |
1039 |
save_cpu_state(ctx, 0); |
|
1041 | 1040 |
gen_load_gpr(t1, rt); |
1042 | 1041 |
op_ldst_sw(t0, t1, ctx); |
1043 | 1042 |
opn = "sw"; |
1044 | 1043 |
break; |
1045 | 1044 |
case OPC_LH: |
1045 |
save_cpu_state(ctx, 0); |
|
1046 | 1046 |
op_ldst_lh(t0, ctx); |
1047 | 1047 |
gen_store_gpr(t0, rt); |
1048 | 1048 |
opn = "lh"; |
1049 | 1049 |
break; |
1050 | 1050 |
case OPC_SH: |
1051 |
save_cpu_state(ctx, 0); |
|
1051 | 1052 |
gen_load_gpr(t1, rt); |
1052 | 1053 |
op_ldst_sh(t0, t1, ctx); |
1053 | 1054 |
opn = "sh"; |
1054 | 1055 |
break; |
1055 | 1056 |
case OPC_LHU: |
1057 |
save_cpu_state(ctx, 0); |
|
1056 | 1058 |
op_ldst_lhu(t0, ctx); |
1057 | 1059 |
gen_store_gpr(t0, rt); |
1058 | 1060 |
opn = "lhu"; |
1059 | 1061 |
break; |
1060 | 1062 |
case OPC_LB: |
1063 |
save_cpu_state(ctx, 0); |
|
1061 | 1064 |
op_ldst_lb(t0, ctx); |
1062 | 1065 |
gen_store_gpr(t0, rt); |
1063 | 1066 |
opn = "lb"; |
1064 | 1067 |
break; |
1065 | 1068 |
case OPC_SB: |
1069 |
save_cpu_state(ctx, 0); |
|
1066 | 1070 |
gen_load_gpr(t1, rt); |
1067 | 1071 |
op_ldst_sb(t0, t1, ctx); |
1068 | 1072 |
opn = "sb"; |
1069 | 1073 |
break; |
1070 | 1074 |
case OPC_LBU: |
1075 |
save_cpu_state(ctx, 0); |
|
1071 | 1076 |
op_ldst_lbu(t0, ctx); |
1072 | 1077 |
gen_store_gpr(t0, rt); |
1073 | 1078 |
opn = "lbu"; |
... | ... | |
1099 | 1104 |
opn = "swr"; |
1100 | 1105 |
break; |
1101 | 1106 |
case OPC_LL: |
1107 |
save_cpu_state(ctx, 0); |
|
1102 | 1108 |
op_ldst_ll(t0, t1, ctx); |
1103 | 1109 |
gen_store_gpr(t0, rt); |
1104 | 1110 |
opn = "ll"; |
1105 | 1111 |
break; |
1112 |
} |
|
1113 |
MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]); |
|
1114 |
tcg_temp_free(t0); |
|
1115 |
tcg_temp_free(t1); |
|
1116 |
} |
|
1117 |
|
|
1118 |
/* Store conditional */ |
|
1119 |
static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt, |
|
1120 |
int base, int16_t offset) |
|
1121 |
{ |
|
1122 |
const char *opn = "st_cond"; |
|
1123 |
TCGv t0, t1; |
|
1124 |
|
|
1125 |
t0 = tcg_temp_local_new(); |
|
1126 |
|
|
1127 |
if (base == 0) { |
|
1128 |
tcg_gen_movi_tl(t0, offset); |
|
1129 |
} else if (offset == 0) { |
|
1130 |
gen_load_gpr(t0, base); |
|
1131 |
} else { |
|
1132 |
tcg_gen_movi_tl(t0, offset); |
|
1133 |
gen_op_addr_add(ctx, t0, cpu_gpr[base]); |
|
1134 |
} |
|
1135 |
/* Don't do NOP if destination is zero: we must perform the actual |
|
1136 |
memory access. */ |
|
1137 |
|
|
1138 |
t1 = tcg_temp_local_new(); |
|
1139 |
gen_load_gpr(t1, rt); |
|
1140 |
switch (opc) { |
|
1141 |
#if defined(TARGET_MIPS64) |
|
1142 |
case OPC_SCD: |
|
1143 |
save_cpu_state(ctx, 0); |
|
1144 |
op_ldst_scd(t0, t1, ctx); |
|
1145 |
opn = "scd"; |
|
1146 |
break; |
|
1147 |
#endif |
|
1106 | 1148 |
case OPC_SC: |
1107 |
save_cpu_state(ctx, 1); |
|
1108 |
gen_load_gpr(t1, rt); |
|
1149 |
save_cpu_state(ctx, 0); |
|
1109 | 1150 |
op_ldst_sc(t0, t1, ctx); |
1110 |
gen_store_gpr(t0, rt); |
|
1111 | 1151 |
opn = "sc"; |
1112 | 1152 |
break; |
1113 |
default: |
|
1114 |
MIPS_INVAL(opn); |
|
1115 |
generate_exception(ctx, EXCP_RI); |
|
1116 |
goto out; |
|
1117 | 1153 |
} |
1118 | 1154 |
MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]); |
1119 |
out: |
|
1120 |
tcg_temp_free(t0); |
|
1121 | 1155 |
tcg_temp_free(t1); |
1156 |
gen_store_gpr(t0, rt); |
|
1157 |
tcg_temp_free(t0); |
|
1122 | 1158 |
} |
1123 | 1159 |
|
1124 | 1160 |
/* Load and store */ |
... | ... | |
7997 | 8033 |
case OPC_SB ... OPC_SW: |
7998 | 8034 |
case OPC_SWR: |
7999 | 8035 |
case OPC_LL: |
8000 |
case OPC_SC: |
|
8001 | 8036 |
gen_ldst(ctx, op, rt, rs, imm); |
8002 | 8037 |
break; |
8038 |
case OPC_SC: |
|
8039 |
gen_st_cond(ctx, op, rt, rs, imm); |
|
8040 |
break; |
|
8003 | 8041 |
case OPC_CACHE: |
8004 | 8042 |
check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32); |
8005 | 8043 |
/* Treat as NOP. */ |
... | ... | |
8128 | 8166 |
case OPC_SDL ... OPC_SDR: |
8129 | 8167 |
case OPC_LLD: |
8130 | 8168 |
case OPC_LD: |
8131 |
case OPC_SCD: |
|
8132 | 8169 |
case OPC_SD: |
8133 | 8170 |
check_insn(env, ctx, ISA_MIPS3); |
8134 | 8171 |
check_mips_64(ctx); |
8135 | 8172 |
gen_ldst(ctx, op, rt, rs, imm); |
8136 | 8173 |
break; |
8174 |
case OPC_SCD: |
|
8175 |
check_insn(env, ctx, ISA_MIPS3); |
|
8176 |
check_mips_64(ctx); |
|
8177 |
gen_st_cond(ctx, op, rt, rs, imm); |
|
8178 |
break; |
|
8137 | 8179 |
case OPC_DADDI: |
8138 | 8180 |
case OPC_DADDIU: |
8139 | 8181 |
check_insn(env, ctx, ISA_MIPS3); |
Also available in: Unified diff