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); | ... | ... |