1 //===-- Aarch64 implementations of the fma function -------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_LIBC_SRC_SUPPORT_FPUTIL_AARCH64_FMA_H
10 #define LLVM_LIBC_SRC_SUPPORT_FPUTIL_AARCH64_FMA_H
11
12 #include "src/__support/architectures.h"
13
14 #if !defined(LLVM_LIBC_ARCH_AARCH64)
15 #error "Invalid include"
16 #endif
17
18 #if !defined(LIBC_TARGET_HAS_FMA)
19 #error "FMA instructions are not supported"
20 #endif
21
22 #include "src/__support/CPP/TypeTraits.h"
23
24 namespace __llvm_libc {
25 namespace fputil {
26
27 template <typename T>
fma(T x,T y,T z)28 cpp::EnableIfType<cpp::IsSame<T, float>::Value, T> fma(T x, T y, T z) {
29 float result;
30 __asm__ __volatile__("fmadd %s0, %s1, %s2, %s3\n\t"
31 : "=w"(result)
32 : "w"(x), "w"(y), "w"(z));
33 return result;
34 }
35
36 template <typename T>
fma(T x,T y,T z)37 cpp::EnableIfType<cpp::IsSame<T, double>::Value, T> fma(T x, T y, T z) {
38 double result;
39 __asm__ __volatile__("fmadd %d0, %d1, %d2, %d3\n\t"
40 : "=w"(result)
41 : "w"(x), "w"(y), "w"(z));
42 return result;
43 }
44
45 } // namespace fputil
46 } // namespace __llvm_libc
47
48 #endif // LLVM_LIBC_SRC_SUPPORT_FPUTIL_AARCH64_FMA_H
49