180ee5cbfSDavid du ColombierTS = 0 280ee5cbfSDavid du ColombierTE = 1 380ee5cbfSDavid du ColombierFROM = 2 480ee5cbfSDavid du ColombierN = 3 580ee5cbfSDavid du ColombierTMP = 3 /* N and TMP don't overlap */ 680ee5cbfSDavid du ColombierTMP1 = 4 780ee5cbfSDavid du Colombier 880ee5cbfSDavid du ColombierTEXT memcpy(SB), $-4 980ee5cbfSDavid du Colombier B _memmove 1080ee5cbfSDavid du ColombierTEXT memmove(SB), $-4 1180ee5cbfSDavid du Colombier_memmove: 1280ee5cbfSDavid du Colombier MOVW R(TS), to+0(FP) /* need to save for return value */ 1380ee5cbfSDavid du Colombier MOVW from+4(FP), R(FROM) 1480ee5cbfSDavid du Colombier MOVW n+8(FP), R(N) 1580ee5cbfSDavid du Colombier 1680ee5cbfSDavid du Colombier ADD R(N), R(TS), R(TE) /* to end pointer */ 1780ee5cbfSDavid du Colombier 1880ee5cbfSDavid du Colombier CMP R(FROM), R(TS) 1980ee5cbfSDavid du Colombier BLS _forward 2080ee5cbfSDavid du Colombier 2180ee5cbfSDavid du Colombier_back: 2280ee5cbfSDavid du Colombier ADD R(N), R(FROM) /* from end pointer */ 2380ee5cbfSDavid du Colombier CMP $4, R(N) /* need at least 4 bytes to copy */ 2480ee5cbfSDavid du Colombier BLT _b1tail 2580ee5cbfSDavid du Colombier 2680ee5cbfSDavid du Colombier_b4align: /* align destination on 4 */ 2780ee5cbfSDavid du Colombier AND.S $3, R(TE), R(TMP) 2880ee5cbfSDavid du Colombier BEQ _b4aligned 2980ee5cbfSDavid du Colombier 3080ee5cbfSDavid du Colombier MOVBU.W -1(R(FROM)), R(TMP) /* pre-indexed */ 3180ee5cbfSDavid du Colombier MOVBU.W R(TMP), -1(R(TE)) /* pre-indexed */ 3280ee5cbfSDavid du Colombier B _b4align 3380ee5cbfSDavid du Colombier 3480ee5cbfSDavid du Colombier_b4aligned: /* is source now aligned? */ 3580ee5cbfSDavid du Colombier AND.S $3, R(FROM), R(TMP) 3680ee5cbfSDavid du Colombier BNE _bunaligned 3780ee5cbfSDavid du Colombier 3880ee5cbfSDavid du Colombier ADD $31, R(TS), R(TMP) /* do 32-byte chunks if possible */ 3980ee5cbfSDavid du Colombier_b32loop: 4080ee5cbfSDavid du Colombier CMP R(TMP), R(TE) 4180ee5cbfSDavid du Colombier BLS _b4tail 4280ee5cbfSDavid du Colombier 43*51480713SDavid du Colombier MOVM.DB.W (R(FROM)), [R4-R7] 44*51480713SDavid du Colombier MOVM.DB.W [R4-R7], (R(TE)) 45*51480713SDavid du Colombier MOVM.DB.W (R(FROM)), [R4-R7] 46*51480713SDavid du Colombier MOVM.DB.W [R4-R7], (R(TE)) 4780ee5cbfSDavid du Colombier B _b32loop 4880ee5cbfSDavid du Colombier 4980ee5cbfSDavid du Colombier_b4tail: /* do remaining words if possible */ 5080ee5cbfSDavid du Colombier ADD $3, R(TS), R(TMP) 5180ee5cbfSDavid du Colombier_b4loop: 5280ee5cbfSDavid du Colombier CMP R(TMP), R(TE) 5380ee5cbfSDavid du Colombier BLS _b1tail 5480ee5cbfSDavid du Colombier 5580ee5cbfSDavid du Colombier MOVW.W -4(R(FROM)), R(TMP1) /* pre-indexed */ 5680ee5cbfSDavid du Colombier MOVW.W R(TMP1), -4(R(TE)) /* pre-indexed */ 5780ee5cbfSDavid du Colombier B _b4loop 5880ee5cbfSDavid du Colombier 5980ee5cbfSDavid du Colombier_b1tail: /* remaining bytes */ 6080ee5cbfSDavid du Colombier CMP R(TE), R(TS) 6180ee5cbfSDavid du Colombier BEQ _return 6280ee5cbfSDavid du Colombier 6380ee5cbfSDavid du Colombier MOVBU.W -1(R(FROM)), R(TMP) /* pre-indexed */ 6480ee5cbfSDavid du Colombier MOVBU.W R(TMP), -1(R(TE)) /* pre-indexed */ 6580ee5cbfSDavid du Colombier B _b1tail 6680ee5cbfSDavid du Colombier 6780ee5cbfSDavid du Colombier_forward: 6880ee5cbfSDavid du Colombier CMP $4, R(N) /* need at least 4 bytes to copy */ 6980ee5cbfSDavid du Colombier BLT _f1tail 7080ee5cbfSDavid du Colombier 7180ee5cbfSDavid du Colombier_f4align: /* align destination on 4 */ 7280ee5cbfSDavid du Colombier AND.S $3, R(TS), R(TMP) 7380ee5cbfSDavid du Colombier BEQ _f4aligned 7480ee5cbfSDavid du Colombier 7580ee5cbfSDavid du Colombier MOVBU.P 1(R(FROM)), R(TMP) /* implicit write back */ 7680ee5cbfSDavid du Colombier MOVBU.P R(TMP), 1(R(TS)) /* implicit write back */ 7780ee5cbfSDavid du Colombier B _f4align 7880ee5cbfSDavid du Colombier 7980ee5cbfSDavid du Colombier_f4aligned: /* is source now aligned? */ 8080ee5cbfSDavid du Colombier AND.S $3, R(FROM), R(TMP) 8180ee5cbfSDavid du Colombier BNE _funaligned 8280ee5cbfSDavid du Colombier 8380ee5cbfSDavid du Colombier SUB $31, R(TE), R(TMP) /* do 32-byte chunks if possible */ 8480ee5cbfSDavid du Colombier_f32loop: 8580ee5cbfSDavid du Colombier CMP R(TMP), R(TS) 8680ee5cbfSDavid du Colombier BHS _f4tail 8780ee5cbfSDavid du Colombier 88*51480713SDavid du Colombier MOVM.IA.W (R(FROM)), [R4-R7] 89*51480713SDavid du Colombier MOVM.IA.W [R4-R7], (R(TS)) 90*51480713SDavid du Colombier MOVM.IA.W (R(FROM)), [R4-R7] 91*51480713SDavid du Colombier MOVM.IA.W [R4-R7], (R(TS)) 9280ee5cbfSDavid du Colombier B _f32loop 9380ee5cbfSDavid du Colombier 9480ee5cbfSDavid du Colombier_f4tail: 9580ee5cbfSDavid du Colombier SUB $3, R(TE), R(TMP) /* do remaining words if possible */ 9680ee5cbfSDavid du Colombier_f4loop: 9780ee5cbfSDavid du Colombier CMP R(TMP), R(TS) 9880ee5cbfSDavid du Colombier BHS _f1tail 9980ee5cbfSDavid du Colombier 10080ee5cbfSDavid du Colombier MOVW.P 4(R(FROM)), R(TMP1) /* implicit write back */ 10180ee5cbfSDavid du Colombier MOVW.P R4, 4(R(TS)) /* implicit write back */ 10280ee5cbfSDavid du Colombier B _f4loop 10380ee5cbfSDavid du Colombier 10480ee5cbfSDavid du Colombier_f1tail: 10580ee5cbfSDavid du Colombier CMP R(TS), R(TE) 10680ee5cbfSDavid du Colombier BEQ _return 10780ee5cbfSDavid du Colombier 10880ee5cbfSDavid du Colombier MOVBU.P 1(R(FROM)), R(TMP) /* implicit write back */ 10980ee5cbfSDavid du Colombier MOVBU.P R(TMP), 1(R(TS)) /* implicit write back */ 11080ee5cbfSDavid du Colombier B _f1tail 11180ee5cbfSDavid du Colombier 11280ee5cbfSDavid du Colombier_return: 11380ee5cbfSDavid du Colombier MOVW to+0(FP), R0 11480ee5cbfSDavid du Colombier RET 11580ee5cbfSDavid du Colombier 11680ee5cbfSDavid du ColombierRSHIFT = 4 11780ee5cbfSDavid du ColombierLSHIFT = 5 118*51480713SDavid du ColombierOFFSET = 11 11980ee5cbfSDavid du Colombier 120*51480713SDavid du ColombierBR0 = 6 121*51480713SDavid du ColombierBW0 = 7 122*51480713SDavid du ColombierBR1 = 7 123*51480713SDavid du ColombierBW1 = 8 12480ee5cbfSDavid du Colombier 12580ee5cbfSDavid du Colombier_bunaligned: 12680ee5cbfSDavid du Colombier CMP $2, R(TMP) /* is R(TMP) < 2 ? */ 12780ee5cbfSDavid du Colombier 12880ee5cbfSDavid du Colombier MOVW.LT $8, R(RSHIFT) /* (R(n)<<24)|(R(n-1)>>8) */ 12980ee5cbfSDavid du Colombier MOVW.LT $24, R(LSHIFT) 13080ee5cbfSDavid du Colombier MOVW.LT $1, R(OFFSET) 13180ee5cbfSDavid du Colombier 13280ee5cbfSDavid du Colombier MOVW.EQ $16, R(RSHIFT) /* (R(n)<<16)|(R(n-1)>>16) */ 13380ee5cbfSDavid du Colombier MOVW.EQ $16, R(LSHIFT) 13480ee5cbfSDavid du Colombier MOVW.EQ $2, R(OFFSET) 13580ee5cbfSDavid du Colombier 13680ee5cbfSDavid du Colombier MOVW.GT $24, R(RSHIFT) /* (R(n)<<8)|(R(n-1)>>24) */ 13780ee5cbfSDavid du Colombier MOVW.GT $8, R(LSHIFT) 13880ee5cbfSDavid du Colombier MOVW.GT $3, R(OFFSET) 13980ee5cbfSDavid du Colombier 140*51480713SDavid du Colombier ADD $8, R(TS), R(TMP) /* do 8-byte chunks if possible */ 14180ee5cbfSDavid du Colombier CMP R(TMP), R(TE) 14280ee5cbfSDavid du Colombier BLS _b1tail 14380ee5cbfSDavid du Colombier 144*51480713SDavid du Colombier BIC $3, R(FROM) /* align source */ 14580ee5cbfSDavid du Colombier MOVW (R(FROM)), R(BR0) /* prime first block register */ 14680ee5cbfSDavid du Colombier 147*51480713SDavid du Colombier_bu8loop: 14880ee5cbfSDavid du Colombier CMP R(TMP), R(TE) 14980ee5cbfSDavid du Colombier BLS _bu1tail 15080ee5cbfSDavid du Colombier 151*51480713SDavid du Colombier MOVW R(BR0)<<R(LSHIFT), R(BW1) 152*51480713SDavid du Colombier MOVM.DB.W (R(FROM)), [R(BR0)-R(BR1)] 15380ee5cbfSDavid du Colombier ORR R(BR1)>>R(RSHIFT), R(BW1) 15480ee5cbfSDavid du Colombier 15580ee5cbfSDavid du Colombier MOVW R(BR1)<<R(LSHIFT), R(BW0) 15680ee5cbfSDavid du Colombier ORR R(BR0)>>R(RSHIFT), R(BW0) 15780ee5cbfSDavid du Colombier 158*51480713SDavid du Colombier MOVM.DB.W [R(BW0)-R(BW1)], (R(TE)) 159*51480713SDavid du Colombier B _bu8loop 16080ee5cbfSDavid du Colombier 16180ee5cbfSDavid du Colombier_bu1tail: 16280ee5cbfSDavid du Colombier ADD R(OFFSET), R(FROM) 16380ee5cbfSDavid du Colombier B _b1tail 16480ee5cbfSDavid du Colombier 165*51480713SDavid du ColombierRSHIFT = 4 166*51480713SDavid du ColombierLSHIFT = 5 167*51480713SDavid du ColombierOFFSET = 11 168*51480713SDavid du Colombier 169*51480713SDavid du ColombierFW0 = 6 170*51480713SDavid du ColombierFR0 = 7 171*51480713SDavid du ColombierFW1 = 7 172*51480713SDavid du ColombierFR1 = 8 17380ee5cbfSDavid du Colombier 17480ee5cbfSDavid du Colombier_funaligned: 17580ee5cbfSDavid du Colombier CMP $2, R(TMP) 17680ee5cbfSDavid du Colombier 17780ee5cbfSDavid du Colombier MOVW.LT $8, R(RSHIFT) /* (R(n+1)<<24)|(R(n)>>8) */ 17880ee5cbfSDavid du Colombier MOVW.LT $24, R(LSHIFT) 17980ee5cbfSDavid du Colombier MOVW.LT $3, R(OFFSET) 18080ee5cbfSDavid du Colombier 18180ee5cbfSDavid du Colombier MOVW.EQ $16, R(RSHIFT) /* (R(n+1)<<16)|(R(n)>>16) */ 18280ee5cbfSDavid du Colombier MOVW.EQ $16, R(LSHIFT) 18380ee5cbfSDavid du Colombier MOVW.EQ $2, R(OFFSET) 18480ee5cbfSDavid du Colombier 18580ee5cbfSDavid du Colombier MOVW.GT $24, R(RSHIFT) /* (R(n+1)<<8)|(R(n)>>24) */ 18680ee5cbfSDavid du Colombier MOVW.GT $8, R(LSHIFT) 18780ee5cbfSDavid du Colombier MOVW.GT $1, R(OFFSET) 18880ee5cbfSDavid du Colombier 189*51480713SDavid du Colombier SUB $8, R(TE), R(TMP) /* do 8-byte chunks if possible */ 19080ee5cbfSDavid du Colombier CMP R(TMP), R(TS) 19180ee5cbfSDavid du Colombier BHS _f1tail 19280ee5cbfSDavid du Colombier 193*51480713SDavid du Colombier BIC $3, R(FROM) /* align source */ 194*51480713SDavid du Colombier MOVW.P 4(R(FROM)), R(FR1) /* prime last block register, implicit write back */ 19580ee5cbfSDavid du Colombier 196*51480713SDavid du Colombier_fu8loop: 19780ee5cbfSDavid du Colombier CMP R(TMP), R(TS) 19880ee5cbfSDavid du Colombier BHS _fu1tail 19980ee5cbfSDavid du Colombier 200*51480713SDavid du Colombier MOVW R(FR1)>>R(RSHIFT), R(FW0) 201*51480713SDavid du Colombier MOVM.IA.W (R(FROM)), [R(FR0)-R(FR1)] 20280ee5cbfSDavid du Colombier ORR R(FR0)<<R(LSHIFT), R(FW0) 20380ee5cbfSDavid du Colombier 20480ee5cbfSDavid du Colombier MOVW R(FR0)>>R(RSHIFT), R(FW1) 20580ee5cbfSDavid du Colombier ORR R(FR1)<<R(LSHIFT), R(FW1) 20680ee5cbfSDavid du Colombier 207*51480713SDavid du Colombier MOVM.IA.W [R(FW0)-R(FW1)], (R(TS)) 208*51480713SDavid du Colombier B _fu8loop 20980ee5cbfSDavid du Colombier 21080ee5cbfSDavid du Colombier_fu1tail: 21180ee5cbfSDavid du Colombier SUB R(OFFSET), R(FROM) 21280ee5cbfSDavid du Colombier B _f1tail 213