@@ -5,20 +5,12 @@ mod intrinsic;
55mod types;
66mod xml_parser;
77
8- use rayon:: prelude:: * ;
9- use std:: fs:: { self , File } ;
10-
8+ use crate :: common:: SupportedArchitectureTest ;
119use crate :: common:: cli:: ProcessedCli ;
1210use 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 } ;
11+ use crate :: common:: compile_c:: CppCompilation ;
12+ use crate :: common:: intrinsic:: Intrinsic ;
1813use 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;
2214use intrinsic:: X86IntrinsicType ;
2315use xml_parser:: get_xml_intrinsics;
2416
@@ -28,7 +20,30 @@ pub struct X86ArchitectureTest {
2820}
2921
3022impl SupportedArchitectureTest for X86ArchitectureTest {
31- fn create ( cli_options : ProcessedCli ) -> Box < Self > {
23+ type IntrinsicImpl = X86IntrinsicType ;
24+
25+ fn cli_options ( & self ) -> & ProcessedCli {
26+ & self . cli_options
27+ }
28+
29+ fn intrinsics ( & self ) -> & [ Intrinsic < X86IntrinsicType > ] {
30+ & self . intrinsics
31+ }
32+
33+ fn cpp_compilation ( & self ) -> Option < CppCompilation > {
34+ compile:: build_cpp_compilation ( & self . cli_options )
35+ }
36+
37+ const NOTICE : & str = config:: NOTICE ;
38+
39+ const PLATFORM_C_HEADERS : & [ & str ] = & [ "immintrin.h" ] ;
40+ const PLATFORM_C_DEFINITIONS : & str = config:: LANE_FUNCTION_HELPERS ;
41+ const PLATFORM_C_FORWARD_DECLARATIONS : & str = "" ;
42+
43+ const PLATFORM_RUST_DEFINITIONS : & str = config:: F16_FORMATTING_DEF ;
44+ const PLATFORM_RUST_CFGS : & str = config:: X86_CONFIGURATIONS ;
45+
46+ fn create ( cli_options : ProcessedCli ) -> Self {
3247 let intrinsics =
3348 get_xml_intrinsics ( & cli_options. filename ) . expect ( "Error parsing input file" ) ;
3449
@@ -37,7 +52,7 @@ impl SupportedArchitectureTest for X86ArchitectureTest {
3752 // Not sure how we would compare intrinsic that returns void.
3853 . filter ( |i| i. results . kind ( ) != TypeKind :: Void )
3954 . filter ( |i| i. results . kind ( ) != TypeKind :: BFloat )
40- . filter ( |i| i. arguments ( ) . args . len ( ) > 0 )
55+ . filter ( |i| i. arguments . args . len ( ) > 0 )
4156 . filter ( |i| !i. arguments . iter ( ) . any ( |a| a. ty . kind ( ) == TypeKind :: BFloat ) )
4257 // Skip pointers for now, we would probably need to look at the return
4358 // type to work out how many elements we need to point to.
@@ -47,132 +62,10 @@ impl SupportedArchitectureTest for X86ArchitectureTest {
4762 . collect :: < Vec < _ > > ( ) ;
4863
4964 intrinsics. sort_by ( |a, b| a. name . cmp ( & b. name ) ) ;
50- Box :: new ( Self {
65+ Self {
5166 intrinsics : intrinsics,
5267 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:?}" ) ;
11668 }
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)
17669 }
17770
17871 fn compare_outputs ( & self ) -> bool {
0 commit comments