Commit c26f7550f0

Andrew Kelley <andrew@ziglang.org>
2022-04-28 04:34:33
stage1: add missing comptime float ops
These are only as accurate as f64 even for f128 comptime functions. This is OK for now; improvements will come with the launch of self-hosted (#89) and enhancements to compiler-rt implementations.
1 parent 7d80678
Changed files (1)
src
stage1
src/stage1/ir.cpp
@@ -24337,25 +24337,94 @@ static ErrorMsg *ir_eval_float_op(IrAnalyze *ira, Scope *scope, AstNode *source_
             break;
         case BuiltinFnIdCeil:
             f128M_roundToInt(in, softfloat_round_max, false, out);
-        break;
+            break;
         case BuiltinFnIdTrunc:
             f128M_trunc(in, out);
             break;
         case BuiltinFnIdRound:
             f128M_roundToInt(in, softfloat_round_near_maxMag, false, out);
             break;
-        case BuiltinFnIdNearbyInt:
-        case BuiltinFnIdSin:
-        case BuiltinFnIdCos:
-        case BuiltinFnIdTan:
-        case BuiltinFnIdExp:
-        case BuiltinFnIdExp2:
-        case BuiltinFnIdLog:
-        case BuiltinFnIdLog10:
-        case BuiltinFnIdLog2:
-            return ir_add_error_node(ira, source_node,
-                buf_sprintf("compiler bug: TODO: implement '%s' for type '%s'. See https://github.com/ziglang/zig/issues/4026",
-                    float_un_op_to_name(fop), buf_ptr(&float_type->name)));
+        case BuiltinFnIdNearbyInt: {
+            float64_t f64_value = f128M_to_f64(in);
+            double double_value;
+            memcpy(&double_value, &f64_value, sizeof(double));
+            double_value = nearbyint(double_value);
+            memcpy(&f64_value, &double_value, sizeof(double));
+            f64_to_f128M(f64_value, out);
+            break;
+        }
+        case BuiltinFnIdSin: {
+            float64_t f64_value = f128M_to_f64(in);
+            double double_value;
+            memcpy(&double_value, &f64_value, sizeof(double));
+            double_value = sin(double_value);
+            memcpy(&f64_value, &double_value, sizeof(double));
+            f64_to_f128M(f64_value, out);
+            break;
+        }
+        case BuiltinFnIdCos: {
+            float64_t f64_value = f128M_to_f64(in);
+            double double_value;
+            memcpy(&double_value, &f64_value, sizeof(double));
+            double_value = cos(double_value);
+            memcpy(&f64_value, &double_value, sizeof(double));
+            f64_to_f128M(f64_value, out);
+            break;
+        }
+        case BuiltinFnIdTan: {
+            float64_t f64_value = f128M_to_f64(in);
+            double double_value;
+            memcpy(&double_value, &f64_value, sizeof(double));
+            double_value = tan(double_value);
+            memcpy(&f64_value, &double_value, sizeof(double));
+            f64_to_f128M(f64_value, out);
+            break;
+        }
+        case BuiltinFnIdExp: {
+            float64_t f64_value = f128M_to_f64(in);
+            double double_value;
+            memcpy(&double_value, &f64_value, sizeof(double));
+            double_value = exp(double_value);
+            memcpy(&f64_value, &double_value, sizeof(double));
+            f64_to_f128M(f64_value, out);
+            break;
+        }
+        case BuiltinFnIdExp2: {
+            float64_t f64_value = f128M_to_f64(in);
+            double double_value;
+            memcpy(&double_value, &f64_value, sizeof(double));
+            double_value = exp2(double_value);
+            memcpy(&f64_value, &double_value, sizeof(double));
+            f64_to_f128M(f64_value, out);
+            break;
+        }
+        case BuiltinFnIdLog: {
+            float64_t f64_value = f128M_to_f64(in);
+            double double_value;
+            memcpy(&double_value, &f64_value, sizeof(double));
+            double_value = log(double_value);
+            memcpy(&f64_value, &double_value, sizeof(double));
+            f64_to_f128M(f64_value, out);
+            break;
+        }
+        case BuiltinFnIdLog10: {
+            float64_t f64_value = f128M_to_f64(in);
+            double double_value;
+            memcpy(&double_value, &f64_value, sizeof(double));
+            double_value = log10(double_value);
+            memcpy(&f64_value, &double_value, sizeof(double));
+            f64_to_f128M(f64_value, out);
+            break;
+        }
+        case BuiltinFnIdLog2: {
+            float64_t f64_value = f128M_to_f64(in);
+            double double_value;
+            memcpy(&double_value, &f64_value, sizeof(double));
+            double_value = log2(double_value);
+            memcpy(&f64_value, &double_value, sizeof(double));
+            f64_to_f128M(f64_value, out);
+            break;
+        }
         default:
             zig_unreachable();
         }