History

Implement or forward math functionality to std. Update not implemented message in Math module.

arr committed 9 years ago

Commit 92473681 parent 5520e671 file · +151 −65Browse files

Unified · Split

src/vm/math/Mathmod.cpp+151−65
@@ -4,6 +4,7 @@ · 3 unmodified lines
44 // Author: arr
55 //
66
7+#include <debug.h>
78 #include "Mathmod.h"
89
910 using namespace disvm;
@@ -97,7 +98,9 @@ Math_FPcontrol(vm_registers_t &r, vm_t &vm) · 87 unmodified lines
9798 {
9899 auto &fp = r.stack.peek_frame()->base<F_Math_FPcontrol>();
99100
100− // [PAL] Properly implment floating point control
101+ // [PAL] Properly implement floating point control
102+ debug::log_msg(debug::component_trace_t::builtin, debug::log_level_t::warning, "FPControl is not properly implemented");
103+
101104 *fp.ret = fp.mask;
102105 }
103106
@@ -105,56 +108,56 @@ void · 1 unmodified line
105108 Math_FPstatus(vm_registers_t &r, vm_t &vm)
106109 {
107110 auto &fp = r.stack.peek_frame()->base<F_Math_FPstatus>();
108− throw vm_system_exception{ "Instruction not implemented" };
111+ throw vm_system_exception{ "Function not implemented" };
109112 }
110113
111114 void
112115 Math_acos(vm_registers_t &r, vm_t &vm)
113116 {
114117 auto &fp = r.stack.peek_frame()->base<F_Math_acos>();
115− throw vm_system_exception{ "Instruction not implemented" };
118+ *fp.ret = std::acos(fp.x);
116119 }
117120
118121 void
119122 Math_acosh(vm_registers_t &r, vm_t &vm)
120123 {
121124 auto &fp = r.stack.peek_frame()->base<F_Math_acosh>();
122− throw vm_system_exception{ "Instruction not implemented" };
125+ *fp.ret = std::acosh(fp.x);
123126 }
124127
125128 void
126129 Math_asin(vm_registers_t &r, vm_t &vm)
127130 {
128131 auto &fp = r.stack.peek_frame()->base<F_Math_asin>();
129− throw vm_system_exception{ "Instruction not implemented" };
132+ *fp.ret = std::asin(fp.x);
130133 }
131134
132135 void
133136 Math_asinh(vm_registers_t &r, vm_t &vm)
134137 {
135138 auto &fp = r.stack.peek_frame()->base<F_Math_asinh>();
136− throw vm_system_exception{ "Instruction not implemented" };
139+ *fp.ret = std::asinh(fp.x);
137140 }
138141
139142 void
140143 Math_atan(vm_registers_t &r, vm_t &vm)
141144 {
142145 auto &fp = r.stack.peek_frame()->base<F_Math_atan>();
143− throw vm_system_exception{ "Instruction not implemented" };
146+ *fp.ret = std::atan(fp.x);
144147 }
145148
146149 void
147150 Math_atan2(vm_registers_t &r, vm_t &vm)
148151 {
149152 auto &fp = r.stack.peek_frame()->base<F_Math_atan2>();
150− throw vm_system_exception{ "Instruction not implemented" };
153+ *fp.ret = std::atan2(fp.x, fp.y);
151154 }
152155
153156 void
154157 Math_atanh(vm_registers_t &r, vm_t &vm)
155158 {
156159 auto &fp = r.stack.peek_frame()->base<F_Math_atanh>();
157− throw vm_system_exception{ "Instruction not implemented" };
160+ *fp.ret = std::atanh(fp.x);
158161 }
159162
160163 void
@@ -186,77 +189,97 @@ void · 25 unmodified lines
186189 Math_cbrt(vm_registers_t &r, vm_t &vm)
187190 {
188191 auto &fp = r.stack.peek_frame()->base<F_Math_cbrt>();
189− throw vm_system_exception{ "Instruction not implemented" };
192+ *fp.ret = std::cbrt(fp.x);
190193 }
191194
192195 void
193196 Math_ceil(vm_registers_t &r, vm_t &vm)
194197 {
195198 auto &fp = r.stack.peek_frame()->base<F_Math_ceil>();
196− throw vm_system_exception{ "Instruction not implemented" };
199+ *fp.ret = std::ceil(fp.x);
197200 }
198201
199202 void
200203 Math_copysign(vm_registers_t &r, vm_t &vm)
201204 {
202205 auto &fp = r.stack.peek_frame()->base<F_Math_copysign>();
203− throw vm_system_exception{ "Instruction not implemented" };
206+ *fp.ret = std::copysign(fp.x, fp.s);
204207 }
205208
206209 void
207210 Math_cos(vm_registers_t &r, vm_t &vm)
208211 {
209212 auto &fp = r.stack.peek_frame()->base<F_Math_cos>();
210− throw vm_system_exception{ "Instruction not implemented" };
213+ *fp.ret = std::cos(fp.x);
211214 }
212215
213216 void
214217 Math_cosh(vm_registers_t &r, vm_t &vm)
215218 {
216219 auto &fp = r.stack.peek_frame()->base<F_Math_cosh>();
217− throw vm_system_exception{ "Instruction not implemented" };
220+ *fp.ret = std::cosh(fp.x);
218221 }
219222
220223 void
221224 Math_dot(vm_registers_t &r, vm_t &vm)
222225 {
226+ // Defined as: dot(x, y) = sum(x[i] * y[i])
223227 auto &fp = r.stack.peek_frame()->base<F_Math_dot>();
224− throw vm_system_exception{ "Instruction not implemented" };
228+
229+ auto xs = vm_alloc_t::from_allocation<vm_array_t>(fp.x);
230+ auto ys = vm_alloc_t::from_allocation<vm_array_t>(fp.y);
231+ if (xs == nullptr || ys == nullptr)
232+ throw dereference_nil{ "dot product" };
233+
234+ assert(xs->get_element_type()->is_equal(intrinsic_type_desc::type<real_t>().get()));
235+ assert(ys->get_element_type()->is_equal(intrinsic_type_desc::type<real_t>().get()));
236+ const auto x_len = xs->get_length();
237+ if (x_len != ys->get_length())
238+ throw vm_user_exception{ "Array lengths must be equal" };
239+
240+ auto x_raw = reinterpret_cast<real_t *>(xs->at(0));
241+ auto y_raw = reinterpret_cast<real_t *>(ys->at(0));
242+
243+ auto result = real_t{ 0 };
244+ for (auto i = 0; i < x_len; ++i)
245+ result += (x_raw[i] * y_raw[i]);
246+
247+ *fp.ret = result;
225248 }
226249
227250 void
228251 Math_erf(vm_registers_t &r, vm_t &vm)
229252 {
230253 auto &fp = r.stack.peek_frame()->base<F_Math_erf>();
231− throw vm_system_exception{ "Instruction not implemented" };
254+ *fp.ret = std::erf(fp.x);
232255 }
233256
234257 void
235258 Math_erfc(vm_registers_t &r, vm_t &vm)
236259 {
237260 auto &fp = r.stack.peek_frame()->base<F_Math_erfc>();
238− throw vm_system_exception{ "Instruction not implemented" };
261+ *fp.ret = std::erfc(fp.x);
239262 }
240263
241264 void
242265 Math_exp(vm_registers_t &r, vm_t &vm)
243266 {
244267 auto &fp = r.stack.peek_frame()->base<F_Math_exp>();
245− throw vm_system_exception{ "Instruction not implemented" };
268+ *fp.ret = std::exp(fp.x);
246269 }
247270
248271 void
249272 Math_expm1(vm_registers_t &r, vm_t &vm)
250273 {
251274 auto &fp = r.stack.peek_frame()->base<F_Math_expm1>();
252− throw vm_system_exception{ "Instruction not implemented" };
275+ *fp.ret = std::expm1(fp.x);
253276 }
254277
255278 void
256279 Math_export_int(vm_registers_t &r, vm_t &vm)
257280 {
258281 auto &fp = r.stack.peek_frame()->base<F_Math_export_int>();
259− throw vm_system_exception{ "Instruction not implemented" };
282+ throw vm_system_exception{ "Function not implemented" };
260283 }
261284
262285 void
@@ -265,10 +288,10 @@ Math_export_real(vm_registers_t &r, vm_t &vm) · 2 unmodified lines
265288 auto &fp = r.stack.peek_frame()->base<F_Math_export_real>();
266289
267290 auto buffer = vm_alloc_t::from_allocation<vm_array_t>(fp.b);
268− assert(buffer->get_element_type()->size_in_bytes == intrinsic_type_desc::type<byte_t>()->size_in_bytes);
291+ assert(buffer->get_element_type()->is_equal(intrinsic_type_desc::type<byte_t>().get()));
269292
270293 auto values = vm_alloc_t::from_allocation<vm_array_t>(fp.x);
271− assert(values->get_element_type()->size_in_bytes == intrinsic_type_desc::type<real_t>()->size_in_bytes);
294+ assert(values->get_element_type()->is_equal(intrinsic_type_desc::type<real_t>().get()));
272295 const auto values_len = values->get_length();
273296
274297 if (buffer->get_length() != (8 * values_len))
@@ -298,105 +321,105 @@ void · 23 unmodified lines
298321 Math_export_real32(vm_registers_t &r, vm_t &vm)
299322 {
300323 auto &fp = r.stack.peek_frame()->base<F_Math_export_real32>();
301− throw vm_system_exception{ "Instruction not implemented" };
324+ throw vm_system_exception{ "Function not implemented" };
302325 }
303326
304327 void
305328 Math_fabs(vm_registers_t &r, vm_t &vm)
306329 {
307330 auto &fp = r.stack.peek_frame()->base<F_Math_fabs>();
308− throw vm_system_exception{ "Instruction not implemented" };
331+ *fp.ret = std::fabs(fp.x);
309332 }
310333
311334 void
312335 Math_fdim(vm_registers_t &r, vm_t &vm)
313336 {
314337 auto &fp = r.stack.peek_frame()->base<F_Math_fdim>();
315− throw vm_system_exception{ "Instruction not implemented" };
338+ *fp.ret = std::fdim(fp.x, fp.y);
316339 }
317340
318341 void
319342 Math_finite(vm_registers_t &r, vm_t &vm)
320343 {
321344 auto &fp = r.stack.peek_frame()->base<F_Math_finite>();
322− throw vm_system_exception{ "Instruction not implemented" };
345+ *fp.ret = std::isfinite(fp.x) ? 1 : 0;
323346 }
324347
325348 void
326349 Math_floor(vm_registers_t &r, vm_t &vm)
327350 {
328351 auto &fp = r.stack.peek_frame()->base<F_Math_floor>();
329− throw vm_system_exception{ "Instruction not implemented" };
352+ *fp.ret = std::floor(fp.x);
330353 }
331354
332355 void
333356 Math_fmax(vm_registers_t &r, vm_t &vm)
334357 {
335358 auto &fp = r.stack.peek_frame()->base<F_Math_fmax>();
336− throw vm_system_exception{ "Instruction not implemented" };
359+ *fp.ret = std::fmax(fp.x, fp.y);
337360 }
338361
339362 void
340363 Math_fmin(vm_registers_t &r, vm_t &vm)
341364 {
342365 auto &fp = r.stack.peek_frame()->base<F_Math_fmin>();
343− throw vm_system_exception{ "Instruction not implemented" };
366+ *fp.ret = std::fmin(fp.x, fp.y);
344367 }
345368
346369 void
347370 Math_fmod(vm_registers_t &r, vm_t &vm)
348371 {
349372 auto &fp = r.stack.peek_frame()->base<F_Math_fmod>();
350− throw vm_system_exception{ "Instruction not implemented" };
373+ *fp.ret = std::fmod(fp.x, fp.y);
351374 }
352375
353376 void
354377 Math_gemm(vm_registers_t &r, vm_t &vm)
355378 {
356379 auto &fp = r.stack.peek_frame()->base<F_Math_gemm>();
357− throw vm_system_exception{ "Instruction not implemented" };
380+ throw vm_system_exception{ "Function not implemented" };
358381 }
359382
360383 void
361384 Math_getFPcontrol(vm_registers_t &r, vm_t &vm)
362385 {
363386 auto &fp = r.stack.peek_frame()->base<F_Math_getFPcontrol>();
364− throw vm_system_exception{ "Instruction not implemented" };
387+ throw vm_system_exception{ "Function not implemented" };
365388 }
366389
367390 void
368391 Math_getFPstatus(vm_registers_t &r, vm_t &vm)
369392 {
370393 auto &fp = r.stack.peek_frame()->base<F_Math_getFPstatus>();
371− throw vm_system_exception{ "Instruction not implemented" };
394+ throw vm_system_exception{ "Function not implemented" };
372395 }
373396
374397 void
375398 Math_hypot(vm_registers_t &r, vm_t &vm)
376399 {
377400 auto &fp = r.stack.peek_frame()->base<F_Math_hypot>();
378− throw vm_system_exception{ "Instruction not implemented" };
401+ *fp.ret = std::hypot(fp.x, fp.y);
379402 }
380403
381404 void
382405 Math_iamax(vm_registers_t &r, vm_t &vm)
383406 {
384407 auto &fp = r.stack.peek_frame()->base<F_Math_iamax>();
385− throw vm_system_exception{ "Instruction not implemented" };
408+ throw vm_system_exception{ "Function not implemented" };
386409 }
387410
388411 void
389412 Math_ilogb(vm_registers_t &r, vm_t &vm)
390413 {
391414 auto &fp = r.stack.peek_frame()->base<F_Math_ilogb>();
392− throw vm_system_exception{ "Instruction not implemented" };
415+ *fp.ret = std::ilogb(fp.x);
393416 }
394417
395418 void
396419 Math_import_int(vm_registers_t &r, vm_t &vm)
397420 {
398421 auto &fp = r.stack.peek_frame()->base<F_Math_import_int>();
399− throw vm_system_exception{ "Instruction not implemented" };
422+ throw vm_system_exception{ "Function not implemented" };
400423 }
401424
402425 void
@@ -405,10 +428,10 @@ Math_import_real(vm_registers_t &r, vm_t &vm) · 2 unmodified lines
405428 auto &fp = r.stack.peek_frame()->base<F_Math_import_real>();
406429
407430 auto buffer = vm_alloc_t::from_allocation<vm_array_t>(fp.b);
408− assert(buffer->get_element_type()->size_in_bytes == intrinsic_type_desc::type<byte_t>()->size_in_bytes);
431+ assert(buffer->get_element_type()->is_equal(intrinsic_type_desc::type<byte_t>().get()));
409432
410433 auto result = vm_alloc_t::from_allocation<vm_array_t>(fp.x);
411− assert(result->get_element_type()->size_in_bytes == intrinsic_type_desc::type<real_t>()->size_in_bytes);
434+ assert(result->get_element_type()->is_equal(intrinsic_type_desc::type<real_t>().get()));
412435 const auto result_len = result->get_length();
413436
414437 if (buffer->get_length() != (8 * result_len))
@@ -433,7 +456,7 @@ void · 18 unmodified lines
433456 Math_import_real32(vm_registers_t &r, vm_t &vm)
434457 {
435458 auto &fp = r.stack.peek_frame()->base<F_Math_import_real32>();
436− throw vm_system_exception{ "Instruction not implemented" };
459+ throw vm_system_exception{ "Function not implemented" };
437460 }
438461
439462 void
@@ -447,91 +470,126 @@ void · 7 unmodified lines
447470 Math_j0(vm_registers_t &r, vm_t &vm)
448471 {
449472 auto &fp = r.stack.peek_frame()->base<F_Math_j0>();
450− throw vm_system_exception{ "Instruction not implemented" };
473+ throw vm_system_exception{ "Function not implemented" };
451474 }
452475
453476 void
454477 Math_j1(vm_registers_t &r, vm_t &vm)
455478 {
456479 auto &fp = r.stack.peek_frame()->base<F_Math_j1>();
457− throw vm_system_exception{ "Instruction not implemented" };
480+ throw vm_system_exception{ "Function not implemented" };
458481 }
459482
460483 void
461484 Math_jn(vm_registers_t &r, vm_t &vm)
462485 {
463486 auto &fp = r.stack.peek_frame()->base<F_Math_jn>();
464− throw vm_system_exception{ "Instruction not implemented" };
487+ throw vm_system_exception{ "Function not implemented" };
465488 }
466489
467490 void
468491 Math_lgamma(vm_registers_t &r, vm_t &vm)
469492 {
470493 auto &fp = r.stack.peek_frame()->base<F_Math_lgamma>();
471− throw vm_system_exception{ "Instruction not implemented" };
494+ throw vm_system_exception{ "Function not implemented" };
472495 }
473496
474497 void
475498 Math_log(vm_registers_t &r, vm_t &vm)
476499 {
477500 auto &fp = r.stack.peek_frame()->base<F_Math_log>();
478− throw vm_system_exception{ "Instruction not implemented" };
501+ *fp.ret = std::log(fp.x);
479502 }
480503
481504 void
482505 Math_log10(vm_registers_t &r, vm_t &vm)
483506 {
484507 auto &fp = r.stack.peek_frame()->base<F_Math_log10>();
485− throw vm_system_exception{ "Instruction not implemented" };
508+ *fp.ret = std::log10(fp.x);
486509 }
487510
488511 void
489512 Math_log1p(vm_registers_t &r, vm_t &vm)
490513 {
491514 auto &fp = r.stack.peek_frame()->base<F_Math_log1p>();
492− throw vm_system_exception{ "Instruction not implemented" };
515+ *fp.ret = std::log1p(fp.x);
493516 }
494517
495518 void
496519 Math_modf(vm_registers_t &r, vm_t &vm)
497520 {
498521 auto &fp = r.stack.peek_frame()->base<F_Math_modf>();
499− throw vm_system_exception{ "Instruction not implemented" };
522+ throw vm_system_exception{ "Function not implemented" };
500523 }
501524
502525 void
503526 Math_nextafter(vm_registers_t &r, vm_t &vm)
504527 {
505528 auto &fp = r.stack.peek_frame()->base<F_Math_nextafter>();
506− throw vm_system_exception{ "Instruction not implemented" };
529+ *fp.ret = std::nextafter(fp.x, fp.y);
507530 }
508531
509532 void
510533 Math_norm1(vm_registers_t &r, vm_t &vm)
511534 {
535+ // Defined as: norm1(x) = sum(fabs(x[i]))
512536 auto &fp = r.stack.peek_frame()->base<F_Math_norm1>();
513− throw vm_system_exception{ "Instruction not implemented" };
537+
538+ auto xs = vm_alloc_t::from_allocation<vm_array_t>(fp.x);
539+ if (xs == nullptr)
540+ throw dereference_nil{ "norm1" };
541+
542+ assert(xs->get_element_type()->is_equal(intrinsic_type_desc::type<real_t>().get()));
543+
544+ const auto x_len = xs->get_length();
545+ auto x_raw = reinterpret_cast<real_t *>(xs->at(0));
546+
547+ auto result = real_t{ 0 };
548+ for (auto i = 0; i < x_len; ++i)
549+ result += std::fabs(x_raw[i]);
550+
551+ *fp.ret = result;
514552 }
515553
516554 void
517555 Math_norm2(vm_registers_t &r, vm_t &vm)
518556 {
557+ // [SPEC] This function is defined as: norm2(x) = sqrt(dot(x, x))
558+ // The Inferno implementation (libmath/blas.c) doesn't appear to take
559+ // the square root of the resulting dot product.
519560 auto &fp = r.stack.peek_frame()->base<F_Math_norm2>();
520− throw vm_system_exception{ "Instruction not implemented" };
561+
562+ auto xs = vm_alloc_t::from_allocation<vm_array_t>(fp.x);
563+ if (xs == nullptr)
564+ throw dereference_nil{ "norm2" };
565+
566+ assert(xs->get_element_type()->is_equal(intrinsic_type_desc::type<real_t>().get()));
567+
568+ const auto x_len = xs->get_length();
569+ auto x_raw = reinterpret_cast<real_t *>(xs->at(0));
570+
571+ auto result = real_t{ 0 };
572+ for (auto i = 0; i < x_len; ++i)
573+ {
574+ const auto x_l = x_raw[i];
575+ result += (x_l * x_l);
576+ }
577+
578+ *fp.ret = std::sqrt(result);
521579 }
522580
523581 void
524582 Math_pow(vm_registers_t &r, vm_t &vm)
525583 {
526584 auto &fp = r.stack.peek_frame()->base<F_Math_pow>();
527− throw vm_system_exception{ "Instruction not implemented" };
585+ *fp.ret = std::pow(fp.x, fp.y);
528586 }
529587
530588 void
531589 Math_pow10(vm_registers_t &r, vm_t &vm)
532590 {
533591 auto &fp = r.stack.peek_frame()->base<F_Math_pow10>();
534− throw vm_system_exception{ "Instruction not implemented" };
592+ throw vm_system_exception{ "Function not implemented" };
535593 }
536594
537595 void
@@ -563,82 +621,110 @@ void · 25 unmodified lines
563621 Math_remainder(vm_registers_t &r, vm_t &vm)
564622 {
565623 auto &fp = r.stack.peek_frame()->base<F_Math_remainder>();
566− throw vm_system_exception{ "Instruction not implemented" };
624+ *fp.ret = std::remainder(fp.x, fp.p);
567625 }
568626
569627 void
570628 Math_rint(vm_registers_t &r, vm_t &vm)
571629 {
572630 auto &fp = r.stack.peek_frame()->base<F_Math_rint>();
573− throw vm_system_exception{ "Instruction not implemented" };
631+ *fp.ret = std::rint(fp.x);
574632 }
575633
576634 void
577635 Math_scalbn(vm_registers_t &r, vm_t &vm)
578636 {
579637 auto &fp = r.stack.peek_frame()->base<F_Math_scalbn>();
580− throw vm_system_exception{ "Instruction not implemented" };
638+ throw vm_system_exception{ "Function not implemented" };
581639 }
582640
583641 void
584642 Math_sin(vm_registers_t &r, vm_t &vm)
585643 {
586644 auto &fp = r.stack.peek_frame()->base<F_Math_sin>();
587− throw vm_system_exception{ "Instruction not implemented" };
645+ *fp.ret = std::sin(fp.x);
588646 }
589647
590648 void
591649 Math_sinh(vm_registers_t &r, vm_t &vm)
592650 {
593651 auto &fp = r.stack.peek_frame()->base<F_Math_sinh>();
594− throw vm_system_exception{ "Instruction not implemented" };
652+ *fp.ret = std::sinh(fp.x);
595653 }
596654
597655 void
598656 Math_sort(vm_registers_t &r, vm_t &vm)
599657 {
600658 auto &fp = r.stack.peek_frame()->base<F_Math_sort>();
601− throw vm_system_exception{ "Instruction not implemented" };
659+
660+ auto reals = vm_alloc_t::from_allocation<vm_array_t>(fp.x);
661+ auto words = vm_alloc_t::from_allocation<vm_array_t>(fp.pi);
662+ if (reals == nullptr || words == nullptr)
663+ throw dereference_nil{ "Sort reals" };
664+
665+ assert(reals->get_element_type()->is_equal(intrinsic_type_desc::type<real_t>().get()));
666+ assert(words->get_element_type()->is_equal(intrinsic_type_desc::type<word_t>().get()));
667+
668+ const auto words_len = words->get_length();
669+ if (reals->get_length() != words_len)
670+ throw vm_user_exception{ "Array lengths must be equal" };
671+
672+ // Handle trivial sort cases
673+ if (words_len <= 1)
674+ return;
675+
676+ auto begin_words = reinterpret_cast<word_t *>(words->at(0));
677+ auto end_words = begin_words + words_len;
678+
679+ // Validate array of indices
680+ for (auto iter = begin_words; iter != end_words; ++iter)
681+ {
682+ if (*iter < 0 || words_len <= *iter)
683+ throw vm_user_exception{ "Invalid sort index values" };
684+ }
685+
686+ const auto reals_raw = reinterpret_cast<real_t *>(reals->at(0));
687+ std::sort(begin_words, end_words, [reals_raw](word_t l, word_t r) { return reals_raw[l] < reals_raw[r]; });
602688 }
603689
604690 void
605691 Math_sqrt(vm_registers_t &r, vm_t &vm)
606692 {
607693 auto &fp = r.stack.peek_frame()->base<F_Math_sqrt>();
608− throw vm_system_exception{ "Instruction not implemented" };
694+ *fp.ret = std::sqrt(fp.x);
609695 }
610696
611697 void
612698 Math_tan(vm_registers_t &r, vm_t &vm)
613699 {
614700 auto &fp = r.stack.peek_frame()->base<F_Math_tan>();
615− throw vm_system_exception{ "Instruction not implemented" };
701+ *fp.ret = std::tan(fp.x);
616702 }
617703
618704 void
619705 Math_tanh(vm_registers_t &r, vm_t &vm)
620706 {
621707 auto &fp = r.stack.peek_frame()->base<F_Math_tanh>();
622− throw vm_system_exception{ "Instruction not implemented" };
708+ *fp.ret = std::tanh(fp.x);
623709 }
624710
625711 void
626712 Math_y0(vm_registers_t &r, vm_t &vm)
627713 {
628714 auto &fp = r.stack.peek_frame()->base<F_Math_y0>();
629− throw vm_system_exception{ "Instruction not implemented" };
715+ throw vm_system_exception{ "Function not implemented" };
630716 }
631717
632718 void
633719 Math_y1(vm_registers_t &r, vm_t &vm)
634720 {
635721 auto &fp = r.stack.peek_frame()->base<F_Math_y1>();
636− throw vm_system_exception{ "Instruction not implemented" };
722+ throw vm_system_exception{ "Function not implemented" };
637723 }
638724
639725 void
640726 Math_yn(vm_registers_t &r, vm_t &vm)
641727 {
642728 auto &fp = r.stack.peek_frame()->base<F_Math_yn>();
643− throw vm_system_exception{ "Instruction not implemented" };
729+ throw vm_system_exception{ "Function not implemented" };
644730 }