lwip operating system abstraction layer implementation based on CMSIS-RTOS

**
Dependents:
**
LwIPNetworking
NetServicesMin
EthernetInterface
EthernetInterface_RSF
... more

# checksum.c

00001 /* Copyright (C) 2013 - Adam Green (https://github.com/adamgreen) 00002 00003 Licensed under the Apache License, Version 2.0 (the "License"); 00004 you may not use this file except in compliance with the License. 00005 You may obtain a copy of the License at 00006 00007 http://www.apache.org/licenses/LICENSE-2.0 00008 00009 Unless required by applicable law or agreed to in writing, software 00010 distributed under the License is distributed on an "AS IS" BASIS, 00011 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00012 See the License for the specific language governing permissions and 00013 limitations under the License. 00014 */ 00015 #if defined(TOOLCHAIN_GCC) && defined(__thumb2__) 00016 00017 00018 /* This is a hand written Thumb-2 assembly language version of the 00019 algorithm 3 version of lwip_standard_chksum in lwIP's inet_chksum.c. It 00020 performs the checksumming 32-bits at a time and even unrolls the loop to 00021 perform two of these 32-bit adds per loop iteration. 00022 00023 Returns: 00024 16-bit 1's complement summation (not inversed). 00025 00026 NOTE: This function does return a uint16_t from the assembly language code 00027 but is marked as void so that GCC doesn't issue warning because it 00028 doesn't know about this low level return. 00029 */ 00030 __attribute__((naked)) void /*uint16_t*/ thumb2_checksum(const void* pData, int length) 00031 { 00032 __asm ( 00033 ".syntax unified\n" 00034 ".thumb\n" 00035 00036 // Push non-volatile registers we use on stack. Push link register too to 00037 // keep stack 8-byte aligned and allow single pop to restore and return. 00038 " push {r4, lr}\n" 00039 // Initialize sum, r2, to 0. 00040 " movs r2, #0\n" 00041 // Remember whether pData was at odd address in r3. This is used later to 00042 // know if it needs to swap the result since the summation will be done at 00043 // an offset of 1, rather than 0. 00044 " ands r3, r0, #1\n" 00045 // Need to 2-byte align? If not skip ahead. 00046 " beq 1$\n" 00047 // We can return if there are no bytes to sum. 00048 " cbz r1, 9$\n" 00049 00050 // 2-byte align. 00051 // Place the first data byte in odd summation location since it needs to be 00052 // swapped later. It's ok to overwrite r2 here as it only had a value of 0 00053 // up until now. Advance r0 pointer and decrement r1 length as we go. 00054 " ldrb r2, [r0], #1\n" 00055 " lsls r2, r2, #8\n" 00056 " subs r1, r1, #1\n" 00057 00058 // Need to 4-byte align? If not skip ahead. 00059 "1$:\n" 00060 " ands r4, r0, #3\n" 00061 " beq 2$\n" 00062 // Have more than 1 byte left to align? If not skip ahead to take care of 00063 // trailing byte. 00064 " cmp r1, #2\n" 00065 " blt 7$\n" 00066 00067 // 4-byte align. 00068 " ldrh r4, [r0], #2\n" 00069 " adds r2, r2, r4\n" 00070 " subs r1, r1, #2\n" 00071 00072 // Main summing loop which sums up data 2 words at a time. 00073 // Make sure that we have more than 7 bytes left to sum. 00074 "2$:\n" 00075 " cmp r1, #8\n" 00076 " blt 3$\n" 00077 // Sum next two words. Applying previous upper 16-bit carry to 00078 // lower 16-bits. 00079 " ldr r4, [r0], #4\n" 00080 " adds r2, r4\n" 00081 " adc r2, r2, #0\n" 00082 " ldr r4, [r0], #4\n" 00083 " adds r2, r4\n" 00084 " adc r2, r2, #0\n" 00085 " subs r1, r1, #8\n" 00086 " b 2$\n" 00087 00088 // Sum up any remaining half-words. 00089 "3$:\n" 00090 // Make sure that we have more than 1 byte left to sum. 00091 " cmp r1, #2\n" 00092 " blt 7$\n" 00093 // Sum up next half word, continue to apply carry. 00094 " ldrh r4, [r0], #2\n" 00095 " adds r2, r4\n" 00096 " adc r2, r2, #0\n" 00097 " subs r1, r1, #2\n" 00098 " b 3$\n" 00099 00100 // Handle trailing byte, if it exists 00101 "7$:\n" 00102 " cbz r1, 8$\n" 00103 " ldrb r4, [r0]\n" 00104 " adds r2, r4\n" 00105 " adc r2, r2, #0\n" 00106 00107 // Fold 32-bit checksum into 16-bit checksum. 00108 "8$:\n" 00109 " ubfx r4, r2, #16, #16\n" 00110 " ubfx r2, r2, #0, #16\n" 00111 " adds r2, r4\n" 00112 " ubfx r4, r2, #16, #16\n" 00113 " ubfx r2, r2, #0, #16\n" 00114 " adds r2, r4\n" 00115 00116 // Swap bytes if started at odd address 00117 " cbz r3, 9$\n" 00118 " rev16 r2, r2\n" 00119 00120 // Return final sum. 00121 "9$: mov r0, r2\n" 00122 " pop {r4, pc}\n" 00123 ); 00124 } 00125 00126 #endif

Generated on Tue Jul 12 2022 18:38:06 by 1.7.2