aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2024-07-07 12:24:31 +0900
committernsfisis <nsfisis@gmail.com>2024-07-07 12:24:31 +0900
commit1cd492d63328b77173d1a74ee061fa3cdd43ee44 (patch)
treeebd417993b8c49f6081bc141ba870ab169059bb6 /src
parent3d30b262fab3beeee738cc98d8862a012012c2a4 (diff)
downloadphp-waddiwasi-1cd492d63328b77173d1a74ee061fa3cdd43ee44.tar.gz
php-waddiwasi-1cd492d63328b77173d1a74ee061fa3cdd43ee44.tar.zst
php-waddiwasi-1cd492d63328b77173d1a74ee061fa3cdd43ee44.zip
fix: f32.copysign and f64.copysign
Diffstat (limited to 'src')
-rw-r--r--src/Execution/Runtime.php22
1 files changed, 20 insertions, 2 deletions
diff --git a/src/Execution/Runtime.php b/src/Execution/Runtime.php
index 10bed7c..98893d0 100644
--- a/src/Execution/Runtime.php
+++ b/src/Execution/Runtime.php
@@ -599,7 +599,9 @@ final class Runtime
{
$c2 = $this->stack->popFloat();
$c1 = $this->stack->popFloat();
- $this->stack->pushValue($c1 * ($c2 < 0 ? -1 : 1));
+ $c1Sign = self::getFloatSign($c1);
+ $c2Sign = self::getFloatSign($c2);
+ $this->stack->pushValue($c1Sign === $c2Sign ? $c1 : -$c1);
}
private function execInstrNumericF32DemoteF64(Instrs\Numeric\F32DemoteF64 $instr): void
@@ -793,7 +795,9 @@ final class Runtime
{
$c2 = $this->stack->popFloat();
$c1 = $this->stack->popFloat();
- $this->stack->pushValue($c1 * ($c2 < 0 ? -1 : 1));
+ $c1Sign = self::getFloatSign($c1);
+ $c2Sign = self::getFloatSign($c2);
+ $this->stack->pushValue($c1Sign === $c2Sign ? $c1 : -$c1);
}
private function execInstrNumericF64Div(Instrs\Numeric\F64Div $instr): void
@@ -2606,4 +2610,18 @@ final class Runtime
}
return (int)$result;
}
+
+ private static function getFloatSign(float $p): int
+ {
+ if (is_nan($p)) {
+ $n = BinaryConversion::reinterpretF64AsI64($p);
+ // The MSB is the sign bit.
+ return (($n >> 63) & 1) === 1 ? -1 : 1;
+ } elseif ($p !== 0.0) {
+ return $p < 0.0 ? -1 : 1;
+ } else {
+ // Comparison with 0 does not work for -0.0.
+ return fdiv(1, $p) < 0.0 ? -1 : 1;
+ }
+ }
}