@@ -2,6 +2,7 @@ use super::config::{AARCH_CONFIGURATIONS, POLY128_OSTREAM_DEF, build_notices};
22use super :: intrinsic:: ArmIntrinsicType ;
33use crate :: arm:: constraint:: Constraint ;
44use crate :: common:: argument:: Argument ;
5+ use crate :: common:: compile_c:: CompilationCommandBuilder ;
56use crate :: common:: format:: Indentation ;
67use crate :: common:: gen_c:: { compile_c, create_c_filenames, generate_c_program} ;
78use crate :: common:: gen_rust:: { compile_rust, create_rust_filenames, generate_rust_program} ;
@@ -161,72 +162,67 @@ fn generate_rust_program_arm(
161162
162163fn compile_c_arm (
163164 intrinsics_name_list : & Vec < String > ,
164- filename_mapping : BTreeMap < & String , String > ,
165+ _filename_mapping : BTreeMap < & String , String > ,
165166 compiler : & str ,
166167 target : & str ,
167168 cxx_toolchain_dir : Option < & str > ,
168169) -> bool {
169- let compiler_commands = intrinsics_name_list. iter ( ) . map ( |intrinsic_name| {
170- let c_filename = filename_mapping. get ( intrinsic_name) . unwrap ( ) ;
171- let flags = std:: env:: var ( "CPPFLAGS" ) . unwrap_or ( "" . into ( ) ) ;
172- let arch_flags = if target. contains ( "v7" ) {
173- "-march=armv8.6-a+crypto+crc+dotprod+fp16"
174- } else {
175- "-march=armv8.6-a+crypto+sha3+crc+dotprod+fp16+faminmax+lut"
176- } ;
177-
178- let compiler_command = if target == "aarch64_be-unknown-linux-gnu" {
179- let Some ( cxx_toolchain_dir) = cxx_toolchain_dir else {
180- panic ! (
181- "When setting `--target aarch64_be-unknown-linux-gnu` the C++ compilers toolchain directory must be set with `--cxx-toolchain-dir <dest>`"
182- ) ;
170+ let compiler_commands = intrinsics_name_list
171+ . iter ( )
172+ . map ( |intrinsic_name| {
173+ let mut command = CompilationCommandBuilder :: new ( ) ;
174+ if target. contains ( "v7" ) {
175+ command. set_arch_flags ( vec ! [ "armv8.6-a" , "crypto" , "crc" , "dotprod" , "fp16" ] )
176+ } else {
177+ command. set_arch_flags ( vec ! [
178+ "armv8.6-a" ,
179+ "crypto" ,
180+ "crc" ,
181+ "dotprod" ,
182+ "fp16" ,
183+ "sha3" ,
184+ "faminmax" ,
185+ "lut"
186+ ] )
183187 } ;
184188
185- /* clang++ cannot link an aarch64_be object file, so we invoke
186- * aarch64_be-unknown-linux-gnu's C++ linker. This ensures that we
187- * are testing the intrinsics against LLVM.
188- *
189- * Note: setting `--sysroot=<...>` which is the obvious thing to do
190- * does not work as it gets caught up with `#include_next <stdlib.h>`
191- * not existing... */
192- format ! (
193- "{compiler} {flags} {arch_flags} \
194- -ffp-contract=off \
195- -Wno-narrowing \
196- -O2 \
197- --target=aarch64_be-unknown-linux-gnu \
198- -I{cxx_toolchain_dir}/include \
199- -I{cxx_toolchain_dir}/aarch64_be-none-linux-gnu/include \
200- -I{cxx_toolchain_dir}/aarch64_be-none-linux-gnu/include/c++/14.2.1 \
201- -I{cxx_toolchain_dir}/aarch64_be-none-linux-gnu/include/c++/14.2.1/aarch64_be-none-linux-gnu \
202- -I{cxx_toolchain_dir}/aarch64_be-none-linux-gnu/include/c++/14.2.1/backward \
203- -I{cxx_toolchain_dir}/aarch64_be-none-linux-gnu/libc/usr/include \
204- -c {c_filename} \
205- -o c_programs/{intrinsic_name}.o && \
206- {cxx_toolchain_dir}/bin/aarch64_be-none-linux-gnu-g++ c_programs/{intrinsic_name}.o -o c_programs/{intrinsic_name} && \
207- rm c_programs/{intrinsic_name}.o",
208- )
209- } else {
210- // -ffp-contract=off emulates Rust's approach of not fusing separate mul-add operations
211- let base_compiler_command = format ! (
212- "{compiler} {flags} {arch_flags} -o c_programs/{intrinsic_name} {c_filename} -ffp-contract=off -Wno-narrowing -O2"
213- ) ;
189+ command = command
190+ . set_compiler ( compiler)
191+ . set_output_name ( intrinsic_name)
192+ . set_target ( target)
193+ . set_opt_level ( "2" )
194+ . set_cxx_toolchain_dir ( cxx_toolchain_dir)
195+ . set_project_root ( "c_programs" )
196+ . set_input_name ( intrinsic_name)
197+ . add_extra_flags ( vec ! [ "-ffp-contract=off" , "-Wno-narrowing" ] ) ;
214198
215- /* `-target` can be passed to some c++ compilers, however if we want to
216- * use a c++ compiler does not support this flag we do not want to pass
217- * the flag. */
218- if compiler. contains ( "clang" ) {
219- format ! ( "{base_compiler_command} -target {target}" )
199+ command = if target == "aarch64_be-unknown-linux-gnu" {
200+ command
201+ . set_linker (
202+ cxx_toolchain_dir. unwrap_or ( "" ) . to_string ( )
203+ + "/bin/aarch64_be-none-linux-gnu-g++" ,
204+ )
205+ . set_include_paths ( vec ! [
206+ "/include" ,
207+ "/aarch64_be-none-linux-gnu/include" ,
208+ "/aarch64_be-none-linux-gnu/include/c++/14.2.1" ,
209+ "/aarch64_be-none-linux-gnu/include/c++/14.2.1/aarch64_be-none-linux-gnu" ,
210+ "/aarch64_be-none-linux-gnu/include/c++/14.2.1/backward" ,
211+ "/aarch64_be-none-linux-gnu/libc/usr/include"
212+ ] )
220213 } else {
221- format ! ( "{base_compiler_command} -flax-vector-conversions" )
222- }
223- } ;
214+ if compiler. contains ( "clang" ) {
215+ command. add_extra_flag ( format ! ( "-target {target}" ) . as_str ( ) )
216+ } else {
217+ command. add_extra_flag ( "-flax-vector-conversions" )
218+ }
219+ } ;
224220
225- compiler_command
226- } )
227- . collect :: < Vec < _ > > ( ) ;
221+ command . as_str ( )
222+ } )
223+ . collect :: < Vec < _ > > ( ) ;
228224
229- compile_c ( & compiler_commands)
225+ compile_c ( & compiler_commands)
230226}
231227
232228pub fn build_c (
0 commit comments