Commit fbcc68286a427fe75e7af98d28dee92c71ba0cb5

Authored by ths
1 parent 923617a3

Implement FP madd/msub, wire up bc1any[24][ft].


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2802 c046a42c-6fe2-441c-8c8c-71466251a162
target-mips/op.c
... ... @@ -2185,6 +2185,7 @@ FLOAT_OP(name, d) \
2185 2185 FDT2 = float64_ ## name (FDT0, FDT1, &env->fp_status); \
2186 2186 update_fcr31(); \
2187 2187 DEBUG_FPU_STATE(); \
  2188 + RETURN(); \
2188 2189 } \
2189 2190 FLOAT_OP(name, s) \
2190 2191 { \
... ... @@ -2192,6 +2193,7 @@ FLOAT_OP(name, s) \
2192 2193 FST2 = float32_ ## name (FST0, FST1, &env->fp_status); \
2193 2194 update_fcr31(); \
2194 2195 DEBUG_FPU_STATE(); \
  2196 + RETURN(); \
2195 2197 } \
2196 2198 FLOAT_OP(name, ps) \
2197 2199 { \
... ... @@ -2200,6 +2202,7 @@ FLOAT_OP(name, ps) \
2200 2202 FSTH2 = float32_ ## name (FSTH0, FSTH1, &env->fp_status); \
2201 2203 update_fcr31(); \
2202 2204 DEBUG_FPU_STATE(); \
  2205 + RETURN(); \
2203 2206 }
2204 2207 FLOAT_BINOP(add)
2205 2208 FLOAT_BINOP(sub)
... ... @@ -2207,6 +2210,16 @@ FLOAT_BINOP(mul)
2207 2210 FLOAT_BINOP(div)
2208 2211 #undef FLOAT_BINOP
2209 2212  
  2213 +FLOAT_OP(addr, ps)
  2214 +{
  2215 + set_float_exception_flags(0, &env->fp_status);
  2216 + FST2 = float32_add (FST0, FSTH0, &env->fp_status);
  2217 + FSTH2 = float32_add (FST1, FSTH1, &env->fp_status);
  2218 + update_fcr31();
  2219 + DEBUG_FPU_STATE();
  2220 + RETURN();
  2221 +}
  2222 +
2210 2223 /* ternary operations */
2211 2224 #define FLOAT_TERNOP(name1, name2) \
2212 2225 FLOAT_OP(name1 ## name2, d) \
... ... @@ -2214,12 +2227,14 @@ FLOAT_OP(name1 ## name2, d) \
2214 2227 FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fp_status); \
2215 2228 FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fp_status); \
2216 2229 DEBUG_FPU_STATE(); \
  2230 + RETURN(); \
2217 2231 } \
2218 2232 FLOAT_OP(name1 ## name2, s) \
2219 2233 { \
2220 2234 FST0 = float32_ ## name1 (FST0, FST1, &env->fp_status); \
2221 2235 FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status); \
2222 2236 DEBUG_FPU_STATE(); \
  2237 + RETURN(); \
2223 2238 } \
2224 2239 FLOAT_OP(name1 ## name2, ps) \
2225 2240 { \
... ... @@ -2228,28 +2243,65 @@ FLOAT_OP(name1 ## name2, ps) \
2228 2243 FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status); \
2229 2244 FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fp_status); \
2230 2245 DEBUG_FPU_STATE(); \
  2246 + RETURN(); \
2231 2247 }
2232 2248 FLOAT_TERNOP(mul, add)
2233 2249 FLOAT_TERNOP(mul, sub)
2234 2250 #undef FLOAT_TERNOP
2235 2251  
  2252 +/* negated ternary operations */
  2253 +#define FLOAT_NTERNOP(name1, name2) \
  2254 +FLOAT_OP(n ## name1 ## name2, d) \
  2255 +{ \
  2256 + FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fp_status); \
  2257 + FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fp_status); \
  2258 + FDT2 ^= 1ULL << 63; \
  2259 + DEBUG_FPU_STATE(); \
  2260 + RETURN(); \
  2261 +} \
  2262 +FLOAT_OP(n ## name1 ## name2, s) \
  2263 +{ \
  2264 + FST0 = float32_ ## name1 (FST0, FST1, &env->fp_status); \
  2265 + FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status); \
  2266 + FST2 ^= 1 << 31; \
  2267 + DEBUG_FPU_STATE(); \
  2268 + RETURN(); \
  2269 +} \
  2270 +FLOAT_OP(n ## name1 ## name2, ps) \
  2271 +{ \
  2272 + FST0 = float32_ ## name1 (FST0, FST1, &env->fp_status); \
  2273 + FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fp_status); \
  2274 + FST2 = float32_ ## name2 (FST0, FST2, &env->fp_status); \
  2275 + FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fp_status); \
  2276 + FST2 ^= 1 << 31; \
  2277 + FSTH2 ^= 1 << 31; \
  2278 + DEBUG_FPU_STATE(); \
  2279 + RETURN(); \
  2280 +}
  2281 +FLOAT_NTERNOP(mul, add)
  2282 +FLOAT_NTERNOP(mul, sub)
  2283 +#undef FLOAT_NTERNOP
  2284 +
