mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-09 21:11:36 -07:00
Add intrinsics.sqrt for floating-point values
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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},
|
||||
|
||||
|
||||
@@ -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, "");
|
||||
|
||||
Reference in New Issue
Block a user