@@ -38,33 +38,27 @@ pub unsafe fn copy_forward(dest: *mut u8, src: *const u8, count: usize) {
38
38
pub unsafe fn copy_forward ( mut dest : * mut u8 , mut src : * const u8 , count : usize ) {
39
39
let ( pre_byte_count, qword_count, byte_count) = rep_param ( dest, count) ;
40
40
// Separating the blocks gives the compiler more freedom to reorder instructions.
41
- // It also allows us to trivially skip the rep movsb, which is faster when memcpying
42
- // aligned data.
43
- if pre_byte_count > 0 {
44
- asm ! (
45
- "rep movsb" ,
46
- inout( "ecx" ) pre_byte_count => _,
47
- inout( "rdi" ) dest => dest,
48
- inout( "rsi" ) src => src,
49
- options( att_syntax, nostack, preserves_flags)
50
- ) ;
51
- }
41
+ asm ! (
42
+ "rep movsb" ,
43
+ inout( "ecx" ) pre_byte_count => _,
44
+ inout( "rdi" ) dest => dest,
45
+ inout( "rsi" ) src => src,
46
+ options( att_syntax, nostack, preserves_flags)
47
+ ) ;
52
48
asm ! (
53
49
"rep movsq" ,
54
50
inout( "rcx" ) qword_count => _,
55
51
inout( "rdi" ) dest => dest,
56
52
inout( "rsi" ) src => src,
57
53
options( att_syntax, nostack, preserves_flags)
58
54
) ;
59
- if byte_count > 0 {
60
- asm ! (
61
- "rep movsb" ,
62
- inout( "ecx" ) byte_count => _,
63
- inout( "rdi" ) dest => _,
64
- inout( "rsi" ) src => _,
65
- options( att_syntax, nostack, preserves_flags)
66
- ) ;
67
- }
55
+ asm ! (
56
+ "rep movsb" ,
57
+ inout( "ecx" ) byte_count => _,
58
+ inout( "rdi" ) dest => _,
59
+ inout( "rsi" ) src => _,
60
+ options( att_syntax, nostack, preserves_flags)
61
+ ) ;
68
62
}
69
63
70
64
#[ inline( always) ]
@@ -73,21 +67,16 @@ pub unsafe fn copy_backward(dest: *mut u8, src: *const u8, count: usize) {
73
67
// We can't separate this block due to std/cld
74
68
asm ! (
75
69
"std" ,
76
- "test %ecx, %ecx" ,
77
- "jz 1f" ,
78
70
"rep movsb" ,
79
- "1:" ,
80
71
"sub $7, %rsi" ,
81
72
"sub $7, %rdi" ,
82
73
"mov {qword_count}, %rcx" ,
83
74
"rep movsq" ,
84
75
"test {pre_byte_count:e}, {pre_byte_count:e}" ,
85
- "jz 1f" ,
86
76
"add $7, %rsi" ,
87
77
"add $7, %rdi" ,
88
78
"mov {pre_byte_count:e}, %ecx" ,
89
79
"rep movsb" ,
90
- "1:" ,
91
80
"cld" ,
92
81
pre_byte_count = in( reg) pre_byte_count,
93
82
qword_count = in( reg) qword_count,
@@ -118,33 +107,27 @@ pub unsafe fn set_bytes(mut dest: *mut u8, c: u8, count: usize) {
118
107
let c = c as u64 * 0x0101_0101_0101_0101 ;
119
108
let ( pre_byte_count, qword_count, byte_count) = rep_param ( dest, count) ;
120
109
// Separating the blocks gives the compiler more freedom to reorder instructions.
121
- // It also allows us to trivially skip the rep stosb, which is faster when memcpying
122
- // aligned data.
123
- if pre_byte_count > 0 {
124
- asm ! (
125
- "rep stosb" ,
126
- inout( "ecx" ) pre_byte_count => _,
127
- inout( "rdi" ) dest => dest,
128
- in( "rax" ) c,
129
- options( att_syntax, nostack, preserves_flags)
130
- ) ;
131
- }
110
+ asm ! (
111
+ "rep stosb" ,
112
+ inout( "ecx" ) pre_byte_count => _,
113
+ inout( "rdi" ) dest => dest,
114
+ in( "rax" ) c,
115
+ options( att_syntax, nostack, preserves_flags)
116
+ ) ;
132
117
asm ! (
133
118
"rep stosq" ,
134
119
inout( "rcx" ) qword_count => _,
135
120
inout( "rdi" ) dest => dest,
136
121
in( "rax" ) c,
137
122
options( att_syntax, nostack, preserves_flags)
138
123
) ;
139
- if byte_count > 0 {
140
- asm ! (
141
- "rep stosb" ,
142
- inout( "ecx" ) byte_count => _,
143
- inout( "rdi" ) dest => _,
144
- in( "rax" ) c,
145
- options( att_syntax, nostack, preserves_flags)
146
- ) ;
147
- }
124
+ asm ! (
125
+ "rep stosb" ,
126
+ inout( "ecx" ) byte_count => _,
127
+ inout( "rdi" ) dest => _,
128
+ in( "rax" ) c,
129
+ options( att_syntax, nostack, preserves_flags)
130
+ ) ;
148
131
}
149
132
150
133
#[ inline( always) ]
0 commit comments