Unified · Split
| @@ -4,6 +4,7 @@ · 3 unmodified lines | |||
| 4 | // Author: arr | 4 | // Author: arr |
| 5 | // | 5 | // |
| 6 | 6 | ||
| 7 | #include <debug.h> | ||
| 7 | #include "Mathmod.h" | 8 | #include "Mathmod.h" |
| 8 | 9 | ||
| 9 | using namespace disvm; | 10 | using namespace disvm; |
| @@ -97,7 +98,9 @@ Math_FPcontrol(vm_registers_t &r, vm_t &vm) · 87 unmodified lines | |||
| 97 | { | 98 | { |
| 98 | auto &fp = r.stack.peek_frame()->base<F_Math_FPcontrol>(); | 99 | auto &fp = r.stack.peek_frame()->base<F_Math_FPcontrol>(); |
| 99 | 100 | ||
| 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 | |||
| 101 | *fp.ret = fp.mask; | 104 | *fp.ret = fp.mask; |
| 102 | } | 105 | } |
| 103 | 106 | ||
| @@ -105,56 +108,56 @@ void · 1 unmodified line | |||
| 105 | Math_FPstatus(vm_registers_t &r, vm_t &vm) | 108 | Math_FPstatus(vm_registers_t &r, vm_t &vm) |
| 106 | { | 109 | { |
| 107 | auto &fp = r.stack.peek_frame()->base<F_Math_FPstatus>(); | 110 | 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" }; |
| 109 | } | 112 | } |
| 110 | 113 | ||
| 111 | void | 114 | void |
| 112 | Math_acos(vm_registers_t &r, vm_t &vm) | 115 | Math_acos(vm_registers_t &r, vm_t &vm) |
| 113 | { | 116 | { |
| 114 | auto &fp = r.stack.peek_frame()->base<F_Math_acos>(); | 117 | 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); |
| 116 | } | 119 | } |
| 117 | 120 | ||
| 118 | void | 121 | void |
| 119 | Math_acosh(vm_registers_t &r, vm_t &vm) | 122 | Math_acosh(vm_registers_t &r, vm_t &vm) |
| 120 | { | 123 | { |
| 121 | auto &fp = r.stack.peek_frame()->base<F_Math_acosh>(); | 124 | 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); |
| 123 | } | 126 | } |
| 124 | 127 | ||
| 125 | void | 128 | void |
| 126 | Math_asin(vm_registers_t &r, vm_t &vm) | 129 | Math_asin(vm_registers_t &r, vm_t &vm) |
| 127 | { | 130 | { |
| 128 | auto &fp = r.stack.peek_frame()->base<F_Math_asin>(); | 131 | 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); |
| 130 | } | 133 | } |
| 131 | 134 | ||
| 132 | void | 135 | void |
| 133 | Math_asinh(vm_registers_t &r, vm_t &vm) | 136 | Math_asinh(vm_registers_t &r, vm_t &vm) |
| 134 | { | 137 | { |
| 135 | auto &fp = r.stack.peek_frame()->base<F_Math_asinh>(); | 138 | 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); |
| 137 | } | 140 | } |
| 138 | 141 | ||
| 139 | void | 142 | void |
| 140 | Math_atan(vm_registers_t &r, vm_t &vm) | 143 | Math_atan(vm_registers_t &r, vm_t &vm) |
| 141 | { | 144 | { |
| 142 | auto &fp = r.stack.peek_frame()->base<F_Math_atan>(); | 145 | 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); |
| 144 | } | 147 | } |
| 145 | 148 | ||
| 146 | void | 149 | void |
| 147 | Math_atan2(vm_registers_t &r, vm_t &vm) | 150 | Math_atan2(vm_registers_t &r, vm_t &vm) |
| 148 | { | 151 | { |
| 149 | auto &fp = r.stack.peek_frame()->base<F_Math_atan2>(); | 152 | 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); |
| 151 | } | 154 | } |
| 152 | 155 | ||
| 153 | void | 156 | void |
| 154 | Math_atanh(vm_registers_t &r, vm_t &vm) | 157 | Math_atanh(vm_registers_t &r, vm_t &vm) |
| 155 | { | 158 | { |
| 156 | auto &fp = r.stack.peek_frame()->base<F_Math_atanh>(); | 159 | 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); |
| 158 | } | 161 | } |
| 159 | 162 | ||
| 160 | void | 163 | void |
| @@ -186,77 +189,97 @@ void · 25 unmodified lines | |||
| 186 | Math_cbrt(vm_registers_t &r, vm_t &vm) | 189 | Math_cbrt(vm_registers_t &r, vm_t &vm) |
| 187 | { | 190 | { |
| 188 | auto &fp = r.stack.peek_frame()->base<F_Math_cbrt>(); | 191 | 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); |
| 190 | } | 193 | } |
| 191 | 194 | ||
| 192 | void | 195 | void |
| 193 | Math_ceil(vm_registers_t &r, vm_t &vm) | 196 | Math_ceil(vm_registers_t &r, vm_t &vm) |
| 194 | { | 197 | { |
| 195 | auto &fp = r.stack.peek_frame()->base<F_Math_ceil>(); | 198 | 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); |
| 197 | } | 200 | } |
| 198 | 201 | ||
| 199 | void | 202 | void |
| 200 | Math_copysign(vm_registers_t &r, vm_t &vm) | 203 | Math_copysign(vm_registers_t &r, vm_t &vm) |
| 201 | { | 204 | { |
| 202 | auto &fp = r.stack.peek_frame()->base<F_Math_copysign>(); | 205 | 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); |
| 204 | } | 207 | } |
| 205 | 208 | ||
| 206 | void | 209 | void |
| 207 | Math_cos(vm_registers_t &r, vm_t &vm) | 210 | Math_cos(vm_registers_t &r, vm_t &vm) |
| 208 | { | 211 | { |
| 209 | auto &fp = r.stack.peek_frame()->base<F_Math_cos>(); | 212 | 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); |
| 211 | } | 214 | } |
| 212 | 215 | ||
| 213 | void | 216 | void |
| 214 | Math_cosh(vm_registers_t &r, vm_t &vm) | 217 | Math_cosh(vm_registers_t &r, vm_t &vm) |
| 215 | { | 218 | { |
| 216 | auto &fp = r.stack.peek_frame()->base<F_Math_cosh>(); | 219 | 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); |
| 218 | } | 221 | } |
| 219 | 222 | ||
| 220 | void | 223 | void |
| 221 | Math_dot(vm_registers_t &r, vm_t &vm) | 224 | Math_dot(vm_registers_t &r, vm_t &vm) |
| 222 | { | 225 | { |
| 226 | // Defined as: dot(x, y) = sum(x[i] * y[i]) | ||
| 223 | auto &fp = r.stack.peek_frame()->base<F_Math_dot>(); | 227 | 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; | ||
| 225 | } | 248 | } |
| 226 | 249 | ||
| 227 | void | 250 | void |
| 228 | Math_erf(vm_registers_t &r, vm_t &vm) | 251 | Math_erf(vm_registers_t &r, vm_t &vm) |
| 229 | { | 252 | { |
| 230 | auto &fp = r.stack.peek_frame()->base<F_Math_erf>(); | 253 | 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); |
| 232 | } | 255 | } |
| 233 | 256 | ||
| 234 | void | 257 | void |
| 235 | Math_erfc(vm_registers_t &r, vm_t &vm) | 258 | Math_erfc(vm_registers_t &r, vm_t &vm) |
| 236 | { | 259 | { |
| 237 | auto &fp = r.stack.peek_frame()->base<F_Math_erfc>(); | 260 | 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); |
| 239 | } | 262 | } |
| 240 | 263 | ||
| 241 | void | 264 | void |
| 242 | Math_exp(vm_registers_t &r, vm_t &vm) | 265 | Math_exp(vm_registers_t &r, vm_t &vm) |
| 243 | { | 266 | { |
| 244 | auto &fp = r.stack.peek_frame()->base<F_Math_exp>(); | 267 | 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); |
| 246 | } | 269 | } |
| 247 | 270 | ||
| 248 | void | 271 | void |
| 249 | Math_expm1(vm_registers_t &r, vm_t &vm) | 272 | Math_expm1(vm_registers_t &r, vm_t &vm) |
| 250 | { | 273 | { |
| 251 | auto &fp = r.stack.peek_frame()->base<F_Math_expm1>(); | 274 | 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); |
| 253 | } | 276 | } |
| 254 | 277 | ||
| 255 | void | 278 | void |
| 256 | Math_export_int(vm_registers_t &r, vm_t &vm) | 279 | Math_export_int(vm_registers_t &r, vm_t &vm) |
| 257 | { | 280 | { |
| 258 | auto &fp = r.stack.peek_frame()->base<F_Math_export_int>(); | 281 | 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" }; |
| 260 | } | 283 | } |
| 261 | 284 | ||
| 262 | void | 285 | void |
| @@ -265,10 +288,10 @@ Math_export_real(vm_registers_t &r, vm_t &vm) · 2 unmodified lines | |||
| 265 | auto &fp = r.stack.peek_frame()->base<F_Math_export_real>(); | 288 | auto &fp = r.stack.peek_frame()->base<F_Math_export_real>(); |
| 266 | 289 | ||
| 267 | auto buffer = vm_alloc_t::from_allocation<vm_array_t>(fp.b); | 290 | 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())); |
| 269 | 292 | ||
| 270 | auto values = vm_alloc_t::from_allocation<vm_array_t>(fp.x); | 293 | 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())); |
| 272 | const auto values_len = values->get_length(); | 295 | const auto values_len = values->get_length(); |
| 273 | 296 | ||
| 274 | if (buffer->get_length() != (8 * values_len)) | 297 | if (buffer->get_length() != (8 * values_len)) |
| @@ -298,105 +321,105 @@ void · 23 unmodified lines | |||
| 298 | Math_export_real32(vm_registers_t &r, vm_t &vm) | 321 | Math_export_real32(vm_registers_t &r, vm_t &vm) |
| 299 | { | 322 | { |
| 300 | auto &fp = r.stack.peek_frame()->base<F_Math_export_real32>(); | 323 | 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" }; |
| 302 | } | 325 | } |
| 303 | 326 | ||
| 304 | void | 327 | void |
| 305 | Math_fabs(vm_registers_t &r, vm_t &vm) | 328 | Math_fabs(vm_registers_t &r, vm_t &vm) |
| 306 | { | 329 | { |
| 307 | auto &fp = r.stack.peek_frame()->base<F_Math_fabs>(); | 330 | 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); |
| 309 | } | 332 | } |
| 310 | 333 | ||
| 311 | void | 334 | void |
| 312 | Math_fdim(vm_registers_t &r, vm_t &vm) | 335 | Math_fdim(vm_registers_t &r, vm_t &vm) |
| 313 | { | 336 | { |
| 314 | auto &fp = r.stack.peek_frame()->base<F_Math_fdim>(); | 337 | 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); |
| 316 | } | 339 | } |
| 317 | 340 | ||
| 318 | void | 341 | void |
| 319 | Math_finite(vm_registers_t &r, vm_t &vm) | 342 | Math_finite(vm_registers_t &r, vm_t &vm) |
| 320 | { | 343 | { |
| 321 | auto &fp = r.stack.peek_frame()->base<F_Math_finite>(); | 344 | 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; |
| 323 | } | 346 | } |
| 324 | 347 | ||
| 325 | void | 348 | void |
| 326 | Math_floor(vm_registers_t &r, vm_t &vm) | 349 | Math_floor(vm_registers_t &r, vm_t &vm) |
| 327 | { | 350 | { |
| 328 | auto &fp = r.stack.peek_frame()->base<F_Math_floor>(); | 351 | 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); |
| 330 | } | 353 | } |
| 331 | 354 | ||
| 332 | void | 355 | void |
| 333 | Math_fmax(vm_registers_t &r, vm_t &vm) | 356 | Math_fmax(vm_registers_t &r, vm_t &vm) |
| 334 | { | 357 | { |
| 335 | auto &fp = r.stack.peek_frame()->base<F_Math_fmax>(); | 358 | 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); |
| 337 | } | 360 | } |
| 338 | 361 | ||
| 339 | void | 362 | void |
| 340 | Math_fmin(vm_registers_t &r, vm_t &vm) | 363 | Math_fmin(vm_registers_t &r, vm_t &vm) |
| 341 | { | 364 | { |
| 342 | auto &fp = r.stack.peek_frame()->base<F_Math_fmin>(); | 365 | 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); |
| 344 | } | 367 | } |
| 345 | 368 | ||
| 346 | void | 369 | void |
| 347 | Math_fmod(vm_registers_t &r, vm_t &vm) | 370 | Math_fmod(vm_registers_t &r, vm_t &vm) |
| 348 | { | 371 | { |
| 349 | auto &fp = r.stack.peek_frame()->base<F_Math_fmod>(); | 372 | 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); |
| 351 | } | 374 | } |
| 352 | 375 | ||
| 353 | void | 376 | void |
| 354 | Math_gemm(vm_registers_t &r, vm_t &vm) | 377 | Math_gemm(vm_registers_t &r, vm_t &vm) |
| 355 | { | 378 | { |
| 356 | auto &fp = r.stack.peek_frame()->base<F_Math_gemm>(); | 379 | 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" }; |
| 358 | } | 381 | } |
| 359 | 382 | ||
| 360 | void | 383 | void |
| 361 | Math_getFPcontrol(vm_registers_t &r, vm_t &vm) | 384 | Math_getFPcontrol(vm_registers_t &r, vm_t &vm) |
| 362 | { | 385 | { |
| 363 | auto &fp = r.stack.peek_frame()->base<F_Math_getFPcontrol>(); | 386 | 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" }; |
| 365 | } | 388 | } |
| 366 | 389 | ||
| 367 | void | 390 | void |
| 368 | Math_getFPstatus(vm_registers_t &r, vm_t &vm) | 391 | Math_getFPstatus(vm_registers_t &r, vm_t &vm) |
| 369 | { | 392 | { |
| 370 | auto &fp = r.stack.peek_frame()->base<F_Math_getFPstatus>(); | 393 | 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" }; |
| 372 | } | 395 | } |
| 373 | 396 | ||
| 374 | void | 397 | void |
| 375 | Math_hypot(vm_registers_t &r, vm_t &vm) | 398 | Math_hypot(vm_registers_t &r, vm_t &vm) |
| 376 | { | 399 | { |
| 377 | auto &fp = r.stack.peek_frame()->base<F_Math_hypot>(); | 400 | 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); |
| 379 | } | 402 | } |
| 380 | 403 | ||
| 381 | void | 404 | void |
| 382 | Math_iamax(vm_registers_t &r, vm_t &vm) | 405 | Math_iamax(vm_registers_t &r, vm_t &vm) |
| 383 | { | 406 | { |
| 384 | auto &fp = r.stack.peek_frame()->base<F_Math_iamax>(); | 407 | 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" }; |
| 386 | } | 409 | } |
| 387 | 410 | ||
| 388 | void | 411 | void |
| 389 | Math_ilogb(vm_registers_t &r, vm_t &vm) | 412 | Math_ilogb(vm_registers_t &r, vm_t &vm) |
| 390 | { | 413 | { |
| 391 | auto &fp = r.stack.peek_frame()->base<F_Math_ilogb>(); | 414 | 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); |
| 393 | } | 416 | } |
| 394 | 417 | ||
| 395 | void | 418 | void |
| 396 | Math_import_int(vm_registers_t &r, vm_t &vm) | 419 | Math_import_int(vm_registers_t &r, vm_t &vm) |
| 397 | { | 420 | { |
| 398 | auto &fp = r.stack.peek_frame()->base<F_Math_import_int>(); | 421 | 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" }; |
| 400 | } | 423 | } |
| 401 | 424 | ||
| 402 | void | 425 | void |
| @@ -405,10 +428,10 @@ Math_import_real(vm_registers_t &r, vm_t &vm) · 2 unmodified lines | |||
| 405 | auto &fp = r.stack.peek_frame()->base<F_Math_import_real>(); | 428 | auto &fp = r.stack.peek_frame()->base<F_Math_import_real>(); |
| 406 | 429 | ||
| 407 | auto buffer = vm_alloc_t::from_allocation<vm_array_t>(fp.b); | 430 | 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())); |
| 409 | 432 | ||
| 410 | auto result = vm_alloc_t::from_allocation<vm_array_t>(fp.x); | 433 | 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())); |
| 412 | const auto result_len = result->get_length(); | 435 | const auto result_len = result->get_length(); |
| 413 | 436 | ||
| 414 | if (buffer->get_length() != (8 * result_len)) | 437 | if (buffer->get_length() != (8 * result_len)) |
| @@ -433,7 +456,7 @@ void · 18 unmodified lines | |||
| 433 | Math_import_real32(vm_registers_t &r, vm_t &vm) | 456 | Math_import_real32(vm_registers_t &r, vm_t &vm) |
| 434 | { | 457 | { |
| 435 | auto &fp = r.stack.peek_frame()->base<F_Math_import_real32>(); | 458 | 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" }; |
| 437 | } | 460 | } |
| 438 | 461 | ||
| 439 | void | 462 | void |
| @@ -447,91 +470,126 @@ void · 7 unmodified lines | |||
| 447 | Math_j0(vm_registers_t &r, vm_t &vm) | 470 | Math_j0(vm_registers_t &r, vm_t &vm) |
| 448 | { | 471 | { |
| 449 | auto &fp = r.stack.peek_frame()->base<F_Math_j0>(); | 472 | 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" }; |
| 451 | } | 474 | } |
| 452 | 475 | ||
| 453 | void | 476 | void |
| 454 | Math_j1(vm_registers_t &r, vm_t &vm) | 477 | Math_j1(vm_registers_t &r, vm_t &vm) |
| 455 | { | 478 | { |
| 456 | auto &fp = r.stack.peek_frame()->base<F_Math_j1>(); | 479 | 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" }; |
| 458 | } | 481 | } |
| 459 | 482 | ||
| 460 | void | 483 | void |
| 461 | Math_jn(vm_registers_t &r, vm_t &vm) | 484 | Math_jn(vm_registers_t &r, vm_t &vm) |
| 462 | { | 485 | { |
| 463 | auto &fp = r.stack.peek_frame()->base<F_Math_jn>(); | 486 | 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" }; |
| 465 | } | 488 | } |
| 466 | 489 | ||
| 467 | void | 490 | void |
| 468 | Math_lgamma(vm_registers_t &r, vm_t &vm) | 491 | Math_lgamma(vm_registers_t &r, vm_t &vm) |
| 469 | { | 492 | { |
| 470 | auto &fp = r.stack.peek_frame()->base<F_Math_lgamma>(); | 493 | 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" }; |
| 472 | } | 495 | } |
| 473 | 496 | ||
| 474 | void | 497 | void |
| 475 | Math_log(vm_registers_t &r, vm_t &vm) | 498 | Math_log(vm_registers_t &r, vm_t &vm) |
| 476 | { | 499 | { |
| 477 | auto &fp = r.stack.peek_frame()->base<F_Math_log>(); | 500 | 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); |
| 479 | } | 502 | } |
| 480 | 503 | ||
| 481 | void | 504 | void |
| 482 | Math_log10(vm_registers_t &r, vm_t &vm) | 505 | Math_log10(vm_registers_t &r, vm_t &vm) |
| 483 | { | 506 | { |
| 484 | auto &fp = r.stack.peek_frame()->base<F_Math_log10>(); | 507 | 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); |
| 486 | } | 509 | } |
| 487 | 510 | ||
| 488 | void | 511 | void |
| 489 | Math_log1p(vm_registers_t &r, vm_t &vm) | 512 | Math_log1p(vm_registers_t &r, vm_t &vm) |
| 490 | { | 513 | { |
| 491 | auto &fp = r.stack.peek_frame()->base<F_Math_log1p>(); | 514 | 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); |
| 493 | } | 516 | } |
| 494 | 517 | ||
| 495 | void | 518 | void |
| 496 | Math_modf(vm_registers_t &r, vm_t &vm) | 519 | Math_modf(vm_registers_t &r, vm_t &vm) |
| 497 | { | 520 | { |
| 498 | auto &fp = r.stack.peek_frame()->base<F_Math_modf>(); | 521 | 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" }; |
| 500 | } | 523 | } |
| 501 | 524 | ||
| 502 | void | 525 | void |
| 503 | Math_nextafter(vm_registers_t &r, vm_t &vm) | 526 | Math_nextafter(vm_registers_t &r, vm_t &vm) |
| 504 | { | 527 | { |
| 505 | auto &fp = r.stack.peek_frame()->base<F_Math_nextafter>(); | 528 | 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); |
| 507 | } | 530 | } |
| 508 | 531 | ||
| 509 | void | 532 | void |
| 510 | Math_norm1(vm_registers_t &r, vm_t &vm) | 533 | Math_norm1(vm_registers_t &r, vm_t &vm) |
| 511 | { | 534 | { |
| 535 | // Defined as: norm1(x) = sum(fabs(x[i])) | ||
| 512 | auto &fp = r.stack.peek_frame()->base<F_Math_norm1>(); | 536 | 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; | ||
| 514 | } | 552 | } |
| 515 | 553 | ||
| 516 | void | 554 | void |
| 517 | Math_norm2(vm_registers_t &r, vm_t &vm) | 555 | Math_norm2(vm_registers_t &r, vm_t &vm) |
| 518 | { | 556 | { |
| 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. | ||
| 519 | auto &fp = r.stack.peek_frame()->base<F_Math_norm2>(); | 560 | 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); | ||
| 521 | } | 579 | } |
| 522 | 580 | ||
| 523 | void | 581 | void |
| 524 | Math_pow(vm_registers_t &r, vm_t &vm) | 582 | Math_pow(vm_registers_t &r, vm_t &vm) |
| 525 | { | 583 | { |
| 526 | auto &fp = r.stack.peek_frame()->base<F_Math_pow>(); | 584 | 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); |
| 528 | } | 586 | } |
| 529 | 587 | ||
| 530 | void | 588 | void |
| 531 | Math_pow10(vm_registers_t &r, vm_t &vm) | 589 | Math_pow10(vm_registers_t &r, vm_t &vm) |
| 532 | { | 590 | { |
| 533 | auto &fp = r.stack.peek_frame()->base<F_Math_pow10>(); | 591 | 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" }; |
| 535 | } | 593 | } |
| 536 | 594 | ||
| 537 | void | 595 | void |
| @@ -563,82 +621,110 @@ void · 25 unmodified lines | |||
| 563 | Math_remainder(vm_registers_t &r, vm_t &vm) | 621 | Math_remainder(vm_registers_t &r, vm_t &vm) |
| 564 | { | 622 | { |
| 565 | auto &fp = r.stack.peek_frame()->base<F_Math_remainder>(); | 623 | 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); |
| 567 | } | 625 | } |
| 568 | 626 | ||
| 569 | void | 627 | void |
| 570 | Math_rint(vm_registers_t &r, vm_t &vm) | 628 | Math_rint(vm_registers_t &r, vm_t &vm) |
| 571 | { | 629 | { |
| 572 | auto &fp = r.stack.peek_frame()->base<F_Math_rint>(); | 630 | 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); |
| 574 | } | 632 | } |
| 575 | 633 | ||
| 576 | void | 634 | void |
| 577 | Math_scalbn(vm_registers_t &r, vm_t &vm) | 635 | Math_scalbn(vm_registers_t &r, vm_t &vm) |
| 578 | { | 636 | { |
| 579 | auto &fp = r.stack.peek_frame()->base<F_Math_scalbn>(); | 637 | 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" }; |
| 581 | } | 639 | } |
| 582 | 640 | ||
| 583 | void | 641 | void |
| 584 | Math_sin(vm_registers_t &r, vm_t &vm) | 642 | Math_sin(vm_registers_t &r, vm_t &vm) |
| 585 | { | 643 | { |
| 586 | auto &fp = r.stack.peek_frame()->base<F_Math_sin>(); | 644 | 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); |
| 588 | } | 646 | } |
| 589 | 647 | ||
| 590 | void | 648 | void |
| 591 | Math_sinh(vm_registers_t &r, vm_t &vm) | 649 | Math_sinh(vm_registers_t &r, vm_t &vm) |
| 592 | { | 650 | { |
| 593 | auto &fp = r.stack.peek_frame()->base<F_Math_sinh>(); | 651 | 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); |
| 595 | } | 653 | } |
| 596 | 654 | ||
| 597 | void | 655 | void |
| 598 | Math_sort(vm_registers_t &r, vm_t &vm) | 656 | Math_sort(vm_registers_t &r, vm_t &vm) |
| 599 | { | 657 | { |
| 600 | auto &fp = r.stack.peek_frame()->base<F_Math_sort>(); | 658 | 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]; }); | ||
| 602 | } | 688 | } |
| 603 | 689 | ||
| 604 | void | 690 | void |
| 605 | Math_sqrt(vm_registers_t &r, vm_t &vm) | 691 | Math_sqrt(vm_registers_t &r, vm_t &vm) |
| 606 | { | 692 | { |
| 607 | auto &fp = r.stack.peek_frame()->base<F_Math_sqrt>(); | 693 | 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); |
| 609 | } | 695 | } |
| 610 | 696 | ||
| 611 | void | 697 | void |
| 612 | Math_tan(vm_registers_t &r, vm_t &vm) | 698 | Math_tan(vm_registers_t &r, vm_t &vm) |
| 613 | { | 699 | { |
| 614 | auto &fp = r.stack.peek_frame()->base<F_Math_tan>(); | 700 | 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); |
| 616 | } | 702 | } |
| 617 | 703 | ||
| 618 | void | 704 | void |
| 619 | Math_tanh(vm_registers_t &r, vm_t &vm) | 705 | Math_tanh(vm_registers_t &r, vm_t &vm) |
| 620 | { | 706 | { |
| 621 | auto &fp = r.stack.peek_frame()->base<F_Math_tanh>(); | 707 | 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); |
| 623 | } | 709 | } |
| 624 | 710 | ||
| 625 | void | 711 | void |
| 626 | Math_y0(vm_registers_t &r, vm_t &vm) | 712 | Math_y0(vm_registers_t &r, vm_t &vm) |
| 627 | { | 713 | { |
| 628 | auto &fp = r.stack.peek_frame()->base<F_Math_y0>(); | 714 | 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" }; |
| 630 | } | 716 | } |
| 631 | 717 | ||
| 632 | void | 718 | void |
| 633 | Math_y1(vm_registers_t &r, vm_t &vm) | 719 | Math_y1(vm_registers_t &r, vm_t &vm) |
| 634 | { | 720 | { |
| 635 | auto &fp = r.stack.peek_frame()->base<F_Math_y1>(); | 721 | 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" }; |
| 637 | } | 723 | } |
| 638 | 724 | ||
| 639 | void | 725 | void |
| 640 | Math_yn(vm_registers_t &r, vm_t &vm) | 726 | Math_yn(vm_registers_t &r, vm_t &vm) |
| 641 | { | 727 | { |
| 642 | auto &fp = r.stack.peek_frame()->base<F_Math_yn>(); | 728 | 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" }; |
| 644 | } | 730 | } |