|
| 1 | +/* |
| 2 | + Copyright (c) 2015 Arduino LLC. All right reserved. |
| 3 | + |
| 4 | + This library is free software; you can redistribute it and/or |
| 5 | + modify it under the terms of the GNU Lesser General Public |
| 6 | + License as published by the Free Software Foundation; either |
| 7 | + version 2.1 of the License, or (at your option) any later version. |
| 8 | + |
| 9 | + This library is distributed in the hope that it will be useful, |
| 10 | + but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| 12 | + See the GNU Lesser General Public License for more details. |
| 13 | + |
| 14 | + You should have received a copy of the GNU Lesser General Public |
| 15 | + License along with this library; if not, write to the Free Software |
| 16 | + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| 17 | +*/ |
| 18 | + |
| 19 | +/* |
| 20 | + |
| 21 | +The following function has been compiled to ASM with gcc |
| 22 | + |
| 23 | + unsigned long countPulseASM(const volatile uint32_t *port, uint32_t bit, uint32_t stateMask, unsigned long maxloops) |
| 24 | + { |
| 25 | + unsigned long width = 0; |
| 26 | + |
| 27 | + // wait for any previous pulse to end |
| 28 | + while ((*port & bit) == stateMask) |
| 29 | + if (--maxloops == 0) |
| 30 | + return 0; |
| 31 | + |
| 32 | + // wait for the pulse to start |
| 33 | + while ((*port & bit) != stateMask) |
| 34 | + if (--maxloops == 0) |
| 35 | + return 0; |
| 36 | + |
| 37 | + // wait for the pulse to stop |
| 38 | + while ((*port & bit) == stateMask) { |
| 39 | + if (++width == maxloops) |
| 40 | + return 0; |
| 41 | + } |
| 42 | + return width; |
| 43 | + } |
| 44 | + |
| 45 | +using the command line: |
| 46 | + |
| 47 | + arm-none-eabi-gcc -mcpu=cortex-m0plus -mthumb -c -Os -W -ffunction-sections -fdata-sections \ |
| 48 | + -nostdlib --param max-inline-insns-single=500 -fno-exceptions -MMD \ |
| 49 | + -DF_CPU=48000000L -DARDUINO=10602 -DARDUINO_SAMD_ZERO -DARDUINO_ARCH_SAMD \ |
| 50 | + -D__SAMD21G18A__ -DUSB_VID=0x2341 -DUSB_PID=0x004d -DUSBCON \ |
| 51 | + -DUSB_MANUFACTURER="Arduino LLC" -DUSB_PRODUCT="Arduino Zero" \ |
| 52 | + -I/Code/arduino/build/linux/work/hardware/tools/CMSIS/CMSIS/Include/ \ |
| 53 | + -I/Code/arduino/build/linux/work/hardware/tools/CMSIS/Device/ATMEL/ \ |
| 54 | + -I/Code/arduino/build/linux/work/hardware/arduino/samd/cores/arduino \ |
| 55 | + -I/Code/arduino/build/linux/work/hardware/arduino/samd/variants/arduino_zero \ |
| 56 | + count.c -Wa,-ahlmsd=output.lst -dp -fverbose-asm -S |
| 57 | + |
| 58 | +The result has been slightly edited to increase readability. |
| 59 | + |
| 60 | +*/ |
| 61 | + |
| 62 | + .cpu cortex-m0plus |
| 63 | + .fpu softvfp |
| 64 | + .eabi_attribute 20, 1 @ Tag_ABI_FP_denormal |
| 65 | + .eabi_attribute 21, 1 @ Tag_ABI_FP_exceptions |
| 66 | + .eabi_attribute 23, 3 @ Tag_ABI_FP_number_model |
| 67 | + .eabi_attribute 24, 1 @ Tag_ABI_align8_needed |
| 68 | + .eabi_attribute 25, 1 @ Tag_ABI_align8_preserved |
| 69 | + .eabi_attribute 26, 1 @ Tag_ABI_enum_size |
| 70 | + .eabi_attribute 30, 4 @ Tag_ABI_optimization_goals |
| 71 | + .eabi_attribute 34, 0 @ Tag_CPU_unaligned_access |
| 72 | + .eabi_attribute 18, 4 @ Tag_ABI_PCS_wchar_t |
| 73 | + .file "count.c" |
| 74 | +@ GNU C (GNU Tools for ARM Embedded Processors (Arduino build)) version 4.8.3 20140228 (release) [ARM/embedded-4_8-branch revision 208322] (arm-none-eabi) |
| 75 | +@ compiled by GNU C version 4.3.2, GMP version 4.3.2, MPFR version 2.4.2, MPC version 0.8.1 |
| 76 | +@ GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 |
| 77 | +@ options passed: |
| 78 | +@ -I /Code/arduino/build/linux/work/hardware/tools/CMSIS/CMSIS/Include/ |
| 79 | +@ -I /Code/arduino/build/linux/work/hardware/tools/CMSIS/Device/ATMEL/ |
| 80 | +@ -I /Code/arduino/build/linux/work/hardware/arduino/samd/cores/arduino |
| 81 | +@ -I /Code/arduino/build/linux/work/hardware/arduino/samd/variants/arduino_zero |
| 82 | +@ -imultilib armv6-m |
| 83 | +@ -iprefix /Code/arduino/build/linux/work/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/../lib/gcc/arm-none-eabi/4.8.3/ |
| 84 | +@ -isysroot /Code/arduino/build/linux/work/hardware/tools/gcc-arm-none-eabi-4.8.3-2014q1/bin/../arm-none-eabi |
| 85 | +@ -MMD count.d -D__USES_INITFINI__ -D F_CPU=48000000L -D ARDUINO=10602 |
| 86 | +@ -D ARDUINO_SAMD_ZERO -D ARDUINO_ARCH_SAMD -D __SAMD21G18A__ |
| 87 | +@ -D USB_VID=0x2341 -D USB_PID=0x004d -D USBCON |
| 88 | +@ -D USB_MANUFACTURER=Arduino LLC -D USB_PRODUCT=Arduino Zero count.c |
| 89 | +@ -mcpu=cortex-m0plus -mthumb -Os -Wextra -ffunction-sections |
| 90 | +@ -fdata-sections -fno-exceptions -fverbose-asm |
| 91 | +@ --param max-inline-insns-single=500 |
| 92 | +@ options enabled: -faggressive-loop-optimizations -fauto-inc-dec |
| 93 | +@ -fbranch-count-reg -fcaller-saves -fcombine-stack-adjustments -fcommon |
| 94 | +@ -fcompare-elim -fcprop-registers -fcrossjumping -fcse-follow-jumps |
| 95 | +@ -fdata-sections -fdefer-pop -fdelete-null-pointer-checks -fdevirtualize |
| 96 | +@ -fdwarf2-cfi-asm -fearly-inlining -feliminate-unused-debug-types |
| 97 | +@ -fexpensive-optimizations -fforward-propagate -ffunction-cse |
| 98 | +@ -ffunction-sections -fgcse -fgcse-lm -fgnu-runtime |
| 99 | +@ -fguess-branch-probability -fhoist-adjacent-loads -fident -fif-conversion |
| 100 | +@ -fif-conversion2 -findirect-inlining -finline -finline-atomics |
| 101 | +@ -finline-functions -finline-functions-called-once |
| 102 | +@ -finline-small-functions -fipa-cp -fipa-profile -fipa-pure-const |
| 103 | +@ -fipa-reference -fipa-sra -fira-hoist-pressure -fira-share-save-slots |
| 104 | +@ -fira-share-spill-slots -fivopts -fkeep-static-consts |
| 105 | +@ -fleading-underscore -fmath-errno -fmerge-constants -fmerge-debug-strings |
| 106 | +@ -fomit-frame-pointer -foptimize-register-move -foptimize-sibling-calls |
| 107 | +@ -fpartial-inlining -fpeephole -fpeephole2 -fprefetch-loop-arrays |
| 108 | +@ -freg-struct-return -fregmove -freorder-blocks -freorder-functions |
| 109 | +@ -frerun-cse-after-loop -fsched-critical-path-heuristic |
| 110 | +@ -fsched-dep-count-heuristic -fsched-group-heuristic -fsched-interblock |
| 111 | +@ -fsched-last-insn-heuristic -fsched-pressure -fsched-rank-heuristic |
| 112 | +@ -fsched-spec -fsched-spec-insn-heuristic -fsched-stalled-insns-dep |
| 113 | +@ -fschedule-insns2 -fsection-anchors -fshow-column -fshrink-wrap |
| 114 | +@ -fsigned-zeros -fsplit-ivs-in-unroller -fsplit-wide-types |
| 115 | +@ -fstrict-aliasing -fstrict-overflow -fstrict-volatile-bitfields |
| 116 | +@ -fsync-libcalls -fthread-jumps -ftoplevel-reorder -ftrapping-math |
| 117 | +@ -ftree-bit-ccp -ftree-builtin-call-dce -ftree-ccp -ftree-ch |
| 118 | +@ -ftree-coalesce-vars -ftree-copy-prop -ftree-copyrename -ftree-cselim |
| 119 | +@ -ftree-dce -ftree-dominator-opts -ftree-dse -ftree-forwprop -ftree-fre |
| 120 | +@ -ftree-loop-if-convert -ftree-loop-im -ftree-loop-ivcanon |
| 121 | +@ -ftree-loop-optimize -ftree-parallelize-loops= -ftree-phiprop -ftree-pre |
| 122 | +@ -ftree-pta -ftree-reassoc -ftree-scev-cprop -ftree-sink |
| 123 | +@ -ftree-slp-vectorize -ftree-slsr -ftree-sra -ftree-switch-conversion |
| 124 | +@ -ftree-tail-merge -ftree-ter -ftree-vect-loop-version -ftree-vrp |
| 125 | +@ -funit-at-a-time -fverbose-asm -fzero-initialized-in-bss -mlittle-endian |
| 126 | +@ -mpic-data-is-text-relative -msched-prolog -mthumb |
| 127 | +@ -mvectorize-with-neon-quad |
| 128 | + |
| 129 | + .section .text.countPulseASM,"ax",%progbits |
| 130 | + .align 1 |
| 131 | + .global countPulseASM |
| 132 | + .code 16 |
| 133 | + .thumb_func |
| 134 | + .type countPulseASM, %function |
| 135 | +countPulseASM: |
| 136 | + push {r4, r5, lr} @ @ 112 *push_multi [length = 2] |
| 137 | +.L2: |
| 138 | + ldr r4, [r0] @ D.11539, *port_7(D) @ 22 *thumb1_movsi_insn/7 [length = 2] |
| 139 | + and r4, r1 @ D.11539, bit @ 24 *thumb1_andsi3_insn [length = 2] |
| 140 | + cmp r4, r2 @ D.11539, stateMask @ 25 cbranchsi4_insn/1 [length = 4] |
| 141 | + bne .L5 @, |
| 142 | + sub r3, r3, #1 @ maxloops, @ 17 *thumb1_addsi3/2 [length = 2] |
| 143 | + cmp r3, #0 @ maxloops, @ 18 cbranchsi4_insn/1 [length = 4] |
| 144 | + bne .L2 @, |
| 145 | + b .L10 @ @ 127 *thumb_jump [length = 2] |
| 146 | +.L6: |
| 147 | + sub r3, r3, #1 @ maxloops, @ 30 *thumb1_addsi3/2 [length = 2] |
| 148 | + cmp r3, #0 @ maxloops, @ 31 cbranchsi4_insn/1 [length = 4] |
| 149 | + beq .L10 @, |
| 150 | +.L5: |
| 151 | + ldr r4, [r0] @ D.11539, *port_7(D) @ 35 *thumb1_movsi_insn/7 [length = 2] |
| 152 | + and r4, r1 @ D.11539, bit @ 37 *thumb1_andsi3_insn [length = 2] |
| 153 | + cmp r4, r2 @ D.11539, stateMask @ 38 cbranchsi4_insn/1 [length = 4] |
| 154 | + bne .L6 @, |
| 155 | + mov r4, #0 @ width, @ 7 *thumb1_movsi_insn/2 [length = 2] |
| 156 | +.L7: |
| 157 | + ldr r5, [r0] @ D.11539, *port_7(D) @ 48 *thumb1_movsi_insn/7 [length = 2] |
| 158 | + and r5, r1 @ D.11539, bit @ 50 *thumb1_andsi3_insn [length = 2] |
| 159 | + cmp r5, r2 @ D.11539, stateMask @ 51 cbranchsi4_insn/1 [length = 4] |
| 160 | + bne .L13 @, |
| 161 | + add r4, r4, #1 @ width, @ 43 *thumb1_addsi3/1 [length = 2] |
| 162 | + cmp r4, r3 @ width, maxloops @ 44 cbranchsi4_insn/1 [length = 4] |
| 163 | + bne .L7 @, |
| 164 | + mov r0, #0 @ D.11539, @ 11 *thumb1_movsi_insn/2 [length = 2] |
| 165 | + b .L3 @ @ 130 *thumb_jump [length = 2] |
| 166 | +.L13: |
| 167 | + mov r0, r4 @ D.11539, width @ 9 *thumb1_movsi_insn/1 [length = 2] |
| 168 | + b .L3 @ @ 132 *thumb_jump [length = 2] |
| 169 | +.L10: |
| 170 | + mov r0, r3 @ D.11539, maxloops @ 8 *thumb1_movsi_insn/1 [length = 2] |
| 171 | +.L3: |
| 172 | + @ sp needed @ @ 115 force_register_use [length = 0] |
| 173 | + pop {r4, r5, pc} |
| 174 | + .size countPulseASM, .-countPulseASM |
| 175 | + .ident "GCC: (GNU Tools for ARM Embedded Processors (Arduino build)) 4.8.3 20140228 (release) [ARM/embedded-4_8-branch revision 208322]" |
0 commit comments