| ... | @@ -12,6 +12,7 @@ | ... | @@ -12,6 +12,7 @@ |
| 12 | #include "ir_print.hpp" | 12 | #include "ir_print.hpp" |
| 13 | #include "os.hpp" | 13 | #include "os.hpp" |
| 14 | #include "parseh.hpp" | 14 | #include "parseh.hpp" |
| | 15 | #include "quadmath.hpp" |
| 15 | #include "range_set.hpp" | 16 | #include "range_set.hpp" |
| 16 | | 17 | |
| 17 | struct IrExecContext { | 18 | struct IrExecContext { |
| ... | @@ -6272,6 +6273,546 @@ static bool const_val_fits_in_num_lit(ConstExprValue *const_val, TypeTableEntry | ... | @@ -6272,6 +6273,546 @@ static bool const_val_fits_in_num_lit(ConstExprValue *const_val, TypeTableEntry |
| 6272 | (const_val->type->id == TypeTableEntryIdInt || const_val->type->id == TypeTableEntryIdNumLitInt))); | 6273 | (const_val->type->id == TypeTableEntryIdInt || const_val->type->id == TypeTableEntryIdNumLitInt))); |
| 6273 | } | 6274 | } |
| 6274 | | 6275 | |
| | 6276 | static bool float_has_fraction(ConstExprValue *const_val) { |
| | 6277 | if (const_val->type->id == TypeTableEntryIdNumLitFloat) { |
| | 6278 | return bigfloat_has_fraction(&const_val->data.x_bigfloat); |
| | 6279 | } else if (const_val->type->id == TypeTableEntryIdFloat) { |
| | 6280 | switch (const_val->type->data.floating.bit_count) { |
| | 6281 | case 32: |
| | 6282 | return floorf(const_val->data.x_f32) != const_val->data.x_f32; |
| | 6283 | case 64: |
| | 6284 | return floor(const_val->data.x_f64) != const_val->data.x_f64; |
| | 6285 | case 128: |
| | 6286 | return floorq(const_val->data.x_f128) != const_val->data.x_f128; |
| | 6287 | default: |
| | 6288 | zig_unreachable(); |
| | 6289 | } |
| | 6290 | } else { |
| | 6291 | zig_unreachable(); |
| | 6292 | } |
| | 6293 | } |
| | 6294 | |
| | 6295 | static void float_append_buf(Buf *buf, ConstExprValue *const_val) { |
| | 6296 | if (const_val->type->id == TypeTableEntryIdNumLitFloat) { |
| | 6297 | bigfloat_append_buf(buf, &const_val->data.x_bigfloat); |
| | 6298 | } else if (const_val->type->id == TypeTableEntryIdFloat) { |
| | 6299 | switch (const_val->type->data.floating.bit_count) { |
| | 6300 | case 32: |
| | 6301 | buf_appendf(buf, "%f", const_val->data.x_f32); |
| | 6302 | break; |
| | 6303 | case 64: |
| | 6304 | buf_appendf(buf, "%f", const_val->data.x_f64); |
| | 6305 | break; |
| | 6306 | case 128: |
| | 6307 | { |
| | 6308 | const size_t extra_len = 100; |
| | 6309 | size_t old_len = buf_len(buf); |
| | 6310 | buf_resize(buf, old_len + extra_len); |
| | 6311 | int len = quadmath_snprintf(buf_ptr(buf) + old_len, extra_len, "%Qf", const_val->data.x_f128); |
| | 6312 | assert(len > 0); |
| | 6313 | buf_resize(buf, old_len + len); |
| | 6314 | break; |
| | 6315 | } |
| | 6316 | default: |
| | 6317 | zig_unreachable(); |
| | 6318 | } |
| | 6319 | } else { |
| | 6320 | zig_unreachable(); |
| | 6321 | } |
| | 6322 | } |
| | 6323 | |
| | 6324 | static void float_init_bigint(BigInt *bigint, ConstExprValue *const_val) { |
| | 6325 | if (const_val->type->id == TypeTableEntryIdNumLitFloat) { |
| | 6326 | bigint_init_bigfloat(bigint, &const_val->data.x_bigfloat); |
| | 6327 | } else if (const_val->type->id == TypeTableEntryIdFloat) { |
| | 6328 | switch (const_val->type->data.floating.bit_count) { |
| | 6329 | case 32: |
| | 6330 | if (const_val->data.x_f32 >= 0) { |
| | 6331 | bigint_init_unsigned(bigint, (uint64_t)(const_val->data.x_f32)); |
| | 6332 | } else { |
| | 6333 | bigint_init_unsigned(bigint, (uint64_t)(-const_val->data.x_f32)); |
| | 6334 | bigint->is_negative = true; |
| | 6335 | } |
| | 6336 | break; |
| | 6337 | case 64: |
| | 6338 | if (const_val->data.x_f64 >= 0) { |
| | 6339 | bigint_init_unsigned(bigint, (uint64_t)(const_val->data.x_f64)); |
| | 6340 | } else { |
| | 6341 | bigint_init_unsigned(bigint, (uint64_t)(-const_val->data.x_f64)); |
| | 6342 | bigint->is_negative = true; |
| | 6343 | } |
| | 6344 | break; |
| | 6345 | case 128: |
| | 6346 | if (const_val->data.x_f128 >= 0) { |
| | 6347 | bigint_init_u128(bigint, (unsigned __int128)(const_val->data.x_f128)); |
| | 6348 | } else { |
| | 6349 | bigint_init_u128(bigint, (unsigned __int128)(-const_val->data.x_f128)); |
| | 6350 | bigint->is_negative = true; |
| | 6351 | } |
| | 6352 | break; |
| | 6353 | default: |
| | 6354 | zig_unreachable(); |
| | 6355 | } |
| | 6356 | } else { |
| | 6357 | zig_unreachable(); |
| | 6358 | } |
| | 6359 | } |
| | 6360 | |
| | 6361 | static void float_init_bigfloat(ConstExprValue *dest_val, BigFloat *bigfloat) { |
| | 6362 | if (dest_val->type->id == TypeTableEntryIdNumLitFloat) { |
| | 6363 | bigfloat_init_bigfloat(&dest_val->data.x_bigfloat, bigfloat); |
| | 6364 | } else if (dest_val->type->id == TypeTableEntryIdFloat) { |
| | 6365 | switch (dest_val->type->data.floating.bit_count) { |
| | 6366 | case 32: |
| | 6367 | dest_val->data.x_f32 = bigfloat_to_f32(bigfloat); |
| | 6368 | break; |
| | 6369 | case 64: |
| | 6370 | dest_val->data.x_f64 = bigfloat_to_f64(bigfloat); |
| | 6371 | break; |
| | 6372 | case 128: |
| | 6373 | dest_val->data.x_f128 = bigfloat_to_f128(bigfloat); |
| | 6374 | break; |
| | 6375 | default: |
| | 6376 | zig_unreachable(); |
| | 6377 | } |
| | 6378 | } else { |
| | 6379 | zig_unreachable(); |
| | 6380 | } |
| | 6381 | } |
| | 6382 | |
| | 6383 | static void float_init_f32(ConstExprValue *dest_val, float x) { |
| | 6384 | if (dest_val->type->id == TypeTableEntryIdNumLitFloat) { |
| | 6385 | bigfloat_init_32(&dest_val->data.x_bigfloat, x); |
| | 6386 | } else if (dest_val->type->id == TypeTableEntryIdFloat) { |
| | 6387 | switch (dest_val->type->data.floating.bit_count) { |
| | 6388 | case 32: |
| | 6389 | dest_val->data.x_f32 = x; |
| | 6390 | break; |
| | 6391 | case 64: |
| | 6392 | dest_val->data.x_f64 = x; |
| | 6393 | break; |
| | 6394 | case 128: |
| | 6395 | dest_val->data.x_f128 = x; |
| | 6396 | break; |
| | 6397 | default: |
| | 6398 | zig_unreachable(); |
| | 6399 | } |
| | 6400 | } else { |
| | 6401 | zig_unreachable(); |
| | 6402 | } |
| | 6403 | } |
| | 6404 | |
| | 6405 | static void float_init_f64(ConstExprValue *dest_val, double x) { |
| | 6406 | if (dest_val->type->id == TypeTableEntryIdNumLitFloat) { |
| | 6407 | bigfloat_init_64(&dest_val->data.x_bigfloat, x); |
| | 6408 | } else if (dest_val->type->id == TypeTableEntryIdFloat) { |
| | 6409 | switch (dest_val->type->data.floating.bit_count) { |
| | 6410 | case 32: |
| | 6411 | dest_val->data.x_f32 = x; |
| | 6412 | break; |
| | 6413 | case 64: |
| | 6414 | dest_val->data.x_f64 = x; |
| | 6415 | break; |
| | 6416 | case 128: |
| | 6417 | dest_val->data.x_f128 = x; |
| | 6418 | break; |
| | 6419 | default: |
| | 6420 | zig_unreachable(); |
| | 6421 | } |
| | 6422 | } else { |
| | 6423 | zig_unreachable(); |
| | 6424 | } |
| | 6425 | } |
| | 6426 | |
| | 6427 | static void float_init_f128(ConstExprValue *dest_val, __float128 x) { |
| | 6428 | if (dest_val->type->id == TypeTableEntryIdNumLitFloat) { |
| | 6429 | bigfloat_init_128(&dest_val->data.x_bigfloat, x); |
| | 6430 | } else if (dest_val->type->id == TypeTableEntryIdFloat) { |
| | 6431 | switch (dest_val->type->data.floating.bit_count) { |
| | 6432 | case 32: |
| | 6433 | dest_val->data.x_f32 = x; |
| | 6434 | break; |
| | 6435 | case 64: |
| | 6436 | dest_val->data.x_f64 = x; |
| | 6437 | break; |
| | 6438 | case 128: |
| | 6439 | dest_val->data.x_f128 = x; |
| | 6440 | break; |
| | 6441 | default: |
| | 6442 | zig_unreachable(); |
| | 6443 | } |
| | 6444 | } else { |
| | 6445 | zig_unreachable(); |
| | 6446 | } |
| | 6447 | } |
| | 6448 | |
| | 6449 | static void float_init_float(ConstExprValue *dest_val, ConstExprValue *src_val) { |
| | 6450 | if (src_val->type->id == TypeTableEntryIdNumLitFloat) { |
| | 6451 | float_init_bigfloat(dest_val, &src_val->data.x_bigfloat); |
| | 6452 | } else if (src_val->type->id == TypeTableEntryIdFloat) { |
| | 6453 | switch (src_val->type->data.floating.bit_count) { |
| | 6454 | case 32: |
| | 6455 | float_init_f32(dest_val, src_val->data.x_f32); |
| | 6456 | break; |
| | 6457 | case 64: |
| | 6458 | float_init_f64(dest_val, src_val->data.x_f64); |
| | 6459 | break; |
| | 6460 | case 128: |
| | 6461 | float_init_f128(dest_val, src_val->data.x_f128); |
| | 6462 | break; |
| | 6463 | default: |
| | 6464 | zig_unreachable(); |
| | 6465 | } |
| | 6466 | } else { |
| | 6467 | zig_unreachable(); |
| | 6468 | } |
| | 6469 | } |
| | 6470 | |
| | 6471 | static Cmp float_cmp(ConstExprValue *op1, ConstExprValue *op2) { |
| | 6472 | assert(op1->type == op2->type); |
| | 6473 | if (op1->type->id == TypeTableEntryIdNumLitFloat) { |
| | 6474 | return bigfloat_cmp(&op1->data.x_bigfloat, &op2->data.x_bigfloat); |
| | 6475 | } else if (op1->type->id == TypeTableEntryIdFloat) { |
| | 6476 | switch (op1->type->data.floating.bit_count) { |
| | 6477 | case 32: |
| | 6478 | if (op1->data.x_f32 > op2->data.x_f32) { |
| | 6479 | return CmpGT; |
| | 6480 | } else if (op1->data.x_f32 < op2->data.x_f32) { |
| | 6481 | return CmpLT; |
| | 6482 | } else { |
| | 6483 | return CmpEQ; |
| | 6484 | } |
| | 6485 | case 64: |
| | 6486 | if (op1->data.x_f64 > op2->data.x_f64) { |
| | 6487 | return CmpGT; |
| | 6488 | } else if (op1->data.x_f64 < op2->data.x_f64) { |
| | 6489 | return CmpLT; |
| | 6490 | } else { |
| | 6491 | return CmpEQ; |
| | 6492 | } |
| | 6493 | case 128: |
| | 6494 | if (op1->data.x_f128 > op2->data.x_f128) { |
| | 6495 | return CmpGT; |
| | 6496 | } else if (op1->data.x_f128 < op2->data.x_f128) { |
| | 6497 | return CmpLT; |
| | 6498 | } else { |
| | 6499 | return CmpEQ; |
| | 6500 | } |
| | 6501 | default: |
| | 6502 | zig_unreachable(); |
| | 6503 | } |
| | 6504 | } else { |
| | 6505 | zig_unreachable(); |
| | 6506 | } |
| | 6507 | } |
| | 6508 | |
| | 6509 | static Cmp float_cmp_zero(ConstExprValue *op) { |
| | 6510 | if (op->type->id == TypeTableEntryIdNumLitFloat) { |
| | 6511 | return bigfloat_cmp_zero(&op->data.x_bigfloat); |
| | 6512 | } else if (op->type->id == TypeTableEntryIdFloat) { |
| | 6513 | switch (op->type->data.floating.bit_count) { |
| | 6514 | case 32: |
| | 6515 | if (op->data.x_f32 < 0.0) { |
| | 6516 | return CmpLT; |
| | 6517 | } else if (op->data.x_f32 > 0.0) { |
| | 6518 | return CmpGT; |
| | 6519 | } else { |
| | 6520 | return CmpEQ; |
| | 6521 | } |
| | 6522 | case 64: |
| | 6523 | if (op->data.x_f64 < 0.0) { |
| | 6524 | return CmpLT; |
| | 6525 | } else if (op->data.x_f64 > 0.0) { |
| | 6526 | return CmpGT; |
| | 6527 | } else { |
| | 6528 | return CmpEQ; |
| | 6529 | } |
| | 6530 | case 128: |
| | 6531 | if (op->data.x_f128 < 0.0) { |
| | 6532 | return CmpLT; |
| | 6533 | } else if (op->data.x_f128 > 0.0) { |
| | 6534 | return CmpGT; |
| | 6535 | } else { |
| | 6536 | return CmpEQ; |
| | 6537 | } |
| | 6538 | default: |
| | 6539 | zig_unreachable(); |
| | 6540 | } |
| | 6541 | } else { |
| | 6542 | zig_unreachable(); |
| | 6543 | } |
| | 6544 | } |
| | 6545 | |
| | 6546 | static void float_add(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { |
| | 6547 | assert(op1->type == op2->type); |
| | 6548 | out_val->type = op1->type; |
| | 6549 | if (op1->type->id == TypeTableEntryIdNumLitFloat) { |
| | 6550 | bigfloat_add(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); |
| | 6551 | } else if (op1->type->id == TypeTableEntryIdFloat) { |
| | 6552 | switch (op1->type->data.floating.bit_count) { |
| | 6553 | case 32: |
| | 6554 | out_val->data.x_f32 = op1->data.x_f32 + op2->data.x_f32; |
| | 6555 | return; |
| | 6556 | case 64: |
| | 6557 | out_val->data.x_f64 = op1->data.x_f64 + op2->data.x_f64; |
| | 6558 | return; |
| | 6559 | case 128: |
| | 6560 | out_val->data.x_f128 = op1->data.x_f128 + op2->data.x_f128; |
| | 6561 | return; |
| | 6562 | default: |
| | 6563 | zig_unreachable(); |
| | 6564 | } |
| | 6565 | } else { |
| | 6566 | zig_unreachable(); |
| | 6567 | } |
| | 6568 | } |
| | 6569 | |
| | 6570 | static void float_sub(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { |
| | 6571 | assert(op1->type == op2->type); |
| | 6572 | out_val->type = op1->type; |
| | 6573 | if (op1->type->id == TypeTableEntryIdNumLitFloat) { |
| | 6574 | bigfloat_sub(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); |
| | 6575 | } else if (op1->type->id == TypeTableEntryIdFloat) { |
| | 6576 | switch (op1->type->data.floating.bit_count) { |
| | 6577 | case 32: |
| | 6578 | out_val->data.x_f32 = op1->data.x_f32 - op2->data.x_f32; |
| | 6579 | return; |
| | 6580 | case 64: |
| | 6581 | out_val->data.x_f64 = op1->data.x_f64 - op2->data.x_f64; |
| | 6582 | return; |
| | 6583 | case 128: |
| | 6584 | out_val->data.x_f128 = op1->data.x_f128 - op2->data.x_f128; |
| | 6585 | return; |
| | 6586 | default: |
| | 6587 | zig_unreachable(); |
| | 6588 | } |
| | 6589 | } else { |
| | 6590 | zig_unreachable(); |
| | 6591 | } |
| | 6592 | } |
| | 6593 | |
| | 6594 | static void float_mul(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { |
| | 6595 | assert(op1->type == op2->type); |
| | 6596 | out_val->type = op1->type; |
| | 6597 | if (op1->type->id == TypeTableEntryIdNumLitFloat) { |
| | 6598 | bigfloat_mul(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); |
| | 6599 | } else if (op1->type->id == TypeTableEntryIdFloat) { |
| | 6600 | switch (op1->type->data.floating.bit_count) { |
| | 6601 | case 32: |
| | 6602 | out_val->data.x_f32 = op1->data.x_f32 * op2->data.x_f32; |
| | 6603 | return; |
| | 6604 | case 64: |
| | 6605 | out_val->data.x_f64 = op1->data.x_f64 * op2->data.x_f64; |
| | 6606 | return; |
| | 6607 | case 128: |
| | 6608 | out_val->data.x_f128 = op1->data.x_f128 * op2->data.x_f128; |
| | 6609 | return; |
| | 6610 | default: |
| | 6611 | zig_unreachable(); |
| | 6612 | } |
| | 6613 | } else { |
| | 6614 | zig_unreachable(); |
| | 6615 | } |
| | 6616 | } |
| | 6617 | |
| | 6618 | static void float_div(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { |
| | 6619 | assert(op1->type == op2->type); |
| | 6620 | out_val->type = op1->type; |
| | 6621 | if (op1->type->id == TypeTableEntryIdNumLitFloat) { |
| | 6622 | bigfloat_div(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); |
| | 6623 | } else if (op1->type->id == TypeTableEntryIdFloat) { |
| | 6624 | switch (op1->type->data.floating.bit_count) { |
| | 6625 | case 32: |
| | 6626 | out_val->data.x_f32 = op1->data.x_f32 / op2->data.x_f32; |
| | 6627 | return; |
| | 6628 | case 64: |
| | 6629 | out_val->data.x_f64 = op1->data.x_f64 / op2->data.x_f64; |
| | 6630 | return; |
| | 6631 | case 128: |
| | 6632 | out_val->data.x_f128 = op1->data.x_f128 / op2->data.x_f128; |
| | 6633 | return; |
| | 6634 | default: |
| | 6635 | zig_unreachable(); |
| | 6636 | } |
| | 6637 | } else { |
| | 6638 | zig_unreachable(); |
| | 6639 | } |
| | 6640 | } |
| | 6641 | |
| | 6642 | static void float_div_trunc(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { |
| | 6643 | assert(op1->type == op2->type); |
| | 6644 | out_val->type = op1->type; |
| | 6645 | if (op1->type->id == TypeTableEntryIdNumLitFloat) { |
| | 6646 | bigfloat_div_trunc(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); |
| | 6647 | } else if (op1->type->id == TypeTableEntryIdFloat) { |
| | 6648 | switch (op1->type->data.floating.bit_count) { |
| | 6649 | case 32: |
| | 6650 | out_val->data.x_f32 = op1->data.x_f32 / op2->data.x_f32; |
| | 6651 | if (out_val->data.x_f32 >= 0.0) { |
| | 6652 | out_val->data.x_f32 = floorf(out_val->data.x_f32); |
| | 6653 | } else { |
| | 6654 | out_val->data.x_f32 = ceilf(out_val->data.x_f32); |
| | 6655 | } |
| | 6656 | return; |
| | 6657 | case 64: |
| | 6658 | out_val->data.x_f64 = op1->data.x_f64 / op2->data.x_f64; |
| | 6659 | if (out_val->data.x_f64 >= 0.0) { |
| | 6660 | out_val->data.x_f64 = floor(out_val->data.x_f64); |
| | 6661 | } else { |
| | 6662 | out_val->data.x_f64 = ceil(out_val->data.x_f64); |
| | 6663 | } |
| | 6664 | return; |
| | 6665 | case 128: |
| | 6666 | out_val->data.x_f128 = op1->data.x_f128 / op2->data.x_f128; |
| | 6667 | if (out_val->data.x_f128 >= 0.0) { |
| | 6668 | out_val->data.x_f128 = floorq(out_val->data.x_f128); |
| | 6669 | } else { |
| | 6670 | out_val->data.x_f128 = ceilq(out_val->data.x_f128); |
| | 6671 | } |
| | 6672 | return; |
| | 6673 | default: |
| | 6674 | zig_unreachable(); |
| | 6675 | } |
| | 6676 | } else { |
| | 6677 | zig_unreachable(); |
| | 6678 | } |
| | 6679 | } |
| | 6680 | |
| | 6681 | static void float_div_floor(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { |
| | 6682 | assert(op1->type == op2->type); |
| | 6683 | out_val->type = op1->type; |
| | 6684 | if (op1->type->id == TypeTableEntryIdNumLitFloat) { |
| | 6685 | bigfloat_div_floor(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); |
| | 6686 | } else if (op1->type->id == TypeTableEntryIdFloat) { |
| | 6687 | switch (op1->type->data.floating.bit_count) { |
| | 6688 | case 32: |
| | 6689 | out_val->data.x_f32 = floorf(op1->data.x_f32 / op2->data.x_f32); |
| | 6690 | return; |
| | 6691 | case 64: |
| | 6692 | out_val->data.x_f64 = floor(op1->data.x_f64 / op2->data.x_f64); |
| | 6693 | return; |
| | 6694 | case 128: |
| | 6695 | out_val->data.x_f128 = floorq(op1->data.x_f128 / op2->data.x_f128); |
| | 6696 | return; |
| | 6697 | default: |
| | 6698 | zig_unreachable(); |
| | 6699 | } |
| | 6700 | } else { |
| | 6701 | zig_unreachable(); |
| | 6702 | } |
| | 6703 | } |
| | 6704 | |
| | 6705 | static void float_rem(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { |
| | 6706 | assert(op1->type == op2->type); |
| | 6707 | out_val->type = op1->type; |
| | 6708 | if (op1->type->id == TypeTableEntryIdNumLitFloat) { |
| | 6709 | bigfloat_rem(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); |
| | 6710 | } else if (op1->type->id == TypeTableEntryIdFloat) { |
| | 6711 | switch (op1->type->data.floating.bit_count) { |
| | 6712 | case 32: |
| | 6713 | out_val->data.x_f32 = fmodf(op1->data.x_f32, op2->data.x_f32); |
| | 6714 | return; |
| | 6715 | case 64: |
| | 6716 | out_val->data.x_f64 = fmod(op1->data.x_f64, op2->data.x_f64); |
| | 6717 | return; |
| | 6718 | case 128: |
| | 6719 | out_val->data.x_f128 = fmodq(op1->data.x_f128, op2->data.x_f128); |
| | 6720 | return; |
| | 6721 | default: |
| | 6722 | zig_unreachable(); |
| | 6723 | } |
| | 6724 | } else { |
| | 6725 | zig_unreachable(); |
| | 6726 | } |
| | 6727 | } |
| | 6728 | |
| | 6729 | static void float_mod(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { |
| | 6730 | assert(op1->type == op2->type); |
| | 6731 | out_val->type = op1->type; |
| | 6732 | if (op1->type->id == TypeTableEntryIdNumLitFloat) { |
| | 6733 | bigfloat_mod(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); |
| | 6734 | } else if (op1->type->id == TypeTableEntryIdFloat) { |
| | 6735 | switch (op1->type->data.floating.bit_count) { |
| | 6736 | case 32: |
| | 6737 | out_val->data.x_f32 = fmodf(fmodf(op1->data.x_f32, op2->data.x_f32) + op2->data.x_f32, op2->data.x_f32); |
| | 6738 | return; |
| | 6739 | case 64: |
| | 6740 | out_val->data.x_f64 = fmod(fmod(op1->data.x_f64, op2->data.x_f64) + op2->data.x_f64, op2->data.x_f64); |
| | 6741 | return; |
| | 6742 | case 128: |
| | 6743 | out_val->data.x_f128 = fmodq(fmodq(op1->data.x_f128, op2->data.x_f128) + op2->data.x_f128, op2->data.x_f128); |
| | 6744 | return; |
| | 6745 | default: |
| | 6746 | zig_unreachable(); |
| | 6747 | } |
| | 6748 | } else { |
| | 6749 | zig_unreachable(); |
| | 6750 | } |
| | 6751 | } |
| | 6752 | |
| | 6753 | static void float_negate(ConstExprValue *out_val, ConstExprValue *op) { |
| | 6754 | out_val->type = op->type; |
| | 6755 | if (op->type->id == TypeTableEntryIdNumLitFloat) { |
| | 6756 | bigfloat_negate(&out_val->data.x_bigfloat, &op->data.x_bigfloat); |
| | 6757 | } else if (op->type->id == TypeTableEntryIdFloat) { |
| | 6758 | switch (op->type->data.floating.bit_count) { |
| | 6759 | case 32: |
| | 6760 | out_val->data.x_f32 = -op->data.x_f32; |
| | 6761 | return; |
| | 6762 | case 64: |
| | 6763 | out_val->data.x_f64 = -op->data.x_f64; |
| | 6764 | return; |
| | 6765 | case 128: |
| | 6766 | out_val->data.x_f128 = -op->data.x_f128; |
| | 6767 | return; |
| | 6768 | default: |
| | 6769 | zig_unreachable(); |
| | 6770 | } |
| | 6771 | } else { |
| | 6772 | zig_unreachable(); |
| | 6773 | } |
| | 6774 | } |
| | 6775 | |
| | 6776 | void float_write_ieee597(ConstExprValue *op, uint8_t *buf, bool is_big_endian) { |
| | 6777 | if (op->type->id == TypeTableEntryIdFloat) { |
| | 6778 | switch (op->type->data.floating.bit_count) { |
| | 6779 | case 32: |
| | 6780 | memcpy(buf, &op->data.x_f32, 4); // TODO wrong when compiler is big endian |
| | 6781 | return; |
| | 6782 | case 64: |
| | 6783 | memcpy(buf, &op->data.x_f64, 8); // TODO wrong when compiler is big endian |
| | 6784 | return; |
| | 6785 | case 128: |
| | 6786 | memcpy(buf, &op->data.x_f128, 16); // TODO wrong when compiler is big endian |
| | 6787 | return; |
| | 6788 | default: |
| | 6789 | zig_unreachable(); |
| | 6790 | } |
| | 6791 | } else { |
| | 6792 | zig_unreachable(); |
| | 6793 | } |
| | 6794 | } |
| | 6795 | |
| | 6796 | void float_read_ieee597(ConstExprValue *val, uint8_t *buf, bool is_big_endian) { |
| | 6797 | if (val->type->id == TypeTableEntryIdFloat) { |
| | 6798 | switch (val->type->data.floating.bit_count) { |
| | 6799 | case 32: |
| | 6800 | memcpy(&val->data.x_f32, buf, 4); // TODO wrong when compiler is big endian |
| | 6801 | return; |
| | 6802 | case 64: |
| | 6803 | memcpy(&val->data.x_f64, buf, 8); // TODO wrong when compiler is big endian |
| | 6804 | return; |
| | 6805 | case 128: |
| | 6806 | memcpy(&val->data.x_f128, buf, 16); // TODO wrong when compiler is big endian |
| | 6807 | return; |
| | 6808 | default: |
| | 6809 | zig_unreachable(); |
| | 6810 | } |
| | 6811 | } else { |
| | 6812 | zig_unreachable(); |
| | 6813 | } |
| | 6814 | } |
| | 6815 | |
| 6275 | static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruction, TypeTableEntry *other_type, | 6816 | static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruction, TypeTableEntry *other_type, |
| 6276 | bool explicit_cast) | 6817 | bool explicit_cast) |
| 6277 | { | 6818 | { |
| ... | @@ -6314,9 +6855,9 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc | ... | @@ -6314,9 +6855,9 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc |
| 6314 | if (explicit_cast && (other_type->id == TypeTableEntryIdInt || other_type->id == TypeTableEntryIdNumLitInt) && | 6855 | if (explicit_cast && (other_type->id == TypeTableEntryIdInt || other_type->id == TypeTableEntryIdNumLitInt) && |
| 6315 | const_val_is_float) | 6856 | const_val_is_float) |
| 6316 | { | 6857 | { |
| 6317 | if (bigfloat_has_fraction(&const_val->data.x_bigfloat)) { | 6858 | if (float_has_fraction(const_val)) { |
| 6318 | Buf *val_buf = buf_alloc(); | 6859 | Buf *val_buf = buf_alloc(); |
| 6319 | bigfloat_write_buf(val_buf, &const_val->data.x_bigfloat); | 6860 | float_append_buf(val_buf, const_val); |
| 6320 | | 6861 | |
| 6321 | ir_add_error(ira, instruction, | 6862 | ir_add_error(ira, instruction, |
| 6322 | buf_sprintf("fractional component prevents float value %s from being casted to type '%s'", | 6863 | buf_sprintf("fractional component prevents float value %s from being casted to type '%s'", |
| ... | @@ -6324,11 +6865,11 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc | ... | @@ -6324,11 +6865,11 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc |
| 6324 | buf_ptr(&other_type->name))); | 6865 | buf_ptr(&other_type->name))); |
| 6325 | return false; | 6866 | return false; |
| 6326 | } else { | 6867 | } else { |
| 6327 | BigInt bigint; | | |
| 6328 | bigint_init_bigfloat(&bigint, &const_val->data.x_bigfloat); | | |
| 6329 | if (other_type->id == TypeTableEntryIdNumLitInt) { | 6868 | if (other_type->id == TypeTableEntryIdNumLitInt) { |
| 6330 | return true; | 6869 | return true; |
| 6331 | } else { | 6870 | } else { |
| | 6871 | BigInt bigint; |
| | 6872 | float_init_bigint(&bigint, const_val); |
| 6332 | if (bigint_fits_in_bits(&bigint, other_type->data.integral.bit_count, | 6873 | if (bigint_fits_in_bits(&bigint, other_type->data.integral.bit_count, |
| 6333 | other_type->data.integral.is_signed)) | 6874 | other_type->data.integral.is_signed)) |
| 6334 | { | 6875 | { |
| ... | @@ -6342,10 +6883,10 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc | ... | @@ -6342,10 +6883,10 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc |
| 6342 | Buf *val_buf = buf_alloc(); | 6883 | Buf *val_buf = buf_alloc(); |
| 6343 | if (const_val_is_float) { | 6884 | if (const_val_is_float) { |
| 6344 | num_lit_str = "float"; | 6885 | num_lit_str = "float"; |
| 6345 | bigfloat_write_buf(val_buf, &const_val->data.x_bigfloat); | 6886 | float_append_buf(val_buf, const_val); |
| 6346 | } else { | 6887 | } else { |
| 6347 | num_lit_str = "integer"; | 6888 | num_lit_str = "integer"; |
| 6348 | bigint_write_buf(val_buf, &const_val->data.x_bigint, 10); | 6889 | bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); |
| 6349 | } | 6890 | } |
| 6350 | | 6891 | |
| 6351 | ir_add_error(ira, instruction, | 6892 | ir_add_error(ira, instruction, |
| ... | @@ -6767,7 +7308,20 @@ static void eval_const_expr_implicit_cast(CastOp cast_op, | ... | @@ -6767,7 +7308,20 @@ static void eval_const_expr_implicit_cast(CastOp cast_op, |
| 6767 | } | 7308 | } |
| 6768 | case CastOpNumLitToConcrete: | 7309 | case CastOpNumLitToConcrete: |
| 6769 | if (other_val->type->id == TypeTableEntryIdNumLitFloat) { | 7310 | if (other_val->type->id == TypeTableEntryIdNumLitFloat) { |
| 6770 | bigfloat_init_bigfloat(&const_val->data.x_bigfloat, &other_val->data.x_bigfloat); | 7311 | assert(new_type->id == TypeTableEntryIdFloat); |
| | 7312 | switch (new_type->data.floating.bit_count) { |
| | 7313 | case 32: |
| | 7314 | const_val->data.x_f32 = bigfloat_to_f32(&other_val->data.x_bigfloat); |
| | 7315 | break; |
| | 7316 | case 64: |
| | 7317 | const_val->data.x_f64 = bigfloat_to_f64(&other_val->data.x_bigfloat); |
| | 7318 | break; |
| | 7319 | case 128: |
| | 7320 | const_val->data.x_f128 = bigfloat_to_f128(&other_val->data.x_bigfloat); |
| | 7321 | break; |
| | 7322 | default: |
| | 7323 | zig_unreachable(); |
| | 7324 | } |
| 6771 | } else if (other_val->type->id == TypeTableEntryIdNumLitInt) { | 7325 | } else if (other_val->type->id == TypeTableEntryIdNumLitInt) { |
| 6772 | bigint_init_bigint(&const_val->data.x_bigint, &other_val->data.x_bigint); | 7326 | bigint_init_bigint(&const_val->data.x_bigint, &other_val->data.x_bigint); |
| 6773 | } else { | 7327 | } else { |
| ... | @@ -6780,11 +7334,29 @@ static void eval_const_expr_implicit_cast(CastOp cast_op, | ... | @@ -6780,11 +7334,29 @@ static void eval_const_expr_implicit_cast(CastOp cast_op, |
| 6780 | // can't do it | 7334 | // can't do it |
| 6781 | break; | 7335 | break; |
| 6782 | case CastOpIntToFloat: | 7336 | case CastOpIntToFloat: |
| 6783 | bigfloat_init_bigint(&const_val->data.x_bigfloat, &other_val->data.x_bigint); | 7337 | { |
| 6784 | const_val->special = ConstValSpecialStatic; | 7338 | assert(new_type->id == TypeTableEntryIdFloat); |
| 6785 | break; | 7339 | |
| | 7340 | BigFloat bigfloat; |
| | 7341 | bigfloat_init_bigint(&bigfloat, &other_val->data.x_bigint); |
| | 7342 | switch (new_type->data.floating.bit_count) { |
| | 7343 | case 32: |
| | 7344 | const_val->data.x_f32 = bigfloat_to_f32(&bigfloat); |
| | 7345 | break; |
| | 7346 | case 64: |
| | 7347 | const_val->data.x_f64 = bigfloat_to_f64(&bigfloat); |
| | 7348 | break; |
| | 7349 | case 128: |
| | 7350 | const_val->data.x_f128 = bigfloat_to_f128(&bigfloat); |
| | 7351 | break; |
| | 7352 | default: |
| | 7353 | zig_unreachable(); |
| | 7354 | } |
| | 7355 | const_val->special = ConstValSpecialStatic; |
| | 7356 | break; |
| | 7357 | } |
| 6786 | case CastOpFloatToInt: | 7358 | case CastOpFloatToInt: |
| 6787 | bigint_init_bigfloat(&const_val->data.x_bigint, &other_val->data.x_bigfloat); | 7359 | float_init_bigint(&const_val->data.x_bigint, other_val); |
| 6788 | const_val->special = ConstValSpecialStatic; | 7360 | const_val->special = ConstValSpecialStatic; |
| 6789 | break; | 7361 | break; |
| 6790 | case CastOpBoolToInt: | 7362 | case CastOpBoolToInt: |
| ... | @@ -7387,12 +7959,12 @@ static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction | ... | @@ -7387,12 +7959,12 @@ static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction |
| 7387 | } | 7959 | } |
| 7388 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, | 7960 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, |
| 7389 | source_instr->source_node, wanted_type); | 7961 | source_instr->source_node, wanted_type); |
| | 7962 | result->value.type = wanted_type; |
| 7390 | if (wanted_type->id == TypeTableEntryIdInt) { | 7963 | if (wanted_type->id == TypeTableEntryIdInt) { |
| 7391 | bigint_init_bigint(&result->value.data.x_bigint, &val->data.x_bigint); | 7964 | bigint_init_bigint(&result->value.data.x_bigint, &val->data.x_bigint); |
| 7392 | } else { | 7965 | } else { |
| 7393 | bigfloat_init_bigfloat(&result->value.data.x_bigfloat, &val->data.x_bigfloat); | 7966 | float_init_float(&result->value, val); |
| 7394 | } | 7967 | } |
| 7395 | result->value.type = wanted_type; | | |
| 7396 | return result; | 7968 | return result; |
| 7397 | } | 7969 | } |
| 7398 | | 7970 | |
| ... | @@ -7415,7 +7987,7 @@ static IrInstruction *ir_analyze_int_to_enum(IrAnalyze *ira, IrInstruction *sour | ... | @@ -7415,7 +7987,7 @@ static IrInstruction *ir_analyze_int_to_enum(IrAnalyze *ira, IrInstruction *sour |
| 7415 | bigint_init_unsigned(&enum_member_count, wanted_type->data.enumeration.src_field_count); | 7987 | bigint_init_unsigned(&enum_member_count, wanted_type->data.enumeration.src_field_count); |
| 7416 | if (bigint_cmp(&val->data.x_bigint, &enum_member_count) != CmpLT) { | 7988 | if (bigint_cmp(&val->data.x_bigint, &enum_member_count) != CmpLT) { |
| 7417 | Buf *val_buf = buf_alloc(); | 7989 | Buf *val_buf = buf_alloc(); |
| 7418 | bigint_write_buf(val_buf, &val->data.x_bigint, 10); | 7990 | bigint_append_buf(val_buf, &val->data.x_bigint, 10); |
| 7419 | ir_add_error(ira, source_instr, | 7991 | ir_add_error(ira, source_instr, |
| 7420 | buf_sprintf("integer value %s too big for enum '%s' which has %" PRIu32 " fields", | 7992 | buf_sprintf("integer value %s too big for enum '%s' which has %" PRIu32 " fields", |
| 7421 | buf_ptr(val_buf), buf_ptr(&wanted_type->name), wanted_type->data.enumeration.src_field_count)); | 7993 | buf_ptr(val_buf), buf_ptr(&wanted_type->name), wanted_type->data.enumeration.src_field_count)); |
| ... | @@ -7444,7 +8016,7 @@ static IrInstruction *ir_analyze_number_to_literal(IrAnalyze *ira, IrInstruction | ... | @@ -7444,7 +8016,7 @@ static IrInstruction *ir_analyze_number_to_literal(IrAnalyze *ira, IrInstruction |
| 7444 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, | 8016 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, |
| 7445 | source_instr->source_node, wanted_type); | 8017 | source_instr->source_node, wanted_type); |
| 7446 | if (wanted_type->id == TypeTableEntryIdNumLitFloat) { | 8018 | if (wanted_type->id == TypeTableEntryIdNumLitFloat) { |
| 7447 | bigfloat_init_bigfloat(&result->value.data.x_bigfloat, &val->data.x_bigfloat); | 8019 | float_init_float(&result->value, val); |
| 7448 | } else if (wanted_type->id == TypeTableEntryIdNumLitInt) { | 8020 | } else if (wanted_type->id == TypeTableEntryIdNumLitInt) { |
| 7449 | bigint_init_bigint(&result->value.data.x_bigint, &val->data.x_bigint); | 8021 | bigint_init_bigint(&result->value.data.x_bigint, &val->data.x_bigint); |
| 7450 | } else { | 8022 | } else { |
| ... | @@ -7469,7 +8041,7 @@ static IrInstruction *ir_analyze_int_to_err(IrAnalyze *ira, IrInstruction *sourc | ... | @@ -7469,7 +8041,7 @@ static IrInstruction *ir_analyze_int_to_err(IrAnalyze *ira, IrInstruction *sourc |
| 7469 | bigint_init_unsigned(&err_count, ira->codegen->error_decls.length); | 8041 | bigint_init_unsigned(&err_count, ira->codegen->error_decls.length); |
| 7470 | if (bigint_cmp_zero(&val->data.x_bigint) == CmpEQ || bigint_cmp(&val->data.x_bigint, &err_count) != CmpLT) { | 8042 | if (bigint_cmp_zero(&val->data.x_bigint) == CmpEQ || bigint_cmp(&val->data.x_bigint, &err_count) != CmpLT) { |
| 7471 | Buf *val_buf = buf_alloc(); | 8043 | Buf *val_buf = buf_alloc(); |
| 7472 | bigint_write_buf(val_buf, &val->data.x_bigint, 10); | 8044 | bigint_append_buf(val_buf, &val->data.x_bigint, 10); |
| 7473 | ir_add_error(ira, source_instr, | 8045 | ir_add_error(ira, source_instr, |
| 7474 | buf_sprintf("integer value %s represents no error", buf_ptr(val_buf))); | 8046 | buf_sprintf("integer value %s represents no error", buf_ptr(val_buf))); |
| 7475 | return ira->codegen->invalid_instruction; | 8047 | return ira->codegen->invalid_instruction; |
| ... | @@ -8304,7 +8876,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -8304,7 +8876,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp |
| 8304 | if ((value_is_comptime(op1_val) && value_is_comptime(op2_val)) || resolved_type->id == TypeTableEntryIdVoid) { | 8876 | if ((value_is_comptime(op1_val) && value_is_comptime(op2_val)) || resolved_type->id == TypeTableEntryIdVoid) { |
| 8305 | bool answer; | 8877 | bool answer; |
| 8306 | if (resolved_type->id == TypeTableEntryIdNumLitFloat || resolved_type->id == TypeTableEntryIdFloat) { | 8878 | if (resolved_type->id == TypeTableEntryIdNumLitFloat || resolved_type->id == TypeTableEntryIdFloat) { |
| 8307 | Cmp cmp_result = bigfloat_cmp(&op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat); | 8879 | Cmp cmp_result = float_cmp(op1_val, op2_val); |
| 8308 | answer = resolve_cmp_op_id(op_id, cmp_result); | 8880 | answer = resolve_cmp_op_id(op_id, cmp_result); |
| 8309 | } else if (resolved_type->id == TypeTableEntryIdNumLitInt || resolved_type->id == TypeTableEntryIdInt) { | 8881 | } else if (resolved_type->id == TypeTableEntryIdNumLitInt || resolved_type->id == TypeTableEntryIdInt) { |
| 8310 | Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint); | 8882 | Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint); |
| ... | @@ -8379,7 +8951,7 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val, | ... | @@ -8379,7 +8951,7 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val, |
| 8379 | { | 8951 | { |
| 8380 | is_int = false; | 8952 | is_int = false; |
| 8381 | is_float = true; | 8953 | is_float = true; |
| 8382 | op2_zcmp = bigfloat_cmp_zero(&op2_val->data.x_bigfloat); | 8954 | op2_zcmp = float_cmp_zero(op2_val); |
| 8383 | } else { | 8955 | } else { |
| 8384 | zig_unreachable(); | 8956 | zig_unreachable(); |
| 8385 | } | 8957 | } |
| ... | @@ -8447,7 +9019,7 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val, | ... | @@ -8447,7 +9019,7 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val, |
| 8447 | if (is_int) { | 9019 | if (is_int) { |
| 8448 | bigint_add(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); | 9020 | bigint_add(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); |
| 8449 | } else { | 9021 | } else { |
| 8450 | bigfloat_add(&out_val->data.x_bigfloat, &op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat); | 9022 | float_add(out_val, op1_val, op2_val); |
| 8451 | } | 9023 | } |
| 8452 | break; | 9024 | break; |
| 8453 | case IrBinOpAddWrap: | 9025 | case IrBinOpAddWrap: |
| ... | @@ -8459,7 +9031,7 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val, | ... | @@ -8459,7 +9031,7 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val, |
| 8459 | if (is_int) { | 9031 | if (is_int) { |
| 8460 | bigint_sub(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); | 9032 | bigint_sub(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); |
| 8461 | } else { | 9033 | } else { |
| 8462 | bigfloat_sub(&out_val->data.x_bigfloat, &op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat); | 9034 | float_sub(out_val, op1_val, op2_val); |
| 8463 | } | 9035 | } |
| 8464 | break; | 9036 | break; |
| 8465 | case IrBinOpSubWrap: | 9037 | case IrBinOpSubWrap: |
| ... | @@ -8471,7 +9043,7 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val, | ... | @@ -8471,7 +9043,7 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val, |
| 8471 | if (is_int) { | 9043 | if (is_int) { |
| 8472 | bigint_mul(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); | 9044 | bigint_mul(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); |
| 8473 | } else { | 9045 | } else { |
| 8474 | bigfloat_mul(&out_val->data.x_bigfloat, &op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat); | 9046 | float_mul(out_val, op1_val, op2_val); |
| 8475 | } | 9047 | } |
| 8476 | break; | 9048 | break; |
| 8477 | case IrBinOpMultWrap: | 9049 | case IrBinOpMultWrap: |
| ... | @@ -8481,20 +9053,20 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val, | ... | @@ -8481,20 +9053,20 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val, |
| 8481 | break; | 9053 | break; |
| 8482 | case IrBinOpDivUnspecified: | 9054 | case IrBinOpDivUnspecified: |
| 8483 | assert(is_float); | 9055 | assert(is_float); |
| 8484 | bigfloat_div(&out_val->data.x_bigfloat, &op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat); | 9056 | float_div(out_val, op1_val, op2_val); |
| 8485 | break; | 9057 | break; |
| 8486 | case IrBinOpDivTrunc: | 9058 | case IrBinOpDivTrunc: |
| 8487 | if (is_int) { | 9059 | if (is_int) { |
| 8488 | bigint_div_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); | 9060 | bigint_div_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); |
| 8489 | } else { | 9061 | } else { |
| 8490 | bigfloat_div_trunc(&out_val->data.x_bigfloat, &op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat); | 9062 | float_div_trunc(out_val, op1_val, op2_val); |
| 8491 | } | 9063 | } |
| 8492 | break; | 9064 | break; |
| 8493 | case IrBinOpDivFloor: | 9065 | case IrBinOpDivFloor: |
| 8494 | if (is_int) { | 9066 | if (is_int) { |
| 8495 | bigint_div_floor(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); | 9067 | bigint_div_floor(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); |
| 8496 | } else { | 9068 | } else { |
| 8497 | bigfloat_div_floor(&out_val->data.x_bigfloat, &op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat); | 9069 | float_div_floor(out_val, op1_val, op2_val); |
| 8498 | } | 9070 | } |
| 8499 | break; | 9071 | break; |
| 8500 | case IrBinOpDivExact: | 9072 | case IrBinOpDivExact: |
| ... | @@ -8506,10 +9078,10 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val, | ... | @@ -8506,10 +9078,10 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val, |
| 8506 | return ErrorExactDivRemainder; | 9078 | return ErrorExactDivRemainder; |
| 8507 | } | 9079 | } |
| 8508 | } else { | 9080 | } else { |
| 8509 | bigfloat_div_trunc(&out_val->data.x_bigfloat, &op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat); | 9081 | float_div_trunc(out_val, op1_val, op2_val); |
| 8510 | BigFloat remainder; | 9082 | ConstExprValue remainder; |
| 8511 | bigfloat_rem(&remainder, &op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat); | 9083 | float_rem(&remainder, op1_val, op2_val); |
| 8512 | if (bigfloat_cmp_zero(&remainder) != CmpEQ) { | 9084 | if (float_cmp_zero(&remainder) != CmpEQ) { |
| 8513 | return ErrorExactDivRemainder; | 9085 | return ErrorExactDivRemainder; |
| 8514 | } | 9086 | } |
| 8515 | } | 9087 | } |
| ... | @@ -8518,14 +9090,14 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val, | ... | @@ -8518,14 +9090,14 @@ static int ir_eval_math_op(TypeTableEntry *type_entry, ConstExprValue *op1_val, |
| 8518 | if (is_int) { | 9090 | if (is_int) { |
| 8519 | bigint_rem(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); | 9091 | bigint_rem(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); |
| 8520 | } else { | 9092 | } else { |
| 8521 | bigfloat_rem(&out_val->data.x_bigfloat, &op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat); | 9093 | float_rem(out_val, op1_val, op2_val); |
| 8522 | } | 9094 | } |
| 8523 | break; | 9095 | break; |
| 8524 | case IrBinOpRemMod: | 9096 | case IrBinOpRemMod: |
| 8525 | if (is_int) { | 9097 | if (is_int) { |
| 8526 | bigint_mod(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); | 9098 | bigint_mod(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); |
| 8527 | } else { | 9099 | } else { |
| 8528 | bigfloat_mod(&out_val->data.x_bigfloat, &op1_val->data.x_bigfloat, &op2_val->data.x_bigfloat); | 9100 | float_mod(out_val, op1_val, op2_val); |
| 8529 | } | 9101 | } |
| 8530 | break; | 9102 | break; |
| 8531 | } | 9103 | } |
| ... | @@ -8678,16 +9250,16 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp | ... | @@ -8678,16 +9250,16 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp |
| 8678 | ok = bigint_cmp(&rem_result, &mod_result) == CmpEQ; | 9250 | ok = bigint_cmp(&rem_result, &mod_result) == CmpEQ; |
| 8679 | } | 9251 | } |
| 8680 | } else { | 9252 | } else { |
| 8681 | if (bigfloat_cmp_zero(&op2->value.data.x_bigfloat) == CmpEQ) { | 9253 | if (float_cmp_zero(&op2->value) == CmpEQ) { |
| 8682 | // the division by zero error will be caught later, but we don't | 9254 | // the division by zero error will be caught later, but we don't |
| 8683 | // have a remainder function ambiguity problem | 9255 | // have a remainder function ambiguity problem |
| 8684 | ok = true; | 9256 | ok = true; |
| 8685 | } else { | 9257 | } else { |
| 8686 | BigFloat rem_result; | 9258 | ConstExprValue rem_result; |
| 8687 | BigFloat mod_result; | 9259 | ConstExprValue mod_result; |
| 8688 | bigfloat_rem(&rem_result, &op1->value.data.x_bigfloat, &op2->value.data.x_bigfloat); | 9260 | float_rem(&rem_result, &op1->value, &op2->value); |
| 8689 | bigfloat_mod(&mod_result, &op1->value.data.x_bigfloat, &op2->value.data.x_bigfloat); | 9261 | float_mod(&mod_result, &op1->value, &op2->value); |
| 8690 | ok = bigfloat_cmp(&rem_result, &mod_result) == CmpEQ; | 9262 | ok = float_cmp(&rem_result, &mod_result) == CmpEQ; |
| 8691 | } | 9263 | } |
| 8692 | } | 9264 | } |
| 8693 | } | 9265 | } |
| ... | @@ -9835,7 +10407,7 @@ static TypeTableEntry *ir_analyze_negation(IrAnalyze *ira, IrInstructionUnOp *un | ... | @@ -9835,7 +10407,7 @@ static TypeTableEntry *ir_analyze_negation(IrAnalyze *ira, IrInstructionUnOp *un |
| 9835 | | 10407 | |
| 9836 | ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base); | 10408 | ConstExprValue *out_val = ir_build_const_from(ira, &un_op_instruction->base); |
| 9837 | if (is_float) { | 10409 | if (is_float) { |
| 9838 | bigfloat_negate(&out_val->data.x_bigfloat, &target_const_val->data.x_bigfloat); | 10410 | float_negate(out_val, target_const_val); |
| 9839 | } else if (is_wrap_op) { | 10411 | } else if (is_wrap_op) { |
| 9840 | bigint_negate_wrap(&out_val->data.x_bigint, &target_const_val->data.x_bigint, | 10412 | bigint_negate_wrap(&out_val->data.x_bigint, &target_const_val->data.x_bigint, |
| 9841 | expr_type->data.integral.bit_count); | 10413 | expr_type->data.integral.bit_count); |
| ... | @@ -13780,8 +14352,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue | ... | @@ -13780,8 +14352,7 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue |
| 13780 | codegen->is_big_endian); | 14352 | codegen->is_big_endian); |
| 13781 | return; | 14353 | return; |
| 13782 | case TypeTableEntryIdFloat: | 14354 | case TypeTableEntryIdFloat: |
| 13783 | bigfloat_write_ieee597(&val->data.x_bigfloat, buf, val->type->data.floating.bit_count, | 14355 | float_write_ieee597(val, buf, codegen->is_big_endian); |
| 13784 | codegen->is_big_endian); | | |
| 13785 | return; | 14356 | return; |
| 13786 | case TypeTableEntryIdPointer: | 14357 | case TypeTableEntryIdPointer: |
| 13787 | if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { | 14358 | if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { |
| ... | @@ -13841,8 +14412,7 @@ static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue | ... | @@ -13841,8 +14412,7 @@ static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue |
| 13841 | codegen->is_big_endian, val->type->data.integral.is_signed); | 14412 | codegen->is_big_endian, val->type->data.integral.is_signed); |
| 13842 | return; | 14413 | return; |
| 13843 | case TypeTableEntryIdFloat: | 14414 | case TypeTableEntryIdFloat: |
| 13844 | bigfloat_read_ieee597(&val->data.x_bigfloat, buf, val->type->data.floating.bit_count, | 14415 | float_read_ieee597(val, buf, codegen->is_big_endian); |
| 13845 | codegen->is_big_endian); | | |
| 13846 | return; | 14416 | return; |
| 13847 | case TypeTableEntryIdPointer: | 14417 | case TypeTableEntryIdPointer: |
| 13848 | { | 14418 | { |