Skip to content

Commit

Permalink
Sync with Primordial Soup.
Browse files Browse the repository at this point in the history
Enable CI.
  • Loading branch information
rmacnak committed Nov 2, 2024
1 parent 624e634 commit bab479b
Show file tree
Hide file tree
Showing 23 changed files with 425 additions and 457 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: CI

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
linux:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- name: Build
run: make -j
10 changes: 6 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
run_test: out/test_rv64 out/test_rv32
run_test: out out/test_rv64 out/test_rv32
./out/test_rv64
./out/test_rv32

CXX = g++
CFLAGS64 = -O2 -g -std=c++11 -Werror -Wall -Wextra -Wnon-virtual-dtor -Wvla -Wno-unused-parameter -DDEBUG -DXLEN=64 -fno-rtti -fno-exceptions -I.
out:
mkdir -p out

CFLAGS64 = -O2 -g -std=c++17 -Werror -Wall -Wextra -Wnon-virtual-dtor -Wvla -Wno-unused-parameter -DDEBUG -DXLEN=64 -fno-rtti -fno-exceptions -I.

out/test_rv64: out/simulator64.o out/disassembler64.o out/assembler64.o out/test64.o out/assert64.o out/os_macos64.o out/os_linux64.o
$(CXX) $(CFLAGS64) -lm -o out/test_rv64 out/simulator64.o out/disassembler64.o out/assembler64.o out/test64.o out/assert64.o out/os_macos64.o out/os_linux64.o
Expand All @@ -29,7 +31,7 @@ out/os_linux64.o: vm/os_linux.cc vm/*.h Makefile
out/test64.o: vm/test.cc vm/*.h Makefile
$(CXX) $(CFLAGS64) -c -o out/test64.o vm/test.cc

CFLAGSc64 = -O2 -g -std=c++11 -Werror -Wall -Wextra -Wnon-virtual-dtor -Wvla -Wno-unused-parameter -DDEBUG -DXLEN=32 -fno-rtti -fno-exceptions -I.
CFLAGSc64 = -O2 -g -std=c++17 -Werror -Wall -Wextra -Wnon-virtual-dtor -Wvla -Wno-unused-parameter -DDEBUG -DXLEN=32 -fno-rtti -fno-exceptions -I.

out/test_rv32: out/simulatorc64.o out/disassemblerc64.o out/assemblerc64.o out/testc64.o out/assertc64.o out/os_macosc64.o out/os_linuxc64.o
$(CXX) $(CFLAGSc64) -lm -o out/test_rv32 out/simulatorc64.o out/disassemblerc64.o out/assemblerc64.o out/testc64.o out/assertc64.o out/os_macosc64.o out/os_linuxc64.o
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# RISC-V Tools

Assembler, disassembler, simulator for RV32G, RV64G, RV32GC, and RV64GC.

[![Build status](https://github.com/rmacnak/riscv-tools/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/rmacnak/riscv-tools/actions/workflows/ci.yml)
150 changes: 94 additions & 56 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,31 @@ import os
import platform

def BuildVM(cxx, arch, target_os, debug, sanitize):
if target_os == 'windows' and arch == 'ia32':
env = Environment(TARGET_ARCH='x86', tools=['msvc', 'mslink'])
elif target_os == 'windows' and arch == 'x64':
env = Environment(TARGET_ARCH='x86_64', tools=['msvc', 'mslink'])
if target_os == 'windows':
if arch == 'ia32':
win_arch_name = 'x86'
elif arch == 'x64':
win_arch_name = 'x86_64'
else:
win_arch_name = arch
env = Environment(TARGET_ARCH=win_arch_name, tools=['msvc', 'mslink'])
elif target_os == 'emscripten':
env = Environment(ENV = os.environ, tools=['g++', 'gnulink'])
env['CXX'] = cxx or 'em++'
env['CXX'] = cxx
else:
env = Environment(tools=['g++', 'gnulink'])
env['CXX'] = cxx

configname = ''
if debug:
if target_os == 'windows':
env['CCFLAGS'] += ['/DDEBUG=1']
env['CCFLAGS'] += ['/DDEBUG=1', '/DXLEN=64']
else:
env['CCFLAGS'] += ['-DDEBUG', '-DXLEN=64']
configname += 'Debug'
else:
if target_os == 'windows':
env['CCFLAGS'] += ['/DNDEBUG']
env['CCFLAGS'] += ['/DNDEBUG', '/DXLEN=64']
else:
env['CCFLAGS'] += ['-DNDEBUG', '-DXLEN=64']
configname += 'Release'
Expand Down Expand Up @@ -55,13 +59,19 @@ def BuildVM(cxx, arch, target_os, debug, sanitize):
elif arch == 'x64':
if target_os == 'windows':
env['LINKFLAGS'] += ['/MACHINE:X64']
elif target_os == 'macos':
env['CCFLAGS'] += ['-arch', 'x86_64']
env['LINKFLAGS'] += ['-arch', 'x86_64']
else:
env['CCFLAGS'] += ['-m64']
env['LINKFLAGS'] += ['-m64']
configname += 'X64'
elif arch == 'arm':
configname += 'ARM'
elif arch == 'arm64':
if target_os == 'macos':
env['CCFLAGS'] += ['-arch', 'arm64']
env['LINKFLAGS'] += ['-arch', 'arm64']
configname += 'ARM64'
elif arch == 'mips':
env['CCFLAGS'] += ['-EL']
Expand All @@ -72,31 +82,27 @@ def BuildVM(cxx, arch, target_os, debug, sanitize):
env['LINKFLAGS'] += ['-EL']
configname += 'MIPS64'
elif arch == 'riscv32':
env['CCFLAGS'] += ['-m32']
env['LINKFLAGS'] += ['-m32']
configname += 'RISCV32'
elif arch == 'riscv64':
env['CCFLAGS'] += ['-m64']
env['LINKFLAGS'] += ['-m64']
configname += 'RISCV64'
elif arch == 'wasm':
configname += 'WASM'
env['LINKFLAGS'] += [ '-s', 'WASM=1' ]
else:
raise Exception('Unknown architecture: ' + arch)

outdir = os.path.join('out', configname)
outdir = os.path.join('#out', configname)

if target_os == 'windows':
env['CCFLAGS'] += [
'/std:c++17',
'/O2',
'/Z7', # Debug symbols
'/WX', # Warnings as errors
'/W3', # Most warnings
'/wd4200', # Zero-sized array in struct
'/wd4996', # Deprecated POSIX names
'/wd4244', # Implicit narrowing conversion
'/wd4800', # Implicit bool conversion
'/wd4146', # Negating unsigned type
'/D_HAS_EXCEPTIONS=0',
'/DSTRICT',
Expand All @@ -105,7 +111,7 @@ def BuildVM(cxx, arch, target_os, debug, sanitize):
]
else:
env['CCFLAGS'] += [
'-std=c++11',
'-std=c++17',
'-O3',
'-g3',
'-Werror',
Expand All @@ -116,7 +122,7 @@ def BuildVM(cxx, arch, target_os, debug, sanitize):
'-Wno-unused-parameter',
'-fno-rtti',
'-fno-exceptions',
'-fpic',
'-fpie',
'-fvisibility=hidden',
'-fdata-sections',
'-ffunction-sections',
Expand Down Expand Up @@ -169,15 +175,18 @@ def BuildVM(cxx, arch, target_os, debug, sanitize):
'/NXCOMPAT',
'/DEBUG', # Debug symbols
]
env['LIBS'] = [
'Bcrypt.lib',
]
elif target_os == 'emscripten':
env['LINKFLAGS'] += [
'-s', 'ALLOW_MEMORY_GROWTH=1',
'-s', 'ENVIRONMENT=web',
'-s', 'EXPORTED_FUNCTIONS=["_load_snapshot", "_handle_message", "_handle_signal"]',
'-s', 'EXPORTED_FUNCTIONS=["_load_snapshot", "_handle_message", "_handle_signal", "_malloc", "_free"]',
'-s', 'FILESYSTEM=0',
'-s', 'MALLOC=emmalloc',
'-s', 'TOTAL_STACK=131072',
'--shell-file', 'meta/shell.html',
'--shell-file', File('meta/shell.html').path,
]
else:
raise Exception('Unknown operating system: ' + target_os)
Expand Down Expand Up @@ -212,35 +221,35 @@ def BuildVM(cxx, arch, target_os, debug, sanitize):

def Main():
host_os = None
default_host_cxx = None
if platform.system() == 'Linux':
host_os = 'linux'
default_host_cxx = 'g++'
elif platform.system() == 'Darwin':
host_os = 'macos'
default_host_cxx = 'clang++'
elif platform.system() == 'Windows':
host_os = 'windows'
target_os = ARGUMENTS.get('os', host_os)
default_host_cxx = 'cl'
host_cxx = ARGUMENTS.get('cxx_host', default_host_cxx)

target_cxx = ARGUMENTS.get('cxx_target', None)
host_cxx = None
if platform.system() == 'Linux':
host_cxx = 'g++'
elif platform.system() == 'Darwin':
host_cxx = 'clang++'
elif platform.system() == 'Windows':
host_cxx = 'cl'
host_cxx = ARGUMENTS.get('cxx_host', host_cxx)
target_os = ARGUMENTS.get('os', host_os)
default_target_cxx = None
if target_os == 'emscripten':
default_target_cxx = 'em++'
else:
default_target_cxx = default_host_cxx
target_cxx = ARGUMENTS.get('cxx_target', default_target_cxx)

target_arch = ARGUMENTS.get('arch', None)
host_arch = None
if (platform.machine() == 'x86_64' or
platform.machine() == 'AMD64'):
if platform.machine() in ['x86_64', 'AMD64']:
host_arch = 'x64'
elif platform.machine() == 'i386':
elif platform.machine() in ['i386', 'X86']:
host_arch = 'ia32'
elif platform.machine() == 'aarch64':
elif platform.machine() in ['aarch64', 'arm64', 'ARM64']:
host_arch = 'arm64'
elif (platform.machine() == 'armv7l' or
platform.machine() == 'armv6l'):
elif platform.machine() in ['armv7l', 'armv6l', 'ARM']:
host_arch = 'arm'
elif platform.machine() == 'mips':
host_arch = 'mips'
Expand All @@ -258,26 +267,50 @@ def Main():
# Build a release host VM for building the snapshots. Don't use the santizers
# here so the snapshots have a fixed dependency and won't be rebuilt for each
# sanitizer.
host_vm = BuildVM(host_cxx, host_arch, host_os, False, None)
host_debug_vm = BuildVM(host_cxx, host_arch, host_os, True, None)
host_release_vm = BuildVM(host_cxx, host_arch, host_os, False, None)

# Build for the host.
BuildVM(host_cxx, host_arch, host_os, True, sanitize)
# Copy the VM to an architecture-independent path for the convenience of
# other scripts.
Install(os.path.join('#out', 'DebugHost'), host_debug_vm)
Install(os.path.join('#out', 'ReleaseHost'), host_release_vm)

# Build for the host, avoiding specifying the host build twice.
if sanitize != None:
# Avoid specifying the host release build twice.
BuildVM(host_cxx, host_arch, host_os, True, sanitize)
BuildVM(host_cxx, host_arch, host_os, False, sanitize)

if ((target_os != None and host_os != target_os) or
(target_arch != None and host_arch != target_arch)):
# If cross compiling, also build for the target.
BuildVM(target_cxx, target_arch, target_os, True, sanitize)
BuildVM(target_cxx, target_arch, target_os, False, sanitize)
elif host_arch == 'x64' and sanitize != 'thread' and target_arch == None \
and target_os != 'macos' :
# If on X64, also build for IA32. Skip when using TSan or targeting Mac, as
# they don't support IA32. Also skip when a specific architecture was asked
# for.
BuildVM(host_cxx, 'ia32', host_os, True, sanitize)
BuildVM(host_cxx, 'ia32', host_os, False, sanitize)
elif target_arch == None:
# No particular arch was asked for: try to build everything supported.
if target_os == 'macos':
if host_arch != 'x64':
BuildVM(host_cxx, 'x64', host_os, True, sanitize)
BuildVM(host_cxx, 'x64', host_os, False, sanitize)
if host_arch != 'arm64':
BuildVM(host_cxx, 'arm64', host_os, True, sanitize)
BuildVM(host_cxx, 'arm64', host_os, False, sanitize)
elif target_os == 'windows':
if host_arch != 'ia32':
BuildVM(host_cxx, 'ia32', host_os, True, sanitize)
BuildVM(host_cxx, 'ia32', host_os, False, sanitize)
if host_arch != 'x64':
BuildVM(host_cxx, 'x64', host_os, True, sanitize)
BuildVM(host_cxx, 'x64', host_os, False, sanitize)
if host_arch != 'arm':
BuildVM(host_cxx, 'arm', host_os, True, sanitize)
BuildVM(host_cxx, 'arm', host_os, False, sanitize)
if host_arch != 'arm64':
BuildVM(host_cxx, 'arm64', host_os, True, sanitize)
BuildVM(host_cxx, 'arm64', host_os, False, sanitize)
elif target_os == 'linux':
if host_arch == 'x64' and sanitize != 'thread':
BuildVM(host_cxx, 'ia32', host_os, True, sanitize)
BuildVM(host_cxx, 'ia32', host_os, False, sanitize)

ndk = ARGUMENTS.get('ndk', None)
if ndk != None:
Expand All @@ -293,23 +326,28 @@ def Main():
raise Exception("Android NDK paths not known for this OS")

target_cxx = ndk + '/toolchains/llvm/prebuilt/' \
+ android_host_name + '/bin/armv7a-linux-androideabi24-clang++'
BuildVM(target_cxx, 'arm', 'android', False, None);
BuildVM(target_cxx, 'arm', 'android', True, None);
+ android_host_name + '/bin/armv7a-linux-androideabi28-clang++'
BuildVM(target_cxx, 'arm', 'android', False, None)
BuildVM(target_cxx, 'arm', 'android', True, None)

target_cxx = ndk + '/toolchains/llvm/prebuilt/' \
+ android_host_name + '/bin/aarch64-linux-android28-clang++'
BuildVM(target_cxx, 'arm64', 'android', False, None)
BuildVM(target_cxx, 'arm64', 'android', True, None)

target_cxx = ndk + '/toolchains/llvm/prebuilt/' \
+ android_host_name + '/bin/aarch64-linux-android24-clang++'
BuildVM(target_cxx, 'arm64', 'android', False, None);
BuildVM(target_cxx, 'arm64', 'android', True, None);
+ android_host_name + '/bin/i686-linux-android28-clang++'
BuildVM(target_cxx, 'ia32', 'android', False, None)
BuildVM(target_cxx, 'ia32', 'android', True, None)

target_cxx = ndk + '/toolchains/llvm/prebuilt/' \
+ android_host_name + '/bin/i686-linux-android24-clang++'
BuildVM(target_cxx, 'ia32', 'android', False, None);
BuildVM(target_cxx, 'ia32', 'android', True, None);
+ android_host_name + '/bin/x86_64-linux-android28-clang++'
BuildVM(target_cxx, 'x64', 'android', False, None)
BuildVM(target_cxx, 'x64', 'android', True, None)

target_cxx = ndk + '/toolchains/llvm/prebuilt/' \
+ android_host_name + '/bin/x86_64-linux-android24-clang++'
BuildVM(target_cxx, 'x64', 'android', False, None);
BuildVM(target_cxx, 'x64', 'android', True, None);
+ android_host_name + '/bin/riscv64-linux-android35-clang++'
BuildVM(target_cxx, 'riscv64', 'android', False, None)
BuildVM(target_cxx, 'riscv64', 'android', True, None)

Main()
1 change: 0 additions & 1 deletion format

This file was deleted.

26 changes: 8 additions & 18 deletions vm/assert.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,20 @@ class Assert {

} // namespace psoup

#define FATAL(error) psoup::Assert(__FILE__, __LINE__).Fail("%s", error)

#define FATAL1(format, p1) psoup::Assert(__FILE__, __LINE__).Fail(format, (p1))

#define FATAL2(format, p1, p2) \
psoup::Assert(__FILE__, __LINE__).Fail(format, (p1), (p2))
#if defined(_MSC_VER)
#define FATAL(format, ...) \
psoup::Assert(__FILE__, __LINE__).Fail(format, __VA_ARGS__)
#else
#define FATAL(format, ...) \
psoup::Assert(__FILE__, __LINE__).Fail(format, ##__VA_ARGS__)
#endif

#define UNIMPLEMENTED() FATAL("unimplemented code")

#define UNREACHABLE() FATAL("unreachable code")

#define OUT_OF_MEMORY() FATAL("Out of memory.")


#if defined(DEBUG)
// DEBUG binaries use assertions in the code.
// Note: We wrap the if statement in a do-while so that we get a compile
Expand Down Expand Up @@ -71,16 +71,6 @@ class Assert {

#endif // if defined(DEBUG)

#if !defined(COMPILE_ASSERT)
template <bool>
struct CompileAssert {
};
#define COMPILE_ASSERT_JOIN(a, b) COMPILE_ASSERT_JOIN_HELPER(a, b)
#define COMPILE_ASSERT_JOIN_HELPER(a, b) a##b
#define COMPILE_ASSERT(expr) \
ATTRIBUTE_UNUSED typedef CompileAssert<(static_cast<bool>(expr))> \
COMPILE_ASSERT_JOIN(CompileAssertTypeDef, __LINE__)[static_cast<bool>(expr) \
? 1 : -1]
#endif // !defined(COMPILE_ASSERT)
#define COMPILE_ASSERT(cond) static_assert(cond, "")

#endif // VM_ASSERT_H_
4 changes: 2 additions & 2 deletions vm/disassembler_riscv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1640,7 +1640,7 @@ const char* Disassembler::PrintOption(const char* format, Instruction instr) {
return format + 4;
}

FATAL1("Bad format %s\n", format);
FATAL("Bad format %s\n", format);
return nullptr;
}

Expand Down Expand Up @@ -1720,7 +1720,7 @@ const char* Disassembler::PrintOption(const char* format, CInstruction instr) {
return format + 8;
}

FATAL1("Bad format %s\n", format);
FATAL("Bad format %s\n", format);
return nullptr;
}

Expand Down
Loading

0 comments on commit bab479b

Please sign in to comment.