1 /* Copyright (C) 2019-2020 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 */ 688