@@ -125,7 +125,7 @@ fn parse(output: &str) -> HashSet<Function> {
125
125
cached_header = None ;
126
126
break ;
127
127
}
128
- let parts = if cfg ! ( target_env = "msvc" ) {
128
+ let mut parts = if cfg ! ( target_env = "msvc" ) {
129
129
// Each line looks like:
130
130
//
131
131
// > $addr: ab cd ef $instr..
@@ -152,6 +152,29 @@ fn parse(output: &str) -> HashSet<Function> {
152
152
. map ( std:: string:: ToString :: to_string)
153
153
. collect :: < Vec < String > > ( )
154
154
} ;
155
+
156
+ if cfg ! ( target_arch = "aarch64" ) {
157
+ // Normalize [us]shll.* ..., #0 instructions to the preferred form: [us]xtl.* ...
158
+ // as LLVM objdump does not do that.
159
+ // See https://developer.arm.com/documentation/ddi0602/latest/SIMD-FP-Instructions/UXTL--UXTL2--Unsigned-extend-Long--an-alias-of-USHLL--USHLL2-
160
+ // and https://developer.arm.com/documentation/ddi0602/latest/SIMD-FP-Instructions/SXTL--SXTL2--Signed-extend-Long--an-alias-of-SSHLL--SSHLL2-
161
+ // for details.
162
+ match ( parts. first ( ) , parts. last ( ) ) {
163
+ ( Some ( instr) , Some ( last_arg) )
164
+ if ( instr. starts_with ( "ushll." ) || instr. starts_with ( "sshll." ) )
165
+ && last_arg == "#0" =>
166
+ {
167
+ assert_eq ! ( parts. len( ) , 4 ) ;
168
+ let mut new_parts = Vec :: with_capacity ( 3 ) ;
169
+ let new_instr = format ! ( "{}{}{}" , & instr[ ..1 ] , "xtl" , & instr[ 5 ..] ) ;
170
+ new_parts. push ( new_instr) ;
171
+ new_parts. push ( parts[ 1 ] . clone ( ) ) ;
172
+ new_parts. push ( parts[ 2 ] [ 0 ..parts[ 2 ] . len ( ) - 1 ] . to_owned ( ) ) ; // strip trailing comma
173
+ parts = new_parts;
174
+ }
175
+ _ => { }
176
+ } ;
177
+ }
155
178
instructions. push ( parts. join ( " " ) ) ;
156
179
}
157
180
let function = Function {
0 commit comments