@@ -2,6 +2,7 @@ use super::config::{AARCH_CONFIGURATIONS, POLY128_OSTREAM_DEF, build_notices};
2
2
use super :: intrinsic:: ArmIntrinsicType ;
3
3
use crate :: arm:: constraint:: Constraint ;
4
4
use crate :: common:: argument:: Argument ;
5
+ use crate :: common:: compile_c:: CompilationCommandBuilder ;
5
6
use crate :: common:: format:: Indentation ;
6
7
use crate :: common:: gen_c:: { compile_c, create_c_filenames, generate_c_program} ;
7
8
use crate :: common:: gen_rust:: { compile_rust, create_rust_filenames, generate_rust_program} ;
@@ -161,70 +162,55 @@ fn generate_rust_program_arm(
161
162
162
163
fn compile_c_arm (
163
164
intrinsics_name_list : & Vec < String > ,
164
- filename_mapping : BTreeMap < & String , String > ,
165
+ _filename_mapping : BTreeMap < & String , String > ,
165
166
compiler : & str ,
166
167
target : & str ,
167
168
cxx_toolchain_dir : Option < & str > ,
168
169
) -> 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
- } ;
170
+ let mut command = CompilationCommandBuilder :: new ( )
171
+ . add_arch_flags ( vec ! [ "armv8.6-a" , "crypto" , "crc" , "dotprod" , "fp16" ] )
172
+ . set_compiler ( compiler )
173
+ . set_target ( target )
174
+ . set_opt_level ( "2" )
175
+ . set_cxx_toolchain_dir ( cxx_toolchain_dir )
176
+ . set_project_root ( "c_programs" )
177
+ . add_extra_flags ( vec ! [ "-ffp-contract=off" , "-Wno-narrowing" ] ) ;
177
178
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
- ) ;
183
- } ;
179
+ if !target. contains ( "v7" ) {
180
+ command = command. add_arch_flags ( vec ! [ "faminmax" , "lut" , "sha3" ] ) ;
181
+ }
184
182
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",
183
+ command = if target == "aarch64_be-unknown-linux-gnu" {
184
+ command
185
+ . set_linker (
186
+ cxx_toolchain_dir. unwrap_or ( "" ) . to_string ( ) + "/bin/aarch64_be-none-linux-gnu-g++" ,
208
187
)
188
+ . set_include_paths ( vec ! [
189
+ "/include" ,
190
+ "/aarch64_be-none-linux-gnu/include" ,
191
+ "/aarch64_be-none-linux-gnu/include/c++/14.2.1" ,
192
+ "/aarch64_be-none-linux-gnu/include/c++/14.2.1/aarch64_be-none-linux-gnu" ,
193
+ "/aarch64_be-none-linux-gnu/include/c++/14.2.1/backward" ,
194
+ "/aarch64_be-none-linux-gnu/libc/usr/include" ,
195
+ ] )
196
+ } else {
197
+ if compiler. contains ( "clang" ) {
198
+ command. add_extra_flag ( format ! ( "-target {target}" ) . as_str ( ) )
209
199
} 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
- ) ;
214
-
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}" )
220
- } else {
221
- format ! ( "{base_compiler_command} -flax-vector-conversions" )
222
- }
223
- } ;
200
+ command. add_extra_flag ( "-flax-vector-conversions" )
201
+ }
202
+ } ;
224
203
225
- compiler_command
226
- } )
227
- . collect :: < Vec < _ > > ( ) ;
204
+ let compiler_commands = intrinsics_name_list
205
+ . iter ( )
206
+ . map ( |intrinsic_name| {
207
+ command
208
+ . clone ( )
209
+ . set_input_name ( intrinsic_name)
210
+ . set_output_name ( intrinsic_name)
211
+ . to_string ( )
212
+ } )
213
+ . collect :: < Vec < _ > > ( ) ;
228
214
229
215
compile_c ( & compiler_commands)
230
216
}
0 commit comments