Showing the changes to src/vm/execution_table.cpp (1 of 1 file). Show all
Unified · Split
| @@ -348,68 +348,83 @@ namespace · 347 unmodified lines | ||
| 348 | 348 | // Undocumented: (http://www.vitanuova.com/inferno/papers/dis.html) |
| 349 | 349 | // Limbo reference: (http://www.vitanuova.com/inferno/papers/addendum.pdf) |
| 350 | 350 | |
| 351 | + // Fixed point identities | |
| 352 | + // X = s * x | |
| 353 | + // Y = t * y | |
| 354 | + // Z = u * z | |
| 355 | + // | |
| 356 | + // Multiplication: | |
| 357 | + // uz = sx * ty | |
| 358 | + // z = (sx/u) * (ty/u) | |
| 359 | + // z = (st/u) * (xy) | |
| 360 | + // | |
| 361 | + // Division: | |
| 362 | + // uz = sx/ty | |
| 363 | + // z = (sx/ty) * (1/u) | |
| 364 | + // z = (s/tu) * (x/y) | |
| 365 | + | |
| 351 | 366 | // Multiply for fixed point types with final scaling as a power of 2. |
| 352 | 367 | // mulx src1 src2 dst |
| 353 | − // src1 - integer 1 | |
| 354 | − // src2 - integer 2 | |
| 355 | − // fpr_2 - result scaling factor (2^x) | |
| 356 | − // dest - result integer | |
| 368 | + // src1 - integer 1 (y) | |
| 369 | + // src2 - integer 2 (x) | |
| 370 | + // fpr_2 - result scaling factor (2^p) | |
| 371 | + // dest - result integer (z) | |
| 357 | 372 | EXEC_DECL(mulx) |
| 358 | 373 | { |
| 359 | − const auto m = big_t{ vt_ref<word_t>(r.mid) }; | |
| 360 | − const auto s = big_t{ vt_ref<word_t>(r.src) }; | |
| 361 | − auto result = m * s; | |
| 374 | + const auto x = big_t{ vt_ref<word_t>(r.mid) }; | |
| 375 | + const auto y = big_t{ vt_ref<word_t>(r.src) }; | |
| 376 | + auto z = x * y; | |
| 362 | 377 | |
| 363 | 378 | const auto pow2_scale = *reinterpret_cast<word_t *>(r.stack.peek_frame()->fixed_point_register_2()); |
| 364 | 379 | if (pow2_scale >= 0) |
| 365 | − result <<= pow2_scale; | |
| 380 | + z <<= pow2_scale; | |
| 366 | 381 | else |
| 367 | − result >>= (-pow2_scale); | |
| 382 | + z >>= (-pow2_scale); | |
| 368 | 383 | |
| 369 | − vt_ref<word_t>(r.dest) = static_cast<word_t>(result); | |
| 384 | + vt_ref<word_t>(r.dest) = static_cast<word_t>(z); | |
| 370 | 385 | } |
| 371 | 386 | |
| 372 | 387 | // Division for fixed point types with final scaling as a power of 2. |
| 373 | 388 | // divx src1 src2 dst |
| 374 | − // src1 - integer 1 | |
| 375 | − // src2 - integer 2 | |
| 376 | − // fpr_2 - result scaling factor (2^x) | |
| 377 | − // dest - result integer | |
| 389 | + // src1 - integer 1 (y) | |
| 390 | + // src2 - integer 2 (x) | |
| 391 | + // fpr_2 - result scaling factor (2^p) | |
| 392 | + // dest - result integer (z) | |
| 378 | 393 | EXEC_DECL(divx) |
| 379 | 394 | { |
| 380 | − auto numerator = big_t{ vt_ref<word_t>(r.mid) }; | |
| 395 | + auto x = big_t{ vt_ref<word_t>(r.mid) }; | |
| 381 | 396 | const auto pow2_scale = *reinterpret_cast<word_t *>(r.stack.peek_frame()->fixed_point_register_2()); |
| 382 | 397 | if (pow2_scale >= 0) |
| 383 | − numerator <<= pow2_scale; | |
| 398 | + x <<= pow2_scale; | |
| 384 | 399 | else |
| 385 | − numerator >>= (-pow2_scale); | |
| 400 | + x >>= (-pow2_scale); | |
| 386 | 401 | |
| 387 | − const auto denom = big_t{ vt_ref<word_t>(r.src) }; | |
| 388 | − if (denom == 0) | |
| 402 | + const auto y = big_t{ vt_ref<word_t>(r.src) }; | |
| 403 | + if (y == 0) | |
| 389 | 404 | throw divide_by_zero{}; |
| 390 | 405 | |
| 391 | − const auto result = numerator / denom; | |
| 392 | − vt_ref<word_t>(r.dest) = static_cast<word_t>(result); | |
| 406 | + const auto z = x / y; | |
| 407 | + vt_ref<word_t>(r.dest) = static_cast<word_t>(z); | |
| 393 | 408 | } |
| 394 | 409 | |
| 395 | 410 | // mulx0 src1 src2 dst |
| 396 | − // src1 - integer 1 | |
| 397 | − // src2 - integer 2 | |
| 411 | + // src1 - integer 1 (y) | |
| 412 | + // src2 - integer 2 (x) | |
| 398 | 413 | // fpr_1 - residual factor |
| 399 | − // fpr_2 - result scaling factor (2^x) | |
| 400 | − // dest - result integer | |
| 414 | + // fpr_2 - result scaling factor (2^p) | |
| 415 | + // dest - result integer (z) | |
| 401 | 416 | EXEC_DECL(mulx0) |
| 402 | 417 | { |
| 403 | − const auto m = big_t{ vt_ref<word_t>(r.mid) }; | |
| 404 | − const auto s = big_t{ vt_ref<word_t>(r.src) }; | |
| 405 | − auto tmp = m * s; | |
| 418 | + const auto x = big_t{ vt_ref<word_t>(r.mid) }; | |
| 419 | + const auto y = big_t{ vt_ref<word_t>(r.src) }; | |
| 406 | 420 | |
| 407 | − if (m == 0 || s == 0) | |
| 421 | + if (x == 0 || y == 0) | |
| 408 | 422 | { |
| 409 | 423 | vt_ref<word_t>(r.dest) = 0; |
| 410 | 424 | return; |
| 411 | 425 | } |
| 412 | 426 | |
| 427 | + auto tmp = x * y; | |
| 413 | 428 | const auto frame = r.stack.peek_frame(); |
| 414 | 429 | const auto pow2_scale = *reinterpret_cast<word_t *>(frame->fixed_point_register_2()); |
| 415 | 430 | if (pow2_scale >= 0) |
| @@ -420,24 +435,24 @@ namespace · 4 unmodified lines | ||
| 420 | 435 | const auto residual_scale = big_t{ *reinterpret_cast<word_t *>(frame->fixed_point_register_1()) }; |
| 421 | 436 | assert(residual_scale != 0); |
| 422 | 437 | |
| 423 | − const auto result = tmp / residual_scale; | |
| 424 | − vt_ref<word_t>(r.dest) = static_cast<word_t>(result); | |
| 438 | + const auto z = tmp / residual_scale; | |
| 439 | + vt_ref<word_t>(r.dest) = static_cast<word_t>(z); | |
| 425 | 440 | } |
| 426 | 441 | |
| 427 | 442 | // divx0 src1 src2 dst |
| 428 | − // src1 - integer 1 | |
| 429 | − // src2 - integer 2 | |
| 443 | + // src1 - integer 1 (y) | |
| 444 | + // src2 - integer 2 (x) | |
| 430 | 445 | // fpr_1 - residual factor |
| 431 | − // fpr_2 - result scaling factor (2^x) | |
| 432 | − // dest - result integer | |
| 446 | + // fpr_2 - result scaling factor (2^p) | |
| 447 | + // dest - result integer (z) | |
| 433 | 448 | EXEC_DECL(divx0) |
| 434 | 449 | { |
| 435 | − const auto m = big_t{ vt_ref<word_t>(r.mid) }; | |
| 436 | − const auto s = big_t{ vt_ref<word_t>(r.src) }; | |
| 437 | − if (s == 0) | |
| 450 | + const auto x = big_t{ vt_ref<word_t>(r.mid) }; | |
| 451 | + const auto y = big_t{ vt_ref<word_t>(r.src) }; | |
| 452 | + if (y == 0) | |
| 438 | 453 | throw divide_by_zero{}; |
| 439 | 454 | |
| 440 | − if (m == 0) | |
| 455 | + if (x == 0) | |
| 441 | 456 | { |
| 442 | 457 | vt_ref<word_t>(r.dest) = 0; |
| 443 | 458 | return; |
| @@ -446,15 +461,15 @@ namespace · 2 unmodified lines | ||
| 446 | 461 | const auto frame = r.stack.peek_frame(); |
| 447 | 462 | const auto residual_scale = big_t{ *reinterpret_cast<word_t *>(frame->fixed_point_register_1()) }; |
| 448 | 463 | |
| 449 | − auto tmp = m * residual_scale; | |
| 464 | + auto tmp = x * residual_scale; | |
| 450 | 465 | const auto pow2_scale = *reinterpret_cast<word_t *>(frame->fixed_point_register_2()); |
| 451 | 466 | if (pow2_scale >= 0) |
| 452 | 467 | tmp <<= pow2_scale; |
| 453 | 468 | else |
| 454 | 469 | tmp >>= (-pow2_scale); |
| 455 | 470 | |
| 456 | − const auto result = tmp / s; | |
| 457 | − vt_ref<word_t>(r.dest) = static_cast<word_t>(result); | |
| 471 | + const auto z = tmp / y; | |
| 472 | + vt_ref<word_t>(r.dest) = static_cast<word_t>(z); | |
| 458 | 473 | } |
| 459 | 474 | |
| 460 | 475 | // |