-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMakefile
More file actions
282 lines (244 loc) · 10.5 KB
/
Copy pathMakefile
File metadata and controls
282 lines (244 loc) · 10.5 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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
# =============================================================================
# RISC-V Virtual Machine - GNU Makefile
# =============================================================================
# This Makefile replaces the CMake build system. Usage:
#
# make # Build riscv_vm (default)
# make riscv_vm # Build riscv_vm
# make all # Build all enabled targets
# make test # Run all RISC-V test programs
# make tests # Clean build + run all tests
# make clean # Remove build artifacts
#
# Options (set on command line or as environment variables):
# make RVVM_STRICT=1 # Enable strict compiler warnings
# make RVVM_SUPPORT_RV32M=0 # Disable RV32M ISA
# make RVVM_SUPPORT_RV32F=0 # Disable RV32F ISA
# make RVVM_SUPPORT_RV32A=0 # Disable RV32A ISA
# make RVVM_SUPPORT_RV32Zicsr=0 # Disable Zicsr ISA
# make RVVM_SUPPORT_RV32Zifencei=0 # Disable Zifencei ISA
# make RVVM_SUPPORT_RV64=1 # Enable RV64I base ISA
# make RVVM_SUPPORT_RVC=1 # Enable RVC compressed instructions
# =============================================================================
# ---------------------------------------------------------------------------
# Compiler and tools
# ---------------------------------------------------------------------------
CC := gcc
CXX := g++
AR := ar
RM := rm -rf
# ---------------------------------------------------------------------------
# Build directory
# ---------------------------------------------------------------------------
BUILD_DIR := build
OBJ_DIR := $(BUILD_DIR)/obj
LIB_DIR := $(BUILD_DIR)/lib
BIN_DIR := $(BUILD_DIR)/bin
# ---------------------------------------------------------------------------
# User options (defaults match CMakeLists.txt defaults)
# ---------------------------------------------------------------------------
RVVM_STRICT ?= 0
RVVM_SUPPORT_RV32M ?= 1
RVVM_SUPPORT_RV32F ?= 1
RVVM_SUPPORT_RV32A ?= 1
RVVM_SUPPORT_RV32Zicsr ?= 1
RVVM_SUPPORT_RV32Zifencei ?= 1
RVVM_SUPPORT_RV64 ?= 0
RVVM_SUPPORT_RVC ?= 0
# ---------------------------------------------------------------------------
# Defines (mapped from options)
# ---------------------------------------------------------------------------
DEFINES := \
-DRISCV_VM_SUPPORT_RV32M=$(RVVM_SUPPORT_RV32M) \
-DRISCV_VM_SUPPORT_RV32F=$(RVVM_SUPPORT_RV32F) \
-DRISCV_VM_SUPPORT_RV32A=$(RVVM_SUPPORT_RV32A) \
-DRISCV_VM_SUPPORT_Zicsr=$(RVVM_SUPPORT_RV32Zicsr) \
-DRISCV_VM_SUPPORT_Zifencei=$(RVVM_SUPPORT_RV32Zifencei) \
-DRISCV_VM_SUPPORT_RV64=$(RVVM_SUPPORT_RV64) \
-DRISCV_VM_SUPPORT_RVC=$(RVVM_SUPPORT_RVC) \
-D_CRT_SECURE_NO_WARNINGS
# ---------------------------------------------------------------------------
# Compiler flags
# ---------------------------------------------------------------------------
CFLAGS := -std=gnu23 $(DEFINES)
CXXFLAGS := -std=c++14 $(DEFINES)
# Strict warning mode (matches CMake non-MSVC path)
ifeq ($(RVVM_STRICT),1)
CFLAGS += -Wall -Wextra -pedantic -Werror
CXXFLAGS += -Wall -Wextra -pedantic -Werror
endif
# Include paths
INCLUDES := -Iriscv_core -Iriscv_vm
# ---------------------------------------------------------------------------
# Automatic dependency generation
# ---------------------------------------------------------------------------
DEPFLAGS = -MMD -MP -MF $(@:.o=.d)
# ---------------------------------------------------------------------------
# Source files
# ---------------------------------------------------------------------------
# --- riscv_common library sources ---
RISCV_COMMON_SRCS := \
riscv_core/riscv_common.c
# --- riscv_core library sources ---
RISCV_CORE_SRCS := \
riscv_core/riscv.c \
riscv_core/decode.c
# --- riscv_vm executable sources ---
VM_SRCS := \
riscv_vm/elf.cpp \
riscv_vm/main.cpp \
riscv_vm/syscall.cpp \
riscv_vm/args.cpp
# ---------------------------------------------------------------------------
# Object files (mapped into build/obj/)
# ---------------------------------------------------------------------------
RISCV_COMMON_OBJS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(RISCV_COMMON_SRCS))
RISCV_CORE_OBJS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(RISCV_CORE_SRCS))
VM_OBJS := $(patsubst %.cpp,$(OBJ_DIR)/%.o,$(VM_SRCS))
# ---------------------------------------------------------------------------
# Static libraries
# ---------------------------------------------------------------------------
RISCV_COMMON_LIB := $(LIB_DIR)/libriscv_common.a
RISCV_CORE_LIB := $(LIB_DIR)/libriscv_core.a
# ---------------------------------------------------------------------------
# Executables
# ---------------------------------------------------------------------------
RISCV_VM := $(BIN_DIR)/riscv_vm
# ---------------------------------------------------------------------------
# All object files (for dependency tracking)
# ---------------------------------------------------------------------------
ALL_OBJS := $(RISCV_COMMON_OBJS) \
$(RISCV_CORE_OBJS) \
$(VM_OBJS)
# Include generated dependency files
-include $(ALL_OBJS:.o=.d)
# ---------------------------------------------------------------------------
# Targets
# ---------------------------------------------------------------------------
.PHONY: all
all: $(BIN_DIR) riscv_vm
.PHONY: riscv_vm
riscv_vm: $(BIN_DIR) $(RISCV_VM)
# ---------------------------------------------------------------------------
# Build rules
# ---------------------------------------------------------------------------
# Create build directories
$(BUILD_DIR) $(OBJ_DIR) $(LIB_DIR) $(BIN_DIR):
mkdir -p $@
# Pattern rule for C source files
$(OBJ_DIR)/%.o: %.c | $(OBJ_DIR)
@mkdir -p $(dir $@)
$(CC) $(CFLAGS) $(INCLUDES) $(DEPFLAGS) -c $< -o $@
# Pattern rule for C++ source files
$(OBJ_DIR)/%.o: %.cpp | $(OBJ_DIR)
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) $(INCLUDES) $(DEPFLAGS) -c $< -o $@
# Static libraries
$(RISCV_COMMON_LIB): $(RISCV_COMMON_OBJS) | $(LIB_DIR)
$(AR) rcs $@ $^
$(RISCV_CORE_LIB): $(RISCV_CORE_OBJS) | $(LIB_DIR)
$(AR) rcs $@ $^
# riscv_vm executable (always built)
$(RISCV_VM): $(VM_OBJS) $(RISCV_COMMON_LIB) $(RISCV_CORE_LIB) | $(BIN_DIR)
$(CXX) $^ -o $@
# ---------------------------------------------------------------------------
# Test targets
# ---------------------------------------------------------------------------
# Tests are pre-built RISC-V ELF files. To run them, we use the riscv_vm
# simulator. These targets first build riscv_vm if needed, then execute each
# test binary through the VM.
# Test timeout (seconds). Quick functional tests complete instantly;
# synthetic benchmarks may take very long and will be killed if they
# exceed this limit.
TEST_TIMEOUT ?= 15
# Test definitions: interpreter-friendly smoke set
TEST_ELFS := \
tests/helloworld/helloworld \
tests/multiply/multiply.elf \
tests/mandelbrot/mandelbrot.elf \
tests/rsort/rsort.elf \
tests/towers/towers.elf \
tests/puzzle/puzzle.elf
.PHONY: tests tests-jit tests-rvc
tests: clean
$(MAKE) -j$(shell nproc)
$(MAKE) test
tests-rvc: clean
$(MAKE) -j$(shell nproc) RVVM_SUPPORT_RVC=1
$(MAKE) test
tests-rv64: clean
$(MAKE) -j$(shell nproc) RVVM_SUPPORT_RV64=1
$(MAKE) test TEST_BIN=$(BIN_DIR)/riscv_vm RVVM_SUPPORT_RV64=1
tests-bench: clean
$(MAKE) -j$(shell nproc)
$(MAKE) test TEST_BIN=$(BIN_DIR)/riscv_vm TEST_ELFS="tests/pi/pi.elf tests/smallpt/smallpt.elf tests/dhrystone/dhrystone.elf tests/coremark/coremark.elf tests/linpack/linpack.elf tests/whetstone/whetstone.elf" TEST_TIMEOUT=240
# Test binary
TEST_BIN ?= $(RISCV_VM)
.PHONY: test
test: $(TEST_BIN)
@echo "==========================================="
@echo " Running RISC-V tests through $(TEST_BIN)"
@echo " (timeout: $(TEST_TIMEOUT)s per test)"
@echo "==========================================="
@total=0; passed=0; failed=0; timedout=0; \
for elf in $(TEST_ELFS); do \
name=$$(basename $$elf .elf); \
if [ "$$name" = "helloworld" ]; then name=$$(basename $$elf); fi; \
total=$$((total + 1)); \
printf " [%2d/%-2d] %-20s ... " $$total $$(echo $(TEST_ELFS) | wc -w) "$$name"; \
if timeout $(TEST_TIMEOUT) $(TEST_BIN) "$$elf" > /dev/null 2>&1; then \
echo "PASS"; \
passed=$$((passed + 1)); \
elif [ $$? -eq 124 ]; then \
echo "TIMEOUT"; \
timedout=$$((timedout + 1)); \
else \
echo "FAIL"; \
failed=$$((failed + 1)); \
fi; \
done; \
echo "==========================================="; \
echo " Results: $$passed passed, $$failed failed, $$timedout timed out, $$total total"; \
echo "==========================================="
# ---------------------------------------------------------------------------
# Clean targets
# ---------------------------------------------------------------------------
.PHONY: clean
clean:
$(RM) $(BUILD_DIR)
.PHONY: distclean
distclean: clean
# ---------------------------------------------------------------------------
# Help target
# ---------------------------------------------------------------------------
.PHONY: help
help:
@echo "RISC-V Virtual Machine - Makefile"
@echo ""
@echo "Targets:"
@echo " all Build riscv_vm (default)"
@echo " riscv_vm Build the RISC-V VM interpreter"
@echo " tests Clean build + run all tests"
@echo " tests-rvc Clean build with RVC + run all tests"
@echo " tests-rv64 Clean build with RV64 + run all tests"
@echo " test Run all RISC-V test programs (incremental)"
@echo " clean Remove build artifacts"
@echo " help Show this help"
@echo ""
@echo "Options (defaults in parentheses):"
@echo " RVVM_STRICT=0 Enable strict compiler warnings (OFF)"
@echo " RVVM_SUPPORT_RV32M=1 Enable RV32M ISA (ON)"
@echo " RVVM_SUPPORT_RV32F=1 Enable RV32F ISA (ON)"
@echo " RVVM_SUPPORT_RV32A=1 Enable RV32A ISA (ON)"
@echo " RVVM_SUPPORT_RV32Zicsr=1 Enable Zicsr ISA (ON)"
@echo " RVVM_SUPPORT_RV32Zifencei=1 Enable Zifencei ISA (ON)"
@echo " RVVM_SUPPORT_RV64=0 Enable RV64I base ISA (OFF)"
@echo " RVVM_SUPPORT_RVC=0 Enable RVC compressed instructions (OFF)"
@echo ""
@echo "Examples:"
@echo " make # Default build"
@echo " make RVVM_STRICT=1 # Build with strict warnings"
@echo " make RVVM_SUPPORT_RV64=1 riscv_vm # Build RV64 version"
@echo " make tests # Clean build + run all tests"
@echo " make tests-rvc # Clean build with RVC + run all tests"
@echo " make test # Run all tests (incremental)"