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.
This commit is contained in:
Andrew Kelley 2022-04-27 19:34:33 -07:00
parent 7d8067878d
commit c26f7550f0

View File

@ -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();
}