2023-08-15 Joern Rennecke gcc/testsuite/ * lib/target-supports.exp (check_effective_target_rv_float_abi_soft): New proc. (check_effective_target_riscv_d): Likewise. (check_effective_target_riscv_v): Likewise. (check_effective_target_riscv_zfh): Likewise. (check_effective_target_riscv_v_ok): likewise. (check_effective_target_riscv_zfh_ok): Likewise. (riscv_get_arch, add_options_for_riscv_v): Likewise. (add_options_for_riscv_zfh): Likewise. (add_options_for_riscv_d): Likewise. diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index 92b6f69730e..cdd00b4a064 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -1887,6 +1887,167 @@ proc check_effective_target_rv64 { } { }] } +# Return 1 if the target abi is __riscv_float_abi_soft, 0 otherwise. +# Cache the result. + +proc check_effective_target_rv_float_abi_soft { } { + # Check that we are compiling for RV64 by checking the xlen size. + return [check_no_compiler_messages riscv_riscv_float_abi_soft assembly { + #ifndef __riscv_float_abi_soft + #error "Not __riscv_float_abi_soft" + #endif + }] +} + +# Return 1 if the target arch supports the double precision floating point +# extension, 0 otherwise. Cache the result. + +proc check_effective_target_riscv_d { } { + return [check_no_compiler_messages riscv_ext_d assembly { + #ifndef __riscv_d + #error "Not __riscv_d" + #endif + }] +} + +# Return 1 if the target arch supports the vector extension, 0 otherwise. +# Cache the result. + +proc check_effective_target_riscv_v { } { + return [check_no_compiler_messages riscv_ext_v assembly { + #ifndef __riscv_v + #error "Not __riscv_v" + #endif + }] +} + +# Return 1 if the target arch supports half float, 0 otherwise. +# Note, this differs from the test performed by +# /* dg-skip-if "" { *-*-* } { "*" } { "-march=rv*zfh*" } */ +# in that it takes default behaviour into account. +# Cache the result. + +proc check_effective_target_riscv_zfh { } { + return [check_no_compiler_messages riscv_ext_zfh assembly { + #ifndef __riscv_zfh + #error "Not __riscv_zfh" + #endif + }] +} + +# Return 1 if we can execute code when using dg-add-options riscv_v + +proc check_effective_target_riscv_v_ok { } { + # If the target already supports v without any added options, + # we may assume we can execute just fine. + if { [check_effective_target_riscv_v] } { + return 1 + } + + # check if we can execute vector insns with the given hardware or + # simulator + set gcc_march [regsub {[[:alnum:]]*} [riscv_get_arch] &v] + if { [check_runtime ${gcc_march}_exec { + int main() { asm("vsetivli t0, 9, e8, m1, tu, ma"); return 0; } } "-march=${gcc_march}"] } { + return 1 + } + + # Possible future extensions: If the target is a simulator, dg-add-options + # might change its config to make it allow vector insns, or we might use + # options to set special elf flags / sections to effect that. + + return 0 +} + +# Return 1 if we can execute code when using dg-add-options riscv_zfh + +proc check_effective_target_riscv_zfh_ok { } { + # If the target already supports zfh without any added options, + # we may assume we can execute just fine. + # ??? Other cases we should consider: + # - target / simulator already supports zfh extension - test for that. + # - target is a simulator, and dg-add-options knows how to enable zfh support in that simulator + if { [check_effective_target_riscv_zfh] } { + return 1 + } + + # check if we can execute zfh insns with the given hardware or + # simulator + set gcc_march [riscv_get_arch] + if { [check_runtime ${gcc_march}_zfh_exec { + int main() { asm("feq.h a3,fa5,fa4"); return 0; } } "-march=${gcc_march}_zfh"] } { + return 1 + } + + # Possible future extensions: If the target is a simulator, dg-add-options + # might change its config to make it allow half float insns, or we might + # use options to set special elf flags / sections to effect that. + + return 0 +} + +proc riscv_get_arch { } { + set gcc_march "" + # ??? do we neeed to add more extensions to the list below? + foreach ext { i m a f d q c v zicsr zifencei zfh zba zbb zbc zbs } { + if { [check_no_compiler_messages riscv_ext_$ext assembly [string map [list DEF __riscv_$ext] { + #ifndef DEF + #error "Not DEF" + #endif + }]] } { + if { [string length $ext] > 1 } { + set ext _${ext} + } + set gcc_march $gcc_march$ext + } + if { [string equal $gcc_march "imafd"] } { + set gcc_march "g" + } + } + if { [check_effective_target_rv32] } { + set gcc_march rv32$gcc_march + } elseif { [check_effective_target_rv64] } { + set gcc_march rv64$gcc_march + } else { + set gcc_march "" + } + return "$gcc_march" +} + +proc add_options_for_riscv_d { flags } { + if { [lsearch $flags -march=*] >= 0 } { + # If there are multiple -march flags, we have to adjust all of them. + return [regsub -all -- {((?^|[[:space:]])-march=rv[[:digit:]]*[a-ce-rt-wy]*)d*} $flags \\1d ] + } + if { [check_effective_target_riscv_d] } { + return "$flags" + } + return "$flags -march=[regsub {[[:alnum:]]*} [riscv_get_arch] &d]" +} + +proc add_options_for_riscv_v { flags } { + if { [lsearch $flags -march=*] >= 0 } { + # If there are multiple -march flags, we have to adjust all of them. + return [regsub -all -- {((?^|[[:space:]])-march=rv[[:digit:]]*[a-rt-uwy]*)v*} $flags \\1v ] + } + if { [check_effective_target_riscv_v] } { + return "$flags" + } + return "$flags -march=[regsub {[[:alnum:]]*} [riscv_get_arch] &v]" +} + +proc add_options_for_riscv_zfh { flags } { + if { [lsearch $flags -march=*] >= 0 } { + # If there are multiple -march flags, we have to adjust all of them. + set flags [regsub -all -- {(?^|[[:space:]])-march=[[:alnum:]_.]*} $flags &_zfh ] + return [regsub -all -- {((?^|[[:space:]])-march=[[:alnum:]_.]*_zfh[[:alnum:]_.]*)_zfh} $flags \\1 ] + } + if { [check_effective_target_riscv_zfh] } { + return "$flags" + } + return "$flags -march=[riscv_get_arch]_zfh" +} + # Return 1 if the target OS supports running SSE executables, 0 # otherwise. Cache the result.