diff --git a/arch/sw_64/lib/deep-copy_template.S b/arch/sw_64/lib/deep-copy_template.S index aa6ab8e29f057576ddcc922d31847314933f66c2..f2dbc8c502083d8cc46d1bafa6567b8b78f8944a 100644 --- a/arch/sw_64/lib/deep-copy_template.S +++ b/arch/sw_64/lib/deep-copy_template.S @@ -5,6 +5,10 @@ * * $4: 8-byte misalignment of src when dest is 8-byte aligned * $5: 32-byte misalignment of src when dest is 32-byte aligned + * $7: SIMD status + * 0: not in simd loop + * 1: in simd loop + * 2: in simd_u loop * $16: latest dest, clobbered * $17: latest src, clobbered * $18: bytes left to copy @@ -18,14 +22,16 @@ addl $sp, 0x1f, $23; \ bic $23, 0x1f, $23; \ vstd $f1, 0($23); \ - vstd $f2, 0x20($23) + vstd $f2, 0x20($23); \ + ldi $7, 1 #define RESTORE_SIMD_REGS \ addl $sp, 0x1f, $23; \ bic $23, 0x1f, $23; \ vldd $f1, 0($23); \ vldd $f2, 0x20($23); \ - ldi $sp, 0x60($sp) + ldi $sp, 0x60($sp); \ + bis $31, $31, $7 #define SAVE_SIMD_U_REGS \ ldi $sp, -0xc0($sp); \ @@ -35,7 +41,8 @@ vstd $f2, 0x20($23); \ vstd $f4, 0x40($23); \ vstd $f5, 0x60($23); \ - vstd $f3, 0x80($23) + vstd $f3, 0x80($23); \ + ldi $7, 2 #define RESTORE_SIMD_U_REGS \ addl $sp, 0x1f, $23; \ @@ -45,7 +52,8 @@ vldd $f4, 0x40($23); \ vldd $f5, 0x60($23); \ vldd $f3, 0x80($23); \ - ldi $sp, 0xc0($sp) + ldi $sp, 0xc0($sp); \ + bis $31, $31, $7 ble $18, $out and $16, 7, $1 diff --git a/arch/sw_64/lib/deep-copy_user.S b/arch/sw_64/lib/deep-copy_user.S index 145e1cc6ba18505f518401e73d112c6b7f2e3e0d..327cab322765ab2f4758812cd178d437726eb44d 100644 --- a/arch/sw_64/lib/deep-copy_user.S +++ b/arch/sw_64/lib/deep-copy_user.S @@ -10,13 +10,34 @@ ldi $31, $out-99b($31); \ .previous +/* + * $7: SIMD status + * 0: not in simd loop + * 1: in simd loop + * 2: in simd_u loop + * $18: bytes left to copy + * + */ .globl __copy_user .ent __copy_user __copy_user: .prologue 0 + bis $31, $31, $7 #include "deep-copy_template.S" $out: bis $31, $18, $0 + beq $7, $return + subl $7, 1, $7 + beq $7, $restore_simd + +$restore_simd_u: + RESTORE_SIMD_U_REGS + br $31, $return + +$restore_simd: + RESTORE_SIMD_REGS + +$return: ret .end __copy_user EXPORT_SYMBOL(__copy_user)