Path: blob/master/arch/cris/arch-v32/lib/checksum.S
15125 views
/*1* A fast checksum routine using movem2* Copyright (c) 1998-2007 Axis Communications AB3*4* csum_partial(const unsigned char * buff, int len, unsigned int sum)5*/67.globl csum_partial8.type csum_partial,@function9csum_partial:1011;; r10 - src12;; r11 - length13;; r12 - checksum1415;; Optimized for large packets16subq 10*4, $r1117blt _word_loop18move.d $r11, $acr1920subq 9*4,$sp21clearf c22movem $r8,[$sp]2324;; do a movem checksum2526_mloop: movem [$r10+],$r9 ; read 10 longwords27;; Loop count without touching the c flag.28addoq -10*4, $acr, $acr29;; perform dword checksumming on the 10 longwords3031addc $r0,$r1232addc $r1,$r1233addc $r2,$r1234addc $r3,$r1235addc $r4,$r1236addc $r5,$r1237addc $r6,$r1238addc $r7,$r1239addc $r8,$r1240addc $r9,$r124142;; test $acr without trashing carry.43move.d $acr, $acr44bpl _mloop45;; r11 <= acr is not really needed in the mloop, just using the dslot46;; to prepare for what is needed after mloop.47move.d $acr, $r114849;; fold the last carry into r1350addc 0, $r1251movem [$sp+],$r8 ; restore regs5253_word_loop:54addq 10*4,$r11 ; compensate for last loop underflowing length5556moveq -1,$r9 ; put 0xffff in r9, faster than move.d 0xffff,r957lsrq 16,$r95859move.d $r12,$r1360lsrq 16,$r13 ; r13 = checksum >> 1661and.d $r9,$r12 ; checksum = checksum & 0xffff6263_no_fold:64subq 2,$r1165blt _no_words66add.d $r13,$r12 ; checksum += r136768;; checksum the rest of the words69_wloop: subq 2,$r1170bge _wloop71addu.w [$r10+],$r127273_no_words:74addq 2,$r1175;; see if we have one odd byte more76bne _do_byte77nop78ret79move.d $r12,$r108081_do_byte:82;; copy and checksum the last byte83addu.b [$r10],$r1284ret85move.d $r12,$r108687.size csum_partial, .-csum_partial888990