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