1#ifndef __INC_LIB8TION_MATH_H
2#define __INC_LIB8TION_MATH_H
31 unsigned int t = i + j;
34#elif QADD8_AVRASM == 1
50#elif QADD8_ARM_DSP_ASM == 1
51 asm volatile(
"uqadd8 %0, %0, %1" :
"+r" (i) :
"r" (j));
54#error "No implementation for qadd8 available."
67 else if( t < -128) t = -128;
69#elif QADD7_AVRASM == 1
83 "adc %0, __zero_reg__\n\t"
89#elif QADD7_ARM_DSP_ASM == 1
90 asm volatile(
"qadd8 %0, %0, %1" :
"+r" (i) :
"r" (j));
93#error "No implementation for qadd7 available."
107#elif QSUB8_AVRASM == 1
125#error "No implementation for qsub8 available."
139#elif ADD8_AVRASM == 1
141 asm volatile(
"add %0, %1" :
"+a" (i) :
"a" (j));
144#error "No implementation for add8 available."
158#elif ADD8_AVRASM == 1
161 "add %A[j], %[i] \n\t"
162 "adc %B[j], __zero_reg__ \n\t"
168#error "No implementation for add8to16 available."
183#elif SUB8_AVRASM == 1
185 asm volatile(
"sub %0, %1" :
"+a" (i) :
"a" (j));
188#error "No implementation for sub8 available."
202#elif AVG8_AVRASM == 1
213#error "No implementation for avg8 available."
226 return (uint32_t)((uint32_t)(i) + (uint32_t)(j)) >> 1;
227#elif AVG16_AVRASM == 1
230 "add %A[i], %A[j] \n\t"
232 "adc %B[i], %B[j] \n\t"
242#error "No implementation for avg16 available."
255 return (i + j + 1) >> 1;
256#elif AVG8R_AVRASM == 1
263 "adc %0, __zero_reg__\n\t"
269#error "No implementation for avg8r available."
282 return (uint32_t)((uint32_t)(i) + (uint32_t)(j) + 1) >> 1;
283#elif AVG16R_AVRASM == 1
286 "add %A[i], %A[j] \n\t"
288 "adc %B[i], %B[j] \n\t"
294 "adc %A[i], __zero_reg__\n\t"
295 "adc %B[i], __zero_reg__\n\t"
301#error "No implementation for avg16r available."
316 return (i>>1) + (j>>1) + (i & 0x1);
317#elif AVG7_AVRASM == 1
327#error "No implementation for avg7 available."
341 return (i>>1) + (j>>1) + (i & 0x1);
342#elif AVG15_AVRASM == 1
351 "adc %A[i], %A[j] \n\t"
352 "adc %B[i], %B[j] \n\t"
358#error "No implementation for avg15 available."
378 "L_%=: sub %[a],%[m] \n\t"
380 " add %[a],%[m] \n\t"
385 while( a >= m) a -= m;
411 " add %[a],%[b] \n\t"
412 "L_%=: sub %[a],%[m] \n\t"
414 " add %[a],%[m] \n\t"
416 : [b]
"r" (b), [m]
"r" (m)
420 while( a >= m) a -= m;
446 " sub %[a],%[b] \n\t"
447 "L_%=: sub %[a],%[m] \n\t"
449 " add %[a],%[m] \n\t"
451 : [b]
"r" (b), [m]
"r" (m)
455 while( a >= m) a -= m;
468 return ((
int)i * (
int)(j) ) & 0xFF;
469#elif MUL8_AVRASM == 1
476 "clr __zero_reg__ \n\t"
483#error "No implementation for mul8 available."
495 unsigned p = (unsigned)i * (
unsigned)j;
496 if( p > 255) p = 255;
498#elif QMUL8_AVRASM == 1
506 " breq Lnospill_%= \n\t"
511 " clr __zero_reg__ \n\t"
518#error "No implementation for qmul8 available."
529#elif ABS8_AVRASM == 1
541#error "No implementation for abs8 available."
564 mid = (low + hi) >> 1;
565 if ((uint16_t)(mid * mid) > x) {
583#if (FASTLED_BLEND_FIXED == 1)
610# if (FASTLED_SCALE8_FIXED == 1)
611 partial = (a << 8) | b;
614 partial += (b * amountOfB);
615 partial -= (a * amountOfB);
618 uint8_t amountOfA = 255 - amountOfB;
621 partial = (a * amountOfA);
622 partial += (b * amountOfB);
625 result = partial >> 8;
629#elif BLEND8_AVRASM == 1
631# if (FASTLED_SCALE8_FIXED == 1)
634 partial = (a << 8) | b;
638 " mul %[a], %[amountOfB] \n\t"
639 " sub %A[partial], r0 \n\t"
640 " sbc %B[partial], r1 \n\t"
641 " mul %[b], %[amountOfB] \n\t"
642 " add %A[partial], r0 \n\t"
643 " adc %B[partial], r1 \n\t"
644 " clr __zero_reg__ \n\t"
645 : [partial]
"+r" (partial)
646 : [amountOfB]
"r" (amountOfB),
659 " mul %[b], %[amountOfB] \n\t"
660 " movw %A[partial], r0 \n\t"
663 " com %[amountOfB] \n\t"
666 " mul %[a], %[amountOfB] \n\t"
668 " add %A[partial], r0 \n\t"
669 " adc %B[partial], r1 \n\t"
671 " clr __zero_reg__ \n\t"
673 : [partial]
"=r" (partial),
674 [amountOfB]
"+a" (amountOfB)
682 result = partial >> 8;
687# error "No implementation for blend8 available."
698 uint8_t amountOfA = 255 - amountOfB;
LIB8STATIC_ALWAYS_INLINE uint8_t qadd8(uint8_t i, uint8_t j)
Add one byte to another, saturating at 0xFF.
LIB8STATIC_ALWAYS_INLINE int8_t abs8(int8_t i)
Take the absolute value of a signed 8-bit uint8_t.
LIB8STATIC_ALWAYS_INLINE uint8_t qmul8(uint8_t i, uint8_t j)
8x8 bit multiplication with 8-bit result, saturating at 0xFF.
LIB8STATIC_ALWAYS_INLINE uint16_t avg16(uint16_t i, uint16_t j)
Calculate an integer average of two unsigned 16-bit integer values (uint16_t), rounded down.
LIB8STATIC_ALWAYS_INLINE int16_t avg15(int16_t i, int16_t j)
Calculate an integer average of two signed 15-bit integers (int16_t).
LIB8STATIC uint8_t addmod8(uint8_t a, uint8_t b, uint8_t m)
Add two numbers, and calculate the modulo of the sum and a third number, M.
LIB8STATIC_ALWAYS_INLINE uint16_t avg16r(uint16_t i, uint16_t j)
Calculate an integer average of two unsigned 16-bit integer values (uint16_t), rounded up.
LIB8STATIC_ALWAYS_INLINE int8_t qadd7(int8_t i, int8_t j)
Add one byte to another, saturating at 0x7F and -0x80.
LIB8STATIC_ALWAYS_INLINE uint8_t avg8(uint8_t i, uint8_t j)
Calculate an integer average of two unsigned 8-bit integer values (uint8_t), rounded down.
LIB8STATIC uint8_t sqrt16(uint16_t x)
Square root for 16-bit integers.
LIB8STATIC_ALWAYS_INLINE uint8_t add8(uint8_t i, uint8_t j)
Add one byte to another, with 8-bit result.
LIB8STATIC_ALWAYS_INLINE uint8_t avg8r(uint8_t i, uint8_t j)
Calculate an integer average of two unsigned 8-bit integer values (uint8_t), rounded up.
LIB8STATIC uint8_t submod8(uint8_t a, uint8_t b, uint8_t m)
Subtract two numbers, and calculate the modulo of the difference and a third number,...
LIB8STATIC uint8_t blend8(uint8_t a, uint8_t b, uint8_t amountOfB)
Blend a variable proportion (0-255) of one byte to another.
LIB8STATIC_ALWAYS_INLINE uint8_t mod8(uint8_t a, uint8_t m)
Calculate the remainder of one unsigned 8-bit value divided by anoter, aka A % M.
LIB8STATIC_ALWAYS_INLINE uint16_t add8to16(uint8_t i, uint16_t j)
Add one byte to two bytes, with 16-bit result.
LIB8STATIC_ALWAYS_INLINE uint8_t sub8(uint8_t i, uint8_t j)
Subtract one byte from another, 8-bit result.
LIB8STATIC_ALWAYS_INLINE int8_t avg7(int8_t i, int8_t j)
Calculate an integer average of two signed 7-bit integers (int8_t).
LIB8STATIC_ALWAYS_INLINE uint8_t qsub8(uint8_t i, uint8_t j)
Subtract one byte from another, saturating at 0x00.
LIB8STATIC_ALWAYS_INLINE uint8_t mul8(uint8_t i, uint8_t j)
8x8 bit multiplication, with 8-bit result.
LIB8STATIC_ALWAYS_INLINE void cleanup_R1()
Clean up the r1 register after a series of *LEAVING_R1_DIRTY calls.
LIB8STATIC_ALWAYS_INLINE uint8_t scale8_LEAVING_R1_DIRTY(uint8_t i, fract8 scale)
This version of scale8() does not clean up the R1 register on AVR.
#define LIB8STATIC
Define a LIB8TION member function as static inline with an "unused" attribute.
#define LIB8STATIC_ALWAYS_INLINE
Define a LIB8TION member function as always static inline.
Fast, efficient 8-bit scaling functions specifically designed for high-performance LED programming.