Apply shorthand Assembler macros
This commit is contained in:
		| @@ -23,6 +23,8 @@ | ||||
| #ifndef _MATH_AVR_H_ | ||||
| #define _MATH_AVR_H_ | ||||
|  | ||||
| #define a(CODE) " " CODE "\n\t" | ||||
|  | ||||
| /** | ||||
|  * Optimized math functions for AVR | ||||
|  */ | ||||
| @@ -39,41 +41,41 @@ | ||||
| // | ||||
| #define MultiU24X32toH16(intRes, longIn1, longIn2) \ | ||||
|   asm volatile ( \ | ||||
|                  "clr r26 \n\t" \ | ||||
|                  "mul %A1, %B2 \n\t" \ | ||||
|                  "mov r27, r1 \n\t" \ | ||||
|                  "mul %B1, %C2 \n\t" \ | ||||
|                  "movw %A0, r0 \n\t" \ | ||||
|                  "mul %C1, %C2 \n\t" \ | ||||
|                  "add %B0, r0 \n\t" \ | ||||
|                  "mul %C1, %B2 \n\t" \ | ||||
|                  "add %A0, r0 \n\t" \ | ||||
|                  "adc %B0, r1 \n\t" \ | ||||
|                  "mul %A1, %C2 \n\t" \ | ||||
|                  "add r27, r0 \n\t" \ | ||||
|                  "adc %A0, r1 \n\t" \ | ||||
|                  "adc %B0, r26 \n\t" \ | ||||
|                  "mul %B1, %B2 \n\t" \ | ||||
|                  "add r27, r0 \n\t" \ | ||||
|                  "adc %A0, r1 \n\t" \ | ||||
|                  "adc %B0, r26 \n\t" \ | ||||
|                  "mul %C1, %A2 \n\t" \ | ||||
|                  "add r27, r0 \n\t" \ | ||||
|                  "adc %A0, r1 \n\t" \ | ||||
|                  "adc %B0, r26 \n\t" \ | ||||
|                  "mul %B1, %A2 \n\t" \ | ||||
|                  "add r27, r1 \n\t" \ | ||||
|                  "adc %A0, r26 \n\t" \ | ||||
|                  "adc %B0, r26 \n\t" \ | ||||
|                  "lsr r27 \n\t" \ | ||||
|                  "adc %A0, r26 \n\t" \ | ||||
|                  "adc %B0, r26 \n\t" \ | ||||
|                  "mul %D2, %A1 \n\t" \ | ||||
|                  "add %A0, r0 \n\t" \ | ||||
|                  "adc %B0, r1 \n\t" \ | ||||
|                  "mul %D2, %B1 \n\t" \ | ||||
|                  "add %B0, r0 \n\t" \ | ||||
|                  "clr r1 \n\t" \ | ||||
|                  A("clr r26")      \ | ||||
|                  A("mul %A1, %B2") \ | ||||
|                  A("mov r27, r1")  \ | ||||
|                  A("mul %B1, %C2") \ | ||||
|                  A("movw %A0, r0") \ | ||||
|                  A("mul %C1, %C2") \ | ||||
|                  A("add %B0, r0")  \ | ||||
|                  A("mul %C1, %B2") \ | ||||
|                  A("add %A0, r0")  \ | ||||
|                  A("adc %B0, r1")  \ | ||||
|                  A("mul %A1, %C2") \ | ||||
|                  A("add r27, r0")  \ | ||||
|                  A("adc %A0, r1")  \ | ||||
|                  A("adc %B0, r26") \ | ||||
|                  A("mul %B1, %B2") \ | ||||
|                  A("add r27, r0")  \ | ||||
|                  A("adc %A0, r1")  \ | ||||
|                  A("adc %B0, r26") \ | ||||
|                  A("mul %C1, %A2") \ | ||||
|                  A("add r27, r0")  \ | ||||
|                  A("adc %A0, r1")  \ | ||||
|                  A("adc %B0, r26") \ | ||||
|                  A("mul %B1, %A2") \ | ||||
|                  A("add r27, r1")  \ | ||||
|                  A("adc %A0, r26") \ | ||||
|                  A("adc %B0, r26") \ | ||||
|                  A("lsr r27")      \ | ||||
|                  A("adc %A0, r26") \ | ||||
|                  A("adc %B0, r26") \ | ||||
|                  A("mul %D2, %A1") \ | ||||
|                  A("add %A0, r0")  \ | ||||
|                  A("adc %B0, r1")  \ | ||||
|                  A("mul %D2, %B1") \ | ||||
|                  A("add %B0, r0")  \ | ||||
|                  A("clr r1")       \ | ||||
|                  : \ | ||||
|                  "=&r" (intRes) \ | ||||
|                  : \ | ||||
| @@ -89,16 +91,16 @@ | ||||
| // r27 to store the byte 1 of the 24 bit result | ||||
| #define MultiU16X8toH16(intRes, charIn1, intIn2) \ | ||||
|   asm volatile ( \ | ||||
|                  "clr r26 \n\t" \ | ||||
|                  "mul %A1, %B2 \n\t" \ | ||||
|                  "movw %A0, r0 \n\t" \ | ||||
|                  "mul %A1, %A2 \n\t" \ | ||||
|                  "add %A0, r1 \n\t" \ | ||||
|                  "adc %B0, r26 \n\t" \ | ||||
|                  "lsr r0 \n\t" \ | ||||
|                  "adc %A0, r26 \n\t" \ | ||||
|                  "adc %B0, r26 \n\t" \ | ||||
|                  "clr r1 \n\t" \ | ||||
|                  A("clr r26")      \ | ||||
|                  A("mul %A1, %B2") \ | ||||
|                  A("movw %A0, r0") \ | ||||
|                  A("mul %A1, %A2") \ | ||||
|                  A("add %A0, r1")  \ | ||||
|                  A("adc %B0, r26") \ | ||||
|                  A("lsr r0")       \ | ||||
|                  A("adc %A0, r26") \ | ||||
|                  A("adc %B0, r26") \ | ||||
|                  A("clr r1")       \ | ||||
|                  : \ | ||||
|                  "=&r" (intRes) \ | ||||
|                  : \ | ||||
|   | ||||
| @@ -36,7 +36,7 @@ | ||||
| // state we are when running them | ||||
|  | ||||
| // A SW memory barrier, to ensure GCC does not overoptimize loops | ||||
| #define sw_barrier() asm volatile("": : :"memory"); | ||||
| #define sw_barrier() __asm__ volatile("": : :"memory"); | ||||
|  | ||||
| // (re)initialize UART0 as a monitor output to 250000,n,8,1 | ||||
| static void TXBegin(void) { | ||||
| @@ -230,106 +230,106 @@ void HardFault_HandlerC(unsigned long *sp, unsigned long lr, unsigned long cause | ||||
|  | ||||
| __attribute__((naked)) void NMI_Handler(void) { | ||||
|   __asm__ __volatile__ ( | ||||
|     ".syntax unified        \n" | ||||
|     " tst lr, #4            \n" | ||||
|     " ite eq                \n" | ||||
|     " mrseq r0, msp         \n" | ||||
|     " mrsne r0, psp         \n" | ||||
|     " mov r1,lr             \n" | ||||
|     " mov r2,#0             \n" | ||||
|     " b HardFault_HandlerC  \n" | ||||
|     ".syntax unified" "\n\t" | ||||
|     A("tst lr, #4") | ||||
|     A("ite eq") | ||||
|     A("mrseq r0, msp") | ||||
|     A("mrsne r0, psp") | ||||
|     A("mov r1,lr") | ||||
|     A("mov r2,#0") | ||||
|     A("b HardFault_HandlerC") | ||||
|   ); | ||||
| } | ||||
|  | ||||
| __attribute__((naked)) void HardFault_Handler(void) { | ||||
|   __asm__ __volatile__ ( | ||||
|     ".syntax unified        \n" | ||||
|     " tst lr, #4            \n" | ||||
|     " ite eq                \n" | ||||
|     " mrseq r0, msp         \n" | ||||
|     " mrsne r0, psp         \n" | ||||
|     " mov r1,lr             \n" | ||||
|     " mov r2,#1             \n" | ||||
|     " b HardFault_HandlerC  \n" | ||||
|     ".syntax unified" "\n\t" | ||||
|     A("tst lr, #4") | ||||
|     A("ite eq") | ||||
|     A("mrseq r0, msp") | ||||
|     A("mrsne r0, psp") | ||||
|     A("mov r1,lr") | ||||
|     A("mov r2,#1") | ||||
|     A("b HardFault_HandlerC") | ||||
|   ); | ||||
| } | ||||
|  | ||||
| __attribute__((naked)) void MemManage_Handler(void) { | ||||
|   __asm__ __volatile__ ( | ||||
|     ".syntax unified        \n" | ||||
|     " tst lr, #4            \n" | ||||
|     " ite eq                \n" | ||||
|     " mrseq r0, msp         \n" | ||||
|     " mrsne r0, psp         \n" | ||||
|     " mov r1,lr             \n" | ||||
|     " mov r2,#2             \n" | ||||
|     " b HardFault_HandlerC  \n" | ||||
|     ".syntax unified" "\n\t" | ||||
|     A("tst lr, #4") | ||||
|     A("ite eq") | ||||
|     A("mrseq r0, msp") | ||||
|     A("mrsne r0, psp") | ||||
|     A("mov r1,lr") | ||||
|     A("mov r2,#2") | ||||
|     A("b HardFault_HandlerC") | ||||
|   ); | ||||
| } | ||||
|  | ||||
| __attribute__((naked)) void BusFault_Handler(void) { | ||||
|   __asm__ __volatile__ ( | ||||
|     ".syntax unified        \n" | ||||
|     " tst lr, #4            \n" | ||||
|     " ite eq                \n" | ||||
|     " mrseq r0, msp         \n" | ||||
|     " mrsne r0, psp         \n" | ||||
|     " mov r1,lr             \n" | ||||
|     " mov r2,#3             \n" | ||||
|     " b HardFault_HandlerC  \n" | ||||
|     ".syntax unified" "\n\t" | ||||
|     A("tst lr, #4") | ||||
|     A("ite eq") | ||||
|     A("mrseq r0, msp") | ||||
|     A("mrsne r0, psp") | ||||
|     A("mov r1,lr") | ||||
|     A("mov r2,#3") | ||||
|     A("b HardFault_HandlerC") | ||||
|   ); | ||||
| } | ||||
|  | ||||
| __attribute__((naked)) void UsageFault_Handler(void) { | ||||
|   __asm__ __volatile__ ( | ||||
|     ".syntax unified        \n" | ||||
|     " tst lr, #4            \n" | ||||
|     " ite eq                \n" | ||||
|     " mrseq r0, msp         \n" | ||||
|     " mrsne r0, psp         \n" | ||||
|     " mov r1,lr             \n" | ||||
|     " mov r2,#4             \n" | ||||
|     " b HardFault_HandlerC  \n" | ||||
|     ".syntax unified" "\n\t" | ||||
|     A("tst lr, #4") | ||||
|     A("ite eq") | ||||
|     A("mrseq r0, msp") | ||||
|     A("mrsne r0, psp") | ||||
|     A("mov r1,lr") | ||||
|     A("mov r2,#4") | ||||
|     A("b HardFault_HandlerC") | ||||
|   ); | ||||
| } | ||||
|  | ||||
| __attribute__((naked)) void DebugMon_Handler(void) { | ||||
|   __asm__ __volatile__ ( | ||||
|     ".syntax unified        \n" | ||||
|     " tst lr, #4            \n" | ||||
|     " ite eq                \n" | ||||
|     " mrseq r0, msp         \n" | ||||
|     " mrsne r0, psp         \n" | ||||
|     " mov r1,lr             \n" | ||||
|     " mov r2,#5             \n" | ||||
|     " b HardFault_HandlerC  \n" | ||||
|     ".syntax unified" "\n\t" | ||||
|     A("tst lr, #4") | ||||
|     A("ite eq") | ||||
|     A("mrseq r0, msp") | ||||
|     A("mrsne r0, psp") | ||||
|     A("mov r1,lr") | ||||
|     A("mov r2,#5") | ||||
|     A("b HardFault_HandlerC") | ||||
|   ); | ||||
| } | ||||
|  | ||||
| /* This is NOT an exception, it is an interrupt handler - Nevertheless, the framing is the same */ | ||||
| __attribute__((naked)) void WDT_Handler(void) { | ||||
|   __asm__ __volatile__ ( | ||||
|     ".syntax unified        \n" | ||||
|     " tst lr, #4            \n" | ||||
|     " ite eq                \n" | ||||
|     " mrseq r0, msp         \n" | ||||
|     " mrsne r0, psp         \n" | ||||
|     " mov r1,lr             \n" | ||||
|     " mov r2,#6             \n" | ||||
|     " b HardFault_HandlerC  \n" | ||||
|     ".syntax unified" "\n\t" | ||||
|     A("tst lr, #4") | ||||
|     A("ite eq") | ||||
|     A("mrseq r0, msp") | ||||
|     A("mrsne r0, psp") | ||||
|     A("mov r1,lr") | ||||
|     A("mov r2,#6") | ||||
|     A("b HardFault_HandlerC") | ||||
|   ); | ||||
| } | ||||
|  | ||||
| __attribute__((naked)) void RSTC_Handler(void) { | ||||
|   __asm__ __volatile__ ( | ||||
|     ".syntax unified        \n" | ||||
|     " tst lr, #4            \n" | ||||
|     " ite eq                \n" | ||||
|     " mrseq r0, msp         \n" | ||||
|     " mrsne r0, psp         \n" | ||||
|     " mov r1,lr             \n" | ||||
|     " mov r2,#7             \n" | ||||
|     " b HardFault_HandlerC  \n" | ||||
|     ".syntax unified" "\n\t" | ||||
|     A("tst lr, #4") | ||||
|     A("ite eq") | ||||
|     A("mrseq r0, msp") | ||||
|     A("mrsne r0, psp") | ||||
|     A("mov r1,lr") | ||||
|     A("mov r2,#7") | ||||
|     A("b HardFault_HandlerC") | ||||
|   ); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -77,10 +77,10 @@ | ||||
|     __asm__ __volatile__( | ||||
|       ".syntax unified" "\n\t" // is to prevent CM0,CM1 non-unified syntax | ||||
|  | ||||
|       "loop%=:" "\n\t" | ||||
|       " subs %[cnt],#1" "\n\t" | ||||
|       EXTRA_NOP_CYCLES "\n\t" | ||||
|       " bne loop%=" "\n\t" | ||||
|       L("loop%=") | ||||
|       A("subs %[cnt],#1") | ||||
|       A(EXTRA_NOP_CYCLES) | ||||
|       A("bne loop%=") | ||||
|       : [cnt]"+r"(cy) // output: +r means input+output | ||||
|       : // input: | ||||
|       : "cc" // clobbers: | ||||
| @@ -141,54 +141,54 @@ | ||||
|       ".syntax unified" "\n\t" // is to prevent CM0,CM1 non-unified syntax | ||||
|  | ||||
|       /* Bit 7 */ | ||||
|       " ubfx %[idx],%[txval],#7,#1" "\n\t"                      /* Place bit 7 in bit 0 of idx*/ | ||||
|       A("ubfx %[idx],%[txval],#7,#1")                      /* Place bit 7 in bit 0 of idx*/ | ||||
|  | ||||
|       " str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]" "\n\t"  /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */ | ||||
|       " ubfx %[idx],%[txval],#6,#1" "\n\t"                      /* Place bit 6 in bit 0 of idx*/ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */ | ||||
|       A("str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]")  /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")                   /* SODR */ | ||||
|       A("ubfx %[idx],%[txval],#6,#1")                      /* Place bit 6 in bit 0 of idx*/ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")              /* CODR */ | ||||
|  | ||||
|       /* Bit 6 */ | ||||
|       " str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]" "\n\t"  /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */ | ||||
|       " ubfx %[idx],%[txval],#5,#1" "\n\t"                      /* Place bit 5 in bit 0 of idx*/ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */ | ||||
|       A("str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]")  /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")                   /* SODR */ | ||||
|       A("ubfx %[idx],%[txval],#5,#1")                      /* Place bit 5 in bit 0 of idx*/ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")              /* CODR */ | ||||
|  | ||||
|       /* Bit 5 */ | ||||
|       " str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]" "\n\t"  /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */ | ||||
|       " ubfx %[idx],%[txval],#4,#1" "\n\t"                      /* Place bit 4 in bit 0 of idx*/ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */ | ||||
|       A("str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]")  /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")                   /* SODR */ | ||||
|       A("ubfx %[idx],%[txval],#4,#1")                      /* Place bit 4 in bit 0 of idx*/ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")              /* CODR */ | ||||
|  | ||||
|       /* Bit 4 */ | ||||
|       " str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]" "\n\t"  /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */ | ||||
|       " ubfx %[idx],%[txval],#3,#1" "\n\t"                      /* Place bit 3 in bit 0 of idx*/ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */ | ||||
|       A("str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]")  /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")                   /* SODR */ | ||||
|       A("ubfx %[idx],%[txval],#3,#1")                      /* Place bit 3 in bit 0 of idx*/ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")              /* CODR */ | ||||
|  | ||||
|       /* Bit 3 */ | ||||
|       " str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]" "\n\t"  /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */ | ||||
|       " ubfx %[idx],%[txval],#2,#1" "\n\t"                      /* Place bit 2 in bit 0 of idx*/ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */ | ||||
|       A("str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]")  /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")                   /* SODR */ | ||||
|       A("ubfx %[idx],%[txval],#2,#1")                      /* Place bit 2 in bit 0 of idx*/ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")              /* CODR */ | ||||
|  | ||||
|       /* Bit 2 */ | ||||
|       " str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]" "\n\t"  /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */ | ||||
|       " ubfx %[idx],%[txval],#1,#1" "\n\t"                      /* Place bit 1 in bit 0 of idx*/ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */ | ||||
|       A("str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]")  /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")                   /* SODR */ | ||||
|       A("ubfx %[idx],%[txval],#1,#1")                      /* Place bit 1 in bit 0 of idx*/ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")              /* CODR */ | ||||
|  | ||||
|       /* Bit 1 */ | ||||
|       " str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]" "\n\t"  /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */ | ||||
|       " ubfx %[idx],%[txval],#0,#1" "\n\t"                      /* Place bit 0 in bit 0 of idx*/ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */ | ||||
|       A("str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]")  /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")                   /* SODR */ | ||||
|       A("ubfx %[idx],%[txval],#0,#1")                      /* Place bit 0 in bit 0 of idx*/ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")              /* CODR */ | ||||
|  | ||||
|       /* Bit 0 */ | ||||
|       " str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]" "\n\t"  /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */ | ||||
|       " nop" "\n\t"                                             /* Result will be 0 */ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */ | ||||
|       A("str %[mosi_mask],[%[mosi_port], %[idx],LSL #2]")  /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")                   /* SODR */ | ||||
|       A("nop")                                             /* Result will be 0 */ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")              /* CODR */ | ||||
|  | ||||
|       : [idx]"+r"( idx ) | ||||
|       : [txval]"r"( bout ) , | ||||
| @@ -222,52 +222,52 @@ | ||||
|       ".syntax unified" "\n\t" // is to prevent CM0,CM1 non-unified syntax | ||||
|  | ||||
|       /* bit 7 */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */ | ||||
|       " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */ | ||||
|       " bfi %[bin],%[work],#7,#1" "\n\t"                /* Store read bit as the bit 7 */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")           /* SODR */ | ||||
|       A("ldr %[work],[%[bitband_miso_port]]")      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")      /* CODR */ | ||||
|       A("bfi %[bin],%[work],#7,#1")                /* Store read bit as the bit 7 */ | ||||
|  | ||||
|       /* bit 6 */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */ | ||||
|       " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */ | ||||
|       " bfi %[bin],%[work],#6,#1" "\n\t"                /* Store read bit as the bit 6 */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")           /* SODR */ | ||||
|       A("ldr %[work],[%[bitband_miso_port]]")      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")      /* CODR */ | ||||
|       A("bfi %[bin],%[work],#6,#1")                /* Store read bit as the bit 6 */ | ||||
|  | ||||
|       /* bit 5 */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */ | ||||
|       " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */ | ||||
|       " bfi %[bin],%[work],#5,#1" "\n\t"                /* Store read bit as the bit 5 */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")           /* SODR */ | ||||
|       A("ldr %[work],[%[bitband_miso_port]]")      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")      /* CODR */ | ||||
|       A("bfi %[bin],%[work],#5,#1")                /* Store read bit as the bit 5 */ | ||||
|  | ||||
|       /* bit 4 */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */ | ||||
|       " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */ | ||||
|       " bfi %[bin],%[work],#4,#1" "\n\t"                /* Store read bit as the bit 4 */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")           /* SODR */ | ||||
|       A("ldr %[work],[%[bitband_miso_port]]")      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")      /* CODR */ | ||||
|       A("bfi %[bin],%[work],#4,#1")                /* Store read bit as the bit 4 */ | ||||
|  | ||||
|       /* bit 3 */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */ | ||||
|       " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */ | ||||
|       " bfi %[bin],%[work],#3,#1" "\n\t"                /* Store read bit as the bit 3 */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")           /* SODR */ | ||||
|       A("ldr %[work],[%[bitband_miso_port]]")      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")      /* CODR */ | ||||
|       A("bfi %[bin],%[work],#3,#1")                /* Store read bit as the bit 3 */ | ||||
|  | ||||
|       /* bit 2 */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */ | ||||
|       " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */ | ||||
|       " bfi %[bin],%[work],#2,#1" "\n\t"                /* Store read bit as the bit 2 */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")           /* SODR */ | ||||
|       A("ldr %[work],[%[bitband_miso_port]]")      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")      /* CODR */ | ||||
|       A("bfi %[bin],%[work],#2,#1")                /* Store read bit as the bit 2 */ | ||||
|  | ||||
|       /* bit 1 */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */ | ||||
|       " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */ | ||||
|       " bfi %[bin],%[work],#1,#1" "\n\t"                /* Store read bit as the bit 1 */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")           /* SODR */ | ||||
|       A("ldr %[work],[%[bitband_miso_port]]")      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")      /* CODR */ | ||||
|       A("bfi %[bin],%[work],#1,#1")                /* Store read bit as the bit 1 */ | ||||
|  | ||||
|       /* bit 0 */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */ | ||||
|       " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */ | ||||
|       " bfi %[bin],%[work],#0,#1" "\n\t"                /* Store read bit as the bit 0 */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")           /* SODR */ | ||||
|       A("ldr %[work],[%[bitband_miso_port]]")      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")      /* CODR */ | ||||
|       A("bfi %[bin],%[work],#0,#1")                /* Store read bit as the bit 0 */ | ||||
|  | ||||
|       : [bin]"+r"(bin), | ||||
|         [work]"+r"(work) | ||||
| @@ -335,60 +335,60 @@ | ||||
|     __asm__ __volatile__( | ||||
|       ".syntax unified" "\n\t" // is to prevent CM0,CM1 non-unified syntax | ||||
|  | ||||
|       " loop%=:" "\n\t" | ||||
|       " ldrb.w %[txval], [%[ptr]], #1" "\n\t"                   /* Load value to send, increment buffer */ | ||||
|       " mvn %[txval],%[txval]" "\n\t"                           /* Negate value */ | ||||
|       L("loop%=") | ||||
|       A("ldrb.w %[txval], [%[ptr]], #1")                   /* Load value to send, increment buffer */ | ||||
|       A("mvn %[txval],%[txval]")                           /* Negate value */ | ||||
|  | ||||
|       /* Bit 7 */ | ||||
|       " ubfx %[work],%[txval],#7,#1" "\n\t"                     /* Place bit 7 in bit 0 of work*/ | ||||
|       A("ubfx %[work],%[txval],#7,#1")                     /* Place bit 7 in bit 0 of work*/ | ||||
|  | ||||
|       " str %[mosi_mask],[%[mosi_port], %[work],LSL #2]" "\n\t" /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */ | ||||
|       " ubfx %[work],%[txval],#6,#1" "\n\t"                     /* Place bit 6 in bit 0 of work*/ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */ | ||||
|       A("str %[mosi_mask],[%[mosi_port], %[work],LSL #2]") /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")                   /* SODR */ | ||||
|       A("ubfx %[work],%[txval],#6,#1")                     /* Place bit 6 in bit 0 of work*/ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")              /* CODR */ | ||||
|  | ||||
|       /* Bit 6 */ | ||||
|       " str %[mosi_mask],[%[mosi_port], %[work],LSL #2]" "\n\t" /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */ | ||||
|       " ubfx %[work],%[txval],#5,#1" "\n\t"                     /* Place bit 5 in bit 0 of work*/ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */ | ||||
|       A("str %[mosi_mask],[%[mosi_port], %[work],LSL #2]") /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")                   /* SODR */ | ||||
|       A("ubfx %[work],%[txval],#5,#1")                     /* Place bit 5 in bit 0 of work*/ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")              /* CODR */ | ||||
|  | ||||
|       /* Bit 5 */ | ||||
|       " str %[mosi_mask],[%[mosi_port], %[work],LSL #2]" "\n\t" /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */ | ||||
|       " ubfx %[work],%[txval],#4,#1" "\n\t"                     /* Place bit 4 in bit 0 of work*/ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */ | ||||
|       A("str %[mosi_mask],[%[mosi_port], %[work],LSL #2]") /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")                   /* SODR */ | ||||
|       A("ubfx %[work],%[txval],#4,#1")                     /* Place bit 4 in bit 0 of work*/ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")              /* CODR */ | ||||
|  | ||||
|       /* Bit 4 */ | ||||
|       " str %[mosi_mask],[%[mosi_port], %[work],LSL #2]" "\n\t" /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */ | ||||
|       " ubfx %[work],%[txval],#3,#1" "\n\t"                     /* Place bit 3 in bit 0 of work*/ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */ | ||||
|       A("str %[mosi_mask],[%[mosi_port], %[work],LSL #2]") /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")                   /* SODR */ | ||||
|       A("ubfx %[work],%[txval],#3,#1")                     /* Place bit 3 in bit 0 of work*/ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")              /* CODR */ | ||||
|  | ||||
|       /* Bit 3 */ | ||||
|       " str %[mosi_mask],[%[mosi_port], %[work],LSL #2]" "\n\t" /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */ | ||||
|       " ubfx %[work],%[txval],#2,#1" "\n\t"                     /* Place bit 2 in bit 0 of work*/ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */ | ||||
|       A("str %[mosi_mask],[%[mosi_port], %[work],LSL #2]") /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")                   /* SODR */ | ||||
|       A("ubfx %[work],%[txval],#2,#1")                     /* Place bit 2 in bit 0 of work*/ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")              /* CODR */ | ||||
|  | ||||
|       /* Bit 2 */ | ||||
|       " str %[mosi_mask],[%[mosi_port], %[work],LSL #2]" "\n\t" /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */ | ||||
|       " ubfx %[work],%[txval],#1,#1" "\n\t"                     /* Place bit 1 in bit 0 of work*/ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */ | ||||
|       A("str %[mosi_mask],[%[mosi_port], %[work],LSL #2]") /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")                   /* SODR */ | ||||
|       A("ubfx %[work],%[txval],#1,#1")                     /* Place bit 1 in bit 0 of work*/ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")              /* CODR */ | ||||
|  | ||||
|       /* Bit 1 */ | ||||
|       " str %[mosi_mask],[%[mosi_port], %[work],LSL #2]" "\n\t" /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */ | ||||
|       " ubfx %[work],%[txval],#0,#1" "\n\t"                     /* Place bit 0 in bit 0 of work*/ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */ | ||||
|       A("str %[mosi_mask],[%[mosi_port], %[work],LSL #2]") /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")                   /* SODR */ | ||||
|       A("ubfx %[work],%[txval],#0,#1")                     /* Place bit 0 in bit 0 of work*/ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")              /* CODR */ | ||||
|  | ||||
|       /* Bit 0 */ | ||||
|       " str %[mosi_mask],[%[mosi_port], %[work],LSL #2]" "\n\t"  /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"                   /* SODR */ | ||||
|       " subs %[todo],#1" "\n\t"                                 /* Decrement count of pending words to send, update status */ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"              /* CODR */ | ||||
|       " bne.n loop%=" "\n\t"                                    /* Repeat until done */ | ||||
|       A("str %[mosi_mask],[%[mosi_port], %[work],LSL #2]")  /* Access the proper SODR or CODR registers based on that bit */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")                   /* SODR */ | ||||
|       A("subs %[todo],#1")                                 /* Decrement count of pending words to send, update status */ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")              /* CODR */ | ||||
|       A("bne.n loop%=")                                    /* Repeat until done */ | ||||
|  | ||||
|       : [ptr]"+r" ( ptr ) , | ||||
|         [todo]"+r" ( todo ) , | ||||
| @@ -413,59 +413,59 @@ | ||||
|     __asm__ __volatile__( | ||||
|       ".syntax unified" "\n\t" // is to prevent CM0,CM1 non-unified syntax | ||||
|  | ||||
|       " loop%=:" "\n\t" | ||||
|       L("loop%=") | ||||
|  | ||||
|       /* bit 7 */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */ | ||||
|       " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */ | ||||
|       " bfi %[bin],%[work],#7,#1" "\n\t"                /* Store read bit as the bit 7 */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")           /* SODR */ | ||||
|       A("ldr %[work],[%[bitband_miso_port]]")      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")      /* CODR */ | ||||
|       A("bfi %[bin],%[work],#7,#1")                /* Store read bit as the bit 7 */ | ||||
|  | ||||
|       /* bit 6 */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */ | ||||
|       " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */ | ||||
|       " bfi %[bin],%[work],#6,#1" "\n\t"                /* Store read bit as the bit 6 */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")           /* SODR */ | ||||
|       A("ldr %[work],[%[bitband_miso_port]]")      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")      /* CODR */ | ||||
|       A("bfi %[bin],%[work],#6,#1")                /* Store read bit as the bit 6 */ | ||||
|  | ||||
|       /* bit 5 */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */ | ||||
|       " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */ | ||||
|       " bfi %[bin],%[work],#5,#1" "\n\t"                /* Store read bit as the bit 5 */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")           /* SODR */ | ||||
|       A("ldr %[work],[%[bitband_miso_port]]")      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")      /* CODR */ | ||||
|       A("bfi %[bin],%[work],#5,#1")                /* Store read bit as the bit 5 */ | ||||
|  | ||||
|       /* bit 4 */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */ | ||||
|       " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */ | ||||
|       " bfi %[bin],%[work],#4,#1" "\n\t"                /* Store read bit as the bit 4 */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")           /* SODR */ | ||||
|       A("ldr %[work],[%[bitband_miso_port]]")      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")      /* CODR */ | ||||
|       A("bfi %[bin],%[work],#4,#1")                /* Store read bit as the bit 4 */ | ||||
|  | ||||
|       /* bit 3 */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */ | ||||
|       " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */ | ||||
|       " bfi %[bin],%[work],#3,#1" "\n\t"                /* Store read bit as the bit 3 */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")           /* SODR */ | ||||
|       A("ldr %[work],[%[bitband_miso_port]]")      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")      /* CODR */ | ||||
|       A("bfi %[bin],%[work],#3,#1")                /* Store read bit as the bit 3 */ | ||||
|  | ||||
|       /* bit 2 */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */ | ||||
|       " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */ | ||||
|       " bfi %[bin],%[work],#2,#1" "\n\t"                /* Store read bit as the bit 2 */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")           /* SODR */ | ||||
|       A("ldr %[work],[%[bitband_miso_port]]")      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")      /* CODR */ | ||||
|       A("bfi %[bin],%[work],#2,#1")                /* Store read bit as the bit 2 */ | ||||
|  | ||||
|       /* bit 1 */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */ | ||||
|       " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */ | ||||
|       " bfi %[bin],%[work],#1,#1" "\n\t"                /* Store read bit as the bit 1 */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")           /* SODR */ | ||||
|       A("ldr %[work],[%[bitband_miso_port]]")      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")      /* CODR */ | ||||
|       A("bfi %[bin],%[work],#1,#1")                /* Store read bit as the bit 1 */ | ||||
|  | ||||
|       /* bit 0 */ | ||||
|       " str %[sck_mask],[%[sck_port]]" "\n\t"           /* SODR */ | ||||
|       " ldr %[work],[%[bitband_miso_port]]" "\n\t"      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       " str %[sck_mask],[%[sck_port],#0x4]" "\n\t"      /* CODR */ | ||||
|       " bfi %[bin],%[work],#0,#1" "\n\t"                /* Store read bit as the bit 0 */ | ||||
|       A("str %[sck_mask],[%[sck_port]]")           /* SODR */ | ||||
|       A("ldr %[work],[%[bitband_miso_port]]")      /* PDSR on bitband area for required bit: work will be 1 or 0 based on port */ | ||||
|       A("str %[sck_mask],[%[sck_port],#0x4]")      /* CODR */ | ||||
|       A("bfi %[bin],%[work],#0,#1")                /* Store read bit as the bit 0 */ | ||||
|  | ||||
|       " subs %[todo],#1" "\n\t"                         /* Decrement count of pending words to send, update status */ | ||||
|       " strb.w %[bin], [%[ptr]], #1" "\n\t"             /* Store read value into buffer, increment buffer pointer */ | ||||
|       " bne.n loop%=" "\n\t"                            /* Repeat until done */ | ||||
|       A("subs %[todo],#1")                         /* Decrement count of pending words to send, update status */ | ||||
|       A("strb.w %[bin], [%[ptr]], #1")             /* Store read value into buffer, increment buffer pointer */ | ||||
|       A("bne.n loop%=")                            /* Repeat until done */ | ||||
|  | ||||
|       : [ptr]"+r"(ptr), | ||||
|         [todo]"+r"(todo), | ||||
|   | ||||
| @@ -71,8 +71,6 @@ void u8g_SetPILevel_DUE(u8g_t *u8g, uint8_t pin_index, uint8_t level) { | ||||
|   else port->PIO_CODR = mask; | ||||
| } | ||||
|  | ||||
| #define nop() __asm__ __volatile__("nop;\n\t":::) | ||||
|  | ||||
| void __delay_4cycles(uint32_t cy) __attribute__ ((weak)); | ||||
|  | ||||
| FORCE_INLINE void __delay_4cycles(uint32_t cy) { // +1 cycle | ||||
| @@ -85,10 +83,10 @@ FORCE_INLINE void __delay_4cycles(uint32_t cy) { // +1 cycle | ||||
|   __asm__ __volatile__( | ||||
|     ".syntax unified" "\n\t" // is to prevent CM0,CM1 non-unified syntax | ||||
|  | ||||
|     "loop%=:" "\n\t" | ||||
|     " subs %[cnt],#1" "\n\t" | ||||
|     EXTRA_NOP_CYCLES "\n\t" | ||||
|     " bne loop%=" "\n\t" | ||||
|     L("loop%=") | ||||
|     A("subs %[cnt],#1") | ||||
|     A(EXTRA_NOP_CYCLES) | ||||
|     A("bne loop%=") | ||||
|     : [cnt]"+r"(cy) // output: +r means input+output | ||||
|     : // input: | ||||
|     : "cc" // clobbers: | ||||
|   | ||||
| @@ -291,7 +291,7 @@ static inline __attribute__((always_inline)) uint32_t read_psp(void) { | ||||
|   /* Read the current PSP and return its value as a pointer */ | ||||
|   uint32_t psp; | ||||
|  | ||||
|   __asm volatile ( | ||||
|   __asm__ volatile ( | ||||
|     "   mrs %0, psp \n" | ||||
|     : "=r" (psp) : : | ||||
|   ); | ||||
|   | ||||
| @@ -110,6 +110,9 @@ | ||||
| #define STRINGIFY_(M) #M | ||||
| #define STRINGIFY(M) STRINGIFY_(M) | ||||
|  | ||||
| #define A(CODE) " " CODE "\n\t" | ||||
| #define L(CODE) CODE ":\n\t" | ||||
|  | ||||
| // Macros for bit masks | ||||
| #undef _BV | ||||
| #define _BV(b) (1 << (b)) | ||||
|   | ||||
| @@ -639,7 +639,7 @@ class DigitalPin { | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| /** Nop for timing. */ | ||||
| #define nop asm volatile ("nop\n\t") | ||||
| #define nop __asm__ volatile ("nop") | ||||
| //------------------------------------------------------------------------------ | ||||
| /** Pin Mode for MISO is input.*/ | ||||
| const bool MISO_MODE  = false; | ||||
|   | ||||
| @@ -409,7 +409,7 @@ void Planner::init() { | ||||
|         // %8:%7:%6 = interval | ||||
|         // r31:r30: MUST be those registers, and they must point to the inv_tab | ||||
|  | ||||
|         " clr %13" "\n\t"                 // %13 = 0 | ||||
|         A("clr %13")                       // %13 = 0 | ||||
|  | ||||
|         // Now we must compute | ||||
|         // result = 0xFFFFFF / d | ||||
| @@ -421,122 +421,122 @@ void Planner::init() { | ||||
|         // use Newton-Raphson for the calculation, and will strive to get way less cycles | ||||
|         // for the same result - Using C division, it takes 500cycles to complete . | ||||
|  | ||||
|         " clr %3" "\n\t"                  // idx = 0 | ||||
|         " mov %14,%6" "\n\t" | ||||
|         " mov %15,%7" "\n\t" | ||||
|         " mov %16,%8" "\n\t"              // nr = interval | ||||
|         " tst %16" "\n\t"                 // nr & 0xFF0000 == 0 ? | ||||
|         " brne 2f" "\n\t"                 // No, skip this | ||||
|         " mov %16,%15" "\n\t" | ||||
|         " mov %15,%14" "\n\t"             // nr <<= 8, %14 not needed | ||||
|         " subi %3,-8" "\n\t"              // idx += 8 | ||||
|         " tst %16" "\n\t"                 // nr & 0xFF0000 == 0 ? | ||||
|         " brne 2f" "\n\t"                 // No, skip this | ||||
|         " mov %16,%15" "\n\t"             // nr <<= 8, %14 not needed | ||||
|         " clr %15" "\n\t"                 // We clear %14 | ||||
|         " subi %3,-8" "\n\t"              // idx += 8 | ||||
|         A("clr %3")                        // idx = 0 | ||||
|         A("mov %14,%6")       | ||||
|         A("mov %15,%7")       | ||||
|         A("mov %16,%8")                    // nr = interval | ||||
|         A("tst %16")                       // nr & 0xFF0000 == 0 ? | ||||
|         A("brne 2f")                       // No, skip this | ||||
|         A("mov %16,%15")       | ||||
|         A("mov %15,%14")                   // nr <<= 8, %14 not needed | ||||
|         A("subi %3,-8")                    // idx += 8 | ||||
|         A("tst %16")                       // nr & 0xFF0000 == 0 ? | ||||
|         A("brne 2f")                       // No, skip this | ||||
|         A("mov %16,%15")                   // nr <<= 8, %14 not needed | ||||
|         A("clr %15")                       // We clear %14 | ||||
|         A("subi %3,-8")                    // idx += 8 | ||||
|  | ||||
|         // here %16 != 0 and %16:%15 contains at least 9 MSBits, or both %16:%15 are 0 | ||||
|         "2:" "\n\t" | ||||
|         " cpi %16,0x10" "\n\t"            // (nr & 0xf00000) == 0 ? | ||||
|         " brcc 3f" "\n\t"                 // No, skip this | ||||
|         " swap %15" "\n\t"                // Swap nibbles | ||||
|         " swap %16" "\n\t"                // Swap nibbles. Low nibble is 0 | ||||
|         " mov %14, %15" "\n\t" | ||||
|         " andi %14,0x0f" "\n\t"           // Isolate low nibble | ||||
|         " andi %15,0xf0" "\n\t"           // Keep proper nibble in %15 | ||||
|         " or %16, %14" "\n\t"             // %16:%15 <<= 4 | ||||
|         " subi %3,-4" "\n\t"              // idx += 4 | ||||
|         L("2") | ||||
|         A("cpi %16,0x10")                  // (nr & 0xF00000) == 0 ? | ||||
|         A("brcc 3f")                       // No, skip this | ||||
|         A("swap %15")                      // Swap nibbles | ||||
|         A("swap %16")                      // Swap nibbles. Low nibble is 0 | ||||
|         A("mov %14, %15")       | ||||
|         A("andi %14,0x0F")                 // Isolate low nibble | ||||
|         A("andi %15,0xF0")                 // Keep proper nibble in %15 | ||||
|         A("or %16, %14")                   // %16:%15 <<= 4 | ||||
|         A("subi %3,-4")                    // idx += 4 | ||||
|  | ||||
|         "3:" "\n\t" | ||||
|         " cpi %16,0x40" "\n\t"            // (nr & 0xc00000) == 0 ? | ||||
|         " brcc 4f" "\n\t"                 // No, skip this | ||||
|         " add %15,%15" "\n\t" | ||||
|         " adc %16,%16" "\n\t" | ||||
|         " add %15,%15" "\n\t" | ||||
|         " adc %16,%16" "\n\t"             // %16:%15 <<= 2 | ||||
|         " subi %3,-2" "\n\t"              // idx += 2 | ||||
|         L("3") | ||||
|         A("cpi %16,0x40")                  // (nr & 0xC00000) == 0 ? | ||||
|         A("brcc 4f")                       // No, skip this | ||||
|         A("add %15,%15")       | ||||
|         A("adc %16,%16")       | ||||
|         A("add %15,%15")       | ||||
|         A("adc %16,%16")                   // %16:%15 <<= 2 | ||||
|         A("subi %3,-2")                    // idx += 2 | ||||
|  | ||||
|         "4:" "\n\t" | ||||
|         " cpi %16,0x80" "\n\t"            // (nr & 0x800000) == 0 ? | ||||
|         " brcc 5f" "\n\t"                 // No, skip this | ||||
|         " add %15,%15" "\n\t" | ||||
|         " adc %16,%16" "\n\t"             // %16:%15 <<= 1 | ||||
|         " inc %3" "\n\t"                  // idx += 1 | ||||
|         L("4") | ||||
|         A("cpi %16,0x80")                  // (nr & 0x800000) == 0 ? | ||||
|         A("brcc 5f")                       // No, skip this | ||||
|         A("add %15,%15")       | ||||
|         A("adc %16,%16")                   // %16:%15 <<= 1 | ||||
|         A("inc %3")                        // idx += 1 | ||||
|  | ||||
|         // Now %16:%15 contains its MSBit set to 1, or %16:%15 is == 0. We are now absolutely sure | ||||
|         // we have at least 9 MSBits available to enter the initial estimation table | ||||
|         "5:" "\n\t" | ||||
|         " add %15,%15" "\n\t" | ||||
|         " adc %16,%16" "\n\t"             // %16:%15 = tidx = (nr <<= 1), we lose the top MSBit (always set to 1, %16 is the index into the inverse table) | ||||
|         " add r30,%16" "\n\t"             // Only use top 8 bits | ||||
|         " adc r31,%13" "\n\t"             // r31:r30 = inv_tab + (tidx) | ||||
|         " lpm %14, Z" "\n\t"              // %14 = inv_tab[tidx] | ||||
|         " ldi %15, 1" "\n\t"              // %15 = 1  %15:%14 = inv_tab[tidx] + 256 | ||||
|         L("5") | ||||
|         A("add %15,%15")       | ||||
|         A("adc %16,%16")                   // %16:%15 = tidx = (nr <<= 1), we lose the top MSBit (always set to 1, %16 is the index into the inverse table) | ||||
|         A("add r30,%16")                   // Only use top 8 bits | ||||
|         A("adc r31,%13")                   // r31:r30 = inv_tab + (tidx) | ||||
|         A("lpm %14, Z")                    // %14 = inv_tab[tidx] | ||||
|         A("ldi %15, 1")                    // %15 = 1  %15:%14 = inv_tab[tidx] + 256 | ||||
|  | ||||
|         // We must scale the approximation to the proper place | ||||
|         " clr %16" "\n\t"                 // %16 will always be 0 here | ||||
|         " subi %3,8" "\n\t"               // idx == 8 ? | ||||
|         " breq 6f" "\n\t"                 // yes, no need to scale | ||||
|         " brcs 7f" "\n\t"                 // If C=1, means idx < 8, result was negative! | ||||
|         A("clr %16")                       // %16 will always be 0 here | ||||
|         A("subi %3,8")                     // idx == 8 ? | ||||
|         A("breq 6f")                       // yes, no need to scale | ||||
|         A("brcs 7f")                       // If C=1, means idx < 8, result was negative! | ||||
|  | ||||
|         // idx > 8, now %3 = idx - 8. We must perform a left shift. idx range:[1-8] | ||||
|         " sbrs %3,0" "\n\t"               // shift by 1bit position? | ||||
|         " rjmp 8f" "\n\t"                 // No | ||||
|         " add %14,%14" "\n\t" | ||||
|         " adc %15,%15" "\n\t"             // %15:16 <<= 1 | ||||
|         "8:" "\n\t" | ||||
|         " sbrs %3,1" "\n\t"               // shift by 2bit position? | ||||
|         " rjmp 9f" "\n\t"                 // No | ||||
|         " add %14,%14" "\n\t" | ||||
|         " adc %15,%15" "\n\t" | ||||
|         " add %14,%14" "\n\t" | ||||
|         " adc %15,%15" "\n\t"             // %15:16 <<= 1 | ||||
|         "9:" "\n\t" | ||||
|         " sbrs %3,2" "\n\t"               // shift by 4bits position? | ||||
|         " rjmp 16f" "\n\t"                // No | ||||
|         " swap %15" "\n\t"                // Swap nibbles. lo nibble of %15 will always be 0 | ||||
|         " swap %14" "\n\t"                // Swap nibbles | ||||
|         " mov %12,%14" "\n\t" | ||||
|         " andi %12,0x0f" "\n\t"           // isolate low nibble | ||||
|         " andi %14,0xf0" "\n\t"           // and clear it | ||||
|         " or %15,%12" "\n\t"              // %15:%16 <<= 4 | ||||
|         "16:" "\n\t" | ||||
|         " sbrs %3,3" "\n\t"               // shift by 8bits position? | ||||
|         " rjmp 6f" "\n\t"                 // No, we are done | ||||
|         " mov %16,%15" "\n\t" | ||||
|         " mov %15,%14" "\n\t" | ||||
|         " clr %14" "\n\t" | ||||
|         " jmp 6f" "\n\t" | ||||
|         A("sbrs %3,0")                     // shift by 1bit position? | ||||
|         A("rjmp 8f")                       // No | ||||
|         A("add %14,%14")       | ||||
|         A("adc %15,%15")                   // %15:16 <<= 1 | ||||
|         L("8") | ||||
|         A("sbrs %3,1")                     // shift by 2bit position? | ||||
|         A("rjmp 9f")                       // No | ||||
|         A("add %14,%14")       | ||||
|         A("adc %15,%15")       | ||||
|         A("add %14,%14")       | ||||
|         A("adc %15,%15")                   // %15:16 <<= 1 | ||||
|         L("9") | ||||
|         A("sbrs %3,2")                     // shift by 4bits position? | ||||
|         A("rjmp 16f")                      // No | ||||
|         A("swap %15")                      // Swap nibbles. lo nibble of %15 will always be 0 | ||||
|         A("swap %14")                      // Swap nibbles | ||||
|         A("mov %12,%14")       | ||||
|         A("andi %12,0x0F")                 // isolate low nibble | ||||
|         A("andi %14,0xF0")                 // and clear it | ||||
|         A("or %15,%12")                    // %15:%16 <<= 4 | ||||
|         L("16") | ||||
|         A("sbrs %3,3")                     // shift by 8bits position? | ||||
|         A("rjmp 6f")                       // No, we are done | ||||
|         A("mov %16,%15")       | ||||
|         A("mov %15,%14")       | ||||
|         A("clr %14")       | ||||
|         A("jmp 6f")       | ||||
|  | ||||
|         // idx < 8, now %3 = idx - 8. Get the count of bits | ||||
|         "7:" "\n\t" | ||||
|         " neg %3" "\n\t"                  // %3 = -idx = count of bits to move right. idx range:[1...8] | ||||
|         " sbrs %3,0" "\n\t"               // shift by 1 bit position ? | ||||
|         " rjmp 10f" "\n\t"                // No, skip it | ||||
|         " asr %15" "\n\t"                 // (bit7 is always 0 here) | ||||
|         " ror %14" "\n\t" | ||||
|         "10:" "\n\t" | ||||
|         " sbrs %3,1" "\n\t"               // shift by 2 bit position ? | ||||
|         " rjmp 11f" "\n\t"                // No, skip it | ||||
|         " asr %15" "\n\t"                 // (bit7 is always 0 here) | ||||
|         " ror %14" "\n\t" | ||||
|         " asr %15" "\n\t"                 // (bit7 is always 0 here) | ||||
|         " ror %14" "\n\t" | ||||
|         "11:" "\n\t" | ||||
|         " sbrs %3,2" "\n\t"               // shift by 4 bit position ? | ||||
|         " rjmp 12f" "\n\t"                // No, skip it | ||||
|         " swap %15" "\n\t"                // Swap nibbles | ||||
|         " andi %14, 0xf0" "\n\t"          // Lose the lowest nibble | ||||
|         " swap %14" "\n\t"                // Swap nibbles. Upper nibble is 0 | ||||
|         " or %14,%15" "\n\t"              // Pass nibble from upper byte | ||||
|         " andi %15, 0x0f" "\n\t"          // And get rid of that nibble | ||||
|         "12:" "\n\t" | ||||
|         " sbrs %3,3" "\n\t"               // shift by 8 bit position ? | ||||
|         " rjmp 6f" "\n\t"                 // No, skip it | ||||
|         " mov %14,%15" "\n\t" | ||||
|         " clr %15" "\n\t" | ||||
|         "6:" "\n\t"                       // %16:%15:%14 = initial estimation of 0x1000000 / d | ||||
|         L("7") | ||||
|         A("neg %3")                        // %3 = -idx = count of bits to move right. idx range:[1...8] | ||||
|         A("sbrs %3,0")                     // shift by 1 bit position ? | ||||
|         A("rjmp 10f")                      // No, skip it | ||||
|         A("asr %15")                       // (bit7 is always 0 here) | ||||
|         A("ror %14")       | ||||
|         L("10") | ||||
|         A("sbrs %3,1")                     // shift by 2 bit position ? | ||||
|         A("rjmp 11f")                      // No, skip it | ||||
|         A("asr %15")                       // (bit7 is always 0 here) | ||||
|         A("ror %14")       | ||||
|         A("asr %15")                       // (bit7 is always 0 here) | ||||
|         A("ror %14")       | ||||
|         L("11") | ||||
|         A("sbrs %3,2")                     // shift by 4 bit position ? | ||||
|         A("rjmp 12f")                      // No, skip it | ||||
|         A("swap %15")                      // Swap nibbles | ||||
|         A("andi %14, 0xF0")                // Lose the lowest nibble | ||||
|         A("swap %14")                      // Swap nibbles. Upper nibble is 0 | ||||
|         A("or %14,%15")                    // Pass nibble from upper byte | ||||
|         A("andi %15, 0x0F")                // And get rid of that nibble | ||||
|         L("12") | ||||
|         A("sbrs %3,3")                     // shift by 8 bit position ? | ||||
|         A("rjmp 6f")                       // No, skip it | ||||
|         A("mov %14,%15")       | ||||
|         A("clr %15")       | ||||
|         L("6")                       // %16:%15:%14 = initial estimation of 0x1000000 / d | ||||
|  | ||||
|         // Now, we must refine the estimation present on %16:%15:%14 using 1 iteration | ||||
|         // of Newton-Raphson. As it has a quadratic convergence, 1 iteration is enough | ||||
| @@ -549,36 +549,36 @@ void Planner::init() { | ||||
|         // %3:%2:%1:%0 = working accumulator | ||||
|  | ||||
|         // Compute 1<<25 - x*d. Result should never exceed 25 bits and should always be positive | ||||
|         " clr %0" "\n\t" | ||||
|         " clr %1" "\n\t" | ||||
|         " clr %2" "\n\t" | ||||
|         " ldi %3,2" "\n\t"                // %3:%2:%1:%0 = 0x2000000 | ||||
|         " mul %6,%14" "\n\t"              // r1:r0 = LO(d) * LO(x) | ||||
|         " sub %0,r0" "\n\t" | ||||
|         " sbc %1,r1" "\n\t" | ||||
|         " sbc %2,%13" "\n\t" | ||||
|         " sbc %3,%13" "\n\t"              // %3:%2:%1:%0 -= LO(d) * LO(x) | ||||
|         " mul %7,%14" "\n\t"              // r1:r0 = MI(d) * LO(x) | ||||
|         " sub %1,r0" "\n\t" | ||||
|         " sbc %2,r1"  "\n\t" | ||||
|         " sbc %3,%13" "\n\t"              // %3:%2:%1:%0 -= MI(d) * LO(x) << 8 | ||||
|         " mul %8,%14" "\n\t"              // r1:r0 = HI(d) * LO(x) | ||||
|         " sub %2,r0" "\n\t" | ||||
|         " sbc %3,r1" "\n\t"               // %3:%2:%1:%0 -= MIL(d) * LO(x) << 16 | ||||
|         " mul %6,%15" "\n\t"              // r1:r0 = LO(d) * MI(x) | ||||
|         " sub %1,r0" "\n\t" | ||||
|         " sbc %2,r1" "\n\t" | ||||
|         " sbc %3,%13" "\n\t"              // %3:%2:%1:%0 -= LO(d) * MI(x) << 8 | ||||
|         " mul %7,%15" "\n\t"              // r1:r0 = MI(d) * MI(x) | ||||
|         " sub %2,r0" "\n\t" | ||||
|         " sbc %3,r1" "\n\t"               // %3:%2:%1:%0 -= MI(d) * MI(x) << 16 | ||||
|         " mul %8,%15" "\n\t"              // r1:r0 = HI(d) * MI(x) | ||||
|         " sub %3,r0" "\n\t"               // %3:%2:%1:%0 -= MIL(d) * MI(x) << 24 | ||||
|         " mul %6,%16" "\n\t"              // r1:r0 = LO(d) * HI(x) | ||||
|         " sub %2,r0" "\n\t" | ||||
|         " sbc %3,r1" "\n\t"               // %3:%2:%1:%0 -= LO(d) * HI(x) << 16 | ||||
|         " mul %7,%16" "\n\t"              // r1:r0 = MI(d) * HI(x) | ||||
|         " sub %3,r0" "\n\t"               // %3:%2:%1:%0 -= MI(d) * HI(x) << 24 | ||||
|         A("clr %0")       | ||||
|         A("clr %1")       | ||||
|         A("clr %2")       | ||||
|         A("ldi %3,2")                      // %3:%2:%1:%0 = 0x2000000 | ||||
|         A("mul %6,%14")                    // r1:r0 = LO(d) * LO(x) | ||||
|         A("sub %0,r0")       | ||||
|         A("sbc %1,r1")       | ||||
|         A("sbc %2,%13")       | ||||
|         A("sbc %3,%13")                    // %3:%2:%1:%0 -= LO(d) * LO(x) | ||||
|         A("mul %7,%14")                    // r1:r0 = MI(d) * LO(x) | ||||
|         A("sub %1,r0")       | ||||
|         A("sbc %2,r1" )       | ||||
|         A("sbc %3,%13")                    // %3:%2:%1:%0 -= MI(d) * LO(x) << 8 | ||||
|         A("mul %8,%14")                    // r1:r0 = HI(d) * LO(x) | ||||
|         A("sub %2,r0")       | ||||
|         A("sbc %3,r1")                     // %3:%2:%1:%0 -= MIL(d) * LO(x) << 16 | ||||
|         A("mul %6,%15")                    // r1:r0 = LO(d) * MI(x) | ||||
|         A("sub %1,r0")       | ||||
|         A("sbc %2,r1")       | ||||
|         A("sbc %3,%13")                    // %3:%2:%1:%0 -= LO(d) * MI(x) << 8 | ||||
|         A("mul %7,%15")                    // r1:r0 = MI(d) * MI(x) | ||||
|         A("sub %2,r0")       | ||||
|         A("sbc %3,r1")                     // %3:%2:%1:%0 -= MI(d) * MI(x) << 16 | ||||
|         A("mul %8,%15")                    // r1:r0 = HI(d) * MI(x) | ||||
|         A("sub %3,r0")                     // %3:%2:%1:%0 -= MIL(d) * MI(x) << 24 | ||||
|         A("mul %6,%16")                    // r1:r0 = LO(d) * HI(x) | ||||
|         A("sub %2,r0")       | ||||
|         A("sbc %3,r1")                     // %3:%2:%1:%0 -= LO(d) * HI(x) << 16 | ||||
|         A("mul %7,%16")                    // r1:r0 = MI(d) * HI(x) | ||||
|         A("sub %3,r0")                     // %3:%2:%1:%0 -= MI(d) * HI(x) << 24 | ||||
|         // %3:%2:%1:%0 = (1<<25) - x*d     [169] | ||||
|  | ||||
|         // We need to multiply that result by x, and we are only interested in the top 24bits of that multiply | ||||
| @@ -588,62 +588,62 @@ void Planner::init() { | ||||
|         // %13 = 0 | ||||
|  | ||||
|         // result = %11:%10:%9:%5:%4 | ||||
|         " mul %14,%0" "\n\t"              // r1:r0 = LO(x) * LO(acc) | ||||
|         " mov %4,r1" "\n\t" | ||||
|         " clr %5" "\n\t" | ||||
|         " clr %9" "\n\t" | ||||
|         " clr %10" "\n\t" | ||||
|         " clr %11" "\n\t"                 // %11:%10:%9:%5:%4 = LO(x) * LO(acc) >> 8 | ||||
|         " mul %15,%0" "\n\t"              // r1:r0 = MI(x) * LO(acc) | ||||
|         " add %4,r0" "\n\t" | ||||
|         " adc %5,r1" "\n\t" | ||||
|         " adc %9,%13" "\n\t" | ||||
|         " adc %10,%13" "\n\t" | ||||
|         " adc %11,%13" "\n\t"             // %11:%10:%9:%5:%4 += MI(x) * LO(acc) | ||||
|         " mul %16,%0" "\n\t"              // r1:r0 = HI(x) * LO(acc) | ||||
|         " add %5,r0" "\n\t" | ||||
|         " adc %9,r1" "\n\t" | ||||
|         " adc %10,%13" "\n\t" | ||||
|         " adc %11,%13" "\n\t"             // %11:%10:%9:%5:%4 += MI(x) * LO(acc) << 8 | ||||
|         A("mul %14,%0")                    // r1:r0 = LO(x) * LO(acc) | ||||
|         A("mov %4,r1")       | ||||
|         A("clr %5")       | ||||
|         A("clr %9")       | ||||
|         A("clr %10")       | ||||
|         A("clr %11")                       // %11:%10:%9:%5:%4 = LO(x) * LO(acc) >> 8 | ||||
|         A("mul %15,%0")                    // r1:r0 = MI(x) * LO(acc) | ||||
|         A("add %4,r0")       | ||||
|         A("adc %5,r1")       | ||||
|         A("adc %9,%13")       | ||||
|         A("adc %10,%13")       | ||||
|         A("adc %11,%13")                   // %11:%10:%9:%5:%4 += MI(x) * LO(acc) | ||||
|         A("mul %16,%0")                    // r1:r0 = HI(x) * LO(acc) | ||||
|         A("add %5,r0")       | ||||
|         A("adc %9,r1")       | ||||
|         A("adc %10,%13")       | ||||
|         A("adc %11,%13")                   // %11:%10:%9:%5:%4 += MI(x) * LO(acc) << 8 | ||||
|  | ||||
|         " mul %14,%1" "\n\t"              // r1:r0 = LO(x) * MIL(acc) | ||||
|         " add %4,r0" "\n\t" | ||||
|         " adc %5,r1" "\n\t" | ||||
|         " adc %9,%13" "\n\t" | ||||
|         " adc %10,%13" "\n\t" | ||||
|         " adc %11,%13" "\n\t"             // %11:%10:%9:%5:%4 = LO(x) * MIL(acc) | ||||
|         " mul %15,%1" "\n\t"              // r1:r0 = MI(x) * MIL(acc) | ||||
|         " add %5,r0" "\n\t" | ||||
|         " adc %9,r1" "\n\t" | ||||
|         " adc %10,%13" "\n\t" | ||||
|         " adc %11,%13" "\n\t"             // %11:%10:%9:%5:%4 += MI(x) * MIL(acc) << 8 | ||||
|         " mul %16,%1" "\n\t"              // r1:r0 = HI(x) * MIL(acc) | ||||
|         " add %9,r0" "\n\t" | ||||
|         " adc %10,r1" "\n\t" | ||||
|         " adc %11,%13" "\n\t"             // %11:%10:%9:%5:%4 += MI(x) * MIL(acc) << 16 | ||||
|         A("mul %14,%1")                    // r1:r0 = LO(x) * MIL(acc) | ||||
|         A("add %4,r0")       | ||||
|         A("adc %5,r1")       | ||||
|         A("adc %9,%13")       | ||||
|         A("adc %10,%13")       | ||||
|         A("adc %11,%13")                   // %11:%10:%9:%5:%4 = LO(x) * MIL(acc) | ||||
|         A("mul %15,%1")                    // r1:r0 = MI(x) * MIL(acc) | ||||
|         A("add %5,r0")       | ||||
|         A("adc %9,r1")       | ||||
|         A("adc %10,%13")       | ||||
|         A("adc %11,%13")                   // %11:%10:%9:%5:%4 += MI(x) * MIL(acc) << 8 | ||||
|         A("mul %16,%1")                    // r1:r0 = HI(x) * MIL(acc) | ||||
|         A("add %9,r0")       | ||||
|         A("adc %10,r1")       | ||||
|         A("adc %11,%13")                   // %11:%10:%9:%5:%4 += MI(x) * MIL(acc) << 16 | ||||
|  | ||||
|         " mul %14,%2" "\n\t"              // r1:r0 = LO(x) * MIH(acc) | ||||
|         " add %5,r0" "\n\t" | ||||
|         " adc %9,r1" "\n\t" | ||||
|         " adc %10,%13" "\n\t" | ||||
|         " adc %11,%13" "\n\t"             // %11:%10:%9:%5:%4 = LO(x) * MIH(acc) << 8 | ||||
|         " mul %15,%2" "\n\t"              // r1:r0 = MI(x) * MIH(acc) | ||||
|         " add %9,r0" "\n\t" | ||||
|         " adc %10,r1" "\n\t" | ||||
|         " adc %11,%13" "\n\t"             // %11:%10:%9:%5:%4 += MI(x) * MIH(acc) << 16 | ||||
|         " mul %16,%2" "\n\t"              // r1:r0 = HI(x) * MIH(acc) | ||||
|         " add %10,r0" "\n\t" | ||||
|         " adc %11,r1" "\n\t"              // %11:%10:%9:%5:%4 += MI(x) * MIH(acc) << 24 | ||||
|         A("mul %14,%2")                    // r1:r0 = LO(x) * MIH(acc) | ||||
|         A("add %5,r0")       | ||||
|         A("adc %9,r1")       | ||||
|         A("adc %10,%13")       | ||||
|         A("adc %11,%13")                   // %11:%10:%9:%5:%4 = LO(x) * MIH(acc) << 8 | ||||
|         A("mul %15,%2")                    // r1:r0 = MI(x) * MIH(acc) | ||||
|         A("add %9,r0")       | ||||
|         A("adc %10,r1")       | ||||
|         A("adc %11,%13")                   // %11:%10:%9:%5:%4 += MI(x) * MIH(acc) << 16 | ||||
|         A("mul %16,%2")                    // r1:r0 = HI(x) * MIH(acc) | ||||
|         A("add %10,r0")       | ||||
|         A("adc %11,r1")                    // %11:%10:%9:%5:%4 += MI(x) * MIH(acc) << 24 | ||||
|  | ||||
|         " mul %14,%3" "\n\t"              // r1:r0 = LO(x) * HI(acc) | ||||
|         " add %9,r0" "\n\t" | ||||
|         " adc %10,r1" "\n\t" | ||||
|         " adc %11,%13" "\n\t"             // %11:%10:%9:%5:%4 = LO(x) * HI(acc) << 16 | ||||
|         " mul %15,%3" "\n\t"              // r1:r0 = MI(x) * HI(acc) | ||||
|         " add %10,r0" "\n\t" | ||||
|         " adc %11,r1" "\n\t"              // %11:%10:%9:%5:%4 += MI(x) * HI(acc) << 24 | ||||
|         " mul %16,%3" "\n\t"              // r1:r0 = HI(x) * HI(acc) | ||||
|         " add %11,r0" "\n\t"              // %11:%10:%9:%5:%4 += MI(x) * HI(acc) << 32 | ||||
|         A("mul %14,%3")                    // r1:r0 = LO(x) * HI(acc) | ||||
|         A("add %9,r0")       | ||||
|         A("adc %10,r1")       | ||||
|         A("adc %11,%13")                   // %11:%10:%9:%5:%4 = LO(x) * HI(acc) << 16 | ||||
|         A("mul %15,%3")                    // r1:r0 = MI(x) * HI(acc) | ||||
|         A("add %10,r0")       | ||||
|         A("adc %11,r1")                    // %11:%10:%9:%5:%4 += MI(x) * HI(acc) << 24 | ||||
|         A("mul %16,%3")                    // r1:r0 = HI(x) * HI(acc) | ||||
|         A("add %11,r0")                    // %11:%10:%9:%5:%4 += MI(x) * HI(acc) << 32 | ||||
|  | ||||
|         // At this point, %11:%10:%9 contains the new estimation of x. | ||||
|  | ||||
| @@ -651,54 +651,54 @@ void Planner::init() { | ||||
|         // (1<<24) - x*d | ||||
|         // %11:%10:%9 = x | ||||
|         // %8:%7:%6 = d = interval" "\n\t" | ||||
|         " ldi %3,1" "\n\t" | ||||
|         " clr %2" "\n\t" | ||||
|         " clr %1" "\n\t" | ||||
|         " clr %0" "\n\t"                  // %3:%2:%1:%0 = 0x1000000 | ||||
|         " mul %6,%9" "\n\t"               // r1:r0 = LO(d) * LO(x) | ||||
|         " sub %0,r0" "\n\t" | ||||
|         " sbc %1,r1" "\n\t" | ||||
|         " sbc %2,%13" "\n\t" | ||||
|         " sbc %3,%13" "\n\t"              // %3:%2:%1:%0 -= LO(d) * LO(x) | ||||
|         " mul %7,%9" "\n\t"               // r1:r0 = MI(d) * LO(x) | ||||
|         " sub %1,r0" "\n\t" | ||||
|         " sbc %2,r1" "\n\t" | ||||
|         " sbc %3,%13" "\n\t"              // %3:%2:%1:%0 -= MI(d) * LO(x) << 8 | ||||
|         " mul %8,%9" "\n\t"               // r1:r0 = HI(d) * LO(x) | ||||
|         " sub %2,r0" "\n\t" | ||||
|         " sbc %3,r1" "\n\t"               // %3:%2:%1:%0 -= MIL(d) * LO(x) << 16 | ||||
|         " mul %6,%10" "\n\t"              // r1:r0 = LO(d) * MI(x) | ||||
|         " sub %1,r0" "\n\t" | ||||
|         " sbc %2,r1" "\n\t" | ||||
|         " sbc %3,%13" "\n\t"              // %3:%2:%1:%0 -= LO(d) * MI(x) << 8 | ||||
|         " mul %7,%10" "\n\t"              // r1:r0 = MI(d) * MI(x) | ||||
|         " sub %2,r0" "\n\t" | ||||
|         " sbc %3,r1" "\n\t"               // %3:%2:%1:%0 -= MI(d) * MI(x) << 16 | ||||
|         " mul %8,%10" "\n\t"              // r1:r0 = HI(d) * MI(x) | ||||
|         " sub %3,r0" "\n\t"               // %3:%2:%1:%0 -= MIL(d) * MI(x) << 24 | ||||
|         " mul %6,%11" "\n\t"              // r1:r0 = LO(d) * HI(x) | ||||
|         " sub %2,r0" "\n\t" | ||||
|         " sbc %3,r1" "\n\t"               // %3:%2:%1:%0 -= LO(d) * HI(x) << 16 | ||||
|         " mul %7,%11" "\n\t"              // r1:r0 = MI(d) * HI(x) | ||||
|         " sub %3,r0" "\n\t"               // %3:%2:%1:%0 -= MI(d) * HI(x) << 24 | ||||
|         A("ldi %3,1")       | ||||
|         A("clr %2")       | ||||
|         A("clr %1")       | ||||
|         A("clr %0")                        // %3:%2:%1:%0 = 0x1000000 | ||||
|         A("mul %6,%9")                     // r1:r0 = LO(d) * LO(x) | ||||
|         A("sub %0,r0")       | ||||
|         A("sbc %1,r1")       | ||||
|         A("sbc %2,%13")       | ||||
|         A("sbc %3,%13")                    // %3:%2:%1:%0 -= LO(d) * LO(x) | ||||
|         A("mul %7,%9")                     // r1:r0 = MI(d) * LO(x) | ||||
|         A("sub %1,r0")       | ||||
|         A("sbc %2,r1")       | ||||
|         A("sbc %3,%13")                    // %3:%2:%1:%0 -= MI(d) * LO(x) << 8 | ||||
|         A("mul %8,%9")                     // r1:r0 = HI(d) * LO(x) | ||||
|         A("sub %2,r0")       | ||||
|         A("sbc %3,r1")                     // %3:%2:%1:%0 -= MIL(d) * LO(x) << 16 | ||||
|         A("mul %6,%10")                    // r1:r0 = LO(d) * MI(x) | ||||
|         A("sub %1,r0")       | ||||
|         A("sbc %2,r1")       | ||||
|         A("sbc %3,%13")                    // %3:%2:%1:%0 -= LO(d) * MI(x) << 8 | ||||
|         A("mul %7,%10")                    // r1:r0 = MI(d) * MI(x) | ||||
|         A("sub %2,r0")       | ||||
|         A("sbc %3,r1")                     // %3:%2:%1:%0 -= MI(d) * MI(x) << 16 | ||||
|         A("mul %8,%10")                    // r1:r0 = HI(d) * MI(x) | ||||
|         A("sub %3,r0")                     // %3:%2:%1:%0 -= MIL(d) * MI(x) << 24 | ||||
|         A("mul %6,%11")                    // r1:r0 = LO(d) * HI(x) | ||||
|         A("sub %2,r0")       | ||||
|         A("sbc %3,r1")                     // %3:%2:%1:%0 -= LO(d) * HI(x) << 16 | ||||
|         A("mul %7,%11")                    // r1:r0 = MI(d) * HI(x) | ||||
|         A("sub %3,r0")                     // %3:%2:%1:%0 -= MI(d) * HI(x) << 24 | ||||
|         // %3:%2:%1:%0 = r = (1<<24) - x*d | ||||
|         // %8:%7:%6 = d = interval | ||||
|  | ||||
|         // Perform the final correction | ||||
|         " sub %0,%6" "\n\t" | ||||
|         " sbc %1,%7" "\n\t" | ||||
|         " sbc %2,%8" "\n\t"               // r -= d | ||||
|         " brcs 14f" "\n\t"                // if ( r >= d) | ||||
|         A("sub %0,%6")       | ||||
|         A("sbc %1,%7")       | ||||
|         A("sbc %2,%8")                     // r -= d | ||||
|         A("brcs 14f")                      // if ( r >= d) | ||||
|  | ||||
|         // %11:%10:%9 = x | ||||
|         " ldi %3,1" "\n\t" | ||||
|         " add %9,%3" "\n\t" | ||||
|         " adc %10,%13" "\n\t" | ||||
|         " adc %11,%13" "\n\t"             // x++ | ||||
|         "14:" "\n\t" | ||||
|         A("ldi %3,1")       | ||||
|         A("add %9,%3")       | ||||
|         A("adc %10,%13")       | ||||
|         A("adc %11,%13")                   // x++ | ||||
|         L("14") | ||||
|  | ||||
|         // Estimation is done. %11:%10:%9 = x | ||||
|         " clr __zero_reg__" "\n\t"        // Make C runtime happy | ||||
|         A("clr __zero_reg__")              // Make C runtime happy | ||||
|         // [211 cycles total] | ||||
|         : "=r" (r2), | ||||
|           "=r" (r3), | ||||
|   | ||||
| @@ -581,68 +581,68 @@ void Stepper::set_directions() { | ||||
|         /*  %10 (must be high register!)*/ | ||||
|  | ||||
|         /* Store initial velocity*/ | ||||
|         " sts bezier_F, %0" "\n\t" | ||||
|         " sts bezier_F+1, %1" "\n\t" | ||||
|         " sts bezier_F+2, %10" "\n\t"    /* bezier_F = %10:%1:%0 = v0 */ | ||||
|         A("sts bezier_F, %0") | ||||
|         A("sts bezier_F+1, %1") | ||||
|         A("sts bezier_F+2, %10")    /* bezier_F = %10:%1:%0 = v0 */ | ||||
|  | ||||
|         /* Get delta speed */ | ||||
|         " ldi %2,-1" "\n\t"              /* %2 = 0xff, means A_negative = true */ | ||||
|         " clr %8" "\n\t"                 /* %8 = 0 */ | ||||
|         " sub %0,%3" "\n\t" | ||||
|         " sbc %1,%4" "\n\t" | ||||
|         " sbc %10,%5" "\n\t"             /*  v0 -= v1, C=1 if result is negative */ | ||||
|         " brcc 1f" "\n\t"                /* branch if result is positive (C=0), that means v0 >= v1 */ | ||||
|         A("ldi %2,-1")              /* %2 = 0xFF, means A_negative = true */ | ||||
|         A("clr %8")                 /* %8 = 0 */ | ||||
|         A("sub %0,%3") | ||||
|         A("sbc %1,%4") | ||||
|         A("sbc %10,%5")             /*  v0 -= v1, C=1 if result is negative */ | ||||
|         A("brcc 1f")                /* branch if result is positive (C=0), that means v0 >= v1 */ | ||||
|  | ||||
|         /*  Result was negative, get the absolute value*/ | ||||
|         " com %10" "\n\t" | ||||
|         " com %1" "\n\t" | ||||
|         " neg %0" "\n\t" | ||||
|         " sbc %1,%2" "\n\t" | ||||
|         " sbc %10,%2" "\n\t"             /* %10:%1:%0 +1  -> %10:%1:%0 = -(v0 - v1) = (v1 - v0) */ | ||||
|         " clr %2" "\n\t"                 /* %2 = 0, means A_negative = false */ | ||||
|         A("com %10") | ||||
|         A("com %1") | ||||
|         A("neg %0") | ||||
|         A("sbc %1,%2") | ||||
|         A("sbc %10,%2")             /* %10:%1:%0 +1  -> %10:%1:%0 = -(v0 - v1) = (v1 - v0) */ | ||||
|         A("clr %2")                 /* %2 = 0, means A_negative = false */ | ||||
|  | ||||
|         /*  Store negative flag*/ | ||||
|         "1:" "\n\t" | ||||
|         " sts A_negative, %2" "\n\t"     /* Store negative flag */ | ||||
|         L("1") | ||||
|         A("sts A_negative, %2")     /* Store negative flag */ | ||||
|  | ||||
|         /*  Compute coefficients A,B and C   [20 cycles worst case]*/ | ||||
|         " ldi %9,6" "\n\t"               /* %9 = 6 */ | ||||
|         " mul %0,%9" "\n\t"              /* r1:r0 = 6*LO(v0-v1) */ | ||||
|         " sts bezier_A, r0" "\n\t" | ||||
|         " mov %6,r1" "\n\t" | ||||
|         " clr %7" "\n\t"                 /* %7:%6:r0 = 6*LO(v0-v1) */ | ||||
|         " mul %1,%9" "\n\t"              /* r1:r0 = 6*MI(v0-v1) */ | ||||
|         " add %6,r0" "\n\t" | ||||
|         " adc %7,r1" "\n\t"              /* %7:%6:?? += 6*MI(v0-v1) << 8 */ | ||||
|         " mul %10,%9" "\n\t"             /* r1:r0 = 6*HI(v0-v1) */ | ||||
|         " add %7,r0" "\n\t"              /* %7:%6:?? += 6*HI(v0-v1) << 16 */ | ||||
|         " sts bezier_A+1, %6" "\n\t" | ||||
|         " sts bezier_A+2, %7" "\n\t"     /* bezier_A = %7:%6:?? = 6*(v0-v1) [35 cycles worst] */ | ||||
|         A("ldi %9,6")               /* %9 = 6 */ | ||||
|         A("mul %0,%9")              /* r1:r0 = 6*LO(v0-v1) */ | ||||
|         A("sts bezier_A, r0") | ||||
|         A("mov %6,r1") | ||||
|         A("clr %7")                 /* %7:%6:r0 = 6*LO(v0-v1) */ | ||||
|         A("mul %1,%9")              /* r1:r0 = 6*MI(v0-v1) */ | ||||
|         A("add %6,r0") | ||||
|         A("adc %7,r1")              /* %7:%6:?? += 6*MI(v0-v1) << 8 */ | ||||
|         A("mul %10,%9")             /* r1:r0 = 6*HI(v0-v1) */ | ||||
|         A("add %7,r0")              /* %7:%6:?? += 6*HI(v0-v1) << 16 */ | ||||
|         A("sts bezier_A+1, %6") | ||||
|         A("sts bezier_A+2, %7")     /* bezier_A = %7:%6:?? = 6*(v0-v1) [35 cycles worst] */ | ||||
|  | ||||
|         " ldi %9,15" "\n\t"              /* %9 = 15 */ | ||||
|         " mul %0,%9" "\n\t"              /* r1:r0 = 5*LO(v0-v1) */ | ||||
|         " sts bezier_B, r0" "\n\t" | ||||
|         " mov %6,r1" "\n\t" | ||||
|         " clr %7" "\n\t"                 /* %7:%6:?? = 5*LO(v0-v1) */ | ||||
|         " mul %1,%9" "\n\t"              /* r1:r0 = 5*MI(v0-v1) */ | ||||
|         " add %6,r0" "\n\t" | ||||
|         " adc %7,r1" "\n\t"              /* %7:%6:?? += 5*MI(v0-v1) << 8 */ | ||||
|         " mul %10,%9" "\n\t"             /* r1:r0 = 5*HI(v0-v1) */ | ||||
|         " add %7,r0" "\n\t"              /* %7:%6:?? += 5*HI(v0-v1) << 16 */ | ||||
|         " sts bezier_B+1, %6" "\n\t" | ||||
|         " sts bezier_B+2, %7" "\n\t"     /* bezier_B = %7:%6:?? = 5*(v0-v1) [50 cycles worst] */ | ||||
|         A("ldi %9,15")              /* %9 = 15 */ | ||||
|         A("mul %0,%9")              /* r1:r0 = 5*LO(v0-v1) */ | ||||
|         A("sts bezier_B, r0") | ||||
|         A("mov %6,r1") | ||||
|         A("clr %7")                 /* %7:%6:?? = 5*LO(v0-v1) */ | ||||
|         A("mul %1,%9")              /* r1:r0 = 5*MI(v0-v1) */ | ||||
|         A("add %6,r0") | ||||
|         A("adc %7,r1")              /* %7:%6:?? += 5*MI(v0-v1) << 8 */ | ||||
|         A("mul %10,%9")             /* r1:r0 = 5*HI(v0-v1) */ | ||||
|         A("add %7,r0")              /* %7:%6:?? += 5*HI(v0-v1) << 16 */ | ||||
|         A("sts bezier_B+1, %6") | ||||
|         A("sts bezier_B+2, %7")     /* bezier_B = %7:%6:?? = 5*(v0-v1) [50 cycles worst] */ | ||||
|  | ||||
|         " ldi %9,10" "\n\t"              /* %9 = 10 */ | ||||
|         " mul %0,%9" "\n\t"              /* r1:r0 = 10*LO(v0-v1) */ | ||||
|         " sts bezier_C, r0" "\n\t" | ||||
|         " mov %6,r1" "\n\t" | ||||
|         " clr %7" "\n\t"                 /* %7:%6:?? = 10*LO(v0-v1) */ | ||||
|         " mul %1,%9" "\n\t"              /* r1:r0 = 10*MI(v0-v1) */ | ||||
|         " add %6,r0" "\n\t" | ||||
|         " adc %7,r1" "\n\t"              /* %7:%6:?? += 10*MI(v0-v1) << 8 */ | ||||
|         " mul %10,%9" "\n\t"             /* r1:r0 = 10*HI(v0-v1) */ | ||||
|         " add %7,r0" "\n\t"              /* %7:%6:?? += 10*HI(v0-v1) << 16 */ | ||||
|         " sts bezier_C+1, %6" "\n\t" | ||||
|         A("ldi %9,10")              /* %9 = 10 */ | ||||
|         A("mul %0,%9")              /* r1:r0 = 10*LO(v0-v1) */ | ||||
|         A("sts bezier_C, r0") | ||||
|         A("mov %6,r1") | ||||
|         A("clr %7")                 /* %7:%6:?? = 10*LO(v0-v1) */ | ||||
|         A("mul %1,%9")              /* r1:r0 = 10*MI(v0-v1) */ | ||||
|         A("add %6,r0") | ||||
|         A("adc %7,r1")              /* %7:%6:?? += 10*MI(v0-v1) << 8 */ | ||||
|         A("mul %10,%9")             /* r1:r0 = 10*HI(v0-v1) */ | ||||
|         A("add %7,r0")              /* %7:%6:?? += 10*HI(v0-v1) << 16 */ | ||||
|         A("sts bezier_C+1, %6") | ||||
|         " sts bezier_C+2, %7"            /* bezier_C = %7:%6:?? = 10*(v0-v1) [65 cycles worst] */ | ||||
|         : "+r" (r2), | ||||
|           "+d" (r3), | ||||
| @@ -674,358 +674,358 @@ void Stepper::set_directions() { | ||||
|  | ||||
|       __asm__ __volatile( | ||||
|         /* umul24x24to16hi(t, bezier_AV, curr_step);  t: Range 0 - 1^16 = 16 bits*/ | ||||
|         " lds %9,bezier_AV" "\n\t"       /* %9 = LO(AV)*/ | ||||
|         " mul %9,%2" "\n\t"              /* r1:r0 = LO(bezier_AV)*LO(curr_step)*/ | ||||
|         " mov %7,r1" "\n\t"              /* %7 = LO(bezier_AV)*LO(curr_step) >> 8*/ | ||||
|         " clr %8" "\n\t"                 /* %8:%7  = LO(bezier_AV)*LO(curr_step) >> 8*/ | ||||
|         " lds %10,bezier_AV+1" "\n\t"    /* %10 = MI(AV)*/ | ||||
|         " mul %10,%2" "\n\t"             /* r1:r0  = MI(bezier_AV)*LO(curr_step)*/ | ||||
|         " add %7,r0" "\n\t" | ||||
|         " adc %8,r1" "\n\t"              /* %8:%7 += MI(bezier_AV)*LO(curr_step)*/ | ||||
|         " lds r1,bezier_AV+2" "\n\t"     /* r11 = HI(AV)*/ | ||||
|         " mul r1,%2" "\n\t"              /* r1:r0  = HI(bezier_AV)*LO(curr_step)*/ | ||||
|         " add %8,r0" "\n\t"              /* %8:%7 += HI(bezier_AV)*LO(curr_step) << 8*/ | ||||
|         " mul %9,%3" "\n\t"              /* r1:r0 =  LO(bezier_AV)*MI(curr_step)*/ | ||||
|         " add %7,r0" "\n\t" | ||||
|         " adc %8,r1" "\n\t"              /* %8:%7 += LO(bezier_AV)*MI(curr_step)*/ | ||||
|         " mul %10,%3" "\n\t"             /* r1:r0 =  MI(bezier_AV)*MI(curr_step)*/ | ||||
|         " add %8,r0" "\n\t"              /* %8:%7 += LO(bezier_AV)*MI(curr_step) << 8*/ | ||||
|         " mul %9,%4" "\n\t"              /* r1:r0 =  LO(bezier_AV)*HI(curr_step)*/ | ||||
|         " add %8,r0" "\n\t"              /* %8:%7 += LO(bezier_AV)*HI(curr_step) << 8*/ | ||||
|         A("lds %9,bezier_AV")       /* %9 = LO(AV)*/ | ||||
|         A("mul %9,%2")              /* r1:r0 = LO(bezier_AV)*LO(curr_step)*/ | ||||
|         A("mov %7,r1")              /* %7 = LO(bezier_AV)*LO(curr_step) >> 8*/ | ||||
|         A("clr %8")                 /* %8:%7  = LO(bezier_AV)*LO(curr_step) >> 8*/ | ||||
|         A("lds %10,bezier_AV+1")    /* %10 = MI(AV)*/ | ||||
|         A("mul %10,%2")             /* r1:r0  = MI(bezier_AV)*LO(curr_step)*/ | ||||
|         A("add %7,r0") | ||||
|         A("adc %8,r1")              /* %8:%7 += MI(bezier_AV)*LO(curr_step)*/ | ||||
|         A("lds r1,bezier_AV+2")     /* r11 = HI(AV)*/ | ||||
|         A("mul r1,%2")              /* r1:r0  = HI(bezier_AV)*LO(curr_step)*/ | ||||
|         A("add %8,r0")              /* %8:%7 += HI(bezier_AV)*LO(curr_step) << 8*/ | ||||
|         A("mul %9,%3")              /* r1:r0 =  LO(bezier_AV)*MI(curr_step)*/ | ||||
|         A("add %7,r0") | ||||
|         A("adc %8,r1")              /* %8:%7 += LO(bezier_AV)*MI(curr_step)*/ | ||||
|         A("mul %10,%3")             /* r1:r0 =  MI(bezier_AV)*MI(curr_step)*/ | ||||
|         A("add %8,r0")              /* %8:%7 += LO(bezier_AV)*MI(curr_step) << 8*/ | ||||
|         A("mul %9,%4")              /* r1:r0 =  LO(bezier_AV)*HI(curr_step)*/ | ||||
|         A("add %8,r0")              /* %8:%7 += LO(bezier_AV)*HI(curr_step) << 8*/ | ||||
|         /* %8:%7 = t*/ | ||||
|  | ||||
|         /* uint16_t f = t;*/ | ||||
|         " mov %5,%7" "\n\t"              /* %6:%5 = f*/ | ||||
|         " mov %6,%8" "\n\t" | ||||
|         A("mov %5,%7")              /* %6:%5 = f*/ | ||||
|         A("mov %6,%8") | ||||
|         /* %6:%5 = f*/ | ||||
|  | ||||
|         /* umul16x16to16hi(f, f, t); / Range 16 bits (unsigned) [17] */ | ||||
|         " mul %5,%7" "\n\t"              /* r1:r0 = LO(f) * LO(t)*/ | ||||
|         " mov %9,r1" "\n\t"              /* store MIL(LO(f) * LO(t)) in %9, we need it for rounding*/ | ||||
|         " clr %10" "\n\t"                /* %10 = 0*/ | ||||
|         " clr %11" "\n\t"                /* %11 = 0*/ | ||||
|         " mul %5,%8" "\n\t"              /* r1:r0 = LO(f) * HI(t)*/ | ||||
|         " add %9,r0" "\n\t"              /* %9 += LO(LO(f) * HI(t))*/ | ||||
|         " adc %10,r1" "\n\t"             /* %10 = HI(LO(f) * HI(t))*/ | ||||
|         " adc %11,%0" "\n\t"             /* %11 += carry*/ | ||||
|         " mul %6,%7" "\n\t"              /* r1:r0 = HI(f) * LO(t)*/ | ||||
|         " add %9,r0" "\n\t"              /* %9 += LO(HI(f) * LO(t))*/ | ||||
|         " adc %10,r1" "\n\t"             /* %10 += HI(HI(f) * LO(t)) */ | ||||
|         " adc %11,%0" "\n\t"             /* %11 += carry*/ | ||||
|         " mul %6,%8" "\n\t"              /* r1:r0 = HI(f) * HI(t)*/ | ||||
|         " add %10,r0" "\n\t"             /* %10 += LO(HI(f) * HI(t))*/ | ||||
|         " adc %11,r1" "\n\t"             /* %11 += HI(HI(f) * HI(t))*/ | ||||
|         " mov %5,%10" "\n\t"             /* %6:%5 = */ | ||||
|         " mov %6,%11" "\n\t"             /* f = %10:%11*/ | ||||
|         A("mul %5,%7")              /* r1:r0 = LO(f) * LO(t)*/ | ||||
|         A("mov %9,r1")              /* store MIL(LO(f) * LO(t)) in %9, we need it for rounding*/ | ||||
|         A("clr %10")                /* %10 = 0*/ | ||||
|         A("clr %11")                /* %11 = 0*/ | ||||
|         A("mul %5,%8")              /* r1:r0 = LO(f) * HI(t)*/ | ||||
|         A("add %9,r0")              /* %9 += LO(LO(f) * HI(t))*/ | ||||
|         A("adc %10,r1")             /* %10 = HI(LO(f) * HI(t))*/ | ||||
|         A("adc %11,%0")             /* %11 += carry*/ | ||||
|         A("mul %6,%7")              /* r1:r0 = HI(f) * LO(t)*/ | ||||
|         A("add %9,r0")              /* %9 += LO(HI(f) * LO(t))*/ | ||||
|         A("adc %10,r1")             /* %10 += HI(HI(f) * LO(t)) */ | ||||
|         A("adc %11,%0")             /* %11 += carry*/ | ||||
|         A("mul %6,%8")              /* r1:r0 = HI(f) * HI(t)*/ | ||||
|         A("add %10,r0")             /* %10 += LO(HI(f) * HI(t))*/ | ||||
|         A("adc %11,r1")             /* %11 += HI(HI(f) * HI(t))*/ | ||||
|         A("mov %5,%10")             /* %6:%5 = */ | ||||
|         A("mov %6,%11")             /* f = %10:%11*/ | ||||
|  | ||||
|         /* umul16x16to16hi(f, f, t); / Range 16 bits : f = t^3  (unsigned) [17]*/ | ||||
|         " mul %5,%7" "\n\t"              /* r1:r0 = LO(f) * LO(t)*/ | ||||
|         " mov %1,r1" "\n\t"              /* store MIL(LO(f) * LO(t)) in %1, we need it for rounding*/ | ||||
|         " clr %10" "\n\t"                /* %10 = 0*/ | ||||
|         " clr %11" "\n\t"                /* %11 = 0*/ | ||||
|         " mul %5,%8" "\n\t"              /* r1:r0 = LO(f) * HI(t)*/ | ||||
|         " add %1,r0" "\n\t"              /* %1 += LO(LO(f) * HI(t))*/ | ||||
|         " adc %10,r1" "\n\t"             /* %10 = HI(LO(f) * HI(t))*/ | ||||
|         " adc %11,%0" "\n\t"             /* %11 += carry*/ | ||||
|         " mul %6,%7" "\n\t"              /* r1:r0 = HI(f) * LO(t)*/ | ||||
|         " add %1,r0" "\n\t"              /* %1 += LO(HI(f) * LO(t))*/ | ||||
|         " adc %10,r1" "\n\t"             /* %10 += HI(HI(f) * LO(t))*/ | ||||
|         " adc %11,%0" "\n\t"             /* %11 += carry*/ | ||||
|         " mul %6,%8" "\n\t"              /* r1:r0 = HI(f) * HI(t)*/ | ||||
|         " add %10,r0" "\n\t"             /* %10 += LO(HI(f) * HI(t))*/ | ||||
|         " adc %11,r1" "\n\t"             /* %11 += HI(HI(f) * HI(t))*/ | ||||
|         " mov %5,%10" "\n\t"             /* %6:%5 =*/ | ||||
|         " mov %6,%11" "\n\t"             /* f = %10:%11*/ | ||||
|         A("mul %5,%7")              /* r1:r0 = LO(f) * LO(t)*/ | ||||
|         A("mov %1,r1")              /* store MIL(LO(f) * LO(t)) in %1, we need it for rounding*/ | ||||
|         A("clr %10")                /* %10 = 0*/ | ||||
|         A("clr %11")                /* %11 = 0*/ | ||||
|         A("mul %5,%8")              /* r1:r0 = LO(f) * HI(t)*/ | ||||
|         A("add %1,r0")              /* %1 += LO(LO(f) * HI(t))*/ | ||||
|         A("adc %10,r1")             /* %10 = HI(LO(f) * HI(t))*/ | ||||
|         A("adc %11,%0")             /* %11 += carry*/ | ||||
|         A("mul %6,%7")              /* r1:r0 = HI(f) * LO(t)*/ | ||||
|         A("add %1,r0")              /* %1 += LO(HI(f) * LO(t))*/ | ||||
|         A("adc %10,r1")             /* %10 += HI(HI(f) * LO(t))*/ | ||||
|         A("adc %11,%0")             /* %11 += carry*/ | ||||
|         A("mul %6,%8")              /* r1:r0 = HI(f) * HI(t)*/ | ||||
|         A("add %10,r0")             /* %10 += LO(HI(f) * HI(t))*/ | ||||
|         A("adc %11,r1")             /* %11 += HI(HI(f) * HI(t))*/ | ||||
|         A("mov %5,%10")             /* %6:%5 =*/ | ||||
|         A("mov %6,%11")             /* f = %10:%11*/ | ||||
|         /* [15 +17*2] = [49]*/ | ||||
|  | ||||
|         /* %4:%3:%2 will be acc from now on*/ | ||||
|  | ||||
|         /* uint24_t acc = bezier_F; / Range 20 bits (unsigned)*/ | ||||
|         " clr %9" "\n\t"                 /* "decimal place we get for free"*/ | ||||
|         " lds %2,bezier_F" "\n\t" | ||||
|         " lds %3,bezier_F+1" "\n\t" | ||||
|         " lds %4,bezier_F+2" "\n\t"      /* %4:%3:%2 = acc*/ | ||||
|         A("clr %9")                 /* "decimal place we get for free"*/ | ||||
|         A("lds %2,bezier_F") | ||||
|         A("lds %3,bezier_F+1") | ||||
|         A("lds %4,bezier_F+2")      /* %4:%3:%2 = acc*/ | ||||
|  | ||||
|         /* if (A_negative) {*/ | ||||
|         " lds r0,A_negative" "\n\t" | ||||
|         " or r0,%0" "\n\t"               /* Is flag signalling negative? */ | ||||
|         " brne 3f" "\n\t"                /* If yes, Skip next instruction if A was negative*/ | ||||
|         " rjmp 1f" "\n\t"                /* Otherwise, jump */ | ||||
|         A("lds r0,A_negative") | ||||
|         A("or r0,%0")               /* Is flag signalling negative? */ | ||||
|         A("brne 3f")                /* If yes, Skip next instruction if A was negative*/ | ||||
|         A("rjmp 1f")                /* Otherwise, jump */ | ||||
|  | ||||
|         /* uint24_t v; */ | ||||
|         /* umul16x24to24hi(v, f, bezier_C); / Range 21bits [29] */ | ||||
|         /* acc -= v; */ | ||||
|         "3:" "\n\t" | ||||
|         " lds %10, bezier_C" "\n\t"      /* %10 = LO(bezier_C)*/ | ||||
|         " mul %10,%5" "\n\t"             /* r1:r0 = LO(bezier_C) * LO(f)*/ | ||||
|         " sub %9,r1" "\n\t" | ||||
|         " sbc %2,%0" "\n\t" | ||||
|         " sbc %3,%0" "\n\t" | ||||
|         " sbc %4,%0" "\n\t"              /* %4:%3:%2:%9 -= HI(LO(bezier_C) * LO(f))*/ | ||||
|         " lds %11, bezier_C+1" "\n\t"    /* %11 = MI(bezier_C)*/ | ||||
|         " mul %11,%5" "\n\t"             /* r1:r0 = MI(bezier_C) * LO(f)*/ | ||||
|         " sub %9,r0" "\n\t" | ||||
|         " sbc %2,r1" "\n\t" | ||||
|         " sbc %3,%0" "\n\t" | ||||
|         " sbc %4,%0" "\n\t"              /* %4:%3:%2:%9 -= MI(bezier_C) * LO(f)*/ | ||||
|         " lds %1, bezier_C+2" "\n\t"     /* %1 = HI(bezier_C)*/ | ||||
|         " mul %1,%5" "\n\t"              /* r1:r0 = MI(bezier_C) * LO(f)*/ | ||||
|         " sub %2,r0" "\n\t" | ||||
|         " sbc %3,r1" "\n\t" | ||||
|         " sbc %4,%0" "\n\t"              /* %4:%3:%2:%9 -= HI(bezier_C) * LO(f) << 8*/ | ||||
|         " mul %10,%6" "\n\t"             /* r1:r0 = LO(bezier_C) * MI(f)*/ | ||||
|         " sub %9,r0" "\n\t" | ||||
|         " sbc %2,r1" "\n\t" | ||||
|         " sbc %3,%0" "\n\t" | ||||
|         " sbc %4,%0" "\n\t"              /* %4:%3:%2:%9 -= LO(bezier_C) * MI(f)*/ | ||||
|         " mul %11,%6" "\n\t"             /* r1:r0 = MI(bezier_C) * MI(f)*/ | ||||
|         " sub %2,r0" "\n\t" | ||||
|         " sbc %3,r1" "\n\t" | ||||
|         " sbc %4,%0" "\n\t"              /* %4:%3:%2:%9 -= MI(bezier_C) * MI(f) << 8*/ | ||||
|         " mul %1,%6" "\n\t"              /* r1:r0 = HI(bezier_C) * LO(f)*/ | ||||
|         " sub %3,r0" "\n\t" | ||||
|         " sbc %4,r1" "\n\t"              /* %4:%3:%2:%9 -= HI(bezier_C) * LO(f) << 16*/ | ||||
|         L("3") | ||||
|         A("lds %10, bezier_C")      /* %10 = LO(bezier_C)*/ | ||||
|         A("mul %10,%5")             /* r1:r0 = LO(bezier_C) * LO(f)*/ | ||||
|         A("sub %9,r1") | ||||
|         A("sbc %2,%0") | ||||
|         A("sbc %3,%0") | ||||
|         A("sbc %4,%0")              /* %4:%3:%2:%9 -= HI(LO(bezier_C) * LO(f))*/ | ||||
|         A("lds %11, bezier_C+1")    /* %11 = MI(bezier_C)*/ | ||||
|         A("mul %11,%5")             /* r1:r0 = MI(bezier_C) * LO(f)*/ | ||||
|         A("sub %9,r0") | ||||
|         A("sbc %2,r1") | ||||
|         A("sbc %3,%0") | ||||
|         A("sbc %4,%0")              /* %4:%3:%2:%9 -= MI(bezier_C) * LO(f)*/ | ||||
|         A("lds %1, bezier_C+2")     /* %1 = HI(bezier_C)*/ | ||||
|         A("mul %1,%5")              /* r1:r0 = MI(bezier_C) * LO(f)*/ | ||||
|         A("sub %2,r0") | ||||
|         A("sbc %3,r1") | ||||
|         A("sbc %4,%0")              /* %4:%3:%2:%9 -= HI(bezier_C) * LO(f) << 8*/ | ||||
|         A("mul %10,%6")             /* r1:r0 = LO(bezier_C) * MI(f)*/ | ||||
|         A("sub %9,r0") | ||||
|         A("sbc %2,r1") | ||||
|         A("sbc %3,%0") | ||||
|         A("sbc %4,%0")              /* %4:%3:%2:%9 -= LO(bezier_C) * MI(f)*/ | ||||
|         A("mul %11,%6")             /* r1:r0 = MI(bezier_C) * MI(f)*/ | ||||
|         A("sub %2,r0") | ||||
|         A("sbc %3,r1") | ||||
|         A("sbc %4,%0")              /* %4:%3:%2:%9 -= MI(bezier_C) * MI(f) << 8*/ | ||||
|         A("mul %1,%6")              /* r1:r0 = HI(bezier_C) * LO(f)*/ | ||||
|         A("sub %3,r0") | ||||
|         A("sbc %4,r1")              /* %4:%3:%2:%9 -= HI(bezier_C) * LO(f) << 16*/ | ||||
|  | ||||
|         /* umul16x16to16hi(f, f, t); / Range 16 bits : f = t^3  (unsigned) [17]*/ | ||||
|         " mul %5,%7" "\n\t"              /* r1:r0 = LO(f) * LO(t)*/ | ||||
|         " mov %1,r1" "\n\t"              /* store MIL(LO(f) * LO(t)) in %1, we need it for rounding*/ | ||||
|         " clr %10" "\n\t"                /* %10 = 0*/ | ||||
|         " clr %11" "\n\t"                /* %11 = 0*/ | ||||
|         " mul %5,%8" "\n\t"              /* r1:r0 = LO(f) * HI(t)*/ | ||||
|         " add %1,r0" "\n\t"              /* %1 += LO(LO(f) * HI(t))*/ | ||||
|         " adc %10,r1" "\n\t"             /* %10 = HI(LO(f) * HI(t))*/ | ||||
|         " adc %11,%0" "\n\t"             /* %11 += carry*/ | ||||
|         " mul %6,%7" "\n\t"              /* r1:r0 = HI(f) * LO(t)*/ | ||||
|         " add %1,r0" "\n\t"              /* %1 += LO(HI(f) * LO(t))*/ | ||||
|         " adc %10,r1" "\n\t"             /* %10 += HI(HI(f) * LO(t))*/ | ||||
|         " adc %11,%0" "\n\t"             /* %11 += carry*/ | ||||
|         " mul %6,%8" "\n\t"              /* r1:r0 = HI(f) * HI(t)*/ | ||||
|         " add %10,r0" "\n\t"             /* %10 += LO(HI(f) * HI(t))*/ | ||||
|         " adc %11,r1" "\n\t"             /* %11 += HI(HI(f) * HI(t))*/ | ||||
|         " mov %5,%10" "\n\t"             /* %6:%5 =*/ | ||||
|         " mov %6,%11" "\n\t"             /* f = %10:%11*/ | ||||
|         A("mul %5,%7")              /* r1:r0 = LO(f) * LO(t)*/ | ||||
|         A("mov %1,r1")              /* store MIL(LO(f) * LO(t)) in %1, we need it for rounding*/ | ||||
|         A("clr %10")                /* %10 = 0*/ | ||||
|         A("clr %11")                /* %11 = 0*/ | ||||
|         A("mul %5,%8")              /* r1:r0 = LO(f) * HI(t)*/ | ||||
|         A("add %1,r0")              /* %1 += LO(LO(f) * HI(t))*/ | ||||
|         A("adc %10,r1")             /* %10 = HI(LO(f) * HI(t))*/ | ||||
|         A("adc %11,%0")             /* %11 += carry*/ | ||||
|         A("mul %6,%7")              /* r1:r0 = HI(f) * LO(t)*/ | ||||
|         A("add %1,r0")              /* %1 += LO(HI(f) * LO(t))*/ | ||||
|         A("adc %10,r1")             /* %10 += HI(HI(f) * LO(t))*/ | ||||
|         A("adc %11,%0")             /* %11 += carry*/ | ||||
|         A("mul %6,%8")              /* r1:r0 = HI(f) * HI(t)*/ | ||||
|         A("add %10,r0")             /* %10 += LO(HI(f) * HI(t))*/ | ||||
|         A("adc %11,r1")             /* %11 += HI(HI(f) * HI(t))*/ | ||||
|         A("mov %5,%10")             /* %6:%5 =*/ | ||||
|         A("mov %6,%11")             /* f = %10:%11*/ | ||||
|  | ||||
|         /* umul16x24to24hi(v, f, bezier_B); / Range 22bits [29]*/ | ||||
|         /* acc += v; */ | ||||
|         " lds %10, bezier_B" "\n\t"      /* %10 = LO(bezier_B)*/ | ||||
|         " mul %10,%5" "\n\t"             /* r1:r0 = LO(bezier_B) * LO(f)*/ | ||||
|         " add %9,r1" "\n\t" | ||||
|         " adc %2,%0" "\n\t" | ||||
|         " adc %3,%0" "\n\t" | ||||
|         " adc %4,%0" "\n\t"              /* %4:%3:%2:%9 += HI(LO(bezier_B) * LO(f))*/ | ||||
|         " lds %11, bezier_B+1" "\n\t"    /* %11 = MI(bezier_B)*/ | ||||
|         " mul %11,%5" "\n\t"             /* r1:r0 = MI(bezier_B) * LO(f)*/ | ||||
|         " add %9,r0" "\n\t" | ||||
|         " adc %2,r1" "\n\t" | ||||
|         " adc %3,%0" "\n\t" | ||||
|         " adc %4,%0" "\n\t"              /* %4:%3:%2:%9 += MI(bezier_B) * LO(f)*/ | ||||
|         " lds %1, bezier_B+2" "\n\t"     /* %1 = HI(bezier_B)*/ | ||||
|         " mul %1,%5" "\n\t"              /* r1:r0 = MI(bezier_B) * LO(f)*/ | ||||
|         " add %2,r0" "\n\t" | ||||
|         " adc %3,r1" "\n\t" | ||||
|         " adc %4,%0" "\n\t"              /* %4:%3:%2:%9 += HI(bezier_B) * LO(f) << 8*/ | ||||
|         " mul %10,%6" "\n\t"             /* r1:r0 = LO(bezier_B) * MI(f)*/ | ||||
|         " add %9,r0" "\n\t" | ||||
|         " adc %2,r1" "\n\t" | ||||
|         " adc %3,%0" "\n\t" | ||||
|         " adc %4,%0" "\n\t"              /* %4:%3:%2:%9 += LO(bezier_B) * MI(f)*/ | ||||
|         " mul %11,%6" "\n\t"             /* r1:r0 = MI(bezier_B) * MI(f)*/ | ||||
|         " add %2,r0" "\n\t" | ||||
|         " adc %3,r1" "\n\t" | ||||
|         " adc %4,%0" "\n\t"              /* %4:%3:%2:%9 += MI(bezier_B) * MI(f) << 8*/ | ||||
|         " mul %1,%6" "\n\t"              /* r1:r0 = HI(bezier_B) * LO(f)*/ | ||||
|         " add %3,r0" "\n\t" | ||||
|         " adc %4,r1" "\n\t"              /* %4:%3:%2:%9 += HI(bezier_B) * LO(f) << 16*/ | ||||
|         A("lds %10, bezier_B")      /* %10 = LO(bezier_B)*/ | ||||
|         A("mul %10,%5")             /* r1:r0 = LO(bezier_B) * LO(f)*/ | ||||
|         A("add %9,r1") | ||||
|         A("adc %2,%0") | ||||
|         A("adc %3,%0") | ||||
|         A("adc %4,%0")              /* %4:%3:%2:%9 += HI(LO(bezier_B) * LO(f))*/ | ||||
|         A("lds %11, bezier_B+1")    /* %11 = MI(bezier_B)*/ | ||||
|         A("mul %11,%5")             /* r1:r0 = MI(bezier_B) * LO(f)*/ | ||||
|         A("add %9,r0") | ||||
|         A("adc %2,r1") | ||||
|         A("adc %3,%0") | ||||
|         A("adc %4,%0")              /* %4:%3:%2:%9 += MI(bezier_B) * LO(f)*/ | ||||
|         A("lds %1, bezier_B+2")     /* %1 = HI(bezier_B)*/ | ||||
|         A("mul %1,%5")              /* r1:r0 = MI(bezier_B) * LO(f)*/ | ||||
|         A("add %2,r0") | ||||
|         A("adc %3,r1") | ||||
|         A("adc %4,%0")              /* %4:%3:%2:%9 += HI(bezier_B) * LO(f) << 8*/ | ||||
|         A("mul %10,%6")             /* r1:r0 = LO(bezier_B) * MI(f)*/ | ||||
|         A("add %9,r0") | ||||
|         A("adc %2,r1") | ||||
|         A("adc %3,%0") | ||||
|         A("adc %4,%0")              /* %4:%3:%2:%9 += LO(bezier_B) * MI(f)*/ | ||||
|         A("mul %11,%6")             /* r1:r0 = MI(bezier_B) * MI(f)*/ | ||||
|         A("add %2,r0") | ||||
|         A("adc %3,r1") | ||||
|         A("adc %4,%0")              /* %4:%3:%2:%9 += MI(bezier_B) * MI(f) << 8*/ | ||||
|         A("mul %1,%6")              /* r1:r0 = HI(bezier_B) * LO(f)*/ | ||||
|         A("add %3,r0") | ||||
|         A("adc %4,r1")              /* %4:%3:%2:%9 += HI(bezier_B) * LO(f) << 16*/ | ||||
|  | ||||
|         /* umul16x16to16hi(f, f, t); / Range 16 bits : f = t^5  (unsigned) [17]*/ | ||||
|         " mul %5,%7" "\n\t"              /* r1:r0 = LO(f) * LO(t)*/ | ||||
|         " mov %1,r1" "\n\t"              /* store MIL(LO(f) * LO(t)) in %1, we need it for rounding*/ | ||||
|         " clr %10" "\n\t"                /* %10 = 0*/ | ||||
|         " clr %11" "\n\t"                /* %11 = 0*/ | ||||
|         " mul %5,%8" "\n\t"              /* r1:r0 = LO(f) * HI(t)*/ | ||||
|         " add %1,r0" "\n\t"              /* %1 += LO(LO(f) * HI(t))*/ | ||||
|         " adc %10,r1" "\n\t"             /* %10 = HI(LO(f) * HI(t))*/ | ||||
|         " adc %11,%0" "\n\t"             /* %11 += carry*/ | ||||
|         " mul %6,%7" "\n\t"              /* r1:r0 = HI(f) * LO(t)*/ | ||||
|         " add %1,r0" "\n\t"              /* %1 += LO(HI(f) * LO(t))*/ | ||||
|         " adc %10,r1" "\n\t"             /* %10 += HI(HI(f) * LO(t))*/ | ||||
|         " adc %11,%0" "\n\t"             /* %11 += carry*/ | ||||
|         " mul %6,%8" "\n\t"              /* r1:r0 = HI(f) * HI(t)*/ | ||||
|         " add %10,r0" "\n\t"             /* %10 += LO(HI(f) * HI(t))*/ | ||||
|         " adc %11,r1" "\n\t"             /* %11 += HI(HI(f) * HI(t))*/ | ||||
|         " mov %5,%10" "\n\t"             /* %6:%5 =*/ | ||||
|         " mov %6,%11" "\n\t"             /* f = %10:%11*/ | ||||
|         A("mul %5,%7")              /* r1:r0 = LO(f) * LO(t)*/ | ||||
|         A("mov %1,r1")              /* store MIL(LO(f) * LO(t)) in %1, we need it for rounding*/ | ||||
|         A("clr %10")                /* %10 = 0*/ | ||||
|         A("clr %11")                /* %11 = 0*/ | ||||
|         A("mul %5,%8")              /* r1:r0 = LO(f) * HI(t)*/ | ||||
|         A("add %1,r0")              /* %1 += LO(LO(f) * HI(t))*/ | ||||
|         A("adc %10,r1")             /* %10 = HI(LO(f) * HI(t))*/ | ||||
|         A("adc %11,%0")             /* %11 += carry*/ | ||||
|         A("mul %6,%7")              /* r1:r0 = HI(f) * LO(t)*/ | ||||
|         A("add %1,r0")              /* %1 += LO(HI(f) * LO(t))*/ | ||||
|         A("adc %10,r1")             /* %10 += HI(HI(f) * LO(t))*/ | ||||
|         A("adc %11,%0")             /* %11 += carry*/ | ||||
|         A("mul %6,%8")              /* r1:r0 = HI(f) * HI(t)*/ | ||||
|         A("add %10,r0")             /* %10 += LO(HI(f) * HI(t))*/ | ||||
|         A("adc %11,r1")             /* %11 += HI(HI(f) * HI(t))*/ | ||||
|         A("mov %5,%10")             /* %6:%5 =*/ | ||||
|         A("mov %6,%11")             /* f = %10:%11*/ | ||||
|  | ||||
|         /* umul16x24to24hi(v, f, bezier_A); / Range 21bits [29]*/ | ||||
|         /* acc -= v; */ | ||||
|         " lds %10, bezier_A" "\n\t"      /* %10 = LO(bezier_A)*/ | ||||
|         " mul %10,%5" "\n\t"             /* r1:r0 = LO(bezier_A) * LO(f)*/ | ||||
|         " sub %9,r1" "\n\t" | ||||
|         " sbc %2,%0" "\n\t" | ||||
|         " sbc %3,%0" "\n\t" | ||||
|         " sbc %4,%0" "\n\t"              /* %4:%3:%2:%9 -= HI(LO(bezier_A) * LO(f))*/ | ||||
|         " lds %11, bezier_A+1" "\n\t"    /* %11 = MI(bezier_A)*/ | ||||
|         " mul %11,%5" "\n\t"             /* r1:r0 = MI(bezier_A) * LO(f)*/ | ||||
|         " sub %9,r0" "\n\t" | ||||
|         " sbc %2,r1" "\n\t" | ||||
|         " sbc %3,%0" "\n\t" | ||||
|         " sbc %4,%0" "\n\t"              /* %4:%3:%2:%9 -= MI(bezier_A) * LO(f)*/ | ||||
|         " lds %1, bezier_A+2" "\n\t"     /* %1 = HI(bezier_A)*/ | ||||
|         " mul %1,%5" "\n\t"              /* r1:r0 = MI(bezier_A) * LO(f)*/ | ||||
|         " sub %2,r0" "\n\t" | ||||
|         " sbc %3,r1" "\n\t" | ||||
|         " sbc %4,%0" "\n\t"              /* %4:%3:%2:%9 -= HI(bezier_A) * LO(f) << 8*/ | ||||
|         " mul %10,%6" "\n\t"             /* r1:r0 = LO(bezier_A) * MI(f)*/ | ||||
|         " sub %9,r0" "\n\t" | ||||
|         " sbc %2,r1" "\n\t" | ||||
|         " sbc %3,%0" "\n\t" | ||||
|         " sbc %4,%0" "\n\t"              /* %4:%3:%2:%9 -= LO(bezier_A) * MI(f)*/ | ||||
|         " mul %11,%6" "\n\t"             /* r1:r0 = MI(bezier_A) * MI(f)*/ | ||||
|         " sub %2,r0" "\n\t" | ||||
|         " sbc %3,r1" "\n\t" | ||||
|         " sbc %4,%0" "\n\t"              /* %4:%3:%2:%9 -= MI(bezier_A) * MI(f) << 8*/ | ||||
|         " mul %1,%6" "\n\t"              /* r1:r0 = HI(bezier_A) * LO(f)*/ | ||||
|         " sub %3,r0" "\n\t" | ||||
|         " sbc %4,r1" "\n\t"              /* %4:%3:%2:%9 -= HI(bezier_A) * LO(f) << 16*/ | ||||
|         " jmp 2f" "\n\t"                 /* Done!*/ | ||||
|         A("lds %10, bezier_A")      /* %10 = LO(bezier_A)*/ | ||||
|         A("mul %10,%5")             /* r1:r0 = LO(bezier_A) * LO(f)*/ | ||||
|         A("sub %9,r1") | ||||
|         A("sbc %2,%0") | ||||
|         A("sbc %3,%0") | ||||
|         A("sbc %4,%0")              /* %4:%3:%2:%9 -= HI(LO(bezier_A) * LO(f))*/ | ||||
|         A("lds %11, bezier_A+1")    /* %11 = MI(bezier_A)*/ | ||||
|         A("mul %11,%5")             /* r1:r0 = MI(bezier_A) * LO(f)*/ | ||||
|         A("sub %9,r0") | ||||
|         A("sbc %2,r1") | ||||
|         A("sbc %3,%0") | ||||
|         A("sbc %4,%0")              /* %4:%3:%2:%9 -= MI(bezier_A) * LO(f)*/ | ||||
|         A("lds %1, bezier_A+2")     /* %1 = HI(bezier_A)*/ | ||||
|         A("mul %1,%5")              /* r1:r0 = MI(bezier_A) * LO(f)*/ | ||||
|         A("sub %2,r0") | ||||
|         A("sbc %3,r1") | ||||
|         A("sbc %4,%0")              /* %4:%3:%2:%9 -= HI(bezier_A) * LO(f) << 8*/ | ||||
|         A("mul %10,%6")             /* r1:r0 = LO(bezier_A) * MI(f)*/ | ||||
|         A("sub %9,r0") | ||||
|         A("sbc %2,r1") | ||||
|         A("sbc %3,%0") | ||||
|         A("sbc %4,%0")              /* %4:%3:%2:%9 -= LO(bezier_A) * MI(f)*/ | ||||
|         A("mul %11,%6")             /* r1:r0 = MI(bezier_A) * MI(f)*/ | ||||
|         A("sub %2,r0") | ||||
|         A("sbc %3,r1") | ||||
|         A("sbc %4,%0")              /* %4:%3:%2:%9 -= MI(bezier_A) * MI(f) << 8*/ | ||||
|         A("mul %1,%6")              /* r1:r0 = HI(bezier_A) * LO(f)*/ | ||||
|         A("sub %3,r0") | ||||
|         A("sbc %4,r1")              /* %4:%3:%2:%9 -= HI(bezier_A) * LO(f) << 16*/ | ||||
|         A("jmp 2f")                 /* Done!*/ | ||||
|  | ||||
|         "1:" "\n\t" | ||||
|         L("1") | ||||
|  | ||||
|         /* uint24_t v; */ | ||||
|         /* umul16x24to24hi(v, f, bezier_C); / Range 21bits [29]*/ | ||||
|         /* acc += v; */ | ||||
|         " lds %10, bezier_C" "\n\t"      /* %10 = LO(bezier_C)*/ | ||||
|         " mul %10,%5" "\n\t"             /* r1:r0 = LO(bezier_C) * LO(f)*/ | ||||
|         " add %9,r1" "\n\t" | ||||
|         " adc %2,%0" "\n\t" | ||||
|         " adc %3,%0" "\n\t" | ||||
|         " adc %4,%0" "\n\t"              /* %4:%3:%2:%9 += HI(LO(bezier_C) * LO(f))*/ | ||||
|         " lds %11, bezier_C+1" "\n\t"    /* %11 = MI(bezier_C)*/ | ||||
|         " mul %11,%5" "\n\t"             /* r1:r0 = MI(bezier_C) * LO(f)*/ | ||||
|         " add %9,r0" "\n\t" | ||||
|         " adc %2,r1" "\n\t" | ||||
|         " adc %3,%0" "\n\t" | ||||
|         " adc %4,%0" "\n\t"              /* %4:%3:%2:%9 += MI(bezier_C) * LO(f)*/ | ||||
|         " lds %1, bezier_C+2" "\n\t"     /* %1 = HI(bezier_C)*/ | ||||
|         " mul %1,%5" "\n\t"              /* r1:r0 = MI(bezier_C) * LO(f)*/ | ||||
|         " add %2,r0" "\n\t" | ||||
|         " adc %3,r1" "\n\t" | ||||
|         " adc %4,%0" "\n\t"              /* %4:%3:%2:%9 += HI(bezier_C) * LO(f) << 8*/ | ||||
|         " mul %10,%6" "\n\t"             /* r1:r0 = LO(bezier_C) * MI(f)*/ | ||||
|         " add %9,r0" "\n\t" | ||||
|         " adc %2,r1" "\n\t" | ||||
|         " adc %3,%0" "\n\t" | ||||
|         " adc %4,%0" "\n\t"              /* %4:%3:%2:%9 += LO(bezier_C) * MI(f)*/ | ||||
|         " mul %11,%6" "\n\t"             /* r1:r0 = MI(bezier_C) * MI(f)*/ | ||||
|         " add %2,r0" "\n\t" | ||||
|         " adc %3,r1" "\n\t" | ||||
|         " adc %4,%0" "\n\t"              /* %4:%3:%2:%9 += MI(bezier_C) * MI(f) << 8*/ | ||||
|         " mul %1,%6" "\n\t"              /* r1:r0 = HI(bezier_C) * LO(f)*/ | ||||
|         " add %3,r0" "\n\t" | ||||
|         " adc %4,r1" "\n\t"              /* %4:%3:%2:%9 += HI(bezier_C) * LO(f) << 16*/ | ||||
|         A("lds %10, bezier_C")      /* %10 = LO(bezier_C)*/ | ||||
|         A("mul %10,%5")             /* r1:r0 = LO(bezier_C) * LO(f)*/ | ||||
|         A("add %9,r1") | ||||
|         A("adc %2,%0") | ||||
|         A("adc %3,%0") | ||||
|         A("adc %4,%0")              /* %4:%3:%2:%9 += HI(LO(bezier_C) * LO(f))*/ | ||||
|         A("lds %11, bezier_C+1")    /* %11 = MI(bezier_C)*/ | ||||
|         A("mul %11,%5")             /* r1:r0 = MI(bezier_C) * LO(f)*/ | ||||
|         A("add %9,r0") | ||||
|         A("adc %2,r1") | ||||
|         A("adc %3,%0") | ||||
|         A("adc %4,%0")              /* %4:%3:%2:%9 += MI(bezier_C) * LO(f)*/ | ||||
|         A("lds %1, bezier_C+2")     /* %1 = HI(bezier_C)*/ | ||||
|         A("mul %1,%5")              /* r1:r0 = MI(bezier_C) * LO(f)*/ | ||||
|         A("add %2,r0") | ||||
|         A("adc %3,r1") | ||||
|         A("adc %4,%0")              /* %4:%3:%2:%9 += HI(bezier_C) * LO(f) << 8*/ | ||||
|         A("mul %10,%6")             /* r1:r0 = LO(bezier_C) * MI(f)*/ | ||||
|         A("add %9,r0") | ||||
|         A("adc %2,r1") | ||||
|         A("adc %3,%0") | ||||
|         A("adc %4,%0")              /* %4:%3:%2:%9 += LO(bezier_C) * MI(f)*/ | ||||
|         A("mul %11,%6")             /* r1:r0 = MI(bezier_C) * MI(f)*/ | ||||
|         A("add %2,r0") | ||||
|         A("adc %3,r1") | ||||
|         A("adc %4,%0")              /* %4:%3:%2:%9 += MI(bezier_C) * MI(f) << 8*/ | ||||
|         A("mul %1,%6")              /* r1:r0 = HI(bezier_C) * LO(f)*/ | ||||
|         A("add %3,r0") | ||||
|         A("adc %4,r1")              /* %4:%3:%2:%9 += HI(bezier_C) * LO(f) << 16*/ | ||||
|  | ||||
|         /* umul16x16to16hi(f, f, t); / Range 16 bits : f = t^3  (unsigned) [17]*/ | ||||
|         " mul %5,%7" "\n\t"              /* r1:r0 = LO(f) * LO(t)*/ | ||||
|         " mov %1,r1" "\n\t"              /* store MIL(LO(f) * LO(t)) in %1, we need it for rounding*/ | ||||
|         " clr %10" "\n\t"                /* %10 = 0*/ | ||||
|         " clr %11" "\n\t"                /* %11 = 0*/ | ||||
|         " mul %5,%8" "\n\t"              /* r1:r0 = LO(f) * HI(t)*/ | ||||
|         " add %1,r0" "\n\t"              /* %1 += LO(LO(f) * HI(t))*/ | ||||
|         " adc %10,r1" "\n\t"             /* %10 = HI(LO(f) * HI(t))*/ | ||||
|         " adc %11,%0" "\n\t"             /* %11 += carry*/ | ||||
|         " mul %6,%7" "\n\t"              /* r1:r0 = HI(f) * LO(t)*/ | ||||
|         " add %1,r0" "\n\t"              /* %1 += LO(HI(f) * LO(t))*/ | ||||
|         " adc %10,r1" "\n\t"             /* %10 += HI(HI(f) * LO(t))*/ | ||||
|         " adc %11,%0" "\n\t"             /* %11 += carry*/ | ||||
|         " mul %6,%8" "\n\t"              /* r1:r0 = HI(f) * HI(t)*/ | ||||
|         " add %10,r0" "\n\t"             /* %10 += LO(HI(f) * HI(t))*/ | ||||
|         " adc %11,r1" "\n\t"             /* %11 += HI(HI(f) * HI(t))*/ | ||||
|         " mov %5,%10" "\n\t"             /* %6:%5 =*/ | ||||
|         " mov %6,%11" "\n\t"             /* f = %10:%11*/ | ||||
|         A("mul %5,%7")              /* r1:r0 = LO(f) * LO(t)*/ | ||||
|         A("mov %1,r1")              /* store MIL(LO(f) * LO(t)) in %1, we need it for rounding*/ | ||||
|         A("clr %10")                /* %10 = 0*/ | ||||
|         A("clr %11")                /* %11 = 0*/ | ||||
|         A("mul %5,%8")              /* r1:r0 = LO(f) * HI(t)*/ | ||||
|         A("add %1,r0")              /* %1 += LO(LO(f) * HI(t))*/ | ||||
|         A("adc %10,r1")             /* %10 = HI(LO(f) * HI(t))*/ | ||||
|         A("adc %11,%0")             /* %11 += carry*/ | ||||
|         A("mul %6,%7")              /* r1:r0 = HI(f) * LO(t)*/ | ||||
|         A("add %1,r0")              /* %1 += LO(HI(f) * LO(t))*/ | ||||
|         A("adc %10,r1")             /* %10 += HI(HI(f) * LO(t))*/ | ||||
|         A("adc %11,%0")             /* %11 += carry*/ | ||||
|         A("mul %6,%8")              /* r1:r0 = HI(f) * HI(t)*/ | ||||
|         A("add %10,r0")             /* %10 += LO(HI(f) * HI(t))*/ | ||||
|         A("adc %11,r1")             /* %11 += HI(HI(f) * HI(t))*/ | ||||
|         A("mov %5,%10")             /* %6:%5 =*/ | ||||
|         A("mov %6,%11")             /* f = %10:%11*/ | ||||
|  | ||||
|         /* umul16x24to24hi(v, f, bezier_B); / Range 22bits [29]*/ | ||||
|         /* acc -= v;*/ | ||||
|         " lds %10, bezier_B" "\n\t"      /* %10 = LO(bezier_B)*/ | ||||
|         " mul %10,%5" "\n\t"             /* r1:r0 = LO(bezier_B) * LO(f)*/ | ||||
|         " sub %9,r1" "\n\t" | ||||
|         " sbc %2,%0" "\n\t" | ||||
|         " sbc %3,%0" "\n\t" | ||||
|         " sbc %4,%0" "\n\t"              /* %4:%3:%2:%9 -= HI(LO(bezier_B) * LO(f))*/ | ||||
|         " lds %11, bezier_B+1" "\n\t"    /* %11 = MI(bezier_B)*/ | ||||
|         " mul %11,%5" "\n\t"             /* r1:r0 = MI(bezier_B) * LO(f)*/ | ||||
|         " sub %9,r0" "\n\t" | ||||
|         " sbc %2,r1" "\n\t" | ||||
|         " sbc %3,%0" "\n\t" | ||||
|         " sbc %4,%0" "\n\t"              /* %4:%3:%2:%9 -= MI(bezier_B) * LO(f)*/ | ||||
|         " lds %1, bezier_B+2" "\n\t"     /* %1 = HI(bezier_B)*/ | ||||
|         " mul %1,%5" "\n\t"              /* r1:r0 = MI(bezier_B) * LO(f)*/ | ||||
|         " sub %2,r0" "\n\t" | ||||
|         " sbc %3,r1" "\n\t" | ||||
|         " sbc %4,%0" "\n\t"              /* %4:%3:%2:%9 -= HI(bezier_B) * LO(f) << 8*/ | ||||
|         " mul %10,%6" "\n\t"             /* r1:r0 = LO(bezier_B) * MI(f)*/ | ||||
|         " sub %9,r0" "\n\t" | ||||
|         " sbc %2,r1" "\n\t" | ||||
|         " sbc %3,%0" "\n\t" | ||||
|         " sbc %4,%0" "\n\t"              /* %4:%3:%2:%9 -= LO(bezier_B) * MI(f)*/ | ||||
|         " mul %11,%6" "\n\t"             /* r1:r0 = MI(bezier_B) * MI(f)*/ | ||||
|         " sub %2,r0" "\n\t" | ||||
|         " sbc %3,r1" "\n\t" | ||||
|         " sbc %4,%0" "\n\t"              /* %4:%3:%2:%9 -= MI(bezier_B) * MI(f) << 8*/ | ||||
|         " mul %1,%6" "\n\t"              /* r1:r0 = HI(bezier_B) * LO(f)*/ | ||||
|         " sub %3,r0" "\n\t" | ||||
|         " sbc %4,r1" "\n\t"              /* %4:%3:%2:%9 -= HI(bezier_B) * LO(f) << 16*/ | ||||
|         A("lds %10, bezier_B")      /* %10 = LO(bezier_B)*/ | ||||
|         A("mul %10,%5")             /* r1:r0 = LO(bezier_B) * LO(f)*/ | ||||
|         A("sub %9,r1") | ||||
|         A("sbc %2,%0") | ||||
|         A("sbc %3,%0") | ||||
|         A("sbc %4,%0")              /* %4:%3:%2:%9 -= HI(LO(bezier_B) * LO(f))*/ | ||||
|         A("lds %11, bezier_B+1")    /* %11 = MI(bezier_B)*/ | ||||
|         A("mul %11,%5")             /* r1:r0 = MI(bezier_B) * LO(f)*/ | ||||
|         A("sub %9,r0") | ||||
|         A("sbc %2,r1") | ||||
|         A("sbc %3,%0") | ||||
|         A("sbc %4,%0")              /* %4:%3:%2:%9 -= MI(bezier_B) * LO(f)*/ | ||||
|         A("lds %1, bezier_B+2")     /* %1 = HI(bezier_B)*/ | ||||
|         A("mul %1,%5")              /* r1:r0 = MI(bezier_B) * LO(f)*/ | ||||
|         A("sub %2,r0") | ||||
|         A("sbc %3,r1") | ||||
|         A("sbc %4,%0")              /* %4:%3:%2:%9 -= HI(bezier_B) * LO(f) << 8*/ | ||||
|         A("mul %10,%6")             /* r1:r0 = LO(bezier_B) * MI(f)*/ | ||||
|         A("sub %9,r0") | ||||
|         A("sbc %2,r1") | ||||
|         A("sbc %3,%0") | ||||
|         A("sbc %4,%0")              /* %4:%3:%2:%9 -= LO(bezier_B) * MI(f)*/ | ||||
|         A("mul %11,%6")             /* r1:r0 = MI(bezier_B) * MI(f)*/ | ||||
|         A("sub %2,r0") | ||||
|         A("sbc %3,r1") | ||||
|         A("sbc %4,%0")              /* %4:%3:%2:%9 -= MI(bezier_B) * MI(f) << 8*/ | ||||
|         A("mul %1,%6")              /* r1:r0 = HI(bezier_B) * LO(f)*/ | ||||
|         A("sub %3,r0") | ||||
|         A("sbc %4,r1")              /* %4:%3:%2:%9 -= HI(bezier_B) * LO(f) << 16*/ | ||||
|  | ||||
|         /* umul16x16to16hi(f, f, t); / Range 16 bits : f = t^5  (unsigned) [17]*/ | ||||
|         " mul %5,%7" "\n\t"              /* r1:r0 = LO(f) * LO(t)*/ | ||||
|         " mov %1,r1" "\n\t"              /* store MIL(LO(f) * LO(t)) in %1, we need it for rounding*/ | ||||
|         " clr %10" "\n\t"                /* %10 = 0*/ | ||||
|         " clr %11" "\n\t"                /* %11 = 0*/ | ||||
|         " mul %5,%8" "\n\t"              /* r1:r0 = LO(f) * HI(t)*/ | ||||
|         " add %1,r0" "\n\t"              /* %1 += LO(LO(f) * HI(t))*/ | ||||
|         " adc %10,r1" "\n\t"             /* %10 = HI(LO(f) * HI(t))*/ | ||||
|         " adc %11,%0" "\n\t"             /* %11 += carry*/ | ||||
|         " mul %6,%7" "\n\t"              /* r1:r0 = HI(f) * LO(t)*/ | ||||
|         " add %1,r0" "\n\t"              /* %1 += LO(HI(f) * LO(t))*/ | ||||
|         " adc %10,r1" "\n\t"             /* %10 += HI(HI(f) * LO(t))*/ | ||||
|         " adc %11,%0" "\n\t"             /* %11 += carry*/ | ||||
|         " mul %6,%8" "\n\t"              /* r1:r0 = HI(f) * HI(t)*/ | ||||
|         " add %10,r0" "\n\t"             /* %10 += LO(HI(f) * HI(t))*/ | ||||
|         " adc %11,r1" "\n\t"             /* %11 += HI(HI(f) * HI(t))*/ | ||||
|         " mov %5,%10" "\n\t"             /* %6:%5 =*/ | ||||
|         " mov %6,%11" "\n\t"             /* f = %10:%11*/ | ||||
|         A("mul %5,%7")              /* r1:r0 = LO(f) * LO(t)*/ | ||||
|         A("mov %1,r1")              /* store MIL(LO(f) * LO(t)) in %1, we need it for rounding*/ | ||||
|         A("clr %10")                /* %10 = 0*/ | ||||
|         A("clr %11")                /* %11 = 0*/ | ||||
|         A("mul %5,%8")              /* r1:r0 = LO(f) * HI(t)*/ | ||||
|         A("add %1,r0")              /* %1 += LO(LO(f) * HI(t))*/ | ||||
|         A("adc %10,r1")             /* %10 = HI(LO(f) * HI(t))*/ | ||||
|         A("adc %11,%0")             /* %11 += carry*/ | ||||
|         A("mul %6,%7")              /* r1:r0 = HI(f) * LO(t)*/ | ||||
|         A("add %1,r0")              /* %1 += LO(HI(f) * LO(t))*/ | ||||
|         A("adc %10,r1")             /* %10 += HI(HI(f) * LO(t))*/ | ||||
|         A("adc %11,%0")             /* %11 += carry*/ | ||||
|         A("mul %6,%8")              /* r1:r0 = HI(f) * HI(t)*/ | ||||
|         A("add %10,r0")             /* %10 += LO(HI(f) * HI(t))*/ | ||||
|         A("adc %11,r1")             /* %11 += HI(HI(f) * HI(t))*/ | ||||
|         A("mov %5,%10")             /* %6:%5 =*/ | ||||
|         A("mov %6,%11")             /* f = %10:%11*/ | ||||
|  | ||||
|         /* umul16x24to24hi(v, f, bezier_A); / Range 21bits [29]*/ | ||||
|         /* acc += v; */ | ||||
|         " lds %10, bezier_A" "\n\t"      /* %10 = LO(bezier_A)*/ | ||||
|         " mul %10,%5" "\n\t"             /* r1:r0 = LO(bezier_A) * LO(f)*/ | ||||
|         " add %9,r1" "\n\t" | ||||
|         " adc %2,%0" "\n\t" | ||||
|         " adc %3,%0" "\n\t" | ||||
|         " adc %4,%0" "\n\t"              /* %4:%3:%2:%9 += HI(LO(bezier_A) * LO(f))*/ | ||||
|         " lds %11, bezier_A+1" "\n\t"    /* %11 = MI(bezier_A)*/ | ||||
|         " mul %11,%5" "\n\t"             /* r1:r0 = MI(bezier_A) * LO(f)*/ | ||||
|         " add %9,r0" "\n\t" | ||||
|         " adc %2,r1" "\n\t" | ||||
|         " adc %3,%0" "\n\t" | ||||
|         " adc %4,%0" "\n\t"              /* %4:%3:%2:%9 += MI(bezier_A) * LO(f)*/ | ||||
|         " lds %1, bezier_A+2" "\n\t"     /* %1 = HI(bezier_A)*/ | ||||
|         " mul %1,%5" "\n\t"              /* r1:r0 = MI(bezier_A) * LO(f)*/ | ||||
|         " add %2,r0" "\n\t" | ||||
|         " adc %3,r1" "\n\t" | ||||
|         " adc %4,%0" "\n\t"              /* %4:%3:%2:%9 += HI(bezier_A) * LO(f) << 8*/ | ||||
|         " mul %10,%6" "\n\t"             /* r1:r0 = LO(bezier_A) * MI(f)*/ | ||||
|         " add %9,r0" "\n\t" | ||||
|         " adc %2,r1" "\n\t" | ||||
|         " adc %3,%0" "\n\t" | ||||
|         " adc %4,%0" "\n\t"              /* %4:%3:%2:%9 += LO(bezier_A) * MI(f)*/ | ||||
|         " mul %11,%6" "\n\t"             /* r1:r0 = MI(bezier_A) * MI(f)*/ | ||||
|         " add %2,r0" "\n\t" | ||||
|         " adc %3,r1" "\n\t" | ||||
|         " adc %4,%0" "\n\t"              /* %4:%3:%2:%9 += MI(bezier_A) * MI(f) << 8*/ | ||||
|         " mul %1,%6" "\n\t"              /* r1:r0 = HI(bezier_A) * LO(f)*/ | ||||
|         " add %3,r0" "\n\t" | ||||
|         " adc %4,r1" "\n\t"              /* %4:%3:%2:%9 += HI(bezier_A) * LO(f) << 16*/ | ||||
|         "2:" "\n\t" | ||||
|         A("lds %10, bezier_A")      /* %10 = LO(bezier_A)*/ | ||||
|         A("mul %10,%5")             /* r1:r0 = LO(bezier_A) * LO(f)*/ | ||||
|         A("add %9,r1") | ||||
|         A("adc %2,%0") | ||||
|         A("adc %3,%0") | ||||
|         A("adc %4,%0")              /* %4:%3:%2:%9 += HI(LO(bezier_A) * LO(f))*/ | ||||
|         A("lds %11, bezier_A+1")    /* %11 = MI(bezier_A)*/ | ||||
|         A("mul %11,%5")             /* r1:r0 = MI(bezier_A) * LO(f)*/ | ||||
|         A("add %9,r0") | ||||
|         A("adc %2,r1") | ||||
|         A("adc %3,%0") | ||||
|         A("adc %4,%0")              /* %4:%3:%2:%9 += MI(bezier_A) * LO(f)*/ | ||||
|         A("lds %1, bezier_A+2")     /* %1 = HI(bezier_A)*/ | ||||
|         A("mul %1,%5")              /* r1:r0 = MI(bezier_A) * LO(f)*/ | ||||
|         A("add %2,r0") | ||||
|         A("adc %3,r1") | ||||
|         A("adc %4,%0")              /* %4:%3:%2:%9 += HI(bezier_A) * LO(f) << 8*/ | ||||
|         A("mul %10,%6")             /* r1:r0 = LO(bezier_A) * MI(f)*/ | ||||
|         A("add %9,r0") | ||||
|         A("adc %2,r1") | ||||
|         A("adc %3,%0") | ||||
|         A("adc %4,%0")              /* %4:%3:%2:%9 += LO(bezier_A) * MI(f)*/ | ||||
|         A("mul %11,%6")             /* r1:r0 = MI(bezier_A) * MI(f)*/ | ||||
|         A("add %2,r0") | ||||
|         A("adc %3,r1") | ||||
|         A("adc %4,%0")              /* %4:%3:%2:%9 += MI(bezier_A) * MI(f) << 8*/ | ||||
|         A("mul %1,%6")              /* r1:r0 = HI(bezier_A) * LO(f)*/ | ||||
|         A("add %3,r0") | ||||
|         A("adc %4,r1")              /* %4:%3:%2:%9 += HI(bezier_A) * LO(f) << 16*/ | ||||
|         L("2") | ||||
|         " clr __zero_reg__"              /* C runtime expects r1 = __zero_reg__ = 0 */ | ||||
|         : "+r"(r0), | ||||
|           "+r"(r1), | ||||
| @@ -1071,20 +1071,20 @@ void Stepper::set_directions() { | ||||
|         register int32_t C = bezier_C; | ||||
|  | ||||
|          __asm__ __volatile__( | ||||
|           ".syntax unified"                   "\n\t"  // is to prevent CM0,CM1 non-unified syntax | ||||
|           " lsrs  %[ahi],%[alo],#1"           "\n\t"  // a  = F << 31      1 cycles | ||||
|           " lsls  %[alo],%[alo],#31"          "\n\t"  //                   1 cycles | ||||
|           " umull %[flo],%[fhi],%[fhi],%[t]"  "\n\t"  // f *= t            5 cycles [fhi:flo=64bits] | ||||
|           " umull %[flo],%[fhi],%[fhi],%[t]"  "\n\t"  // f>>=32; f*=t      5 cycles [fhi:flo=64bits] | ||||
|           " lsrs  %[flo],%[fhi],#1"           "\n\t"  //                   1 cycles [31bits] | ||||
|           " smlal %[alo],%[ahi],%[flo],%[C]"  "\n\t"  // a+=(f>>33)*C;     5 cycles | ||||
|           " umull %[flo],%[fhi],%[fhi],%[t]"  "\n\t"  // f>>=32; f*=t      5 cycles [fhi:flo=64bits] | ||||
|           " lsrs  %[flo],%[fhi],#1"           "\n\t"  //                   1 cycles [31bits] | ||||
|           " smlal %[alo],%[ahi],%[flo],%[B]"  "\n\t"  // a+=(f>>33)*B;     5 cycles | ||||
|           " umull %[flo],%[fhi],%[fhi],%[t]"  "\n\t"  // f>>=32; f*=t      5 cycles [fhi:flo=64bits] | ||||
|           " lsrs  %[flo],%[fhi],#1"           "\n\t"  // f>>=33;           1 cycles [31bits] | ||||
|           " smlal %[alo],%[ahi],%[flo],%[A]"  "\n\t"  // a+=(f>>33)*A;     5 cycles | ||||
|           " lsrs  %[alo],%[ahi],#6"           "\n\t"  // a>>=38            1 cycles | ||||
|           ".syntax unified" "\n\t"              // is to prevent CM0,CM1 non-unified syntax | ||||
|           A("lsrs  %[ahi],%[alo],#1")           // a  = F << 31      1 cycles | ||||
|           A("lsls  %[alo],%[alo],#31")          //                   1 cycles | ||||
|           A("umull %[flo],%[fhi],%[fhi],%[t]")  // f *= t            5 cycles [fhi:flo=64bits] | ||||
|           A("umull %[flo],%[fhi],%[fhi],%[t]")  // f>>=32; f*=t      5 cycles [fhi:flo=64bits] | ||||
|           A("lsrs  %[flo],%[fhi],#1")           //                   1 cycles [31bits] | ||||
|           A("smlal %[alo],%[ahi],%[flo],%[C]")  // a+=(f>>33)*C;     5 cycles | ||||
|           A("umull %[flo],%[fhi],%[fhi],%[t]")  // f>>=32; f*=t      5 cycles [fhi:flo=64bits] | ||||
|           A("lsrs  %[flo],%[fhi],#1")           //                   1 cycles [31bits] | ||||
|           A("smlal %[alo],%[ahi],%[flo],%[B]")  // a+=(f>>33)*B;     5 cycles | ||||
|           A("umull %[flo],%[fhi],%[fhi],%[t]")  // f>>=32; f*=t      5 cycles [fhi:flo=64bits] | ||||
|           A("lsrs  %[flo],%[fhi],#1")           // f>>=33;           1 cycles [31bits] | ||||
|           A("smlal %[alo],%[ahi],%[flo],%[A]")  // a+=(f>>33)*A;     5 cycles | ||||
|           A("lsrs  %[alo],%[ahi],#6")           // a>>=38            1 cycles | ||||
|           : [alo]"+r"( alo ) , | ||||
|             [flo]"+r"( flo ) , | ||||
|             [fhi]"+r"( fhi ) , | ||||
|   | ||||
		Reference in New Issue
	
	Block a user