17dd7cddfSDavid du ColombierTS = 0 27dd7cddfSDavid du ColombierTE = 1 37dd7cddfSDavid du ColombierFROM = 2 47dd7cddfSDavid du ColombierN = 3 57dd7cddfSDavid du ColombierTMP = 3 /* N and TMP don't overlap */ 67dd7cddfSDavid du ColombierTMP1 = 4 77dd7cddfSDavid du Colombier 8*6ca8a7e3SDavid du ColombierTEXT memcpy(SB), $0 97dd7cddfSDavid du Colombier B _memmove 10*6ca8a7e3SDavid du ColombierTEXT memmove(SB), $0 117dd7cddfSDavid du Colombier_memmove: 127dd7cddfSDavid du Colombier MOVW R(TS), to+0(FP) /* need to save for return value */ 137dd7cddfSDavid du Colombier MOVW from+4(FP), R(FROM) 147dd7cddfSDavid du Colombier MOVW n+8(FP), R(N) 157dd7cddfSDavid du Colombier 167dd7cddfSDavid du Colombier ADD R(N), R(TS), R(TE) /* to end pointer */ 177dd7cddfSDavid du Colombier 187dd7cddfSDavid du Colombier CMP R(FROM), R(TS) 197dd7cddfSDavid du Colombier BLS _forward 207dd7cddfSDavid du Colombier 217dd7cddfSDavid du Colombier_back: 227dd7cddfSDavid du Colombier ADD R(N), R(FROM) /* from end pointer */ 237dd7cddfSDavid du Colombier CMP $4, R(N) /* need at least 4 bytes to copy */ 247dd7cddfSDavid du Colombier BLT _b1tail 257dd7cddfSDavid du Colombier 267dd7cddfSDavid du Colombier_b4align: /* align destination on 4 */ 277dd7cddfSDavid du Colombier AND.S $3, R(TE), R(TMP) 287dd7cddfSDavid du Colombier BEQ _b4aligned 297dd7cddfSDavid du Colombier 307dd7cddfSDavid du Colombier MOVBU.W -1(R(FROM)), R(TMP) /* pre-indexed */ 317dd7cddfSDavid du Colombier MOVBU.W R(TMP), -1(R(TE)) /* pre-indexed */ 327dd7cddfSDavid du Colombier B _b4align 337dd7cddfSDavid du Colombier 347dd7cddfSDavid du Colombier_b4aligned: /* is source now aligned? */ 357dd7cddfSDavid du Colombier AND.S $3, R(FROM), R(TMP) 367dd7cddfSDavid du Colombier BNE _bunaligned 377dd7cddfSDavid du Colombier 387dd7cddfSDavid du Colombier ADD $31, R(TS), R(TMP) /* do 32-byte chunks if possible */ 397dd7cddfSDavid du Colombier_b32loop: 407dd7cddfSDavid du Colombier CMP R(TMP), R(TE) 417dd7cddfSDavid du Colombier BLS _b4tail 427dd7cddfSDavid du Colombier 4351480713SDavid du Colombier MOVM.DB.W (R(FROM)), [R4-R7] 4451480713SDavid du Colombier MOVM.DB.W [R4-R7], (R(TE)) 4551480713SDavid du Colombier MOVM.DB.W (R(FROM)), [R4-R7] 4651480713SDavid du Colombier MOVM.DB.W [R4-R7], (R(TE)) 477dd7cddfSDavid du Colombier B _b32loop 487dd7cddfSDavid du Colombier 497dd7cddfSDavid du Colombier_b4tail: /* do remaining words if possible */ 507dd7cddfSDavid du Colombier ADD $3, R(TS), R(TMP) 517dd7cddfSDavid du Colombier_b4loop: 527dd7cddfSDavid du Colombier CMP R(TMP), R(TE) 537dd7cddfSDavid du Colombier BLS _b1tail 547dd7cddfSDavid du Colombier 557dd7cddfSDavid du Colombier MOVW.W -4(R(FROM)), R(TMP1) /* pre-indexed */ 567dd7cddfSDavid du Colombier MOVW.W R(TMP1), -4(R(TE)) /* pre-indexed */ 577dd7cddfSDavid du Colombier B _b4loop 587dd7cddfSDavid du Colombier 597dd7cddfSDavid du Colombier_b1tail: /* remaining bytes */ 607dd7cddfSDavid du Colombier CMP R(TE), R(TS) 617dd7cddfSDavid du Colombier BEQ _return 627dd7cddfSDavid du Colombier 637dd7cddfSDavid du Colombier MOVBU.W -1(R(FROM)), R(TMP) /* pre-indexed */ 647dd7cddfSDavid du Colombier MOVBU.W R(TMP), -1(R(TE)) /* pre-indexed */ 657dd7cddfSDavid du Colombier B _b1tail 667dd7cddfSDavid du Colombier 677dd7cddfSDavid du Colombier_forward: 687dd7cddfSDavid du Colombier CMP $4, R(N) /* need at least 4 bytes to copy */ 697dd7cddfSDavid du Colombier BLT _f1tail 707dd7cddfSDavid du Colombier 717dd7cddfSDavid du Colombier_f4align: /* align destination on 4 */ 727dd7cddfSDavid du Colombier AND.S $3, R(TS), R(TMP) 737dd7cddfSDavid du Colombier BEQ _f4aligned 747dd7cddfSDavid du Colombier 757dd7cddfSDavid du Colombier MOVBU.P 1(R(FROM)), R(TMP) /* implicit write back */ 767dd7cddfSDavid du Colombier MOVBU.P R(TMP), 1(R(TS)) /* implicit write back */ 777dd7cddfSDavid du Colombier B _f4align 787dd7cddfSDavid du Colombier 797dd7cddfSDavid du Colombier_f4aligned: /* is source now aligned? */ 807dd7cddfSDavid du Colombier AND.S $3, R(FROM), R(TMP) 817dd7cddfSDavid du Colombier BNE _funaligned 827dd7cddfSDavid du Colombier 837dd7cddfSDavid du Colombier SUB $31, R(TE), R(TMP) /* do 32-byte chunks if possible */ 847dd7cddfSDavid du Colombier_f32loop: 857dd7cddfSDavid du Colombier CMP R(TMP), R(TS) 867dd7cddfSDavid du Colombier BHS _f4tail 877dd7cddfSDavid du Colombier 8851480713SDavid du Colombier MOVM.IA.W (R(FROM)), [R4-R7] 8951480713SDavid du Colombier MOVM.IA.W [R4-R7], (R(TS)) 9051480713SDavid du Colombier MOVM.IA.W (R(FROM)), [R4-R7] 9151480713SDavid du Colombier MOVM.IA.W [R4-R7], (R(TS)) 927dd7cddfSDavid du Colombier B _f32loop 937dd7cddfSDavid du Colombier 947dd7cddfSDavid du Colombier_f4tail: 957dd7cddfSDavid du Colombier SUB $3, R(TE), R(TMP) /* do remaining words if possible */ 967dd7cddfSDavid du Colombier_f4loop: 977dd7cddfSDavid du Colombier CMP R(TMP), R(TS) 987dd7cddfSDavid du Colombier BHS _f1tail 997dd7cddfSDavid du Colombier 1007dd7cddfSDavid du Colombier MOVW.P 4(R(FROM)), R(TMP1) /* implicit write back */ 1017dd7cddfSDavid du Colombier MOVW.P R4, 4(R(TS)) /* implicit write back */ 1027dd7cddfSDavid du Colombier B _f4loop 1037dd7cddfSDavid du Colombier 1047dd7cddfSDavid du Colombier_f1tail: 1057dd7cddfSDavid du Colombier CMP R(TS), R(TE) 1067dd7cddfSDavid du Colombier BEQ _return 1077dd7cddfSDavid du Colombier 1087dd7cddfSDavid du Colombier MOVBU.P 1(R(FROM)), R(TMP) /* implicit write back */ 1097dd7cddfSDavid du Colombier MOVBU.P R(TMP), 1(R(TS)) /* implicit write back */ 1107dd7cddfSDavid du Colombier B _f1tail 1117dd7cddfSDavid du Colombier 1127dd7cddfSDavid du Colombier_return: 1137dd7cddfSDavid du Colombier MOVW to+0(FP), R0 1147dd7cddfSDavid du Colombier RET 1157dd7cddfSDavid du Colombier 1167dd7cddfSDavid du ColombierRSHIFT = 4 1177dd7cddfSDavid du ColombierLSHIFT = 5 11851480713SDavid du ColombierOFFSET = 11 1197dd7cddfSDavid du Colombier 12051480713SDavid du ColombierBR0 = 6 12151480713SDavid du ColombierBW0 = 7 12251480713SDavid du ColombierBR1 = 7 12351480713SDavid du ColombierBW1 = 8 1247dd7cddfSDavid du Colombier 1257dd7cddfSDavid du Colombier_bunaligned: 1267dd7cddfSDavid du Colombier CMP $2, R(TMP) /* is R(TMP) < 2 ? */ 1277dd7cddfSDavid du Colombier 1287dd7cddfSDavid du Colombier MOVW.LT $8, R(RSHIFT) /* (R(n)<<24)|(R(n-1)>>8) */ 1297dd7cddfSDavid du Colombier MOVW.LT $24, R(LSHIFT) 1307dd7cddfSDavid du Colombier MOVW.LT $1, R(OFFSET) 1317dd7cddfSDavid du Colombier 1327dd7cddfSDavid du Colombier MOVW.EQ $16, R(RSHIFT) /* (R(n)<<16)|(R(n-1)>>16) */ 1337dd7cddfSDavid du Colombier MOVW.EQ $16, R(LSHIFT) 1347dd7cddfSDavid du Colombier MOVW.EQ $2, R(OFFSET) 1357dd7cddfSDavid du Colombier 1367dd7cddfSDavid du Colombier MOVW.GT $24, R(RSHIFT) /* (R(n)<<8)|(R(n-1)>>24) */ 1377dd7cddfSDavid du Colombier MOVW.GT $8, R(LSHIFT) 1387dd7cddfSDavid du Colombier MOVW.GT $3, R(OFFSET) 1397dd7cddfSDavid du Colombier 14051480713SDavid du Colombier ADD $8, R(TS), R(TMP) /* do 8-byte chunks if possible */ 1417dd7cddfSDavid du Colombier CMP R(TMP), R(TE) 1427dd7cddfSDavid du Colombier BLS _b1tail 1437dd7cddfSDavid du Colombier 14451480713SDavid du Colombier BIC $3, R(FROM) /* align source */ 1457dd7cddfSDavid du Colombier MOVW (R(FROM)), R(BR0) /* prime first block register */ 1467dd7cddfSDavid du Colombier 14751480713SDavid du Colombier_bu8loop: 1487dd7cddfSDavid du Colombier CMP R(TMP), R(TE) 1497dd7cddfSDavid du Colombier BLS _bu1tail 1507dd7cddfSDavid du Colombier 15151480713SDavid du Colombier MOVW R(BR0)<<R(LSHIFT), R(BW1) 15251480713SDavid du Colombier MOVM.DB.W (R(FROM)), [R(BR0)-R(BR1)] 1537dd7cddfSDavid du Colombier ORR R(BR1)>>R(RSHIFT), R(BW1) 1547dd7cddfSDavid du Colombier 1557dd7cddfSDavid du Colombier MOVW R(BR1)<<R(LSHIFT), R(BW0) 1567dd7cddfSDavid du Colombier ORR R(BR0)>>R(RSHIFT), R(BW0) 1577dd7cddfSDavid du Colombier 15851480713SDavid du Colombier MOVM.DB.W [R(BW0)-R(BW1)], (R(TE)) 15951480713SDavid du Colombier B _bu8loop 1607dd7cddfSDavid du Colombier 1617dd7cddfSDavid du Colombier_bu1tail: 1627dd7cddfSDavid du Colombier ADD R(OFFSET), R(FROM) 1637dd7cddfSDavid du Colombier B _b1tail 1647dd7cddfSDavid du Colombier 16551480713SDavid du ColombierRSHIFT = 4 16651480713SDavid du ColombierLSHIFT = 5 16751480713SDavid du ColombierOFFSET = 11 16851480713SDavid du Colombier 16951480713SDavid du ColombierFW0 = 6 17051480713SDavid du ColombierFR0 = 7 17151480713SDavid du ColombierFW1 = 7 17251480713SDavid du ColombierFR1 = 8 1737dd7cddfSDavid du Colombier 1747dd7cddfSDavid du Colombier_funaligned: 1757dd7cddfSDavid du Colombier CMP $2, R(TMP) 1767dd7cddfSDavid du Colombier 1777dd7cddfSDavid du Colombier MOVW.LT $8, R(RSHIFT) /* (R(n+1)<<24)|(R(n)>>8) */ 1787dd7cddfSDavid du Colombier MOVW.LT $24, R(LSHIFT) 1797dd7cddfSDavid du Colombier MOVW.LT $3, R(OFFSET) 1807dd7cddfSDavid du Colombier 1817dd7cddfSDavid du Colombier MOVW.EQ $16, R(RSHIFT) /* (R(n+1)<<16)|(R(n)>>16) */ 1827dd7cddfSDavid du Colombier MOVW.EQ $16, R(LSHIFT) 1837dd7cddfSDavid du Colombier MOVW.EQ $2, R(OFFSET) 1847dd7cddfSDavid du Colombier 1857dd7cddfSDavid du Colombier MOVW.GT $24, R(RSHIFT) /* (R(n+1)<<8)|(R(n)>>24) */ 1867dd7cddfSDavid du Colombier MOVW.GT $8, R(LSHIFT) 1877dd7cddfSDavid du Colombier MOVW.GT $1, R(OFFSET) 1887dd7cddfSDavid du Colombier 18951480713SDavid du Colombier SUB $8, R(TE), R(TMP) /* do 8-byte chunks if possible */ 1907dd7cddfSDavid du Colombier CMP R(TMP), R(TS) 1917dd7cddfSDavid du Colombier BHS _f1tail 1927dd7cddfSDavid du Colombier 19351480713SDavid du Colombier BIC $3, R(FROM) /* align source */ 19451480713SDavid du Colombier MOVW.P 4(R(FROM)), R(FR1) /* prime last block register, implicit write back */ 1957dd7cddfSDavid du Colombier 19651480713SDavid du Colombier_fu8loop: 1977dd7cddfSDavid du Colombier CMP R(TMP), R(TS) 1987dd7cddfSDavid du Colombier BHS _fu1tail 1997dd7cddfSDavid du Colombier 20051480713SDavid du Colombier MOVW R(FR1)>>R(RSHIFT), R(FW0) 20151480713SDavid du Colombier MOVM.IA.W (R(FROM)), [R(FR0)-R(FR1)] 2027dd7cddfSDavid du Colombier ORR R(FR0)<<R(LSHIFT), R(FW0) 2037dd7cddfSDavid du Colombier 2047dd7cddfSDavid du Colombier MOVW R(FR0)>>R(RSHIFT), R(FW1) 2057dd7cddfSDavid du Colombier ORR R(FR1)<<R(LSHIFT), R(FW1) 2067dd7cddfSDavid du Colombier 20751480713SDavid du Colombier MOVM.IA.W [R(FW0)-R(FW1)], (R(TS)) 20851480713SDavid du Colombier B _fu8loop 2097dd7cddfSDavid du Colombier 2107dd7cddfSDavid du Colombier_fu1tail: 2117dd7cddfSDavid du Colombier SUB R(OFFSET), R(FROM) 2127dd7cddfSDavid du Colombier B _f1tail 213