diff --git a/examples/pos/math.check b/examples/pos/math.check new file mode 100644 index 000000000..e5dfd35b3 --- /dev/null +++ b/examples/pos/math.check @@ -0,0 +1,9 @@ +1 +0 +0 +0 +1 +32 +0 +0 +1 \ No newline at end of file diff --git a/examples/pos/math.effekt b/examples/pos/math.effekt new file mode 100644 index 000000000..1cd4129d7 --- /dev/null +++ b/examples/pos/math.effekt @@ -0,0 +1,11 @@ +def main() = { + println(cos(0.0)) + println(sin(0.0)) + println(log(1.0)) + println(log1p(0.0)) + println(exp(0.0)) + println(pow(2.0, 5.0)) + println(tan(0.0)) + println(atan(0.0)) + println(sin(PI / 2.0)) +} diff --git a/libraries/common/effekt.effekt b/libraries/common/effekt.effekt index 3ddfaade3..6159d3b12 100644 --- a/libraries/common/effekt.effekt +++ b/libraries/common/effekt.effekt @@ -344,21 +344,25 @@ extern pure def cos(x: Double): Double = js "Math.cos(${x})" chez "(cos ${x})" vm "effekt::cos(Double)" + llvm "%z = call %Double @llvm.cos.f64(double ${x}) ret %Double %z" extern pure def sin(x: Double): Double = js "Math.sin(${x})" chez "(sin ${x})" vm "effekt::sin(Double)" + llvm "%z = call %Double @llvm.sin.f64(double ${x}) ret %Double %z" extern pure def atan(x: Double): Double = js "Math.atan(${x})" chez "(atan ${x})" vm "effekt::atan(Double)" + llvm "%z = call %Double @atan(double ${x}) ret %Double %z" extern pure def tan(x: Double): Double = js "Math.tan(${x})" chez "(tan ${x})" vm "effekt::tan(Double)" + llvm "%z = call %Double @tan(double ${x}) ret %Double %z" extern pure def sqrt(x: Double): Double = js "Math.sqrt(${x})" @@ -381,15 +385,18 @@ extern pure def log(x: Double): Double = js "Math.log(${x})" chez "(log ${x})" vm "effekt::log(Double)" + llvm "%z = call %Double @llvm.log.f64(double ${x}) ret %Double %z" extern pure def log1p(x: Double): Double = js "Math.log1p(${x})" chez "(log (+ ${x} 1))" + llvm "%z = call %Double @log1p(double ${x}) ret %Double %z" extern pure def exp(x: Double): Double = js "Math.exp(${x})" chez "(exp ${x})" vm "effekt::exp(Double)" + llvm "%z = call %Double @llvm.exp.f64(double ${x}) ret %Double %z" def pow(base: Double, exponent: Int): Double = { def loop(base: Double, exponent: Int, acc: Double): Double = { @@ -408,12 +415,14 @@ extern pure def pow(base: Double, exponent: Double): Double = js "Math.pow(${base}, ${exponent})" chez "(expt ${base} ${exponent})" vm "effekt::pow(Double, Double)" + llvm "%z = call %Double @llvm.pow.f64(double ${base}, double ${exponent}) ret %Double %z" // since we do not have "extern val", yet extern pure def _pi(): Double = js "Math.PI" chez "(* 4 (atan 1))" vm "effekt::pi()" + llvm "ret double 3.14159265358979323846264338327950288419716939937510582097494459" val PI: Double = _pi() diff --git a/libraries/llvm/rts.ll b/libraries/llvm/rts.ll index cd3fb0d8a..d56faf61f 100644 --- a/libraries/llvm/rts.ll +++ b/libraries/llvm/rts.ll @@ -109,6 +109,15 @@ declare double @llvm.sqrt.f64(double) declare double @llvm.round.f64(double) declare double @llvm.ceil.f64(double) declare double @llvm.floor.f64(double) +declare double @llvm.cos.f64(double) +declare double @llvm.sin.f64(double) +declare double @llvm.log.f64(double) +declare double @llvm.exp.f64(double) +declare double @llvm.pow.f64(double, double) +declare double @log1p(double) +; Intrinsic versions of the following two only added in LLVM 19 +declare double @atan(double) +declare double @tan(double) declare void @print(i64) declare void @exit(i64) declare void @llvm.assume(i1)