Add intrinsics.sqrt for floating-point values

This commit is contained in:
gingerBill
2021-05-19 10:32:41 +01:00
parent 8d044fd442
commit e0225c3579
4 changed files with 60 additions and 11 deletions
+6 -11
View File
@@ -409,11 +409,6 @@ string_decode_rune :: #force_inline proc "contextless" (s: string) -> (rune, int
return rune(s0&MASK4)<<18 | rune(b1&MASKX)<<12 | rune(b2&MASKX)<<6 | rune(b3&MASKX), 4;
}
@(default_calling_convention = "none")
foreign {
@(link_name="llvm.sqrt.f32") _sqrt_f32 :: proc(x: f32) -> f32 ---
@(link_name="llvm.sqrt.f64") _sqrt_f64 :: proc(x: f64) -> f64 ---
}
abs_f16 :: #force_inline proc "contextless" (x: f16) -> f16 {
return -x if x < 0 else x;
}
@@ -445,27 +440,27 @@ max_f64 :: proc(a, b: f64) -> f64 {
abs_complex32 :: #force_inline proc "contextless" (x: complex32) -> f16 {
r, i := real(x), imag(x);
return f16(_sqrt_f32(f32(r*r + i*i)));
return f16(intrinsics.sqrt(f32(r*r + i*i)));
}
abs_complex64 :: #force_inline proc "contextless" (x: complex64) -> f32 {
r, i := real(x), imag(x);
return _sqrt_f32(r*r + i*i);
return intrinsics.sqrt(r*r + i*i);
}
abs_complex128 :: #force_inline proc "contextless" (x: complex128) -> f64 {
r, i := real(x), imag(x);
return _sqrt_f64(r*r + i*i);
return intrinsics.sqrt(r*r + i*i);
}
abs_quaternion64 :: #force_inline proc "contextless" (x: quaternion64) -> f16 {
r, i, j, k := real(x), imag(x), jmag(x), kmag(x);
return f16(_sqrt_f32(f32(r*r + i*i + j*j + k*k)));
return f16(intrinsics.sqrt(f32(r*r + i*i + j*j + k*k)));
}
abs_quaternion128 :: #force_inline proc "contextless" (x: quaternion128) -> f32 {
r, i, j, k := real(x), imag(x), jmag(x), kmag(x);
return _sqrt_f32(r*r + i*i + j*j + k*k);
return intrinsics.sqrt(r*r + i*i + j*j + k*k);
}
abs_quaternion256 :: #force_inline proc "contextless" (x: quaternion256) -> f64 {
r, i, j, k := real(x), imag(x), jmag(x), kmag(x);
return _sqrt_f64(r*r + i*i + j*j + k*k);
return intrinsics.sqrt(r*r + i*i + j*j + k*k);
}
+28
View File
@@ -2026,6 +2026,34 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
}
break;
case BuiltinProc_sqrt:
{
Operand x = {};
check_expr(c, &x, ce->args[0]);
if (x.mode == Addressing_Invalid) {
return false;
}
if (!is_type_float(x.type)) {
gbString xts = type_to_string(x.type);
error(x.expr, "Expected a floating point value for '%.*s', got %s", LIT(builtin_procs[id].name), xts);
gb_string_free(xts);
return false;
}
if (x.mode == Addressing_Constant) {
f64 v = exact_value_to_f64(x.value);
operand->mode = Addressing_Constant;
operand->type = x.type;
operand->value = exact_value_float(gb_sqrt(v));
break;
}
operand->mode = Addressing_Value;
operand->type = default_type(x.type);
}
break;
case BuiltinProc_atomic_fence:
case BuiltinProc_atomic_fence_acq:
case BuiltinProc_atomic_fence_rel:
+4
View File
@@ -56,6 +56,8 @@ enum BuiltinProcId {
BuiltinProc_overflow_sub,
BuiltinProc_overflow_mul,
BuiltinProc_sqrt,
BuiltinProc_volatile_store,
BuiltinProc_volatile_load,
@@ -278,6 +280,8 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
{STR_LIT("overflow_sub"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("overflow_mul"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("sqrt"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("volatile_store"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("volatile_load"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
+22
View File
@@ -9429,6 +9429,28 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
return res;
}
case BuiltinProc_sqrt:
{
Type *type = tv.type;
lbValue x = lb_build_expr(p, ce->args[0]);
x = lb_emit_conv(p, x, type);
char const *name = "llvm.sqrt";
LLVMTypeRef types[1] = {lb_type(p->module, type)};
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
LLVMValueRef args[1] = {};
args[0] = x.value;
lbValue res = {};
res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
res.type = type;
return res;
}
case BuiltinProc_atomic_fence:
LLVMBuildFence(p->builder, LLVMAtomicOrderingSequentiallyConsistent, false, "");