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