@@ -10,31 +10,6 @@ use super::intrinsic_helpers::IntrinsicTypeDefinition;
1010// The number of times each intrinsic will be called.
1111const PASSES : u32 = 20 ;
1212
13- pub fn format_rust_main_template (
14- notices : & str ,
15- definitions : & str ,
16- configurations : & str ,
17- arch_definition : & str ,
18- arglists : & str ,
19- passes : & str ,
20- ) -> String {
21- format ! (
22- r#"{notices}#![feature(simd_ffi)]
23- #![feature(f16)]
24- #![allow(unused)]
25- {configurations}
26- {definitions}
27-
28- use core_arch::arch::{arch_definition}::*;
29-
30- fn main() {{
31- {arglists}
32- {passes}
33- }}
34- "# ,
35- )
36- }
37-
3813fn write_cargo_toml ( w : & mut impl std:: io:: Write , binaries : & [ String ] ) -> std:: io:: Result < ( ) > {
3914 writeln ! (
4015 w,
@@ -123,11 +98,12 @@ pub fn compile_rust_programs(
12398}
12499
125100pub fn generate_rust_test_loop < T : IntrinsicTypeDefinition > (
101+ w : & mut impl std:: io:: Write ,
126102 intrinsic : & dyn IntrinsicDefinition < T > ,
127103 indentation : Indentation ,
128104 additional : & str ,
129105 passes : u32 ,
130- ) -> String {
106+ ) -> std :: io :: Result < ( ) > {
131107 let constraints = intrinsic. arguments ( ) . as_constraint_parameters_rust ( ) ;
132108 let constraints = if !constraints. is_empty ( ) {
133109 format ! ( "::<{constraints}>" )
@@ -138,7 +114,8 @@ pub fn generate_rust_test_loop<T: IntrinsicTypeDefinition>(
138114 let return_value = format_f16_return_value ( intrinsic) ;
139115 let indentation2 = indentation. nested ( ) ;
140116 let indentation3 = indentation2. nested ( ) ;
141- format ! (
117+ write ! (
118+ w,
142119 "{indentation}for i in 0..{passes} {{\n \
143120 {indentation2}unsafe {{\n \
144121 {loaded_args}\
@@ -153,74 +130,77 @@ pub fn generate_rust_test_loop<T: IntrinsicTypeDefinition>(
153130 )
154131}
155132
156- pub fn generate_rust_constraint_blocks < T : IntrinsicTypeDefinition > (
133+ fn generate_rust_constraint_blocks < ' a , T : IntrinsicTypeDefinition + ' a > (
134+ w : & mut impl std:: io:: Write ,
157135 intrinsic : & dyn IntrinsicDefinition < T > ,
158136 indentation : Indentation ,
159- constraints : & [ & Argument < T > ] ,
137+ constraints : & mut ( impl Iterator < Item = & ' a Argument < T > > + Clone ) ,
160138 name : String ,
161- ) -> String {
162- if let Some ( ( current, constraints) ) = constraints. split_last ( ) {
163- let range = current
164- . constraint
165- . iter ( )
166- . map ( |c| c. to_range ( ) )
167- . flat_map ( |r| r. into_iter ( ) ) ;
168-
169- let body_indentation = indentation. nested ( ) ;
170- range
171- . map ( |i| {
172- format ! (
173- "{indentation}{{\n \
174- {body_indentation}const {name}: {ty} = {val};\n \
175- {pass}\n \
176- {indentation}}}",
177- name = current. name,
178- ty = current. ty. rust_type( ) ,
179- val = i,
180- pass = generate_rust_constraint_blocks(
181- intrinsic,
182- body_indentation,
183- constraints,
184- format!( "{name}-{i}" )
185- )
186- )
187- } )
188- . join ( "\n " )
189- } else {
190- generate_rust_test_loop ( intrinsic, indentation, & name, PASSES )
139+ ) -> std:: io:: Result < ( ) > {
140+ let Some ( current) = constraints. next ( ) else {
141+ return generate_rust_test_loop ( w, intrinsic, indentation, & name, PASSES ) ;
142+ } ;
143+
144+ let body_indentation = indentation. nested ( ) ;
145+ for i in current. constraint . iter ( ) . flat_map ( |c| c. to_range ( ) ) {
146+ let ty = current. ty . rust_type ( ) ;
147+
148+ writeln ! ( w, "{indentation}{{" ) ?;
149+
150+ writeln ! ( w, "{body_indentation}const {}: {ty} = {i};" , current. name) ?;
151+
152+ generate_rust_constraint_blocks (
153+ w,
154+ intrinsic,
155+ body_indentation,
156+ & mut constraints. clone ( ) ,
157+ format ! ( "{name}-{i}" ) ,
158+ ) ?;
159+
160+ writeln ! ( w, "{indentation}}}" ) ?;
191161 }
162+
163+ Ok ( ( ) )
192164}
193165
194166// Top-level function to create complete test program
195167pub fn create_rust_test_program < T : IntrinsicTypeDefinition > (
168+ w : & mut impl std:: io:: Write ,
196169 intrinsic : & dyn IntrinsicDefinition < T > ,
197170 target : & str ,
198171 notice : & str ,
199172 definitions : & str ,
200173 cfg : & str ,
201- ) -> String {
174+ ) -> std:: io:: Result < ( ) > {
175+ let indentation = Indentation :: default ( ) ;
176+
177+ write ! ( w, "{notice}" ) ?;
178+
179+ writeln ! ( w, "#![feature(simd_ffi)]" ) ?;
180+ writeln ! ( w, "#![feature(f16)]" ) ?;
181+ writeln ! ( w, "#![allow(unused)]" ) ?;
182+
183+ writeln ! ( w, "{cfg}" ) ?;
184+ writeln ! ( w, "{definitions}" ) ?;
185+
186+ writeln ! ( w, "use core_arch::arch::{target}::*;" ) ?;
187+
188+ writeln ! ( w, "fn main() {{" ) ?;
189+
190+ // Define the arrays of arguments.
202191 let arguments = intrinsic. arguments ( ) ;
203- let constraints = arguments
204- . iter ( )
205- . filter ( |i| i. has_constraint ( ) )
206- . collect_vec ( ) ;
192+ arguments. gen_arglists_rust ( w, indentation. nested ( ) , PASSES ) ?;
207193
208- let indentation = Indentation :: default ( ) ;
209- format_rust_main_template (
210- notice,
211- definitions,
212- cfg,
213- target,
214- intrinsic
215- . arguments ( )
216- . gen_arglists_rust ( indentation. nested ( ) , PASSES )
217- . as_str ( ) ,
218- generate_rust_constraint_blocks (
219- intrinsic,
220- indentation. nested ( ) ,
221- & constraints,
222- Default :: default ( ) ,
223- )
224- . as_str ( ) ,
225- )
194+ // Define any const generics as `const` items, then generate the actual test loop.
195+ generate_rust_constraint_blocks (
196+ w,
197+ intrinsic,
198+ indentation. nested ( ) ,
199+ & mut arguments. iter ( ) . rev ( ) . filter ( |i| i. has_constraint ( ) ) ,
200+ Default :: default ( ) ,
201+ ) ?;
202+
203+ writeln ! ( w, "}}" ) ?;
204+
205+ Ok ( ( ) )
226206}
0 commit comments