📄 memcpy.s
字号:
UMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) andi t8, a2, 0x1c daddu a1, a1, 0x20 daddu a0, a0, 0x20u_do_end_words: beqz t8, u_maybe_end_cruft srl t8, t8, 0x2u_end_words: EX(lw, ta0, 0x00(a1), l_fixup) dsubu t8, t8, 0x1 UEX(usw, ta0, 0x00(a0), s_fixup) daddu a1, a1, 0x4 bnez t8, u_end_words daddu a0, a0, 0x4u_maybe_end_cruft: andi ta2, a2, 0x3u_cannot_optimize: beqz ta2, out move a2, ta2u_end_bytes: EX(lb, ta0, (a1), l_fixup) dsubu a2, a2, 0x1 EX(sb, ta0, (a0), s_fixup) daddu a1, a1, 0x1 bnez a2, u_end_bytes daddu a0, a0, 0x1 jr ra move a2, zero END(memcpy)/* descending order, destination aligned */#define RMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \ lw t0, (offset + 0x10)(src); \ lw t1, (offset + 0x14)(src); \ lw t2, (offset + 0x18)(src); \ lw t3, (offset + 0x1c)(src); \ sw t0, (offset + 0x10)(dst); \ sw t1, (offset + 0x14)(dst); \ sw t2, (offset + 0x18)(dst); \ sw t3, (offset + 0x1c)(dst); \ lw t0, (offset + 0x00)(src); \ lw t1, (offset + 0x04)(src); \ lw t2, (offset + 0x08)(src); \ lw t3, (offset + 0x0c)(src); \ sw t0, (offset + 0x00)(dst); \ sw t1, (offset + 0x04)(dst); \ sw t2, (offset + 0x08)(dst); \ sw t3, (offset + 0x0c)(dst)/* descending order, destination ununaligned */#define RUMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3) \ lw t0, (offset + 0x10)(src); \ lw t1, (offset + 0x14)(src); \ lw t2, (offset + 0x18)(src); \ lw t3, (offset + 0x1c)(src); \ usw t0, (offset + 0x10)(dst); \ usw t1, (offset + 0x14)(dst); \ usw t2, (offset + 0x18)(dst); \ usw t3, (offset + 0x1c)(dst); \ lw t0, (offset + 0x00)(src); \ lw t1, (offset + 0x04)(src); \ lw t2, (offset + 0x08)(src); \ lw t3, (offset + 0x0c)(src); \ usw t0, (offset + 0x00)(dst); \ usw t1, (offset + 0x04)(dst); \ usw t2, (offset + 0x08)(dst); \ usw t3, (offset + 0x0c)(dst) .align 5LEAF(memmove) sltu ta0, a0, a1 # dst < src -> memcpy bnez ta0, memcpy daddu v0, a0, a2 sltu ta0, v0, a1 # dst + len < src -> non- bnez ta0, __memcpy # overlapping, can use memcpy move v0, a0 /* return value */ beqz a2, r_out END(memmove)LEAF(__rmemcpy) /* a0=dst a1=src a2=len */ daddu a0, a2 # dst = dst + len daddu a1, a2 # src = src + len#if 0 /* Horror fix */ xor ta0, a0, a1 andi ta0, ta0, 0x3 move t3, a0 beqz ta0, r_can_align sltiu t8, a2, 0x8 b r_memcpy_u_src # bad alignment move ta2, a2r_can_align: bnez t8, r_small_memcpy # < 8 bytes to copy move ta2, a2 beqz a2, r_out andi t8, a1, 0x1r_hword_align: beqz t8, r_word_align andi t8, a1, 0x2 lb ta0, -1(a1) dsubu a2, a2, 0x1 sb ta0, -1(a0) dsubu a1, a1, 0x1 dsubu a0, a0, 0x1 andi t8, a1, 0x2r_word_align: beqz t8, r_dword_align sltiu t8, a2, 56 lh ta0, -2(a1) dsubu a2, a2, 0x2 sh ta0, -2(a0) sltiu t8, a2, 56 dsubu a0, a0, 0x2 dsubu a1, a1, 0x2r_dword_align: bnez t8, r_do_end_words move t8, a2 andi t8, a1, 0x4 beqz t8, r_qword_align andi t8, a1, 0x8 lw ta0, -4(a1) dsubu a2, a2, 0x4 sw ta0, -4(a0) dsubu a1, a1, 0x4 dsubu a0, a0, 0x4 andi t8, a1, 0x8r_qword_align: beqz t8, r_oword_align andi t8, a1, 0x10 dsubu a1, a1, 0x8 lw ta0, 0x04(a1) lw ta1, 0x00(a1) dsubu a0, a0, 0x8 sw ta0, 0x04(a0) sw ta1, 0x00(a0) dsubu a2, a2, 0x8 andi t8, a1, 0x10r_oword_align: beqz t8, r_begin_movement srl t8, a2, 0x7 dsubu a1, a1, 0x10 lw ta3, 0x08(a1) # assumes subblock ordering lw t0, 0x0c(a1) lw ta0, 0x00(a1) lw ta1, 0x04(a1) dsubu a0, a0, 0x10 sw ta3, 0x08(a0) sw t0, 0x0c(a0) sw ta0, 0x00(a0) sw ta1, 0x04(a0) dsubu a2, a2, 0x10 srl t8, a2, 0x7r_begin_movement: beqz t8, 0f andi ta2, a2, 0x40r_move_128bytes: RMOVE_BIGCHUNK(a1, a0, -0x80, ta0, ta1, ta3, t0) RMOVE_BIGCHUNK(a1, a0, -0x60, ta0, ta1, ta3, t0) RMOVE_BIGCHUNK(a1, a0, -0x40, ta0, ta1, ta3, t0) RMOVE_BIGCHUNK(a1, a0, -0x20, ta0, ta1, ta3, t0) dsubu t8, t8, 0x01 dsubu a1, a1, 0x80 bnez t8, r_move_128bytes dsubu a0, a0, 0x800: beqz ta2, 1f andi ta2, a2, 0x20r_move_64bytes: dsubu a1, a1, 0x40 dsubu a0, a0, 0x40 RMOVE_BIGCHUNK(a1, a0, 0x20, ta0, ta1, ta3, t0) RMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0)1: beqz ta2, r_do_end_words andi t8, a2, 0x1cr_move_32bytes: dsubu a1, a1, 0x20 dsubu a0, a0, 0x20 RMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) andi t8, a2, 0x1cr_do_end_words: beqz t8, r_maybe_end_cruft srl t8, t8, 0x2r_end_words: lw ta0, -4(a1) dsubu t8, t8, 0x1 sw ta0, -4(a0) dsubu a1, a1, 0x4 bnez t8, r_end_words dsubu a0, a0, 0x4r_maybe_end_cruft: andi ta2, a2, 0x3r_small_memcpy: beqz ta2, r_out move a2, ta2#endif /* Horror fix */r_end_bytes: lb ta0, -1(a1) dsubu a2, a2, 0x1 sb ta0, -1(a0) dsubu a1, a1, 0x1 bnez a2, r_end_bytes dsubu a0, a0, 0x1r_out: jr ra move a2, zero#if 0 /* Horror fix *//* ------------------------------------------------------------------------- *//* Bad, bad. At least try to align the source */r_memcpy_u_src: bnez t8, r_small_memcpy # < 8 bytes? move ta2, a2 andi ta0, a1, 7 # ta0: how much to align ulw ta1, -8(a1) # dword alignment ulw ta2, -4(a1) usw ta1, -8(a0) usw ta2, -4(a0) dsubu a1, ta0 # src dsubu a0, ta0 # dst dsubu a2, ta0 # len sltiu t8, a2, 56 bnez t8, ru_do_end_words andi t8, a2, 0x3c andi t8, a1, 8 # now qword aligned?ru_qword_align: beqz t8, ru_oword_align andi t8, a1, 0x10 dsubu a1, a1, 0x8 lw ta0, 0x00(a1) lw ta1, 0x04(a1) dsubu a0, a0, 0x8 usw ta0, 0x00(a0) usw ta1, 0x04(a0) dsubu a2, a2, 0x8 andi t8, a1, 0x10ru_oword_align: beqz t8, ru_begin_movement srl t8, a2, 0x7 dsubu a1, a1, 0x10 lw ta3, 0x08(a1) # assumes subblock ordering lw t0, 0x0c(a1) lw ta0, 0x00(a1) lw ta1, 0x04(a1) dsubu a0, a0, 0x10 usw ta3, 0x08(a0) usw t0, 0x0c(a0) usw ta0, 0x00(a0) usw ta1, 0x04(a0) dsubu a2, a2, 0x10 srl t8, a2, 0x7ru_begin_movement: beqz t8, 0f andi ta2, a2, 0x40ru_move_128bytes: RUMOVE_BIGCHUNK(a1, a0, -0x80, ta0, ta1, ta3, t0) RUMOVE_BIGCHUNK(a1, a0, -0x60, ta0, ta1, ta3, t0) RUMOVE_BIGCHUNK(a1, a0, -0x40, ta0, ta1, ta3, t0) RUMOVE_BIGCHUNK(a1, a0, -0x20, ta0, ta1, ta3, t0) dsubu t8, t8, 0x01 dsubu a1, a1, 0x80 bnez t8, ru_move_128bytes dsubu a0, a0, 0x800: beqz ta2, 1f andi ta2, a2, 0x20ru_move_64bytes: dsubu a1, a1, 0x40 dsubu a0, a0, 0x40 RUMOVE_BIGCHUNK(a1, a0, 0x20, ta0, ta1, ta3, t0) RUMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0)1: beqz ta2, ru_do_end_words andi t8, a2, 0x1cru_move_32bytes: dsubu a1, a1, 0x20 dsubu a0, a0, 0x20 RUMOVE_BIGCHUNK(a1, a0, 0x00, ta0, ta1, ta3, t0) andi t8, a2, 0x1cru_do_end_words: beqz t8, ru_maybe_end_cruft srl t8, t8, 0x2ru_end_words: lw ta0, -4(a1) usw ta0, -4(a0) dsubu t8, t8, 0x1 dsubu a1, a1, 0x4 bnez t8, ru_end_words dsubu a0, a0, 0x4ru_maybe_end_cruft: andi ta2, a2, 0x3ru_cannot_optimize: beqz ta2, r_out move a2, ta2ru_end_bytes: lb ta0, -1(a1) dsubu a2, a2, 0x1 sb ta0, -1(a0) dsubu a1, a1, 0x1 bnez a2, ru_end_bytes dsubu a0, a0, 0x1 jr ra move a2, zero#endif /* Horror fix */ END(__rmemcpy)l_fixup: # clear the rest of the buffer ld ta0, THREAD_BUADDR($28) nop dsubu a2, AT, ta0 # a2 bytes to go daddu a0, ta0 # compute start address in a1 dsubu a0, a1 j __bzero move a1, zeros_fixup: jr ra nop
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -