@@ -125,10 +125,11 @@ pub fn phaddw(a: i16x16, b: i16x16) -> i16x16 {
125125
126126### Modeling defined intrinsics semi-automatically
127127
128- To model a defined intrinsic, we essentially copy the Rust code of
129- the intrinsic from ` core::arch ` and adapt it to use our underlying abstractions. The
130- changes needed to the code are sometimes scriptable, and indeed most
131- of our models were generated from a script, but some changes are still
128+ To model a defined intrinsic, we essentially copy the Rust code of the
129+ intrinsic from ` core::arch ` and adapt it to use our underlying
130+ abstractions. The changes needed to the code are sometimes
131+ scriptable, and indeed most of our models were generated from a script
132+ (see the ANNEX at the bottom of this file), but some changes are still
132133needed by hand.
133134
134135For example, let us say the intrinsic we are modeling is
@@ -176,8 +177,19 @@ pub fn _mm256_bsrli_epi128<const IMM8: i32>(a: __m256i) -> __m256i {
176177```
177178
178179Thus, we then go to ` core_arch/x86/models/avx2.rs ` , and add this implementation.
179- The only change it requires here is that the ` simd_shuffle ` macro is a function in our model,
180- and we discard all the function attributes.
180+ The only changes it requires here are that the ` simd_shuffle ` macro is a function in our model,
181+ the ` ZERO ` constant is now a function, and we discard all the function attributes.
182+
183+ The exact diff between the original and edited code for this function is:
184+
185+ ``` diff
186+ 13,14c13,14
187+ < let r: i8x32 = simd_shuffle(
188+ < i8x32::ZERO(),
189+ ---
190+ > let r: i8x32 = simd_shuffle!(
191+ > i8x32::ZERO,
192+ ```
181193
182194For other intrinsics, we sometimes need to make more changes. Since our model of the builtin intrinsics
183195is more precise concerning the type of their arguments compared to their Rust counterparts, we
@@ -224,3 +236,84 @@ us](https://github.com/rust-lang/stdarch/issues/1822) using a failing
224236test case generated from the testable model and then fixed by [ our
225237PR] ( https://github.com/rust-lang/stdarch/pull/1823 ) in the 2025-06-30
226238version of ` stdarch ` .
239+
240+
241+ ## ANNEX: Extraction Script
242+
243+ The following Rust program is a simple script that uses the ` syn ` crate to process an input Rust file
244+ containing SIMD intrinsics into one suitable for the models described in this document. This code
245+ is provided as illustration; for each set of core libraries we wish to model and test, there will
246+ likely be need for a similar (or extended) script to automate the modeling process.
247+
248+ ``` rust
249+ use syn :: * ;
250+ use std :: fs;
251+ use std :: env;
252+
253+ fn extract_model (input_file_path : & str , output_file_path : & str ) -> Result <()> {
254+ let source_code = fs :: read_to_string (input_file_path ). expect (" unable to read file" );
255+ let mut syntax_tree : File = parse_file (& source_code )? ;
256+
257+ syntax_tree . items. retain (| item |
258+ match item {
259+ Item :: Use (_ ) => false ,
260+ _ => true
261+ }
262+ );
263+
264+ // Clear attributes from the file's top-level items
265+ for item in & mut syntax_tree . items {
266+ match item {
267+ Item :: Const (const_item ) => {
268+ const_item . attrs. retain (| attr | attr . path (). is_ident (" doc" ));
269+ },
270+ Item :: Fn (item_fn ) => {
271+ item_fn . attrs. retain (| attr | attr . path (). is_ident (" doc" ));
272+ item_fn . block. stmts. retain (| stmt |
273+ match stmt {
274+ Stmt :: Item (Item :: ForeignMod (_ )) => false ,
275+ _ => true
276+ }
277+ );
278+ for stmt in & mut item_fn . block. stmts {
279+ match stmt {
280+ Stmt :: Expr (Expr :: Unsafe (u ), tok ) => * stmt = Stmt :: Expr (Expr :: Block (
281+ ExprBlock {attrs : Vec :: new (), label : None , block : u . block. clone ()}), * tok ),
282+ _ => ()
283+ }
284+ }
285+ },
286+ Item :: Struct (item_struct ) => {
287+ item_struct . attrs. clear ();
288+ for field in & mut item_struct . fields {
289+ field . attrs. retain (| attr | attr . path (). is_ident (" doc" ));
290+ }
291+ },
292+ Item :: Enum (item_enum ) => {
293+ item_enum . attrs. clear ();
294+ for variant in & mut item_enum . variants {
295+ variant . attrs. retain (| attr | attr . path (). is_ident (" doc" ));
296+ }
297+ },
298+ // Add more cases for other Item types (e.g., Item::Mod, Item::Impl, etc.)
299+ _ => {
300+ // For other item types, if they have an 'attrs' field, clear it.
301+ // This requires more specific matching or a helper trait.
302+ }
303+ }
304+ }
305+
306+ let formatted_string = prettyplease :: unparse (& syntax_tree );
307+ fs :: write (output_file_path , formatted_string ). expect (" unable to write file" );
308+
309+ Ok (())
310+ }
311+
312+ fn main () -> Result <()> {
313+ let args : Vec <String > = env :: args (). collect ();
314+ if args . len () < 3 {
315+ println! (" usage: modelize <path to input Rust file> <path to output Rust file>" )
316+ }
317+ extract_model (& args [1 ], & args [2 ])
318+ }
319+ ```
0 commit comments