2236 2285 /* unary operations, modifying fp status */
2237 2286 #define FLOAT_UNOP(name) \
2238 2287 FLOAT_OP(name, d) \
2239 2288 { \
2240 2289 FDT2 = float64_ ## name(FDT0, &env->fp_status); \
2241 2290 DEBUG_FPU_STATE(); \
  2291 + RETURN(); \
2242 2292 } \
2243 2293 FLOAT_OP(name, s) \
2244 2294 { \
2245 2295 FST2 = float32_ ## name(FST0, &env->fp_status); \
2246 2296 DEBUG_FPU_STATE(); \
  2297 + RETURN(); \
2247 2298 } \
2248 2299 FLOAT_OP(name, ps) \
2249 2300 { \
2250 2301 FST2 = float32_ ## name(FST0, &env->fp_status); \
2251 2302 FSTH2 = float32_ ## name(FSTH0, &env->fp_status); \
2252 2303 DEBUG_FPU_STATE(); \
  2304 + RETURN(); \
2253 2305 }
2254 2306 FLOAT_UNOP(sqrt)
2255 2307 #undef FLOAT_UNOP
... ... @@ -2260,17 +2312,20 @@ FLOAT_OP(name, d) \
2260 2312 { \
2261 2313 FDT2 = float64_ ## name(FDT0); \
2262 2314 DEBUG_FPU_STATE(); \
  2315 + RETURN(); \
2263 2316 } \
2264 2317 FLOAT_OP(name, s) \
2265 2318 { \
2266 2319 FST2 = float32_ ## name(FST0); \
2267 2320 DEBUG_FPU_STATE(); \
  2321 + RETURN(); \
2268 2322 } \
2269 2323 FLOAT_OP(name, ps) \
2270 2324 { \
2271 2325 FST2 = float32_ ## name(FST0); \
2272 2326 FSTH2 = float32_ ## name(FSTH0); \
2273 2327 DEBUG_FPU_STATE(); \
  2328 + RETURN(); \
2274 2329 }
2275 2330 FLOAT_UNOP(abs)
2276 2331 FLOAT_UNOP(chs)
... ...
target-mips/translate.c
... ... @@ -402,7 +402,7 @@ enum {
402 402 OPC_MSUB_D = 0x29 | OPC_CP3,
403 403 OPC_MSUB_PS = 0x2E | OPC_CP3,
404 404 OPC_NMADD_S = 0x30 | OPC_CP3,
405   - OPC_NMADD_D = 0x32 | OPC_CP3,
  405 + OPC_NMADD_D = 0x31 | OPC_CP3,
406 406 OPC_NMADD_PS= 0x36 | OPC_CP3,
407 407 OPC_NMSUB_S = 0x38 | OPC_CP3,
408 408 OPC_NMSUB_D = 0x39 | OPC_CP3,
... ... @@ -4955,6 +4955,17 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft,
4955 4955 GEN_STORE_FTN_FREG(fd, WTH2);
4956 4956 opn = "movn.ps";
4957 4957 break;
  4958 + case FOP(24, 22):
  4959 + CHECK_FR(ctx, fs | fd | ft);
  4960 + GEN_LOAD_FREG_FTN(WT0, fs);
  4961 + GEN_LOAD_FREG_FTN(WTH0, fs);
  4962 + GEN_LOAD_FREG_FTN(WT1, ft);
  4963 + GEN_LOAD_FREG_FTN(WTH1, ft);
  4964 + gen_op_float_addr_ps();
  4965 + GEN_STORE_FTN_FREG(fd, WT2);
  4966 + GEN_STORE_FTN_FREG(fd, WTH2);
  4967 + opn = "addr.ps";
  4968 + break;
4958 4969 case FOP(32, 22):
4959 4970 CHECK_FR(ctx, fs);
4960 4971 GEN_LOAD_FREG_FTN(WTH0, fs);
... ... @@ -5120,47 +5131,107 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, int fd,
5120 5131 opn = "madd.s";
5121 5132 break;
5122 5133 case OPC_MADD_D:
5123   - generate_exception (ctx, EXCP_RI);
  5134 + GEN_LOAD_FREG_FTN(DT0, fs);
  5135 + GEN_LOAD_FREG_FTN(DT1, ft);
  5136 + GEN_LOAD_FREG_FTN(DT2, fr);
  5137 + gen_op_float_muladd_d();
  5138 + GEN_STORE_FTN_FREG(fd, DT2);
5124 5139 opn = "madd.d";
5125 5140 break;
5126 5141 case OPC_MADD_PS:
5127   - generate_exception (ctx, EXCP_RI);
  5142 + GEN_LOAD_FREG_FTN(WT0, fs);
  5143 + GEN_LOAD_FREG_FTN(WTH0, fs);
  5144 + GEN_LOAD_FREG_FTN(WT1, ft);
  5145 + GEN_LOAD_FREG_FTN(WTH1, ft);
  5146 + GEN_LOAD_FREG_FTN(WT2, fr);
  5147 + GEN_LOAD_FREG_FTN(WTH2, fr);
  5148 + gen_op_float_muladd_ps();
  5149 + GEN_STORE_FTN_FREG(fd, WT2);
  5150 + GEN_STORE_FTN_FREG(fd, WTH2);
5128 5151 opn = "madd.ps";
5129 5152 break;
5130 5153 case OPC_MSUB_S:
5131   - generate_exception (ctx, EXCP_RI);
  5154 + GEN_LOAD_FREG_FTN(WT0, fs);
  5155 + GEN_LOAD_FREG_FTN(WT1, ft);
  5156 + GEN_LOAD_FREG_FTN(WT2, fr);
  5157 + gen_op_float_mulsub_s();
  5158 + GEN_STORE_FTN_FREG(fd, WT2);
5132 5159 opn = "msub.s";
5133 5160 break;
5134 5161 case OPC_MSUB_D:
5135   - generate_exception (ctx, EXCP_RI);
  5162 + GEN_LOAD_FREG_FTN(DT0, fs);
  5163 + GEN_LOAD_FREG_FTN(DT1, ft);
  5164 + GEN_LOAD_FREG_FTN(DT2, fr);
  5165 + gen_op_float_mulsub_d();
  5166 + GEN_STORE_FTN_FREG(fd, DT2);
5136 5167 opn = "msub.d";
5137 5168 break;
5138 5169 case OPC_MSUB_PS:
5139   - generate_exception (ctx, EXCP_RI);
  5170 + GEN_LOAD_FREG_FTN(WT0, fs);
  5171 + GEN_LOAD_FREG_FTN(WTH0, fs);
  5172 + GEN_LOAD_FREG_FTN(WT1, ft);
  5173 + GEN_LOAD_FREG_FTN(WTH1, ft);
  5174 + GEN_LOAD_FREG_FTN(WT2, fr);
  5175 + GEN_LOAD_FREG_FTN(WTH2, fr);
  5176 + gen_op_float_mulsub_ps();
  5177 + GEN_STORE_FTN_FREG(fd, WT2);
  5178 + GEN_STORE_FTN_FREG(fd, WTH2);
5140 5179 opn = "msub.ps";
5141 5180 break;
5142 5181 case OPC_NMADD_S:
5143   - generate_exception (ctx, EXCP_RI);
  5182 + GEN_LOAD_FREG_FTN(WT0, fs);
  5183 + GEN_LOAD_FREG_FTN(WT1, ft);
  5184 + GEN_LOAD_FREG_FTN(WT2, fr);
  5185 + gen_op_float_nmuladd_s();
  5186 + GEN_STORE_FTN_FREG(fd, WT2);
5144 5187 opn = "nmadd.s";
5145 5188 break;
5146 5189 case OPC_NMADD_D:
5147   - generate_exception (ctx, EXCP_RI);
  5190 + GEN_LOAD_FREG_FTN(DT0, fs);
  5191 + GEN_LOAD_FREG_FTN(DT1, ft);
  5192 + GEN_LOAD_FREG_FTN(DT2, fr);
  5193 + gen_op_float_nmuladd_d();
  5194 + GEN_STORE_FTN_FREG(fd, DT2);
5148 5195 opn = "nmadd.d";
5149 5196 break;
5150 5197 case OPC_NMADD_PS:
5151   - generate_exception (ctx, EXCP_RI);
  5198 + GEN_LOAD_FREG_FTN(WT0, fs);
  5199 + GEN_LOAD_FREG_FTN(WTH0, fs);
  5200 + GEN_LOAD_FREG_FTN(WT1, ft);
  5201 + GEN_LOAD_FREG_FTN(WTH1, ft);
  5202 + GEN_LOAD_FREG_FTN(WT2, fr);
  5203 + GEN_LOAD_FREG_FTN(WTH2, fr);
  5204 + gen_op_float_nmuladd_ps();
  5205 + GEN_STORE_FTN_FREG(fd, WT2);
  5206 + GEN_STORE_FTN_FREG(fd, WTH2);
5152 5207 opn = "nmadd.ps";
5153 5208 break;
5154 5209 case OPC_NMSUB_S:
5155   - generate_exception (ctx, EXCP_RI);
  5210 + GEN_LOAD_FREG_FTN(WT0, fs);
  5211 + GEN_LOAD_FREG_FTN(WT1, ft);
  5212 + GEN_LOAD_FREG_FTN(WT2, fr);
  5213 + gen_op_float_nmulsub_s();
  5214 + GEN_STORE_FTN_FREG(fd, WT2);
5156 5215 opn = "nmsub.s";
5157 5216 break;
5158 5217 case OPC_NMSUB_D:
5159   - generate_exception (ctx, EXCP_RI);
  5218 + GEN_LOAD_FREG_FTN(DT0, fs);
  5219 + GEN_LOAD_FREG_FTN(DT1, ft);
  5220 + GEN_LOAD_FREG_FTN(DT2, fr);
  5221 + gen_op_float_nmulsub_d();
  5222 + GEN_STORE_FTN_FREG(fd, DT2);
5160 5223 opn = "nmsub.d";
5161 5224 break;
5162 5225 case OPC_NMSUB_PS:
5163   - generate_exception (ctx, EXCP_RI);
  5226 + GEN_LOAD_FREG_FTN(WT0, fs);
  5227 + GEN_LOAD_FREG_FTN(WTH0, fs);
  5228 + GEN_LOAD_FREG_FTN(WT1, ft);
  5229 + GEN_LOAD_FREG_FTN(WTH1, ft);
  5230 + GEN_LOAD_FREG_FTN(WT2, fr);
  5231 + GEN_LOAD_FREG_FTN(WTH2, fr);
  5232 + gen_op_float_nmulsub_ps();
  5233 + GEN_STORE_FTN_FREG(fd, WT2);
  5234 + GEN_STORE_FTN_FREG(fd, WTH2);
5164 5235 opn = "nmsub.ps";
5165 5236 break;
5166 5237 default:
... ... @@ -5562,6 +5633,8 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
5562 5633 gen_cp1(ctx, op1, rt, rd);
5563 5634 break;
5564 5635 case OPC_BC1:
  5636 + case OPC_BC1ANY2:
  5637 + case OPC_BC1ANY4:
5565 5638 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5566 5639 (rt >> 2) & 0x7, imm << 2);
5567 5640 return;
... ...