1//===-- Common header for multiply-add implementations ----------*- 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_MULTIPLY_ADD_H
10#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_MULTIPLY_ADD_H
11
12#include "src/__support/CPP/type_traits.h"
13#include "src/__support/common.h"
14#include "src/__support/macros/properties/architectures.h"
15#include "src/__support/macros/properties/cpu_features.h" // LIBC_TARGET_CPU_HAS_FMA
16
17namespace LIBC_NAMESPACE {
18namespace fputil {
19
20// Implement a simple wrapper for multiply-add operation:
21// multiply_add(x, y, z) = x*y + z
22// which uses FMA instructions to speed up if available.
23
24template <typename T>
25LIBC_INLINE cpp::enable_if_t<(sizeof(T) > sizeof(void *)), T>
26multiply_add(const T &x, const T &y, const T &z) {
27 return x * y + z;
28}
29
30template <typename T>
31LIBC_INLINE cpp::enable_if_t<(sizeof(T) <= sizeof(void *)), T>
32multiply_add(T x, T y, T z) {
33 return x * y + z;
34}
35
36} // namespace fputil
37} // namespace LIBC_NAMESPACE
38
39#if defined(LIBC_TARGET_CPU_HAS_FMA)
40
41// FMA instructions are available.
42#include "FMA.h"
43
44namespace LIBC_NAMESPACE {
45namespace fputil {
46
47LIBC_INLINE float multiply_add(float x, float y, float z) {
48 return fma(x, y, z);
49}
50
51LIBC_INLINE double multiply_add(double x, double y, double z) {
52 return fma(x, y, z);
53}
54
55} // namespace fputil
56} // namespace LIBC_NAMESPACE
57
58#endif // LIBC_TARGET_CPU_HAS_FMA
59
60#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_MULTIPLY_ADD_H
61

source code of libc/src/__support/FPUtil/multiply_add.h