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
target-mips/translate.c
| ... | ... | @@ -4216,9 +4216,9 @@ static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs) |
| 4216 | 4216 | * Status register equals zero, since the register numbers specify an |
| 4217 | 4217 | * even-odd pair of adjacent coprocessor general registers. When the FR bit |
| 4218 | 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 | 4222 | * CHECK_FR(ctx, freg1 | freg2 | ... | fregN); |
| 4223 | 4223 | */ |
| 4224 | 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 | 4324 | /* 10 - ceil.l */ |
| 4325 | 4325 | /* 11 - floor.l */ |
| 4326 | 4326 | case FOP(12, 17): |
| 4327 | - CHECK_FR(ctx, fs | fd); | |
| 4327 | + CHECK_FR(ctx, fs); | |
| 4328 | 4328 | GEN_LOAD_FREG_FTN(DT0, fs); |
| 4329 | 4329 | gen_op_float_roundw_d(); |
| 4330 | 4330 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4331 | 4331 | opn = "round.w.d"; |
| 4332 | 4332 | break; |
| 4333 | 4333 | case FOP(13, 17): |
| 4334 | - CHECK_FR(ctx, fs | fd); | |
| 4334 | + CHECK_FR(ctx, fs); | |
| 4335 | 4335 | GEN_LOAD_FREG_FTN(DT0, fs); |
| 4336 | 4336 | gen_op_float_truncw_d(); |
| 4337 | 4337 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4338 | 4338 | opn = "trunc.w.d"; |
| 4339 | 4339 | break; |
| 4340 | 4340 | case FOP(14, 17): |
| 4341 | - CHECK_FR(ctx, fs | fd); | |
| 4341 | + CHECK_FR(ctx, fs); | |
| 4342 | 4342 | GEN_LOAD_FREG_FTN(DT0, fs); |
| 4343 | 4343 | gen_op_float_ceilw_d(); |
| 4344 | 4344 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4345 | 4345 | opn = "ceil.w.d"; |
| 4346 | 4346 | break; |
| 4347 | 4347 | case FOP(15, 17): |
| 4348 | - CHECK_FR(ctx, fs | fd); | |
| 4348 | + CHECK_FR(ctx, fs); | |
| 4349 | 4349 | GEN_LOAD_FREG_FTN(DT0, fs); |
| 4350 | 4350 | gen_op_float_floorw_d(); |
| 4351 | 4351 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4352 | 4352 | opn = "floor.w.d"; |
| 4353 | 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 | 4356 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4357 | 4357 | gen_op_float_cvtd_s(); |
| 4358 | 4358 | GEN_STORE_FTN_FREG(fd, DT2); |
| 4359 | 4359 | opn = "cvt.d.s"; |
| 4360 | 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 | 4363 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4364 | 4364 | gen_op_float_cvtd_w(); |
| 4365 | 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 | 4388 | opn = condnames[func-48]; |
| 4389 | 4389 | break; |
| 4390 | 4390 | case FOP(0, 16): |
| 4391 | - CHECK_FR(ctx, fs | ft | fd); | |
| 4392 | 4391 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4393 | 4392 | GEN_LOAD_FREG_FTN(WT1, ft); |
| 4394 | 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 | 4396 | binary = 1; |
| 4398 | 4397 | break; |
| 4399 | 4398 | case FOP(1, 16): |
| 4400 | - CHECK_FR(ctx, fs | ft | fd); | |
| 4401 | 4399 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4402 | 4400 | GEN_LOAD_FREG_FTN(WT1, ft); |
| 4403 | 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 | 4404 | binary = 1; |
| 4407 | 4405 | break; |
| 4408 | 4406 | case FOP(2, 16): |
| 4409 | - CHECK_FR(ctx, fs | ft | fd); | |
| 4410 | 4407 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4411 | 4408 | GEN_LOAD_FREG_FTN(WT1, ft); |
| 4412 | 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 | 4412 | binary = 1; |
| 4416 | 4413 | break; |
| 4417 | 4414 | case FOP(3, 16): |
| 4418 | - CHECK_FR(ctx, fs | ft | fd); | |
| 4419 | 4415 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4420 | 4416 | GEN_LOAD_FREG_FTN(WT1, ft); |
| 4421 | 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 | 4420 | binary = 1; |
| 4425 | 4421 | break; |
| 4426 | 4422 | case FOP(4, 16): |
| 4427 | - CHECK_FR(ctx, fs | fd); | |
| 4428 | 4423 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4429 | 4424 | gen_op_float_sqrt_s(); |
| 4430 | 4425 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4431 | 4426 | opn = "sqrt.s"; |
| 4432 | 4427 | break; |
| 4433 | 4428 | case FOP(5, 16): |
| 4434 | - CHECK_FR(ctx, fs | fd); | |
| 4435 | 4429 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4436 | 4430 | gen_op_float_abs_s(); |
| 4437 | 4431 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4438 | 4432 | opn = "abs.s"; |
| 4439 | 4433 | break; |
| 4440 | 4434 | case FOP(6, 16): |
| 4441 | - CHECK_FR(ctx, fs | fd); | |
| 4442 | 4435 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4443 | 4436 | gen_op_float_mov_s(); |
| 4444 | 4437 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4445 | 4438 | opn = "mov.s"; |
| 4446 | 4439 | break; |
| 4447 | 4440 | case FOP(7, 16): |
| 4448 | - CHECK_FR(ctx, fs | fd); | |
| 4449 | 4441 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4450 | 4442 | gen_op_float_chs_s(); |
| 4451 | 4443 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4452 | 4444 | opn = "neg.s"; |
| 4453 | 4445 | break; |
| 4454 | 4446 | case FOP(12, 16): |
| 4455 | - CHECK_FR(ctx, fs | fd); | |
| 4456 | 4447 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4457 | 4448 | gen_op_float_roundw_s(); |
| 4458 | 4449 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4459 | 4450 | opn = "round.w.s"; |
| 4460 | 4451 | break; |
| 4461 | 4452 | case FOP(13, 16): |
| 4462 | - CHECK_FR(ctx, fs | fd); | |
| 4463 | 4453 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4464 | 4454 | gen_op_float_truncw_s(); |
| 4465 | 4455 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4466 | 4456 | opn = "trunc.w.s"; |
| 4467 | 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 | 4460 | GEN_LOAD_FREG_FTN(DT0, fs); |
| 4471 | 4461 | gen_op_float_cvts_d(); |
| 4472 | 4462 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4473 | 4463 | opn = "cvt.s.d"; |
| 4474 | 4464 | break; |
| 4475 | - case FOP(32, 20): /* cvt.s.w */ | |
| 4476 | - CHECK_FR(ctx, fs | fd); | |
| 4465 | + case FOP(32, 20): | |
| 4477 | 4466 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4478 | 4467 | gen_op_float_cvts_w(); |
| 4479 | 4468 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4480 | 4469 | opn = "cvt.s.w"; |
| 4481 | 4470 | break; |
| 4482 | - case FOP(36, 16): /* cvt.w.s */ | |
| 4483 | - CHECK_FR(ctx, fs | fd); | |
| 4471 | + case FOP(36, 16): | |
| 4484 | 4472 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4485 | 4473 | gen_op_float_cvtw_s(); |
| 4486 | 4474 | GEN_STORE_FTN_FREG(fd, WT2); |
| 4487 | 4475 | opn = "cvt.w.s"; |
| 4488 | 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 | 4479 | GEN_LOAD_FREG_FTN(DT0, fs); |
| 4492 | 4480 | gen_op_float_cvtw_d(); |
| 4493 | 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 | 4497 | case FOP(61, 16): |
| 4510 | 4498 | case FOP(62, 16): |
| 4511 | 4499 | case FOP(63, 16): |
| 4512 | - CHECK_FR(ctx, fs | ft); | |
| 4513 | 4500 | GEN_LOAD_FREG_FTN(WT0, fs); |
| 4514 | 4501 | GEN_LOAD_FREG_FTN(WT1, ft); |
| 4515 | 4502 | gen_cmp_s(func-48); | ... | ... |