-
Notifications
You must be signed in to change notification settings - Fork 277
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
183 lines (161 loc) · 7.16 KB
/
Copy pathCMakeLists.txt
File metadata and controls
183 lines (161 loc) · 7.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# First party tests
# There are three options for cross-compilation of an RV32 program.
#
# 1. Clang, which is sensibly designed to be able to cross-compile to any architecture it supports.
# Unfortunately it is possible to build it without RISC-V support, e.g. RHEL 8 does this, so we
# need to check that. You can download a binary from https://github.com/llvm/llvm-project/releases
# 2. GCC via riscv32-unknown-elf-gcc. Unlike Clang you have to specifically build GCC as a cross
# compiler. You can download a binary from https://github.com/riscv-collab/riscv-gnu-toolchain/releases
# 3. GCC via riscv64-unknown-elf-gcc, but only if it has "multilib" support, so we'll try riscv32-... first.
find_program(CLANG_BIN "clang")
find_program(GCC_BIN_RV32 "riscv32-unknown-elf-gcc")
find_program(GCC_BIN_RV64 "riscv64-unknown-elf-gcc")
if (CLANG_BIN)
message(STATUS "Found clang: ${CLANG_BIN}")
endif()
if (GCC_BIN_RV32)
message(STATUS "Found riscv32-unknown-elf-gcc: ${GCC_BIN_RV32}")
endif()
if (GCC_BIN_RV64)
message(STATUS "Found riscv64-unknown-elf-gcc: ${GCC_BIN_RV64}")
endif()
set(CROSS_COMPILER_COMMAND_RV32)
set(CROSS_COMPILER_COMMAND_RV64)
# Prefer Clang.
if (CLANG_BIN)
# Check it supports RISC-V.
execute_process(
COMMAND clang -print-targets
OUTPUT_VARIABLE clang_targets
COMMAND_ERROR_IS_FATAL ANY
)
# Check if `riscv32` is present in the output
if (clang_targets MATCHES "riscv32")
set(CROSS_COMPILER_COMMAND_RV32 ${CLANG_BIN} --target=riscv32 -fuse-ld=lld)
set(CROSS_COMPILER_COMMAND_RV64 ${CLANG_BIN} --target=riscv64 -fuse-ld=lld)
endif()
endif()
# Prefer riscv32-unknown-elf-gcc to riscv64-unknown-elf-gcc for RV32.
if (GCC_BIN_RV32)
if (NOT CROSS_COMPILER_COMMAND_RV32)
set(CROSS_COMPILER_COMMAND_RV32 ${GCC_BIN_RV32})
endif()
endif()
if (GCC_BIN_RV64)
if (NOT CROSS_COMPILER_COMMAND_RV32)
# It might support multilib.
set(CROSS_COMPILER_COMMAND_RV32 ${GCC_BIN_RV64})
endif()
if (NOT CROSS_COMPILER_COMMAND_RV64)
set(CROSS_COMPILER_COMMAND_RV64 ${GCC_BIN_RV64})
endif()
endif()
if (NOT CROSS_COMPILER_COMMAND_RV32 OR NOT CROSS_COMPILER_COMMAND_RV64)
if (CLANG_BIN)
message(FATAL_ERROR "Your Clang compiler does not support RISC-V (see '${CLANG_BIN} -print-targets') and another suitable cross-compiler was not found. Please download one from https://github.com/llvm/llvm-project/releases")
else()
message(FATAL_ERROR "No suitable cross-compiler found. We recommend downloading Clang from https://github.com/llvm/llvm-project/releases")
endif()
endif()
# On macOS, use lld instead of the system linker which does not support ELF
if (APPLE)
set(CROSS_COMPILER_COMMAND_RV32 ${CROSS_COMPILER_COMMAND_RV32} -fuse-ld=lld)
set(CROSS_COMPILER_COMMAND_RV64 ${CROSS_COMPILER_COMMAND_RV64} -fuse-ld=lld)
endif()
message(STATUS "Compiling RV32 tests with: ${CROSS_COMPILER_COMMAND_RV32}")
message(STATUS "Compiling RV64 tests with: ${CROSS_COMPILER_COMMAND_RV64}")
set(common_deps
"src/common/crt0.S"
"src/common/encoding.h"
"src/common/link.ld"
"src/common/nanoprintf.c"
"src/common/nanoprintf.h"
"src/common/runtime.c"
"src/common/runtime.h"
)
set(tests)
macro(add_first_party_test_with_config name march xlen override_json_file)
list(APPEND tests "${name}" "${march}" "${xlen}" "${override_json_file}")
endmacro()
macro(add_first_party_test name)
set(isa_extension gcv_zfbfmin)
add_first_party_test_with_config("${name}" "rv32${isa_extension}" 32 "no_override.json")
add_first_party_test_with_config("${name}" "rv64${isa_extension}" 64 "no_override.json")
endmacro()
add_first_party_test("test_bf16_nan_boxing.S")
add_first_party_test("test_hello_world.c")
add_first_party_test("test_max_pmp.c")
add_first_party_test("test_minstret.S")
add_first_party_test("test_misaligned_vector_register_groups.S")
add_first_party_test("test_pmp_access.c")
add_first_party_test("test_phys_perms_on_failing_sc.S")
add_first_party_test("test_wfi_wait.S")
add_first_party_test_with_config("test_zilsd.S" "rv32gcv" 32 "no_override.json")
add_first_party_test_with_config("test_zclsd.S" "rv32gv" 32 "test_zclsd.json")
list(LENGTH tests tests_len)
math(EXPR test_last "${tests_len} - 1")
foreach(idx RANGE 0 ${test_last} 4)
list(SUBLIST tests ${idx} 4 entry)
list(GET entry 0 test_source)
list(GET entry 1 march)
list(GET entry 2 xlen)
list(GET entry 3 override_config)
set(arch "rv${xlen}d")
if (xlen EQUAL 32)
set(mabi "ilp32")
else()
set(mabi "lp64")
endif()
set(config "${CMAKE_BINARY_DIR}/config/${arch}_v256_e${xlen}.json")
set(override_config "${CMAKE_CURRENT_SOURCE_DIR}/src/${override_config}")
set(elf "${arch}_${test_source}.elf")
add_custom_command(
OUTPUT ${elf}
DEPENDS ${common_deps} "src/${test_source}"
COMMAND ${CROSS_COMPILER_COMMAND_RV${xlen}}
# The ISA string to compile for.
# TODO: We should get this from running sail_riscv_sim `--print-isa-string`
# but it isn't quite usable with Clang directly yet due to some
# unsupported supervisor extensions and because Clang requires version
# for experimental extensions.
-march=${march}
# Calling convention to use. Valid values are 'ilp32' or 'lp64' for 32/64-bit,
# optionally followed by 'f' or 'd' for hard-float. All combinations are valid.
-mabi=${mabi}d
# Required for compatibility with old versions of LLD. Otherwise you get an error
# "relocation R_RISCV_ALIGN requires unimplemented linker relaxation; recompile with -mno-relax"
-mno-relax
# Indicate we are building in a standalone environment. Implies -fno-builtin
# so the compiler won't assume that memcpy etc. are available.
-ffreestanding
# Don't try to link with libc or libm.
-nostdlib
# Generate a statically linked binary.
-static
# The relocation model. This compiles the code so that it can
# be linked at any address. This means the linker script
# doesn't have to e.g. put all code in the first 2GB of memory.
-mcmodel=medany
# Generate debug info.
-g
# Optimise code generation for a good debugging experience.
-Og
# Enable warnings and upgrade them to errors.
-Wall
-Werror
# The linker script.
-T "${CMAKE_CURRENT_SOURCE_DIR}/src/common/link.ld"
-o ${elf}
"${CMAKE_CURRENT_SOURCE_DIR}/src/${test_source}"
"${CMAKE_CURRENT_SOURCE_DIR}/src/common/crt0.S"
"${CMAKE_CURRENT_SOURCE_DIR}/src/common/nanoprintf.c"
"${CMAKE_CURRENT_SOURCE_DIR}/src/common/runtime.c"
VERBATIM
COMMENT "Compiling ${test_source}"
)
add_custom_target(build_${arch}_${test_source} ALL DEPENDS ${elf} ${config} ${override_config})
add_test(
NAME "first_party_${arch}_${test_source}"
COMMAND $<TARGET_FILE:sail_riscv_sim> --config ${config} --config-override ${override_config} ${elf}
)
endforeach()