@@ -8,17 +8,12 @@ mod xml_parser;
88use  rayon:: prelude:: * ; 
99use  std:: fs:: { self ,  File } ; 
1010
11+ use  crate :: common:: SupportedArchitectureTest ; 
1112use  crate :: common:: cli:: ProcessedCli ; 
1213use  crate :: common:: compare:: compare_outputs; 
13- use  crate :: common:: gen_c:: { write_main_cpp,  write_mod_cpp} ; 
14- use  crate :: common:: gen_rust:: { 
15-     compile_rust_programs,  write_bin_cargo_toml,  write_lib_cargo_toml,  write_lib_rs,  write_main_rs, 
16- } ; 
17- use  crate :: common:: intrinsic:: { Intrinsic ,  IntrinsicDefinition } ; 
14+ use  crate :: common:: compile_c:: CppCompilation ; 
15+ use  crate :: common:: intrinsic:: Intrinsic ; 
1816use  crate :: common:: intrinsic_helpers:: TypeKind ; 
19- use  crate :: common:: { SupportedArchitectureTest ,  chunk_info} ; 
20- use  crate :: x86:: config:: { F16_FORMATTING_DEF ,  LANE_FUNCTION_HELPERS ,  X86_CONFIGURATIONS } ; 
21- use  config:: build_notices; 
2217use  intrinsic:: X86IntrinsicType ; 
2318use  xml_parser:: get_xml_intrinsics; 
2419
@@ -28,7 +23,30 @@ pub struct X86ArchitectureTest {
2823} 
2924
3025impl  SupportedArchitectureTest  for  X86ArchitectureTest  { 
31-     fn  create ( cli_options :  ProcessedCli )  -> Box < Self >  { 
26+     type  IntrinsicImpl  = X86IntrinsicType ; 
27+ 
28+     fn  cli_options ( & self )  -> & ProcessedCli  { 
29+         & self . cli_options 
30+     } 
31+ 
32+     fn  intrinsics ( & self )  -> & [ Intrinsic < X86IntrinsicType > ]  { 
33+         & self . intrinsics 
34+     } 
35+ 
36+     fn  cpp_compilation ( & self )  -> Option < CppCompilation >  { 
37+         compile:: build_cpp_compilation ( & self . cli_options ) 
38+     } 
39+ 
40+     const  NOTICE :  & str  = config:: NOTICE ; 
41+ 
42+     const  PLATFORM_C_HEADERS :  & [ & str ]  = & [ "immintrin.h" ] ; 
43+     const  PLATFORM_C_DEFINITIONS :  & str  = config:: LANE_FUNCTION_HELPERS ; 
44+     const  PLATFORM_C_FORWARD_DECLARATIONS :  & str  = "" ; 
45+ 
46+     const  PLATFORM_RUST_DEFINITIONS :  & str  = config:: F16_FORMATTING_DEF ; 
47+     const  PLATFORM_RUST_CFGS :  & str  = config:: X86_CONFIGURATIONS ; 
48+ 
49+     fn  create ( cli_options :  ProcessedCli )  -> Self  { 
3250        let  intrinsics =
3351            get_xml_intrinsics ( & cli_options. filename ) . expect ( "Error parsing input file" ) ; 
3452
@@ -37,7 +55,7 @@ impl SupportedArchitectureTest for X86ArchitectureTest {
3755            // Not sure how we would compare intrinsic that returns void. 
3856            . filter ( |i| i. results . kind ( )  != TypeKind :: Void ) 
3957            . filter ( |i| i. results . kind ( )  != TypeKind :: BFloat ) 
40-             . filter ( |i| i. arguments ( ) . args . len ( )  > 0 ) 
58+             . filter ( |i| i. arguments . args . len ( )  > 0 ) 
4159            . filter ( |i| !i. arguments . iter ( ) . any ( |a| a. ty . kind ( )  == TypeKind :: BFloat ) ) 
4260            // Skip pointers for now, we would probably need to look at the return 
4361            // type to work out how many elements we need to point to. 
@@ -47,132 +65,10 @@ impl SupportedArchitectureTest for X86ArchitectureTest {
4765            . collect :: < Vec < _ > > ( ) ; 
4866
4967        intrinsics. sort_by ( |a,  b| a. name . cmp ( & b. name ) ) ; 
50-         Box :: new ( Self  { 
68+         Self  { 
5169            intrinsics :  intrinsics, 
5270            cli_options :  cli_options, 
53-         } ) 
54-     } 
55- 
56-     fn  build_c_file ( & self )  -> bool  { 
57-         let  c_target = "x86_64" ; 
58-         let  platform_headers = & [ "immintrin.h" ] ; 
59- 
60-         let  ( chunk_size,  chunk_count)  = chunk_info ( self . intrinsics . len ( ) ) ; 
61- 
62-         let  cpp_compiler_wrapped = compile:: build_cpp_compilation ( & self . cli_options ) ; 
63- 
64-         let  notice = & build_notices ( "// " ) ; 
65-         fs:: create_dir_all ( "c_programs" ) . unwrap ( ) ; 
66-         self . intrinsics 
67-             . par_chunks ( chunk_size) 
68-             . enumerate ( ) 
69-             . map ( |( i,  chunk) | { 
70-                 let  c_filename = format ! ( "c_programs/mod_{i}.cpp" ) ; 
71-                 let  mut  file = File :: create ( & c_filename) . unwrap ( ) ; 
72-                 write_mod_cpp ( & mut  file,  notice,  c_target,  platform_headers,  chunk) . unwrap ( ) ; 
73- 
74-                 // compile this cpp file into a .o file. 
75-                 // 
76-                 // This is done because `cpp_compiler_wrapped` is None when 
77-                 // the --generate-only flag is passed 
78-                 if  let  Some ( cpp_compiler)  = cpp_compiler_wrapped. as_ref ( )  { 
79-                     let  output = cpp_compiler
80-                         . compile_object_file ( & format ! ( "mod_{i}.cpp" ) ,  & format ! ( "mod_{i}.o" ) ) ?; 
81-                     assert ! ( output. status. success( ) ,  "{output:?}" ) ; 
82-                 } 
83- 
84-                 Ok ( ( ) ) 
85-             } ) 
86-             . collect :: < Result < ( ) ,  std:: io:: Error > > ( ) 
87-             . unwrap ( ) ; 
88- 
89-         let  mut  file = File :: create ( "c_programs/main.cpp" ) . unwrap ( ) ; 
90-         write_main_cpp ( 
91-             & mut  file, 
92-             c_target, 
93-             "\n " , 
94-             self . intrinsics . iter ( ) . map ( |i| i. name . as_str ( ) ) , 
95-         ) 
96-         . unwrap ( ) ; 
97- 
98-         // This is done because `cpp_compiler_wrapped` is None when 
99-         // the --generate-only flag is passed 
100-         if  let  Some ( cpp_compiler)  = cpp_compiler_wrapped. as_ref ( )  { 
101-             // compile this cpp file into a .o file 
102-             info ! ( "compiling main.cpp" ) ; 
103-             let  output = cpp_compiler
104-                 . compile_object_file ( "main.cpp" ,  "intrinsic-test-programs.o" ) 
105-                 . unwrap ( ) ; 
106-             assert ! ( output. status. success( ) ,  "{output:?}" ) ; 
107- 
108-             let  object_files = ( 0 ..chunk_count) 
109-                 . map ( |i| format ! ( "mod_{i}.o" ) ) 
110-                 . chain ( [ "intrinsic-test-programs.o" . to_owned ( ) ] ) ; 
111- 
112-             let  output = cpp_compiler
113-                 . link_executable ( object_files,  "intrinsic-test-programs" ) 
114-                 . unwrap ( ) ; 
115-             assert ! ( output. status. success( ) ,  "{output:?}" ) ; 
11671        } 
117- 
118-         true 
119-     } 
120- 
121-     fn  build_rust_file ( & self )  -> bool  { 
122-         std:: fs:: create_dir_all ( "rust_programs/src" ) . unwrap ( ) ; 
123- 
124-         let  architecture = if  self . cli_options . target . contains ( "v7" )  { 
125-             "arm" 
126-         }  else  { 
127-             "aarch64" 
128-         } ; 
129- 
130-         let  ( chunk_size,  chunk_count)  = chunk_info ( self . intrinsics . len ( ) ) ; 
131- 
132-         let  mut  cargo = File :: create ( "rust_programs/Cargo.toml" ) . unwrap ( ) ; 
133-         write_bin_cargo_toml ( & mut  cargo,  chunk_count) . unwrap ( ) ; 
134- 
135-         let  mut  main_rs = File :: create ( "rust_programs/src/main.rs" ) . unwrap ( ) ; 
136-         write_main_rs ( 
137-             & mut  main_rs, 
138-             chunk_count, 
139-             X86_CONFIGURATIONS , 
140-             LANE_FUNCTION_HELPERS , 
141-             self . intrinsics . iter ( ) . map ( |i| i. name . as_str ( ) ) , 
142-         ) 
143-         . unwrap ( ) ; 
144- 
145-         let  target = & self . cli_options . target ; 
146-         let  toolchain = self . cli_options . toolchain . as_deref ( ) ; 
147-         let  linker = self . cli_options . linker . as_deref ( ) ; 
148- 
149-         let  notice = & build_notices ( "// " ) ; 
150-         self . intrinsics 
151-             . par_chunks ( chunk_size) 
152-             . enumerate ( ) 
153-             . map ( |( i,  chunk) | { 
154-                 std:: fs:: create_dir_all ( format ! ( "rust_programs/mod_{i}/src" ) ) ?; 
155- 
156-                 let  rust_filename = format ! ( "rust_programs/mod_{i}/src/lib.rs" ) ; 
157-                 trace ! ( "generating `{rust_filename}`" ) ; 
158-                 let  mut  file = File :: create ( rust_filename) ?; 
159- 
160-                 let  cfg = X86_CONFIGURATIONS ; 
161-                 let  definitions = F16_FORMATTING_DEF ; 
162-                 write_lib_rs ( & mut  file,  architecture,  notice,  cfg,  definitions,  chunk) ?; 
163- 
164-                 let  toml_filename = format ! ( "rust_programs/mod_{i}/Cargo.toml" ) ; 
165-                 trace ! ( "generating `{toml_filename}`" ) ; 
166-                 let  mut  file = File :: create ( toml_filename) . unwrap ( ) ; 
167- 
168-                 write_lib_cargo_toml ( & mut  file,  & format ! ( "mod_{i}" ) ) ?; 
169- 
170-                 Ok ( ( ) ) 
171-             } ) 
172-             . collect :: < Result < ( ) ,  std:: io:: Error > > ( ) 
173-             . unwrap ( ) ; 
174- 
175-         compile_rust_programs ( toolchain,  target,  linker) 
17672    } 
17773
17874    fn  compare_outputs ( & self )  -> bool  { 
0 commit comments