Commit 00a709c7b9f46fee5f2179e3e05adf5f8124f561
1 parent
1124426a
Fix mips FPU emulation, 32 bit data types are allowed to use odd registers.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2454 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
17 additions
and
30 deletions
target-mips/op.c
| @@ -1732,7 +1732,7 @@ void op_mtc1 (void) | @@ -1732,7 +1732,7 @@ void op_mtc1 (void) | ||
| 1732 | 1732 | ||
| 1733 | FLOAT_OP(cvtd, s) | 1733 | FLOAT_OP(cvtd, s) |
| 1734 | { | 1734 | { |
| 1735 | - FDT2 = float32_to_float64(WT0, &env->fp_status); | 1735 | + FDT2 = float32_to_float64(FST0, &env->fp_status); |
| 1736 | DEBUG_FPU_STATE(); | 1736 | DEBUG_FPU_STATE(); |
| 1737 | RETURN(); | 1737 | RETURN(); |
| 1738 | } | 1738 | } |
target-mips/translate.c
| @@ -4216,9 +4216,9 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) | @@ -4216,9 +4216,9 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) | ||
| 4216 | * Status register equals zero, since the register numbers specify an | 4216 | * Status register equals zero, since the register numbers specify an |
| 4217 | * even-odd pair of adjacent coprocessor general registers. When the FR bit | 4217 | * even-odd pair of adjacent coprocessor general registers. When the FR bit |
| 4218 | * in the Status register equals one, both even and odd register numbers | 4218 | * in the Status register equals one, both even and odd register numbers |
| 4219 | - * are valid. | 4219 | + * are valid. This limitation exists only for 64 bit wide (d,l) registers. |
| 4220 | * | 4220 | * |
| 4221 | - * Multiple float registers can be checked by calling | 4221 | + * Multiple 64 bit wide registers can be checked by calling |
| 4222 | * CHECK_FR(ctx, freg1 | freg2 | ... | fregN); | 4222 | * CHECK_FR(ctx, freg1 | freg2 | ... | fregN); |
| 4223 | */ | 4223 | */ |
| 4224 | #define CHECK_FR(ctx, freg) do { \ | 4224 | #define CHECK_FR(ctx, freg) do { \ |
| @@ -4324,42 +4324,42 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd) | @@ -4324,42 +4324,42 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd) | ||
| 4324 | /* 10 - ceil.l */ | 4324 | /* 10 - ceil.l */ |
| 4325 | /* 11 - floor.l */ | 4325 | /* 11 - floor.l */ |
| 4326 | case FOP(12, 17): | 4326 | case FOP(12, 17): |
| 4327 | - CHECK_FR(ctx, fs | fd); | 4327 | + CHECK_FR(ctx, fs); |
| 4328 | GEN_LOAD_FREG_FTN(DT0, fs); | 4328 | GEN_LOAD_FREG_FTN(DT0, fs); |
| 4329 | gen_op_float_roundw_d(); | 4329 | gen_op_float_roundw_d(); |
| 4330 | GEN_STORE_FTN_FREG(fd, WT2); | 4330 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4331 | opn = "round.w.d"; | 4331 | opn = "round.w.d"; |
| 4332 | break; | 4332 | break; |
| 4333 | case FOP(13, 17): | 4333 | case FOP(13, 17): |
| 4334 | - CHECK_FR(ctx, fs | fd); | 4334 | + CHECK_FR(ctx, fs); |
| 4335 | GEN_LOAD_FREG_FTN(DT0, fs); | 4335 | GEN_LOAD_FREG_FTN(DT0, fs); |
| 4336 | gen_op_float_truncw_d(); | 4336 | gen_op_float_truncw_d(); |
| 4337 | GEN_STORE_FTN_FREG(fd, WT2); | 4337 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4338 | opn = "trunc.w.d"; | 4338 | opn = "trunc.w.d"; |
| 4339 | break; | 4339 | break; |
| 4340 | case FOP(14, 17): | 4340 | case FOP(14, 17): |
| 4341 | - CHECK_FR(ctx, fs | fd); | 4341 | + CHECK_FR(ctx, fs); |
| 4342 | GEN_LOAD_FREG_FTN(DT0, fs); | 4342 | GEN_LOAD_FREG_FTN(DT0, fs); |
| 4343 | gen_op_float_ceilw_d(); | 4343 | gen_op_float_ceilw_d(); |
| 4344 | GEN_STORE_FTN_FREG(fd, WT2); | 4344 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4345 | opn = "ceil.w.d"; | 4345 | opn = "ceil.w.d"; |
| 4346 | break; | 4346 | break; |
| 4347 | case FOP(15, 17): | 4347 | case FOP(15, 17): |
| 4348 | - CHECK_FR(ctx, fs | fd); | 4348 | + CHECK_FR(ctx, fs); |
| 4349 | GEN_LOAD_FREG_FTN(DT0, fs); | 4349 | GEN_LOAD_FREG_FTN(DT0, fs); |
| 4350 | gen_op_float_floorw_d(); | 4350 | gen_op_float_floorw_d(); |
| 4351 | GEN_STORE_FTN_FREG(fd, WT2); | 4351 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4352 | opn = "floor.w.d"; | 4352 | opn = "floor.w.d"; |
| 4353 | break; | 4353 | break; |
| 4354 | - case FOP(33, 16): /* cvt.d.s */ | ||
| 4355 | - CHECK_FR(ctx, fs | fd); | 4354 | + case FOP(33, 16): |
| 4355 | + CHECK_FR(ctx, fd); | ||
| 4356 | GEN_LOAD_FREG_FTN(WT0, fs); | 4356 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4357 | gen_op_float_cvtd_s(); | 4357 | gen_op_float_cvtd_s(); |
| 4358 | GEN_STORE_FTN_FREG(fd, DT2); | 4358 | GEN_STORE_FTN_FREG(fd, DT2); |
| 4359 | opn = "cvt.d.s"; | 4359 | opn = "cvt.d.s"; |
| 4360 | break; | 4360 | break; |
| 4361 | - case FOP(33, 20): /* cvt.d.w */ | ||
| 4362 | - CHECK_FR(ctx, fs | fd); | 4361 | + case FOP(33, 20): |
| 4362 | + CHECK_FR(ctx, fd); | ||
| 4363 | GEN_LOAD_FREG_FTN(WT0, fs); | 4363 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4364 | gen_op_float_cvtd_w(); | 4364 | gen_op_float_cvtd_w(); |
| 4365 | GEN_STORE_FTN_FREG(fd, DT2); | 4365 | GEN_STORE_FTN_FREG(fd, DT2); |
| @@ -4388,7 +4388,6 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd) | @@ -4388,7 +4388,6 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd) | ||
| 4388 | opn = condnames[func-48]; | 4388 | opn = condnames[func-48]; |
| 4389 | break; | 4389 | break; |
| 4390 | case FOP(0, 16): | 4390 | case FOP(0, 16): |
| 4391 | - CHECK_FR(ctx, fs | ft | fd); | ||
| 4392 | GEN_LOAD_FREG_FTN(WT0, fs); | 4391 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4393 | GEN_LOAD_FREG_FTN(WT1, ft); | 4392 | GEN_LOAD_FREG_FTN(WT1, ft); |
| 4394 | gen_op_float_add_s(); | 4393 | gen_op_float_add_s(); |
| @@ -4397,7 +4396,6 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd) | @@ -4397,7 +4396,6 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd) | ||
| 4397 | binary = 1; | 4396 | binary = 1; |
| 4398 | break; | 4397 | break; |
| 4399 | case FOP(1, 16): | 4398 | case FOP(1, 16): |
| 4400 | - CHECK_FR(ctx, fs | ft | fd); | ||
| 4401 | GEN_LOAD_FREG_FTN(WT0, fs); | 4399 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4402 | GEN_LOAD_FREG_FTN(WT1, ft); | 4400 | GEN_LOAD_FREG_FTN(WT1, ft); |
| 4403 | gen_op_float_sub_s(); | 4401 | gen_op_float_sub_s(); |
| @@ -4406,7 +4404,6 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd) | @@ -4406,7 +4404,6 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd) | ||
| 4406 | binary = 1; | 4404 | binary = 1; |
| 4407 | break; | 4405 | break; |
| 4408 | case FOP(2, 16): | 4406 | case FOP(2, 16): |
| 4409 | - CHECK_FR(ctx, fs | ft | fd); | ||
| 4410 | GEN_LOAD_FREG_FTN(WT0, fs); | 4407 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4411 | GEN_LOAD_FREG_FTN(WT1, ft); | 4408 | GEN_LOAD_FREG_FTN(WT1, ft); |
| 4412 | gen_op_float_mul_s(); | 4409 | gen_op_float_mul_s(); |
| @@ -4415,7 +4412,6 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd) | @@ -4415,7 +4412,6 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd) | ||
| 4415 | binary = 1; | 4412 | binary = 1; |
| 4416 | break; | 4413 | break; |
| 4417 | case FOP(3, 16): | 4414 | case FOP(3, 16): |
| 4418 | - CHECK_FR(ctx, fs | ft | fd); | ||
| 4419 | GEN_LOAD_FREG_FTN(WT0, fs); | 4415 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4420 | GEN_LOAD_FREG_FTN(WT1, ft); | 4416 | GEN_LOAD_FREG_FTN(WT1, ft); |
| 4421 | gen_op_float_div_s(); | 4417 | gen_op_float_div_s(); |
| @@ -4424,70 +4420,62 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd) | @@ -4424,70 +4420,62 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd) | ||
| 4424 | binary = 1; | 4420 | binary = 1; |
| 4425 | break; | 4421 | break; |
| 4426 | case FOP(4, 16): | 4422 | case FOP(4, 16): |
| 4427 | - CHECK_FR(ctx, fs | fd); | ||
| 4428 | GEN_LOAD_FREG_FTN(WT0, fs); | 4423 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4429 | gen_op_float_sqrt_s(); | 4424 | gen_op_float_sqrt_s(); |
| 4430 | GEN_STORE_FTN_FREG(fd, WT2); | 4425 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4431 | opn = "sqrt.s"; | 4426 | opn = "sqrt.s"; |
| 4432 | break; | 4427 | break; |
| 4433 | case FOP(5, 16): | 4428 | case FOP(5, 16): |
| 4434 | - CHECK_FR(ctx, fs | fd); | ||
| 4435 | GEN_LOAD_FREG_FTN(WT0, fs); | 4429 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4436 | gen_op_float_abs_s(); | 4430 | gen_op_float_abs_s(); |
| 4437 | GEN_STORE_FTN_FREG(fd, WT2); | 4431 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4438 | opn = "abs.s"; | 4432 | opn = "abs.s"; |
| 4439 | break; | 4433 | break; |
| 4440 | case FOP(6, 16): | 4434 | case FOP(6, 16): |
| 4441 | - CHECK_FR(ctx, fs | fd); | ||
| 4442 | GEN_LOAD_FREG_FTN(WT0, fs); | 4435 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4443 | gen_op_float_mov_s(); | 4436 | gen_op_float_mov_s(); |
| 4444 | GEN_STORE_FTN_FREG(fd, WT2); | 4437 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4445 | opn = "mov.s"; | 4438 | opn = "mov.s"; |
| 4446 | break; | 4439 | break; |
| 4447 | case FOP(7, 16): | 4440 | case FOP(7, 16): |
| 4448 | - CHECK_FR(ctx, fs | fd); | ||
| 4449 | GEN_LOAD_FREG_FTN(WT0, fs); | 4441 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4450 | gen_op_float_chs_s(); | 4442 | gen_op_float_chs_s(); |
| 4451 | GEN_STORE_FTN_FREG(fd, WT2); | 4443 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4452 | opn = "neg.s"; | 4444 | opn = "neg.s"; |
| 4453 | break; | 4445 | break; |
| 4454 | case FOP(12, 16): | 4446 | case FOP(12, 16): |
| 4455 | - CHECK_FR(ctx, fs | fd); | ||
| 4456 | GEN_LOAD_FREG_FTN(WT0, fs); | 4447 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4457 | gen_op_float_roundw_s(); | 4448 | gen_op_float_roundw_s(); |
| 4458 | GEN_STORE_FTN_FREG(fd, WT2); | 4449 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4459 | opn = "round.w.s"; | 4450 | opn = "round.w.s"; |
| 4460 | break; | 4451 | break; |
| 4461 | case FOP(13, 16): | 4452 | case FOP(13, 16): |
| 4462 | - CHECK_FR(ctx, fs | fd); | ||
| 4463 | GEN_LOAD_FREG_FTN(WT0, fs); | 4453 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4464 | gen_op_float_truncw_s(); | 4454 | gen_op_float_truncw_s(); |
| 4465 | GEN_STORE_FTN_FREG(fd, WT2); | 4455 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4466 | opn = "trunc.w.s"; | 4456 | opn = "trunc.w.s"; |
| 4467 | break; | 4457 | break; |
| 4468 | - case FOP(32, 17): /* cvt.s.d */ | ||
| 4469 | - CHECK_FR(ctx, fs | fd); | 4458 | + case FOP(32, 17): |
| 4459 | + CHECK_FR(ctx, fs); | ||
| 4470 | GEN_LOAD_FREG_FTN(DT0, fs); | 4460 | GEN_LOAD_FREG_FTN(DT0, fs); |
| 4471 | gen_op_float_cvts_d(); | 4461 | gen_op_float_cvts_d(); |
| 4472 | GEN_STORE_FTN_FREG(fd, WT2); | 4462 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4473 | opn = "cvt.s.d"; | 4463 | opn = "cvt.s.d"; |
| 4474 | break; | 4464 | break; |
| 4475 | - case FOP(32, 20): /* cvt.s.w */ | ||
| 4476 | - CHECK_FR(ctx, fs | fd); | 4465 | + case FOP(32, 20): |
| 4477 | GEN_LOAD_FREG_FTN(WT0, fs); | 4466 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4478 | gen_op_float_cvts_w(); | 4467 | gen_op_float_cvts_w(); |
| 4479 | GEN_STORE_FTN_FREG(fd, WT2); | 4468 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4480 | opn = "cvt.s.w"; | 4469 | opn = "cvt.s.w"; |
| 4481 | break; | 4470 | break; |
| 4482 | - case FOP(36, 16): /* cvt.w.s */ | ||
| 4483 | - CHECK_FR(ctx, fs | fd); | 4471 | + case FOP(36, 16): |
| 4484 | GEN_LOAD_FREG_FTN(WT0, fs); | 4472 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4485 | gen_op_float_cvtw_s(); | 4473 | gen_op_float_cvtw_s(); |
| 4486 | GEN_STORE_FTN_FREG(fd, WT2); | 4474 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4487 | opn = "cvt.w.s"; | 4475 | opn = "cvt.w.s"; |
| 4488 | break; | 4476 | break; |
| 4489 | - case FOP(36, 17): /* cvt.w.d */ | ||
| 4490 | - CHECK_FR(ctx, fs | fd); | 4477 | + case FOP(36, 17): |
| 4478 | + CHECK_FR(ctx, fs); | ||
| 4491 | GEN_LOAD_FREG_FTN(DT0, fs); | 4479 | GEN_LOAD_FREG_FTN(DT0, fs); |
| 4492 | gen_op_float_cvtw_d(); | 4480 | gen_op_float_cvtw_d(); |
| 4493 | GEN_STORE_FTN_FREG(fd, WT2); | 4481 | GEN_STORE_FTN_FREG(fd, WT2); |
| @@ -4509,7 +4497,6 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd) | @@ -4509,7 +4497,6 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd) | ||
| 4509 | case FOP(61, 16): | 4497 | case FOP(61, 16): |
| 4510 | case FOP(62, 16): | 4498 | case FOP(62, 16): |
| 4511 | case FOP(63, 16): | 4499 | case FOP(63, 16): |
| 4512 | - CHECK_FR(ctx, fs | ft); | ||
| 4513 | GEN_LOAD_FREG_FTN(WT0, fs); | 4500 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4514 | GEN_LOAD_FREG_FTN(WT1, ft); | 4501 | GEN_LOAD_FREG_FTN(WT1, ft); |
| 4515 | gen_cmp_s(func-48); | 4502 | gen_cmp_s(func-48); |