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