| /******************************************************************************************************** | |
| * @file div_mod.S | |
| * | |
| * @brief for TLSR chips | |
| * | |
| * @author public@telink-semi.com; | |
| * @date Sep. 30, 2010 | |
| * | |
| * @attention | |
| * | |
| * Copyright (C) 2019-2020 Telink Semiconductor (Shanghai) Co., Ltd. | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); | |
| * you may not use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| * | |
| *******************************************************************************************************/ | |
| #define UDIV #0 | |
| #define SDIV #1 | |
| #define UMOD #2 | |
| #define SMOD #3 | |
| #define MUL2_STEP 8 | |
| .code 16 | |
| .text | |
| .section .ram_code,"ax" //in ram code | |
| .align 2 | |
| .global __modsi3 | |
| .code 16 | |
| .thumb_func | |
| .type __modsi3, %function | |
| __modsi3: | |
| tmov r2, SMOD | |
| tj div | |
| .size __modsi3, .-__modsi3 | |
| .section .ram_code,"ax" //in ram code | |
| .align 2 | |
| .global __divsi3 | |
| .code 16 | |
| .thumb_func | |
| .type __divsi3, %function | |
| __divsi3: | |
| tmov r2, SDIV | |
| tj div | |
| .size __divsi3, .-__divsi3 | |
| .section .ram_code,"ax" //in ram code | |
| .align 2 | |
| .global __umodsi3 | |
| .code 16 | |
| .thumb_func | |
| .type __umodsi3, %function | |
| __umodsi3: | |
| tmov r2, UMOD | |
| tj div | |
| .size __umodsi3, .-__umodsi3 | |
| .section .ram_code,"ax" //in ram code | |
| .align 2 | |
| .global __udivsi3 | |
| .code 16 | |
| .thumb_func | |
| .type __udivsi3, %function | |
| __udivsi3: | |
| tmov r2, UDIV | |
| tj div | |
| .size __udivsi3, .-__udivsi3 | |
| .section .ram_code,"ax" //in ram code | |
| .align 2 | |
| .global div | |
| .code 16 | |
| .thumb_func | |
| .type div, %function | |
| div: | |
| tmrcs r3 | |
| tpush {r3, r4} | |
| tmov r4, #0x80 | |
| tor r3, r4 | |
| tmcsr r3 | |
| tloadr r3, .L11 | |
| tstorer r0, [r3] | |
| tadd r3, r3, #4 | |
| tstorer r1, [r3] | |
| tsub r3, r3, #8 | |
| tstorerb r2, [r3] | |
| .L2: | |
| tloadrb r0, [r3] | |
| tcmp r0, #0 | |
| tjne .L2 | |
| tcmp r2, #1 | |
| tjls .L4 | |
| tadd r3, r3, #8 | |
| tloadr r0, [r3] | |
| tj .L6 | |
| .L4: | |
| tadd r3, r3, #4 | |
| tloadr r0, [r3] | |
| .L6: | |
| tpop {r3, r4} | |
| tmcsr r3 | |
| tjex lr | |
| .align 4 | |
| .L11: | |
| .word(0x800664) | |
| .word(0x800660) | |
| .word(0x800668) | |
| .size div, .-div | |
| //removed | |
| #if 0 | |
| //.section .ram_code,"ax" //in ram code | |
| .align 4 | |
| .global mul32x32_64 | |
| .thumb_func | |
| .type mul32x32_64, %function | |
| mul32x32_64: | |
| tmul r0, r1 | |
| tloadr r1, [pc, #4] | |
| tloadr r1, [r1, #0] | |
| tjex lr | |
| .word(0x008006fc) | |
| #endif | |
| #if 0 | |
| //.section .ram_code,"ax" //in ram code | |
| .align 4 | |
| .global mz_mul1 | |
| .thumb_func | |
| .type mz_mul1, %function | |
| mz_mul1: | |
| tpush {r4, r5, r6, r7} | |
| tmov r4, r8 | |
| tpush {r4} | |
| tmov r4, #1 | |
| tmov r8, r4 //r8 = 1 | |
| tloadr r6, [pc, #4] //r6 REG_ADDR32(0x6fc) | |
| tmovs r5, #0 //clear carry | |
| tj MZ_MUL1_END | |
| .word(0x008006fc) | |
| MZ_MUL1_START: | |
| tmul r4, r3 // l0 = a0 * b | |
| tloadr r7, [r0, #0] // y0 | |
| tadd r4, r5 // l0 + c => c0 | |
| tsubc r5, r5 // c0 - 1 | |
| tadd r4, r7 // l0 + c + y0 => c1 | |
| tloadr r7, [r6, #0] // r7 = h0 | |
| tadd r5, r8 // c0 - 1 + 1 = c0 (nc) | |
| tstorem r0!, {r4} // store y0 | |
| taddc r5, r7 // cn = c0 + h1 + c1 | |
| MZ_MUL1_END: | |
| tloadm r1!, {r4} // load *a | |
| tsub r2, #1 // r2-- | |
| tcmp r2, #0 | |
| tjge MZ_MUL1_START // carry set | |
| tstorem r0!, {r5} | |
| tpop {r4} | |
| tmov r8, r4 | |
| tpop {r4, r5, r6, r7} | |
| tjex lr | |
| #endif | |
| //.section .ram_code,"ax" //in ram code | |
| .align 4 | |
| .global mz_mul2 | |
| .thumb_func | |
| .type mz_mul2, %function | |
| mz_mul2: | |
| tpush {r4, r5, r6, r7} | |
| tmov r4, r8 | |
| tmov r5, r9 | |
| tmov r6, r10 | |
| tmov r7, r11 | |
| tpush {r4, r5, r6, r7} | |
| tmov r8, r2 //r8 = n, loop number | |
| tmov r2, #1 | |
| tmov r10, r2 // r10 = 1 | |
| tsub r2, #(MUL2_STEP + 1) | |
| tmov r9, r2 //r9 = -MUL2_STEP | |
| tmov r2, #0 | |
| tmov r2, #0 | |
| tloadr r6, [pc, #4] //r6 REG_ADDR32(0x6fc) | |
| tmov r11,r2 //r11 = 0 | |
| tj MZ_MUL2_LOOP | |
| //tj MZ_MUL2_LOOP2 | |
| .word(0x008006fc) | |
| MZ_MUL2_START: | |
| //a0 | |
| tmul r4, r3 // l0 = a0 * b | |
| tloadr r7, [r0, #0] // y0 | |
| tadd r4, r2 // l0 + c => c0 | |
| tsubc r2, r2 // c0 - 1 | |
| tadd r4, r7 // l0 + c + y0 => c1 | |
| tloadr r7, [r6, #0] // r7 = h0 | |
| tadd r2, r10 // c0 - 1 + 1 = c0 (nc) | |
| tstorem r0!, {r4} // store y0 y1 | |
| taddc r2, r7 // cn = c0 + h1 + c1 | |
| tmul r5, r3 // l1 = a1 * b | |
| tloadr r7, [r0, #0] // y1 | |
| tadd r5, r2 // l1 + cn => c2 | |
| tsubc r2, r2 // c2 - 1 | |
| tadd r5, r7 // l1 + c + y1 => c3 | |
| tloadr r7, [r6, #0] // r7 = h0 | |
| tadd r2, r10 // c0 - 1 + 1 = c0 (nc) | |
| tstorem r0!, {r5} // store y0 y1 | |
| tloadm r1!, {r4, r5} // load *a | |
| taddc r2, r7 // cn2 = c2 + h1 + c3 | |
| //a0 | |
| tmul r4, r3 // l0 = a0 * b | |
| tloadr r7, [r0, #0] // y0 | |
| tadd r4, r2 // l0 + c => c0 | |
| tsubc r2, r2 // c0 - 1 | |
| tadd r4, r7 // l0 + c + y0 => c1 | |
| tloadr r7, [r6, #0] // r7 = h0 | |
| tadd r2, r10 // c0 - 1 + 1 = c0 (nc) | |
| tstorem r0!, {r4} // store y0 y1 | |
| taddc r2, r7 // cn = c0 + h1 + c1 | |
| tmul r5, r3 // l1 = a1 * b | |
| tloadr r7, [r0, #0] // y1 | |
| tadd r5, r2 // l1 + cn => c2 | |
| tsubc r2, r2 // c2 - 1 | |
| tadd r5, r7 // l1 + c + y1 => c3 | |
| tloadr r7, [r6, #0] // r7 = h0 | |
| tadd r2, r10 // c0 - 1 + 1 = c0 (nc) | |
| tstorem r0!, {r5} // store y0 y1 | |
| tloadm r1!, {r4, r5} // load *a | |
| taddc r2, r7 // cn2 = c2 + h1 + c3 | |
| //a0 | |
| tmul r4, r3 // l0 = a0 * b | |
| tloadr r7, [r0, #0] // y0 | |
| tadd r4, r2 // l0 + c => c0 | |
| tsubc r2, r2 // c0 - 1 | |
| tadd r4, r7 // l0 + c + y0 => c1 | |
| tloadr r7, [r6, #0] // r7 = h0 | |
| tadd r2, r10 // c0 - 1 + 1 = c0 (nc) | |
| tstorem r0!, {r4} // store y0 y1 | |
| taddc r2, r7 // cn = c0 + h1 + c1 | |
| tmul r5, r3 // l1 = a1 * b | |
| tloadr r7, [r0, #0] // y1 | |
| tadd r5, r2 // l1 + cn => c2 | |
| tsubc r2, r2 // c2 - 1 | |
| tadd r5, r7 // l1 + c + y1 => c3 | |
| tloadr r7, [r6, #0] // r7 = h0 | |
| tadd r2, r10 // c0 - 1 + 1 = c0 (nc) | |
| tstorem r0!, {r5} // store y0 y1 | |
| tloadm r1!, {r4, r5} // load *a | |
| taddc r2, r7 // cn2 = c2 + h1 + c3 | |
| ///// next 2 | |
| tmul r4, r3 // l0 = a0 * b | |
| tloadr r7, [r0, #0] // y0 | |
| tadd r4, r2 // l0 + c => c0 | |
| tsubc r2, r2 // c0 - 1 | |
| tadd r4, r7 // l0 + c + y0 => c1 | |
| tloadr r7, [r6, #0] // r7 = h0 | |
| tadd r2, r10 // c0 - 1 + 1 = c0 (nc) | |
| tstorem r0!, {r4} // store y0 y1 | |
| taddc r2, r7 // cn = c0 + h1 + c1 | |
| tmul r5, r3 // l1 = a1 * b | |
| tloadr r7, [r0, #0] // y1 | |
| tadd r5, r2 // l1 + cn => c2 | |
| tsubc r2, r2 // c2 - 1 | |
| tadd r5, r7 // l1 + c + y1 => c3 | |
| tloadr r7, [r6, #0] // r7 = h0 | |
| tadd r2, r10 // c0 - 1 + 1 = c0 (nc) | |
| tstorem r0!, {r5} // store y0 y1 | |
| taddc r2, r7 // cn2 = c2 + h1 + c3 | |
| MZ_MUL2_LOOP: | |
| tloadm r1!, {r4, r5} // load *a | |
| tadd r8, r9 // r8 -= MUL2_STEP | |
| tcmp r8, r11 // const 0 | |
| tjge MZ_MUL2_START // carry set | |
| tmov r5, r8 | |
| tadd r5, #MUL2_STEP | |
| tsub r1, #8 | |
| tj MZ_MUL2_LOOP2 | |
| MZ_MUL2_START2: | |
| tmul r4, r3 // l0 = a0 * b | |
| tloadr r7, [r0, #0] // y0 | |
| tadd r4, r2 // l0 + c => c0 | |
| tsubc r2, r2 // c0 - 1 | |
| tadd r4, r7 // l0 + c + y0 => c1 | |
| tloadr r7, [r6, #0] // r7 = h0 | |
| tadd r2, r10 // c0 - 1 + 1 = c0 (nc) | |
| tstorem r0!, {r4} // store y0 | |
| taddc r2, r7 // cn = c0 + h1 + c1 | |
| MZ_MUL2_LOOP2: | |
| tloadm r1!, {r4} // load *a | |
| tsub r5, #1 // r7-- | |
| tcmp r5, #0 | |
| tjge MZ_MUL2_START2 // carry set | |
| MZ_MUL2_END: | |
| //tmov r2, #13 | |
| tstorem r0!, {r2} | |
| tpop {r4, r5, r6, r7} | |
| tmov r8, r4 | |
| tmov r9, r5 | |
| tmov r10, r6 | |
| tmov r11, r7 | |
| tpop {r4, r5, r6, r7} | |
| tjex lr | |
| tnop | |
| ///////// asm crc24 function 2 | |
| .section .ram_code,"ax" //in ram code | |
| .align 2 | |
| .global blt_packet_crc24_opt | |
| .code 16 | |
| .thumb_func | |
| .type blt_packet_crc24_opt, %function | |
| blt_packet_crc24_opt: | |
| tpush {r3, r4, r5, r6, r7, lr} | |
| tmov r5, r8 | |
| tpush {r5} | |
| tmov r5, r1 | |
| tneg r1, r0 | |
| tmov r4, #3 | |
| tand r1, r4 //number of byte CRC of pre_process to align CRC to word boundary | |
| tsub r5, r1 | |
| tjge CRC24_SAVE_WORD_NUM | |
| tadd r1, r5 | |
| tmov r5, #0 | |
| CRC24_SAVE_WORD_NUM: | |
| tmov r8, r5 //save to r8 | |
| //tloadr r3, CRC24_DAT | |
| tadd r4, r0, #0 | |
| tmov r0, #0 | |
| tmov r7, #60 //r7 = 15 * 4 | |
| CRC24_BYTE_LOOP: //r4: src; r6: dat; r2: crc; r5: tmp | |
| tcmp r0, r1 | |
| tjeq CRC24_BYTE_END | |
| tloadrb r6, [r4, r0] //r6 = dat[r0] | |
| txor r6, r2 //r6 = crc ^ dat | |
| tshftl r5, r6, #2 //r5 = r6 << 2 | |
| tand r5, r7 //r2 = r2 & 60 | |
| tloadr r5, [r5, r3] //load table | |
| tasr r2, r2, #4 //r2 >> 4 (crc >> 4) | |
| tshftr r6, r6, #2 // r6 = r6 >> 2 | |
| txor r2, r5 //r2 = r5 ^ r2 | |
| tand r6, r7 //r6 = r6 & 60 | |
| tloadr r6, [r6, r3] | |
| tasr r2, r2, #4 //r2 >> 4 (crc >> 4) | |
| tadd r0, #1 | |
| txor r2, r6 //r2 = r6 ^ r2 | |
| tjne CRC24_BYTE_LOOP | |
| CRC24_BYTE_END: | |
| tmov r1, r8 | |
| tcmp r1, #0 | |
| tjeq CRC24_END | |
| tmov r5, #0 | |
| tmov r8, r5 | |
| tadd r4, r0 | |
| tmov r0, #0 | |
| CRC24_WORD_LOOP: | |
| tsub r1, #4 | |
| tjlt CRC24_WORD_END | |
| tloadr r0, [r4, #0] //r0 = dat[r0] | |
| tadd r4, #4 | |
| tshftr r6, r0, #0 // r6 = r0 >> 0 | |
| CRC24_WORD_nib0: | |
| txor r6, r2 //r6 = crc ^ dat | |
| tshftl r5, r6, #2 //r5 = r6 << 2 | |
| tand r5, r7 //r2 = r2 & 60 | |
| tloadr r5, [r5, r3] //load table | |
| tasr r2, r2, #4 //r2 >> 4 (crc >> 4) | |
| tshftr r6, r6, #2 // r6 = r6 >> 2 | |
| tand r6, r7 //r6 = r6 & 60 | |
| tloadr r6, [r6, r3] | |
| txor r2, r5 //r2 = r5 ^ r2 | |
| CRC24_WORD_nib1: | |
| tasr r2, r2, #4 //r2 >> 4 (crc >> 4) | |
| tshftr r5, r0, #8 //dat >> 8 | |
| txor r2, r6 //r2 = r6 ^ r2 | |
| CRC24_WORD_nib2: | |
| txor r5, r2 //r6 = crc ^ dat | |
| tshftl r6, r5, #2 //r5 << 2 | |
| tand r6, r7 | |
| tloadr r6, [r6, r3] | |
| tasr r2, r2, #4 //r2 >> 4 (crc >> 4) | |
| tshftr r5, r5, #2 | |
| tand r5, r7 //r6 = r6 & 60 | |
| tloadr r5, [r5, r3] | |
| txor r2, r6 //r2 = r6 ^ r2 | |
| CRC24_WORD_nib3: | |
| tasr r2, r2, #4 //r2 >> 4 (crc >> 4) | |
| tshftr r6, r0, #16 //dat >> 8 | |
| txor r2, r5 //r2 = r6 ^ r2 | |
| CRC24_WORD_nib4: | |
| txor r6, r2 //r6 = crc ^ dat | |
| tshftl r5, r6, #2 //r5 = r6 << 2 | |
| tand r5, r7 //r2 = r2 & 60 | |
| tloadr r5, [r5, r3] //load table | |
| tasr r2, r2, #4 //r2 >> 4 (crc >> 4) | |
| tshftr r6, r6, #2 // r6 = r6 >> 2 | |
| tand r6, r7 //r6 = r6 & 60 | |
| tloadr r6, [r6, r3] | |
| txor r2, r5 //r2 = r5 ^ r2 | |
| CRC24_WORD_nib5: | |
| tasr r2, r2, #4 //r2 >> 4 (crc >> 4) | |
| tshftr r5, r0, #24 //dat >> 8 | |
| txor r2, r6 //r2 = r6 ^ r2 | |
| CRC24_WORD_nib6: | |
| txor r5, r2 //r6 = crc ^ dat | |
| tshftl r6, r5, #2 //r5 << 2 | |
| tand r6, r7 | |
| tloadr r6, [r6, r3] | |
| tasr r2, r2, #4 //r2 >> 4 (crc >> 4) | |
| tshftr r5, r5, #2 | |
| tand r5, r7 //r5 = r5 & 60 | |
| tloadr r5, [r5, r3] | |
| txor r2, r6 //r2 = r6 ^ r2 | |
| CRC24_WORD_nib7: | |
| tasr r2, r2, #4 //r2 >> 4 (crc >> 4) | |
| tmov r0, #0 | |
| txor r2, r5 //r2 = r6 ^ r2 | |
| tj CRC24_WORD_LOOP | |
| CRC24_WORD_END: | |
| tadd r1, #4 | |
| tj CRC24_BYTE_LOOP | |
| CRC24_END: | |
| tadd r0, r2, #0 | |
| tpop {r5} | |
| tmov r8, r5 | |
| tpop {r3, r4, r5, r6, r7, pc} | |
| tnop | |
| // static int Crc24Lookup[16] = { | |
| // 0x0000000,0x01b4c00,0x0369800,0x02dd400, | |
| // 0x06d3000,0x0767c00,0x05ba800,0x040e400, | |
| // 0x0da6000,0x0c12c00,0x0ecf800,0x0f7b400, | |
| // 0x0b75000,0x0ac1c00,0x081c800,0x09a8400, | |
| // }; | |
| // //usage | |
| // //crc = blt_packet_crc24_opt (dat, length, crc_init, Crc24Lookup); |