History

Implement all import/export functions Implement all forwardable to std functions

arr committed 9 years ago

Commit 83d4a881 parent 98ad0161 file · +146 −11Browse files

Unified · Split

src/vm/math/Mathmod.cpp+146−11
@@ -290,7 +290,28 @@ void · 289 unmodified lines
290Math_export_int(vm_registers_t &r, vm_t &vm)290Math_export_int(vm_registers_t &r, vm_t &vm)
291{291{
292 auto &fp = r.stack.peek_frame()->base<F_Math_export_int>();292 auto &fp = r.stack.peek_frame()->base<F_Math_export_int>();
293 throw vm_system_exception{ "Function not implemented" };293
294 auto buffer = vm_alloc_t::from_allocation<vm_array_t>(fp.b);
295 assert(buffer->get_element_type()->is_equal(intrinsic_type_desc::type<byte_t>().get()));
296
297 auto values = vm_alloc_t::from_allocation<vm_array_t>(fp.x);
298 assert(values->get_element_type()->is_equal(intrinsic_type_desc::type<word_t>().get()));
299 const auto values_len = values->get_length();
300
301 if (buffer->get_length() != (sizeof(word_t) * values_len))
302 throw vm_user_exception{ "Invalid buffer size based on conversion" };
303
304 // Insert as big endian
305 for (int i = 0; i < values_len; ++i)
306 {
307 auto x = values->at<word_t>(i);
308
309 auto base = reinterpret_cast<byte_t *>(buffer->at(i * sizeof(x)));
310 base[0] = static_cast<byte_t>(x >> 24);
311 base[1] = static_cast<byte_t>(x >> 16);
312 base[2] = static_cast<byte_t>(x >> 8);
313 base[3] = static_cast<byte_t>(x);
314 }
294}315}
295 316
296void317void
@@ -305,7 +326,7 @@ Math_export_real(vm_registers_t &r, vm_t &vm) · 8 unmodified lines
305 assert(values->get_element_type()->is_equal(intrinsic_type_desc::type<real_t>().get()));326 assert(values->get_element_type()->is_equal(intrinsic_type_desc::type<real_t>().get()));
306 const auto values_len = values->get_length();327 const auto values_len = values->get_length();
307 328
308 if (buffer->get_length() != (8 * values_len))329 if (buffer->get_length() != (sizeof(real_t) * values_len))
309 throw vm_user_exception{ "Invalid buffer size based on conversion" };330 throw vm_user_exception{ "Invalid buffer size based on conversion" };
310 331
311 // Insert as big endian332 // Insert as big endian
@@ -332,7 +353,32 @@ void · 20 unmodified lines
332Math_export_real32(vm_registers_t &r, vm_t &vm)353Math_export_real32(vm_registers_t &r, vm_t &vm)
333{354{
334 auto &fp = r.stack.peek_frame()->base<F_Math_export_real32>();355 auto &fp = r.stack.peek_frame()->base<F_Math_export_real32>();
335 throw vm_system_exception{ "Function not implemented" };356
357 auto buffer = vm_alloc_t::from_allocation<vm_array_t>(fp.b);
358 assert(buffer->get_element_type()->is_equal(intrinsic_type_desc::type<byte_t>().get()));
359
360 auto values = vm_alloc_t::from_allocation<vm_array_t>(fp.x);
361 assert(values->get_element_type()->is_equal(intrinsic_type_desc::type<real_t>().get()));
362 const auto values_len = values->get_length();
363
364 if (buffer->get_length() != (sizeof(float) * values_len))
365 throw vm_user_exception{ "Invalid buffer size based on conversion" };
366
367 // Insert as big endian
368 for (int i = 0; i < values_len; ++i)
369 {
370 auto x_r = values->at<real_t>(i);
371 auto x = static_cast<float>(x_r);
372 uint32_t t;
373 std::memcpy(&t, &x, sizeof(x));
374 static_assert(sizeof(t) == sizeof(x), "Short-real should be 32-bits");
375
376 auto base = reinterpret_cast<byte_t *>(buffer->at(i * sizeof(x)));
377 base[0] = static_cast<byte_t>(t >> 24);
378 base[1] = static_cast<byte_t>(t >> 16);
379 base[2] = static_cast<byte_t>(t >> 8);
380 base[3] = static_cast<byte_t>(t);
381 }
336}382}
337 383
338void384void
@@ -416,7 +462,34 @@ void · 77 unmodified lines
416Math_iamax(vm_registers_t &r, vm_t &vm)462Math_iamax(vm_registers_t &r, vm_t &vm)
417{463{
418 auto &fp = r.stack.peek_frame()->base<F_Math_iamax>();464 auto &fp = r.stack.peek_frame()->base<F_Math_iamax>();
419 throw vm_system_exception{ "Function not implemented" };465
466 // [SPEC] According to the Inferno implementation (libmath/blas.c), 0 is returned
467 // if the array is empty. This means there is no indication the supplied array was
468 // empty or the first index was max. The spec does not describe this condition,
469 // therefore this implementation will indicate with -1.
470 *fp.ret = -1;
471
472 auto result = vm_alloc_t::from_allocation<vm_array_t>(fp.x);
473 assert(result->get_element_type()->is_equal(intrinsic_type_desc::type<real_t>().get()));
474 if (result->get_length() <= 0)
475 return;
476
477 auto r_raw = reinterpret_cast<real_t *>(result->at(0));
478
479 auto max_idx = 0;
480 auto r_len = result->get_length();
481 auto curr_max = std::fabs(r_raw[max_idx]);
482 for (auto i = word_t{ 1 }; i < r_len; ++i)
483 {
484 auto t = std::fabs(r_raw[i]);
485 if (curr_max < t)
486 {
487 max_idx = i;
488 curr_max = t;
489 }
490 }
491
492 *fp.ret = max_idx;
420}493}
421 494
422void495void
@@ -430,7 +503,27 @@ void · 7 unmodified lines
430Math_import_int(vm_registers_t &r, vm_t &vm)503Math_import_int(vm_registers_t &r, vm_t &vm)
431{504{
432 auto &fp = r.stack.peek_frame()->base<F_Math_import_int>();505 auto &fp = r.stack.peek_frame()->base<F_Math_import_int>();
433 throw vm_system_exception{ "Function not implemented" };506
507 auto buffer = vm_alloc_t::from_allocation<vm_array_t>(fp.b);
508 assert(buffer->get_element_type()->is_equal(intrinsic_type_desc::type<byte_t>().get()));
509
510 auto result = vm_alloc_t::from_allocation<vm_array_t>(fp.x);
511 assert(result->get_element_type()->is_equal(intrinsic_type_desc::type<word_t>().get()));
512 const auto result_len = result->get_length();
513
514 if (buffer->get_length() != (sizeof(word_t) * result_len))
515 throw vm_user_exception{ "Invalid buffer size based on conversion" };
516
517 // Process as big endian
518 for (int i = 0; i < result_len; ++i)
519 {
520 uint32_t t = buffer->at<byte_t>(0);
521 for (int j = 1; j < sizeof(word_t); ++j)
522 t = (t << 8) | buffer->at<byte_t>(j);
523
524 auto x = static_cast<word_t>(t);
525 result->at<word_t>(i) = x;
526 }
434}527}
435 528
436void529void
@@ -445,14 +538,14 @@ Math_import_real(vm_registers_t &r, vm_t &vm) · 8 unmodified lines
445 assert(result->get_element_type()->is_equal(intrinsic_type_desc::type<real_t>().get()));538 assert(result->get_element_type()->is_equal(intrinsic_type_desc::type<real_t>().get()));
446 const auto result_len = result->get_length();539 const auto result_len = result->get_length();
447 540
448 if (buffer->get_length() != (8 * result_len))541 if (buffer->get_length() != (sizeof(real_t) * result_len))
449 throw vm_user_exception{ "Invalid buffer size based on conversion" };542 throw vm_user_exception{ "Invalid buffer size based on conversion" };
450 543
451 // Process as big endian544 // Process as big endian
452 for (int i = 0; i < result_len; ++i)545 for (int i = 0; i < result_len; ++i)
453 {546 {
454 uint64_t t = buffer->at<byte_t>(0);547 uint64_t t = buffer->at<byte_t>(0);
455 for (int j = 1; j < 8; ++j)548 for (int j = 1; j < sizeof(real_t); ++j)
456 t = (t << 8) | buffer->at<byte_t>(j);549 t = (t << 8) | buffer->at<byte_t>(j);
457 550
458 real_t x;551 real_t x;
@@ -467,7 +560,31 @@ void · 8 unmodified lines
467Math_import_real32(vm_registers_t &r, vm_t &vm)560Math_import_real32(vm_registers_t &r, vm_t &vm)
468{561{
469 auto &fp = r.stack.peek_frame()->base<F_Math_import_real32>();562 auto &fp = r.stack.peek_frame()->base<F_Math_import_real32>();
470 throw vm_system_exception{ "Function not implemented" };563
564 auto buffer = vm_alloc_t::from_allocation<vm_array_t>(fp.b);
565 assert(buffer->get_element_type()->is_equal(intrinsic_type_desc::type<byte_t>().get()));
566
567 auto result = vm_alloc_t::from_allocation<vm_array_t>(fp.x);
568 assert(result->get_element_type()->is_equal(intrinsic_type_desc::type<real_t>().get()));
569 const auto result_len = result->get_length();
570
571 if (buffer->get_length() != (sizeof(float) * result_len))
572 throw vm_user_exception{ "Invalid buffer size based on conversion" };
573
574 // Process as big endian
575 for (int i = 0; i < result_len; ++i)
576 {
577 uint32_t t = buffer->at<byte_t>(0);
578 for (int j = 1; j < sizeof(float); ++j)
579 t = (t << 8) | buffer->at<byte_t>(j);
580
581 float x_f;
582 std::memcpy(&x_f, &t, sizeof(t));
583 static_assert(sizeof(t) == sizeof(x_f), "Short-real should be 32-bits");
584
585 auto x = real_t{ x_f };
586 result->at<real_t>(i) = x;
587 }
471}588}
472 589
473void590void
@@ -481,6 +598,8 @@ void · 7 unmodified lines
481Math_j0(vm_registers_t &r, vm_t &vm)598Math_j0(vm_registers_t &r, vm_t &vm)
482{599{
483 auto &fp = r.stack.peek_frame()->base<F_Math_j0>();600 auto &fp = r.stack.peek_frame()->base<F_Math_j0>();
601
602 // [PAL] Consume platform API
484 throw vm_system_exception{ "Function not implemented" };603 throw vm_system_exception{ "Function not implemented" };
485}604}
486 605
@@ -488,6 +607,8 @@ void · 1 unmodified line
488Math_j1(vm_registers_t &r, vm_t &vm)607Math_j1(vm_registers_t &r, vm_t &vm)
489{608{
490 auto &fp = r.stack.peek_frame()->base<F_Math_j1>();609 auto &fp = r.stack.peek_frame()->base<F_Math_j1>();
610
611 // [PAL] Consume platform API
491 throw vm_system_exception{ "Function not implemented" };612 throw vm_system_exception{ "Function not implemented" };
492}613}
493 614
@@ -495,6 +616,8 @@ void · 1 unmodified line
495Math_jn(vm_registers_t &r, vm_t &vm)616Math_jn(vm_registers_t &r, vm_t &vm)
496{617{
497 auto &fp = r.stack.peek_frame()->base<F_Math_jn>();618 auto &fp = r.stack.peek_frame()->base<F_Math_jn>();
619
620 // [PAL] Consume platform API
498 throw vm_system_exception{ "Function not implemented" };621 throw vm_system_exception{ "Function not implemented" };
499}622}
500 623
@@ -530,7 +653,13 @@ void · 29 unmodified lines
530Math_modf(vm_registers_t &r, vm_t &vm)653Math_modf(vm_registers_t &r, vm_t &vm)
531{654{
532 auto &fp = r.stack.peek_frame()->base<F_Math_modf>();655 auto &fp = r.stack.peek_frame()->base<F_Math_modf>();
533 throw vm_system_exception{ "Function not implemented" };656
657 real_t integral_out;
658 const auto fractional_part = std::modf(fp.x, &integral_out);
659 const auto integral_part = static_cast<word_t>(integral_out);
660
661 fp.ret->t0 = integral_part;
662 fp.ret->t1 = fractional_part;
534}663}
535 664
536void665void
@@ -600,7 +729,7 @@ void · 63 unmodified lines
600Math_pow10(vm_registers_t &r, vm_t &vm)729Math_pow10(vm_registers_t &r, vm_t &vm)
601{730{
602 auto &fp = r.stack.peek_frame()->base<F_Math_pow10>();731 auto &fp = r.stack.peek_frame()->base<F_Math_pow10>();
603 throw vm_system_exception{ "Function not implemented" };732 *fp.ret = std::pow(10., static_cast<real_t>(fp.p));
604}733}
605 734
606void735void
@@ -646,7 +775,7 @@ void · 39 unmodified lines
646Math_scalbn(vm_registers_t &r, vm_t &vm)775Math_scalbn(vm_registers_t &r, vm_t &vm)
647{776{
648 auto &fp = r.stack.peek_frame()->base<F_Math_scalbn>();777 auto &fp = r.stack.peek_frame()->base<F_Math_scalbn>();
649 throw vm_system_exception{ "Function not implemented" };778 *fp.ret = std::scalbln(fp.x, fp.n);
650}779}
651 780
652void781void
@@ -723,6 +852,8 @@ void · 70 unmodified lines
723Math_y0(vm_registers_t &r, vm_t &vm)852Math_y0(vm_registers_t &r, vm_t &vm)
724{853{
725 auto &fp = r.stack.peek_frame()->base<F_Math_y0>();854 auto &fp = r.stack.peek_frame()->base<F_Math_y0>();
855
856 // [PAL] Consume platform API
726 throw vm_system_exception{ "Function not implemented" };857 throw vm_system_exception{ "Function not implemented" };
727}858}
728 859
@@ -730,6 +861,8 @@ void · 1 unmodified line
730Math_y1(vm_registers_t &r, vm_t &vm)861Math_y1(vm_registers_t &r, vm_t &vm)
731{862{
732 auto &fp = r.stack.peek_frame()->base<F_Math_y1>();863 auto &fp = r.stack.peek_frame()->base<F_Math_y1>();
864
865 // [PAL] Consume platform API
733 throw vm_system_exception{ "Function not implemented" };866 throw vm_system_exception{ "Function not implemented" };
734}867}
735 868
@@ -737,5 +870,7 @@ void · 1 unmodified line
737Math_yn(vm_registers_t &r, vm_t &vm)870Math_yn(vm_registers_t &r, vm_t &vm)
738{871{
739 auto &fp = r.stack.peek_frame()->base<F_Math_yn>();872 auto &fp = r.stack.peek_frame()->base<F_Math_yn>();
873
874 // [PAL] Consume platform API
740 throw vm_system_exception{ "Function not implemented" };875 throw vm_system_exception{ "Function not implemented" };
741}876}