(root)/
gcc-13.2.0/
libgcc/
config/
avr/
libf7/
libf7.h
       1  /* Copyright (C) 2019-2023 Free Software Foundation, Inc.
       2  
       3     This file is part of LIBF7, which is part of GCC.
       4  
       5     GCC is free software; you can redistribute it and/or modify it under
       6     the terms of the GNU General Public License as published by the Free
       7     Software Foundation; either version 3, or (at your option) any later
       8     version.
       9  
      10     GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      11     WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      13     for more details.
      14  
      15     Under Section 7 of GPL version 3, you are granted additional
      16     permissions described in the GCC Runtime Library Exception, version
      17     3.1, as published by the Free Software Foundation.
      18  
      19     You should have received a copy of the GNU General Public License and
      20     a copy of the GCC Runtime Library Exception along with this program;
      21     see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      22     <http://www.gnu.org/licenses/>.  */
      23  
      24  #ifndef LIBF7_H
      25  #define LIBF7_H
      26  #define IN_LIBF7_H
      27  
      28  #include "f7-renames.h"
      29  
      30  #define F7_MANT_BYTES 7
      31  #define F7_MANT_BITS (8 * F7_MANT_BYTES)
      32  
      33  /*  Using the following GCC features:
      34      --  Unnamed structs / unions (GNU-C)
      35      --  Fixed-point types (GNU-C)
      36      --  Inline asm
      37      --  Setting assembler names by means of __asm (GNU-C).
      38      --  Attributes: alias, always_inline, const, noinline, unused,
      39                      progmem, pure, weak, warning
      40      --  GCC built-ins: __builtin_abort, __builtin_constant_p
      41      --  AVR built-ins: __builtin_avr_bitsr, __builtin_avr_rbits
      42  */
      43  
      44  /* We have 2 kinds of flags:
      45  
      46     A)  The flags that are stored in f7_t.flags:
      47         --  f7_t.is_nan (NaN)
      48         --  f7_t.is_inf (+Inf or -Inf)
      49         --  f7_t.sign (negative or -Inf).
      50  
      51     B)  The flags that are returned by f7_classify().  This are the
      52         flags from A) together with
      53         --  _zero: indicate that a number is zero.
      54  */
      55  
      56  #define F7_FLAGNO_sign  0
      57  #define F7_FLAGNO_zero  1
      58  #define F7_FLAGNO_nan   2
      59  #define F7_FLAGNO_inf   7
      60  
      61  #define F7_HAVE_Inf 1
      62  
      63  // Flags that might be set by f7_classify().
      64  #define F7_FLAG_sign            (1 << F7_FLAGNO_sign)
      65  #define F7_FLAG_zero            (1 << F7_FLAGNO_zero)
      66  #define F7_FLAG_nan             (1 << F7_FLAGNO_nan)
      67  #define F7_FLAG_inf   (F7_HAVE_Inf << F7_FLAGNO_inf)
      68  
      69  // Flags that might be set in f7_t.flags.
      70  #define F7_FLAGS (F7_FLAG_inf | F7_FLAG_nan | F7_FLAG_sign)
      71  
      72  #if !defined __ASSEMBLER__
      73  
      74  #ifndef IN_LIBGCC2
      75  #include <stdint.h>
      76  #include <stdbool.h>
      77  #include <stdlib.h>
      78  #include <stdio.h>
      79  #else
      80  /* Do not assume that we have std headers when we build libgcc.  */
      81  
      82  typedef __UINT64_TYPE__ uint64_t;
      83  typedef __UINT32_TYPE__ uint32_t;
      84  typedef __UINT16_TYPE__ uint16_t;
      85  typedef __UINT8_TYPE__  uint8_t;
      86  typedef __INT64_TYPE__ int64_t;
      87  typedef __INT32_TYPE__ int32_t;
      88  typedef __INT16_TYPE__ int16_t;
      89  typedef __INT8_TYPE__  int8_t;
      90  typedef _Bool bool;
      91  #define false 0
      92  #define true  1
      93  #define INT8_MIN  (-1 - __INT8_MAX__)
      94  #define INT16_MAX __INT16_MAX__
      95  #define NULL ((void*) 0)
      96  #endif /* IN_LIBGCC2 */
      97  
      98  #include "asm-defs.h"
      99  
     100  #ifdef __cplusplus
     101  extern "C" {
     102  #define _Static_assert(X, Y) static_assert (X)
     103  #endif // C++
     104  
     105  #define F7_INLINE   inline __attribute__((__always_inline__))
     106  #define F7_NOINLINE __attribute__((__noinline__))
     107  #define F7_WEAK     __attribute__((__weak__))
     108  #define F7_PURE     __attribute__((__pure__))
     109  #define F7_UNUSED   __attribute__((__unused__))
     110  #define F7_CONST    __attribute__((__const__))
     111  
     112  #define F7_STRINGY2(X)  #X
     113  #define F7_STRINGY(X)   F7_STRINGY2(X)
     114  #define F7ASM(X)        __asm (F7_STRINGY2(X))
     115  
     116  typedef struct f7_t
     117  {
     118    union
     119    {
     120      struct
     121      {
     122        uint8_t sign        :1;
     123        uint8_t reserved1   :1;
     124        uint8_t is_nan      :1;
     125        uint8_t reserved2   :4;
     126        uint8_t is_inf      :1;
     127      };
     128      uint8_t flags;
     129    };
     130  
     131    uint8_t mant[7];
     132    int16_t expo;
     133  } f7_t;
     134  
     135  typedef uint64_t f7_double_t;
     136  
     137  #define F7_MANT_HI4(X) \
     138    (*(uint32_t*) & (X)->mant[F7_MANT_BYTES - 4])
     139  
     140  #define F7_MANT_CONST_HI4(X) \
     141    (*(const uint32_t*) & (X)->mant[F7_MANT_BYTES - 4])
     142  
     143  #define F7_MANT_HI2(X) \
     144    (*(uint16_t*) & (X)->mant[F7_MANT_BYTES - 2])
     145  
     146  static F7_INLINE F7_PURE
     147  uint8_t f7_classify (const f7_t *aa)
     148  {
     149    extern void f7_classify_asm (void);
     150    register uint8_t rclass __asm ("r24");
     151    __asm ("%~call %x[f]"
     152  	 : "=r" (rclass)
     153  	 : [f] "i" (f7_classify_asm), "z" (aa));
     154    return rclass;
     155  }
     156  
     157  
     158  // +Inf or -Inf
     159  static F7_INLINE
     160  bool f7_class_inf (uint8_t c)
     161  {
     162  #if defined (F7_HAVE_Inf) && F7_HAVE_Inf == 1
     163    return c >= F7_FLAG_inf;
     164  #elif defined (F7_HAVE_Inf) && F7_HAVE_Inf == 0
     165    (void) c;
     166    return false;
     167  #else
     168  #error macro F7_HAVE_Inf must be defined to 0 or to 1.
     169  #endif // Have Inf
     170  }
     171  
     172  static F7_INLINE
     173  bool f7_is_inf (const f7_t *aa)
     174  {
     175    return f7_class_inf (aa->flags);
     176  }
     177  
     178  // Not-a-Number (NaN).
     179  static F7_INLINE
     180  bool f7_class_nan (uint8_t c)
     181  {
     182    return c & F7_FLAG_nan;
     183  }
     184  
     185  static F7_INLINE
     186  bool f7_is_nan (const f7_t *aa)
     187  {
     188    return f7_class_nan (aa->flags);
     189  }
     190  
     191  // Some number
     192  static F7_INLINE
     193  bool f7_class_number (uint8_t c)
     194  {
     195    return c <= (F7_FLAG_sign | F7_FLAG_zero);
     196  }
     197  
     198  static F7_INLINE
     199  bool f7_is_number (const f7_t *aa)
     200  {
     201    return f7_class_number (f7_classify (aa));
     202  }
     203  
     204  // Zero
     205  static F7_INLINE
     206  bool f7_class_zero (uint8_t c)
     207  {
     208    return c & F7_FLAG_zero;
     209  }
     210  
     211  static F7_INLINE
     212  bool f7_is_zero (const f7_t *aa)
     213  {
     214    return f7_class_zero (f7_classify (aa));
     215  }
     216  
     217  // A non-zero number.
     218  static F7_INLINE
     219  bool f7_class_nonzero (uint8_t c)
     220  {
     221    return c <= F7_FLAG_sign;
     222  }
     223  
     224  static F7_INLINE
     225  bool f7_is_nonzero (const f7_t *aa)
     226  {
     227    return f7_class_nonzero (f7_classify (aa));
     228  }
     229  
     230  static F7_INLINE
     231  bool f7_class_sign (uint8_t c)
     232  {
     233    return c & F7_FLAG_sign;
     234  }
     235  
     236  static F7_INLINE
     237  bool f7_signbit (const f7_t *aa)
     238  {
     239    return aa->flags & F7_FLAG_sign;
     240  }
     241  
     242  static F7_INLINE
     243  void f7_set_sign (f7_t *cc, bool sign)
     244  {
     245    _Static_assert (F7_FLAGNO_sign == 0, "");
     246    cc->flags &= ~F7_FLAG_sign;
     247    cc->flags |= sign;
     248  }
     249  
     250  static F7_INLINE
     251  void f7_set_nan (f7_t *cc)
     252  {
     253    cc->flags = F7_FLAG_nan;
     254  }
     255  
     256  static F7_INLINE
     257  void f7_clr (f7_t *cc)
     258  {
     259    extern void f7_clr_asm (void);
     260    __asm ("%~call %x[f]"
     261  	 :
     262  	 : [f] "i" (f7_clr_asm), "z" (cc)
     263  	 : "memory");
     264  }
     265  
     266  static F7_INLINE
     267  f7_t* f7_copy (f7_t *cc, const f7_t *aa)
     268  {
     269    extern void f7_copy_asm (void);
     270    __asm ("%~call %x[f]"
     271  	 :
     272  	 : [f] "i" (f7_copy_asm), "z" (cc), "x" (aa)
     273  	 : "memory");
     274    return cc;
     275  }
     276  
     277  static F7_INLINE
     278  f7_t* f7_copy_P (f7_t *cc, const f7_t *aa)
     279  {
     280    extern void f7_copy_P_asm (void);
     281    __asm ("%~call %x[f]"
     282  	 :
     283  	 : [f] "i" (f7_copy_P_asm), "x" (cc), "z" (aa)
     284  	 : "memory");
     285    return cc;
     286  }
     287  
     288  static F7_INLINE
     289  void f7_copy_mant (f7_t *cc, const f7_t *aa)
     290  {
     291    extern void f7_copy_mant_asm (void);
     292    __asm ("%~call %x[f]"
     293  	 :
     294  	 : [f] "i" (f7_copy_mant_asm), "z" (cc), "x" (aa)
     295  	 : "memory");
     296  }
     297  
     298  static F7_INLINE
     299  void f7_set_inf (f7_t *cc, bool sign)
     300  {
     301  #if F7_HAVE_Inf == 1
     302    cc->flags = F7_FLAG_inf | sign;
     303  #else
     304    (void) sign;
     305    cc->flags = F7_FLAG_nan;
     306  #endif // Have Inf
     307  }
     308  
     309  
     310  static F7_INLINE
     311  bool f7_msbit (const f7_t *aa)
     312  {
     313    return aa->mant[F7_MANT_BYTES - 1] & 0x80;
     314  }
     315  
     316  // Quick test against 0 if A is known to be a number (neither NaN nor Inf).
     317  static F7_INLINE
     318  bool f7_is0 (const f7_t *aa)
     319  {
     320    return 0 == f7_msbit (aa);
     321  }
     322  
     323  
     324  static F7_INLINE
     325  int8_t f7_cmp_mant (const f7_t *aa, const f7_t *bb)
     326  {
     327    extern void f7_cmp_mant_asm (void);
     328    register int8_t r24 __asm ("r24");
     329    __asm ("%~call %x[f] ;; %1 %3"
     330  	 : "=r" (r24)
     331  	 : [f] "i" (f7_cmp_mant_asm), "x" (aa), "z" (bb));
     332    return r24;
     333  }
     334  
     335  static F7_INLINE
     336  bool f7_store_expo (f7_t *cc, int16_t expo)
     337  {
     338    extern void f7_store_expo_asm (void);
     339    register bool r24 __asm ("r24");
     340    register int16_t rexpo __asm ("r24") = expo;
     341    __asm ("%~call %x[f] ;; %0 %2 %3"
     342  	 : "=r" (r24)
     343  	 : [f] "i" (f7_store_expo_asm), "z" (cc), "r" (rexpo));
     344    return r24;
     345  }
     346  
     347  static F7_INLINE
     348  f7_t* f7_abs (f7_t *cc, const f7_t *aa)
     349  {
     350    f7_copy (cc, aa);
     351    f7_set_sign (cc, 0);
     352  
     353    return cc;
     354  }
     355  
     356  
     357  F7_PURE extern int8_t f7_cmp (const f7_t*, const f7_t*);
     358  F7_PURE extern bool f7_lt_impl (const f7_t*, const f7_t*);
     359  F7_PURE extern bool f7_le_impl (const f7_t*, const f7_t*);
     360  F7_PURE extern bool f7_gt_impl (const f7_t*, const f7_t*);
     361  F7_PURE extern bool f7_ge_impl (const f7_t*, const f7_t*);
     362  F7_PURE extern bool f7_ne_impl (const f7_t*, const f7_t*);
     363  F7_PURE extern bool f7_eq_impl (const f7_t*, const f7_t*);
     364  F7_PURE extern bool f7_unord_impl (const f7_t*, const f7_t*);
     365  
     366  static F7_INLINE
     367  bool f7_lt (const f7_t *aa, const f7_t *bb)
     368  {
     369    return 2 & f7_cmp (aa, bb);
     370  }
     371  
     372  static F7_INLINE
     373  bool f7_gt (const f7_t *aa, const f7_t *bb)
     374  {
     375    return 1 == f7_cmp (aa, bb);
     376  }
     377  
     378  static F7_INLINE
     379  bool f7_le (const f7_t *aa, const f7_t *bb)
     380  {
     381    int8_t c = f7_cmp (aa, bb);
     382    return (uint8_t) (c + 1) <= 1;
     383  }
     384  
     385  static F7_INLINE
     386  bool f7_ge (const f7_t *aa, const f7_t *bb)
     387  {
     388    return f7_cmp (aa, bb) >= 0;
     389  }
     390  
     391  static F7_INLINE
     392  bool f7_unordered (const f7_t *aa, const f7_t *bb)
     393  {
     394    return INT8_MIN == f7_cmp (aa, bb);
     395  }
     396  
     397  static F7_INLINE
     398  bool f7_ordered (const f7_t *aa, const f7_t *bb)
     399  {
     400    return INT8_MIN != f7_cmp (aa, bb);
     401  }
     402  
     403  static F7_INLINE
     404  bool f7_eq (const f7_t *aa, const f7_t *bb)
     405  {
     406    return 0 == f7_cmp (aa, bb);
     407  }
     408  
     409  static F7_INLINE
     410  bool f7_ne (const f7_t *aa, const f7_t *bb)
     411  {
     412    return 1 & f7_cmp (aa, bb);
     413  }
     414  
     415  extern void f7_clr (f7_t*);
     416  
     417  __attribute__((warning ("foo_u16"))) void foo_u16 (void);
     418  __attribute__((warning ("foo_s16"))) void foo_s16 (void);
     419  
     420  extern f7_t* f7_set_s16_impl (f7_t*, int16_t);
     421  extern f7_t* f7_set_u16_impl (f7_t*, uint16_t);
     422  
     423  static F7_INLINE
     424  f7_t* f7_set_u16_worker (f7_t *cc, uint16_t u16)
     425  {
     426    if (__builtin_constant_p (u16))
     427      {
     428        if (u16 == 0)
     429  	return cc;
     430  
     431        uint8_t off = __builtin_clz (u16);
     432        if (15 - off)
     433  	* (uint8_t*) & cc->expo = (uint8_t) (15 - off);
     434        u16 <<= off;
     435        if (u16 & 0xff)
     436  	cc->mant[5] = (uint8_t) u16;
     437        if (u16 & 0xff00)
     438  	cc->mant[6] = (uint8_t) (u16 >> 8);
     439  
     440        return cc;
     441      }
     442    else
     443      {
     444        foo_u16();
     445        __builtin_abort();
     446        return NULL;
     447      }
     448  }
     449  
     450  static F7_INLINE
     451  f7_t* f7_set_u16 (f7_t *cc, uint16_t u16)
     452  {
     453    if (__builtin_constant_p (u16))
     454      {
     455        f7_clr (cc);
     456        return f7_set_u16_worker (cc, u16);
     457      }
     458  
     459    return f7_set_u16_impl (cc, u16);
     460  }
     461  
     462  static F7_INLINE
     463  f7_t* f7_set_s16 (f7_t *cc, int16_t s16)
     464  {
     465    if (__builtin_constant_p (s16))
     466      {
     467        f7_clr (cc);
     468  
     469        uint16_t u16 = (uint16_t) s16;
     470  
     471        if (s16 < 0)
     472          {
     473  	  u16 = -u16;
     474  	  cc->flags = F7_FLAG_sign;
     475          }
     476  
     477        return f7_set_u16_worker (cc, u16);
     478      }
     479  
     480    return f7_set_s16_impl (cc, s16);
     481  }
     482  
     483  static F7_INLINE
     484  void f7_set_eps (f7_t *cc, uint8_t eps, bool sign)
     485  {
     486    cc = f7_set_u16 (cc, 1);
     487    if (!__builtin_constant_p (sign) || sign)
     488      cc->flags = sign;
     489    cc->mant[0] = eps;
     490  }
     491  
     492  static F7_INLINE
     493  f7_t* f7_set_1pow2 (f7_t *cc, int16_t expo, bool sign)
     494  {
     495    cc = f7_set_u16 (cc, 1);
     496    cc->expo = expo;
     497    if (!__builtin_constant_p (sign) || sign)
     498      cc->flags = sign;
     499    return cc;
     500  }
     501  
     502  static F7_INLINE
     503  f7_t* f7_set_u64 (f7_t *cc, uint64_t u64)
     504  {
     505    extern f7_t* f7_set_u64_asm (uint64_t, f7_t*);
     506    return f7_set_u64_asm (u64, cc);
     507  }
     508  
     509  static F7_INLINE
     510  f7_t* f7_set_s64 (f7_t *cc, int64_t s64)
     511  {
     512    extern f7_t* f7_set_s64_asm (int64_t, f7_t*);
     513    return f7_set_s64_asm (s64, cc);
     514  }
     515  
     516  extern void f7_set_double_impl (f7_double_t, f7_t*);
     517  static F7_INLINE
     518  void f7_set_double (f7_t *cc, f7_double_t val64)
     519  {
     520    f7_set_double_impl (val64, cc);
     521  }
     522  
     523  extern f7_t* f7_init_impl (uint64_t, uint8_t, f7_t*, int16_t);
     524  
     525  static F7_INLINE
     526  f7_t* f7_init (f7_t *cc, uint8_t flags, uint64_t mant, int16_t expo)
     527  {
     528    return f7_init_impl (mant, flags, cc, expo);
     529  }
     530  
     531  extern f7_t* f7_set_s32 (f7_t*, int32_t);
     532  extern f7_t* f7_set_u16 (f7_t*, uint16_t);
     533  extern f7_t* f7_set_u32 (f7_t*, uint32_t);
     534  extern void f7_set_float (f7_t*, float);
     535  extern void f7_set_pdouble (f7_t*, const f7_double_t*);
     536  
     537  F7_PURE extern int16_t f7_get_s16 (const f7_t*);
     538  F7_PURE extern int32_t f7_get_s32 (const f7_t*);
     539  F7_PURE extern int64_t f7_get_s64 (const f7_t*);
     540  F7_PURE extern uint16_t f7_get_u16 (const f7_t*);
     541  F7_PURE extern uint32_t f7_get_u32 (const f7_t*);
     542  F7_PURE extern uint64_t f7_get_u64 (const f7_t*);
     543  F7_PURE extern float f7_get_float (const f7_t*);
     544  F7_PURE extern f7_double_t f7_get_double (const f7_t*);
     545  
     546  #if USE_LPM == 1
     547    #define F7_PGMSPACE     __attribute__((__progmem__))
     548    #define f7_copy_flash   f7_copy_P
     549  
     550    #define f7_const(X, NAME) \
     551      f7_copy_P ((X), & F7_(const_ ## NAME ## _P))
     552  
     553    #define F7_CONST_DEF(NAME, FLAGS, M0, M1, M2, M3, M4, M5, M6, EXPO) \
     554      extern const f7_t F7_(const_ ## NAME ## _P);
     555    #include "libf7-const.def"
     556    #undef F7_CONST_DEF
     557  #else
     558    #define F7_PGMSPACE     // Empty
     559    #define f7_copy_flash   f7_copy
     560  
     561    #define f7_const(X, NAME) \
     562      f7_copy ((X), & F7_(const_ ## NAME))
     563  
     564    #define F7_CONST_DEF(NAME, FLAGS, M0, M1, M2, M3, M4, M5, M6, EXPO) \
     565      extern const f7_t F7_(const_ ## NAME);
     566    #include "libf7-const.def"
     567    #undef F7_CONST_DEF
     568  #endif // USE_LPM
     569  
     570  
     571  // Basic floating point arithmetic:
     572  // double output <=> f7_t*
     573  // double input  <=> const f7_t*
     574  extern f7_t* f7_neg (f7_t*, const f7_t*);
     575  extern void f7_add (f7_t*, const f7_t*, const f7_t*);
     576  extern void f7_sub (f7_t*, const f7_t*, const f7_t*);
     577  extern void f7_mul (f7_t*, const f7_t*, const f7_t*);
     578  extern void f7_div (f7_t*, const f7_t*, const f7_t*);
     579  
     580  // Analogies of functions from math.h:
     581  // double output <=> f7_t*
     582  // double input  <=> const f7_t*
     583  extern void f7_fabs (f7_t*, const f7_t*);
     584  extern void f7_fmod (f7_t*, const f7_t*, const f7_t*);
     585  extern void f7_frexp (f7_t*, const f7_t*, int*);
     586  extern void f7_exp (f7_t*, const f7_t*);
     587  extern void f7_log (f7_t*, const f7_t*);
     588  extern void f7_pow (f7_t*, const f7_t*, const f7_t*);
     589  extern void f7_sqrt (f7_t*, const f7_t*);
     590  extern void f7_cbrt (f7_t*, const f7_t*);
     591  extern void f7_hypot (f7_t*, const f7_t*, const f7_t*);
     592  extern f7_t* f7_ldexp (f7_t*, const f7_t*, int);
     593  extern f7_t* f7_fmax (f7_t*, const f7_t*, const f7_t*);
     594  extern f7_t* f7_fmin (f7_t*, const f7_t*, const f7_t*);
     595  extern f7_t* f7_trunc (f7_t*, const f7_t*);
     596  extern f7_t* f7_floor (f7_t*, const f7_t*);
     597  extern void f7_ceil (f7_t*, const f7_t*);
     598  extern void f7_round (f7_t*, const f7_t*);
     599  extern void f7_sin (f7_t*, const f7_t*);
     600  extern void f7_cos (f7_t*, const f7_t*);
     601  extern void f7_tan (f7_t*, const f7_t*);
     602  extern void f7_atan (f7_t*, const f7_t*);
     603  extern void f7_asin (f7_t*, const f7_t*);
     604  extern void f7_acos (f7_t*, const f7_t*);
     605  extern void f7_tanh (f7_t*, const f7_t*);
     606  extern void f7_sinh (f7_t*, const f7_t*);
     607  extern void f7_cosh (f7_t*, const f7_t*);
     608  extern void f7_log2 (f7_t*, const f7_t*);
     609  extern void f7_log10 (f7_t*, const f7_t*);
     610  extern void f7_exp10 (f7_t*, const f7_t*);
     611  extern void f7_pow10 (f7_t*, const f7_t*);
     612  
     613  // Just prototypes, not implemented yet.
     614  extern void f7_atan2 (f7_t*, const f7_t*, const f7_t*);
     615  extern long f7_lrint (const f7_t*);
     616  extern long f7_lround (const f7_t*);
     617  
     618  // Helper functions, aliases, convenience.
     619  extern void f7_div1 (f7_t*, const f7_t*);
     620  extern void f7_square (f7_t*, const f7_t*);
     621  
     622  extern void f7_powi (f7_t*, const f7_t*, int);
     623  extern f7_t* f7_max (f7_t*, const f7_t*, const f7_t*);
     624  extern f7_t* f7_min (f7_t*, const f7_t*, const f7_t*);
     625  extern f7_t* f7_truncx (f7_t*, const f7_t*, bool);
     626  extern void f7_cotan (f7_t*, const f7_t*);
     627  extern void f7_sincos (f7_t*, f7_t*, const f7_t*);
     628  extern void f7_asinacos (f7_t*, const f7_t*, uint8_t);
     629  extern void f7_sinhcosh (f7_t*, const f7_t*, bool);
     630  
     631  extern void f7_horner (f7_t*, const f7_t*, uint8_t, const f7_t *coeff, f7_t*);
     632  extern void f7_mul_noround (f7_t*, const f7_t*, const f7_t*);
     633  extern void f7_clr_mant_lsbs (f7_t*, const f7_t*, uint8_t) F7ASM(f7_clr_mant_lsbs_asm);
     634  
     635  F7_PURE extern int8_t f7_cmp_unordered (const f7_t*, const f7_t*, bool);
     636  F7_PURE extern int8_t f7_cmp_abs (const f7_t*, const f7_t*);
     637  
     638  F7_PURE extern bool f7_abscmp_msb_ge (const f7_t*, uint8_t msb, int16_t expo);
     639  extern void f7_addsub (f7_t*, const f7_t*, const f7_t*, bool neg_b);
     640  extern void f7_madd_msub (f7_t*, const f7_t*, const f7_t*, const f7_t*, bool);
     641  extern void f7_madd (f7_t*, const f7_t*, const f7_t*, const f7_t*);
     642  extern void f7_msub (f7_t*, const f7_t*, const f7_t*, const f7_t*);
     643  extern uint8_t f7_mulx (f7_t*, const f7_t*, const f7_t*, bool);
     644  extern void f7_divx (f7_t*, const f7_t*, const f7_t*, uint8_t);
     645  extern void f7_logx (f7_t*, const f7_t*, const f7_t*);
     646  extern f7_t* f7_minmax (f7_t*, const f7_t*, const f7_t*, bool);
     647  
     648  // Idem:
     649  //    f7_Ifunc (y)    = f7_func (y, y)
     650  //    f7_Ifunc (y, x) = f7_func (y, y, x)
     651  extern void f7_Iadd (f7_t*, const f7_t*);
     652  extern void f7_Isub (f7_t*, const f7_t*);
     653  extern void f7_Imul (f7_t*, const f7_t*);
     654  extern void f7_Idiv (f7_t*, const f7_t*);
     655  extern void f7_IRsub (f7_t*, const f7_t*);
     656  extern void f7_Ineg (f7_t*);
     657  extern void f7_Isqrt (f7_t*);
     658  extern void f7_Isquare (f7_t*);
     659  extern f7_t* f7_Ildexp (f7_t*, int);
     660  
     661  // Protoypes for some functions from libf7-asm.sx.
     662  F7_CONST extern uint16_t f7_sqrt16_round (uint16_t) F7ASM(f7_sqrt16_round_asm);
     663  F7_CONST extern uint8_t  f7_sqrt16_floor (uint16_t) F7ASM(f7_sqrt16_floor_asm);
     664  extern void f7_addsub_mant_scaled_asm (f7_t*, const f7_t*, const f7_t*, uint8_t);
     665  extern uint8_t f7_mul_mant_asm (f7_t*, const f7_t*, const f7_t*, uint8_t);
     666  extern void f7_sqrt_approx_asm (f7_t*, const f7_t*);
     667  extern uint64_t f7_lshrdi3 (uint64_t, uint8_t) F7ASM(f7_lshrdi3_asm);
     668  extern uint64_t f7_ashldi3 (uint64_t, uint8_t) F7ASM(f7_ashldi3_asm);
     669  // Normalize a non-Inf, non-NaN value.  Sets .sign to 0.
     670  extern f7_t* f7_normalize_asm (f7_t*);
     671  
     672  // Dumping.
     673  #ifndef IN_LIBGCC2
     674  extern void f7_dump (const f7_t*);
     675  extern void f7_dump_mant (const f7_t*);
     676  extern void f7_put_C (const f7_t*, FILE*);
     677  extern void f7_put_CDEF (const char *name, const f7_t*, FILE*);
     678  #endif /* IN_LIBGCC2 */
     679  
     680  #ifdef __cplusplus
     681  } // extern "C"
     682  #include "libf7-class.h"
     683  #endif // C++
     684  
     685  #endif /* __ASSEMBLER__ */
     686  #undef IN_LIBF7_H
     687  #endif /* LIBF7_H */