2021-04-15 10:10:20 +00:00
|
|
|
#!/usr/bin/env python3
|
2016-09-23 14:47:36 +00:00
|
|
|
# Copyright 2016 The Dart project authors. All rights reserved.
|
|
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
|
|
# found in the LICENSE file.
|
|
|
|
|
|
|
|
import argparse
|
2016-10-05 02:49:14 +00:00
|
|
|
import os
|
2021-09-28 17:44:32 +00:00
|
|
|
import platform
|
2016-09-23 14:47:36 +00:00
|
|
|
import subprocess
|
|
|
|
import sys
|
2016-10-05 02:49:14 +00:00
|
|
|
import time
|
2016-09-23 14:47:36 +00:00
|
|
|
import utils
|
|
|
|
|
|
|
|
HOST_OS = utils.GuessOS()
|
|
|
|
HOST_ARCH = utils.GuessArchitecture()
|
|
|
|
SCRIPT_DIR = os.path.dirname(sys.argv[0])
|
|
|
|
DART_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR, '..'))
|
2020-07-14 14:10:11 +00:00
|
|
|
AVAILABLE_ARCHS = utils.ARCH_FAMILY.keys()
|
2017-05-07 04:44:59 +00:00
|
|
|
GN = os.path.join(DART_ROOT, 'buildtools', 'gn')
|
2016-09-23 14:47:36 +00:00
|
|
|
|
2017-01-09 23:53:21 +00:00
|
|
|
# Environment variables for default settings.
|
|
|
|
DART_USE_TOOLCHAIN = "DART_USE_TOOLCHAIN" # Use instread of --toolchain-prefix
|
|
|
|
DART_USE_SYSROOT = "DART_USE_SYSROOT" # Use instead of --target-sysroot
|
2018-10-24 13:30:16 +00:00
|
|
|
DART_USE_CRASHPAD = "DART_USE_CRASHPAD" # Use instead of --use-crashpad
|
2017-05-21 06:30:06 +00:00
|
|
|
# use instead of --platform-sdk
|
|
|
|
DART_MAKE_PLATFORM_SDK = "DART_MAKE_PLATFORM_SDK"
|
2017-01-09 23:53:21 +00:00
|
|
|
|
2018-01-09 18:48:56 +00:00
|
|
|
DART_GN_ARGS = "DART_GN_ARGS"
|
|
|
|
|
2019-08-05 20:34:31 +00:00
|
|
|
|
2017-05-07 04:44:59 +00:00
|
|
|
def ToolchainPrefix(args):
|
2019-08-05 20:34:31 +00:00
|
|
|
if args.toolchain_prefix:
|
|
|
|
return args.toolchain_prefix
|
|
|
|
return os.environ.get(DART_USE_TOOLCHAIN)
|
2017-01-09 23:53:21 +00:00
|
|
|
|
|
|
|
|
2017-05-07 04:44:59 +00:00
|
|
|
def TargetSysroot(args):
|
2019-08-05 20:34:31 +00:00
|
|
|
if args.target_sysroot:
|
|
|
|
return args.target_sysroot
|
|
|
|
return os.environ.get(DART_USE_SYSROOT)
|
2017-01-09 23:53:21 +00:00
|
|
|
|
2016-10-05 02:49:14 +00:00
|
|
|
|
2017-05-21 06:30:06 +00:00
|
|
|
def MakePlatformSDK():
|
2019-08-05 20:34:31 +00:00
|
|
|
return DART_MAKE_PLATFORM_SDK in os.environ
|
2017-05-21 06:30:06 +00:00
|
|
|
|
|
|
|
|
2018-01-09 18:48:56 +00:00
|
|
|
def GetGNArgs(args):
|
2019-08-05 20:34:31 +00:00
|
|
|
if args.gn_args != None:
|
|
|
|
return args.gn_args
|
|
|
|
args = os.environ.get(DART_GN_ARGS) or ""
|
|
|
|
return args.split()
|
2018-01-09 18:48:56 +00:00
|
|
|
|
|
|
|
|
2020-06-16 23:37:36 +00:00
|
|
|
def GetOutDir(mode, arch, target_os, sanitizer):
|
|
|
|
return utils.GetBuildRoot(HOST_OS, mode, arch, target_os, sanitizer)
|
2016-10-05 02:49:14 +00:00
|
|
|
|
2016-09-23 14:47:36 +00:00
|
|
|
|
2017-05-07 04:44:59 +00:00
|
|
|
def ToCommandLine(gn_args):
|
2019-08-05 20:34:31 +00:00
|
|
|
|
|
|
|
def merge(key, value):
|
|
|
|
if type(value) is bool:
|
|
|
|
return '%s=%s' % (key, 'true' if value else 'false')
|
|
|
|
elif type(value) is int:
|
|
|
|
return '%s=%d' % (key, value)
|
|
|
|
return '%s="%s"' % (key, value)
|
|
|
|
|
2021-04-15 10:10:20 +00:00
|
|
|
return [merge(x, y) for x, y in gn_args.items()]
|
2016-09-23 14:47:36 +00:00
|
|
|
|
2016-10-05 02:49:14 +00:00
|
|
|
|
2021-09-28 17:44:32 +00:00
|
|
|
# Runs true if the currently executing python interpreter is running under
|
|
|
|
# Rosetta. I.e., python3 is an x64 executable and we're on an arm64 Mac.
|
|
|
|
def IsRosetta():
|
|
|
|
if platform.system() == 'Darwin':
|
|
|
|
p = subprocess.Popen(['sysctl', '-in', 'sysctl.proc_translated'],
|
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
stderr=subprocess.STDOUT)
|
|
|
|
output, _ = p.communicate()
|
|
|
|
return output.decode('utf-8').strip() == '1'
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
2017-05-07 04:44:59 +00:00
|
|
|
def HostCpuForArch(arch):
|
2021-09-28 17:44:32 +00:00
|
|
|
# Check for Rosetta before checking platform.machine(), as the latter
|
|
|
|
# returns 'x86_64' when running under Rosetta.
|
|
|
|
if IsRosetta():
|
|
|
|
if arch in ['x64', 'x64c']:
|
|
|
|
# Without this case, we would try to build with
|
|
|
|
# host_cpu="arm64"
|
|
|
|
# target_cpu="x64"
|
|
|
|
# dart_target_arch="x64"
|
|
|
|
# Which requires the VM to use an x64 simulator in the host
|
|
|
|
# arm64 binaries, and this simulator is unimplemented.
|
|
|
|
return 'x64'
|
|
|
|
else:
|
|
|
|
return 'arm64'
|
|
|
|
|
|
|
|
m = platform.machine()
|
|
|
|
if m == 'aarch64' or m == 'arm64':
|
|
|
|
return 'arm64'
|
|
|
|
if m == 'armv7l' or m == 'armv6l':
|
|
|
|
return 'arm'
|
|
|
|
|
[vm] Support RISC-V.
Implements a backend targeting RV32GC and RV64GC, based on Linux standardizing around GC. The assembler is written to make it easy to disable usage of C, but because the sizes of some instruction sequences are compile-time constants, an additional build configuration would need to be defined to make use of it.
The assembler and disassembler cover every RV32/64GC instruction. The simulator covers all instructions except accessing CSRs and the floating point state accessible through such, include accrued exceptions and dynamic rounding mode.
Quirks:
- RISC-V is a compare-and-branch architecture, but some existing "architecture-independent" parts of the Dart compiler assume a condition code architecture. To avoid rewriting these parts, we use a peephole in the assembler to map to compare-and-branch. See Assembler::BranchIf. Luckily nothing depended on taking multiple branches on the same condition code set.
- There are no hardware overflow checks, so we must use Hacker's Delight style software checks. Often these are very cheap: if the sign of one operand is known, a single branch is needed.
- The ranges of RISC-V branches and jumps are such that we use 3 levels of generation for forward branches, instead of the 2 levels of near and far branches used on ARM[64]. Nearly all code is handled by the first two levels with 20-bits of range, with enormous regex matchers triggering the third level that uses aupic+jalr to get 32-bits of range.
- For PC-relative calls in AOT, we always generate auipc+jalr pairs with 32-bits of range, so we never generate trampolines.
- Only a subset of registers are available in some compressed instructions, so we assign the most popular uses to these registers. In particular, THR, TMP[2], CODE and PP. This has the effect of assigning CODE and PP to volatile registers in the C calling convention, whereas they are assigned preserved registers on the other architectures. As on ARM64, PP is untagged; this is so short indices can be accessed with a compressed instruction.
- There are no push or pop instructions, so combining pushes and pops is preferred so we can update SP once.
- The C calling convention has a strongly aligned stack, but unlike on ARM64 we don't need to use an alternate stack pointer. The author ensured language was added to the RISC-V psABI making the OS responsible for realigning the stack pointer for signal handlers, allowing Dart to leave the stack pointer misaligned from the C calling convention's point of view until a foreign call.
- We don't bother with the link register tracking done on ARM[64]. Instead we make use of an alternate link register to avoid inline spilling in the write barrier.
Unimplemented:
- non-trivial FFI cases
- Compressed pointers - No intention to implement.
- Unboxed SIMD - We might make use of the V extension registers when the V extension is ratified.
- BigInt intrinsics
TEST=existing tests for IL level, new tests for assembler/disassembler/simulator
Bug: https://github.com/dart-lang/sdk/issues/38587
Bug: https://github.com/dart-lang/sdk/issues/48164
Change-Id: I991d1df4be5bf55efec5371b767b332d37dfa3e0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/217289
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2022-01-20 00:57:57 +00:00
|
|
|
if arch in [
|
|
|
|
'ia32', 'arm', 'armv6', 'simarm', 'simarm_x64', 'riscv32',
|
|
|
|
'simriscv32'
|
|
|
|
]:
|
2019-08-05 20:34:31 +00:00
|
|
|
return 'x86'
|
2021-01-28 23:15:15 +00:00
|
|
|
if arch in [
|
[vm] Support RISC-V.
Implements a backend targeting RV32GC and RV64GC, based on Linux standardizing around GC. The assembler is written to make it easy to disable usage of C, but because the sizes of some instruction sequences are compile-time constants, an additional build configuration would need to be defined to make use of it.
The assembler and disassembler cover every RV32/64GC instruction. The simulator covers all instructions except accessing CSRs and the floating point state accessible through such, include accrued exceptions and dynamic rounding mode.
Quirks:
- RISC-V is a compare-and-branch architecture, but some existing "architecture-independent" parts of the Dart compiler assume a condition code architecture. To avoid rewriting these parts, we use a peephole in the assembler to map to compare-and-branch. See Assembler::BranchIf. Luckily nothing depended on taking multiple branches on the same condition code set.
- There are no hardware overflow checks, so we must use Hacker's Delight style software checks. Often these are very cheap: if the sign of one operand is known, a single branch is needed.
- The ranges of RISC-V branches and jumps are such that we use 3 levels of generation for forward branches, instead of the 2 levels of near and far branches used on ARM[64]. Nearly all code is handled by the first two levels with 20-bits of range, with enormous regex matchers triggering the third level that uses aupic+jalr to get 32-bits of range.
- For PC-relative calls in AOT, we always generate auipc+jalr pairs with 32-bits of range, so we never generate trampolines.
- Only a subset of registers are available in some compressed instructions, so we assign the most popular uses to these registers. In particular, THR, TMP[2], CODE and PP. This has the effect of assigning CODE and PP to volatile registers in the C calling convention, whereas they are assigned preserved registers on the other architectures. As on ARM64, PP is untagged; this is so short indices can be accessed with a compressed instruction.
- There are no push or pop instructions, so combining pushes and pops is preferred so we can update SP once.
- The C calling convention has a strongly aligned stack, but unlike on ARM64 we don't need to use an alternate stack pointer. The author ensured language was added to the RISC-V psABI making the OS responsible for realigning the stack pointer for signal handlers, allowing Dart to leave the stack pointer misaligned from the C calling convention's point of view until a foreign call.
- We don't bother with the link register tracking done on ARM[64]. Instead we make use of an alternate link register to avoid inline spilling in the write barrier.
Unimplemented:
- non-trivial FFI cases
- Compressed pointers - No intention to implement.
- Unboxed SIMD - We might make use of the V extension registers when the V extension is ratified.
- BigInt intrinsics
TEST=existing tests for IL level, new tests for assembler/disassembler/simulator
Bug: https://github.com/dart-lang/sdk/issues/38587
Bug: https://github.com/dart-lang/sdk/issues/48164
Change-Id: I991d1df4be5bf55efec5371b767b332d37dfa3e0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/217289
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2022-01-20 00:57:57 +00:00
|
|
|
'x64', 'arm64', 'simarm64', 'arm_x64', 'x64c', 'arm64c',
|
|
|
|
'simarm64c', 'riscv64', 'simriscv64'
|
2021-01-28 23:15:15 +00:00
|
|
|
]:
|
2019-08-05 20:34:31 +00:00
|
|
|
return 'x64'
|
2016-09-23 14:47:36 +00:00
|
|
|
|
2016-10-05 02:49:14 +00:00
|
|
|
|
2017-07-13 21:59:25 +00:00
|
|
|
# The C compiler's target.
|
2017-05-07 04:44:59 +00:00
|
|
|
def TargetCpuForArch(arch, target_os):
|
[vm] Support RISC-V.
Implements a backend targeting RV32GC and RV64GC, based on Linux standardizing around GC. The assembler is written to make it easy to disable usage of C, but because the sizes of some instruction sequences are compile-time constants, an additional build configuration would need to be defined to make use of it.
The assembler and disassembler cover every RV32/64GC instruction. The simulator covers all instructions except accessing CSRs and the floating point state accessible through such, include accrued exceptions and dynamic rounding mode.
Quirks:
- RISC-V is a compare-and-branch architecture, but some existing "architecture-independent" parts of the Dart compiler assume a condition code architecture. To avoid rewriting these parts, we use a peephole in the assembler to map to compare-and-branch. See Assembler::BranchIf. Luckily nothing depended on taking multiple branches on the same condition code set.
- There are no hardware overflow checks, so we must use Hacker's Delight style software checks. Often these are very cheap: if the sign of one operand is known, a single branch is needed.
- The ranges of RISC-V branches and jumps are such that we use 3 levels of generation for forward branches, instead of the 2 levels of near and far branches used on ARM[64]. Nearly all code is handled by the first two levels with 20-bits of range, with enormous regex matchers triggering the third level that uses aupic+jalr to get 32-bits of range.
- For PC-relative calls in AOT, we always generate auipc+jalr pairs with 32-bits of range, so we never generate trampolines.
- Only a subset of registers are available in some compressed instructions, so we assign the most popular uses to these registers. In particular, THR, TMP[2], CODE and PP. This has the effect of assigning CODE and PP to volatile registers in the C calling convention, whereas they are assigned preserved registers on the other architectures. As on ARM64, PP is untagged; this is so short indices can be accessed with a compressed instruction.
- There are no push or pop instructions, so combining pushes and pops is preferred so we can update SP once.
- The C calling convention has a strongly aligned stack, but unlike on ARM64 we don't need to use an alternate stack pointer. The author ensured language was added to the RISC-V psABI making the OS responsible for realigning the stack pointer for signal handlers, allowing Dart to leave the stack pointer misaligned from the C calling convention's point of view until a foreign call.
- We don't bother with the link register tracking done on ARM[64]. Instead we make use of an alternate link register to avoid inline spilling in the write barrier.
Unimplemented:
- non-trivial FFI cases
- Compressed pointers - No intention to implement.
- Unboxed SIMD - We might make use of the V extension registers when the V extension is ratified.
- BigInt intrinsics
TEST=existing tests for IL level, new tests for assembler/disassembler/simulator
Bug: https://github.com/dart-lang/sdk/issues/38587
Bug: https://github.com/dart-lang/sdk/issues/48164
Change-Id: I991d1df4be5bf55efec5371b767b332d37dfa3e0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/217289
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2022-01-20 00:57:57 +00:00
|
|
|
if arch in ['ia32', 'simarm', 'simriscv32']:
|
2019-08-05 20:34:31 +00:00
|
|
|
return 'x86'
|
[vm] Support RISC-V.
Implements a backend targeting RV32GC and RV64GC, based on Linux standardizing around GC. The assembler is written to make it easy to disable usage of C, but because the sizes of some instruction sequences are compile-time constants, an additional build configuration would need to be defined to make use of it.
The assembler and disassembler cover every RV32/64GC instruction. The simulator covers all instructions except accessing CSRs and the floating point state accessible through such, include accrued exceptions and dynamic rounding mode.
Quirks:
- RISC-V is a compare-and-branch architecture, but some existing "architecture-independent" parts of the Dart compiler assume a condition code architecture. To avoid rewriting these parts, we use a peephole in the assembler to map to compare-and-branch. See Assembler::BranchIf. Luckily nothing depended on taking multiple branches on the same condition code set.
- There are no hardware overflow checks, so we must use Hacker's Delight style software checks. Often these are very cheap: if the sign of one operand is known, a single branch is needed.
- The ranges of RISC-V branches and jumps are such that we use 3 levels of generation for forward branches, instead of the 2 levels of near and far branches used on ARM[64]. Nearly all code is handled by the first two levels with 20-bits of range, with enormous regex matchers triggering the third level that uses aupic+jalr to get 32-bits of range.
- For PC-relative calls in AOT, we always generate auipc+jalr pairs with 32-bits of range, so we never generate trampolines.
- Only a subset of registers are available in some compressed instructions, so we assign the most popular uses to these registers. In particular, THR, TMP[2], CODE and PP. This has the effect of assigning CODE and PP to volatile registers in the C calling convention, whereas they are assigned preserved registers on the other architectures. As on ARM64, PP is untagged; this is so short indices can be accessed with a compressed instruction.
- There are no push or pop instructions, so combining pushes and pops is preferred so we can update SP once.
- The C calling convention has a strongly aligned stack, but unlike on ARM64 we don't need to use an alternate stack pointer. The author ensured language was added to the RISC-V psABI making the OS responsible for realigning the stack pointer for signal handlers, allowing Dart to leave the stack pointer misaligned from the C calling convention's point of view until a foreign call.
- We don't bother with the link register tracking done on ARM[64]. Instead we make use of an alternate link register to avoid inline spilling in the write barrier.
Unimplemented:
- non-trivial FFI cases
- Compressed pointers - No intention to implement.
- Unboxed SIMD - We might make use of the V extension registers when the V extension is ratified.
- BigInt intrinsics
TEST=existing tests for IL level, new tests for assembler/disassembler/simulator
Bug: https://github.com/dart-lang/sdk/issues/38587
Bug: https://github.com/dart-lang/sdk/issues/48164
Change-Id: I991d1df4be5bf55efec5371b767b332d37dfa3e0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/217289
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2022-01-20 00:57:57 +00:00
|
|
|
if arch in [
|
|
|
|
'x64', 'simarm64', 'simarm_x64', 'simriscv64', 'x64c', 'simarm64c'
|
|
|
|
]:
|
2019-08-05 20:34:31 +00:00
|
|
|
return 'x64'
|
2019-10-07 10:35:45 +00:00
|
|
|
if arch == 'arm_x64':
|
|
|
|
return 'arm'
|
2021-02-04 17:44:37 +00:00
|
|
|
if arch == 'arm64c':
|
2021-01-28 23:15:15 +00:00
|
|
|
return 'arm64'
|
2019-08-05 20:34:31 +00:00
|
|
|
return arch
|
2016-09-23 14:47:36 +00:00
|
|
|
|
2016-10-05 02:49:14 +00:00
|
|
|
|
2017-07-13 21:59:25 +00:00
|
|
|
# The Dart compiler's target.
|
|
|
|
def DartTargetCpuForArch(arch):
|
2019-08-05 20:34:31 +00:00
|
|
|
if arch in ['ia32']:
|
|
|
|
return 'ia32'
|
2021-02-04 17:44:37 +00:00
|
|
|
if arch in ['x64', 'x64c']:
|
2019-08-05 20:34:31 +00:00
|
|
|
return 'x64'
|
2019-10-07 10:35:45 +00:00
|
|
|
if arch in ['arm', 'simarm', 'simarm_x64', 'arm_x64']:
|
2019-08-05 20:34:31 +00:00
|
|
|
return 'arm'
|
2021-02-04 17:44:37 +00:00
|
|
|
if arch in ['arm64', 'simarm64', 'arm64c', 'simarm64c']:
|
2019-08-05 20:34:31 +00:00
|
|
|
return 'arm64'
|
[vm] Support RISC-V.
Implements a backend targeting RV32GC and RV64GC, based on Linux standardizing around GC. The assembler is written to make it easy to disable usage of C, but because the sizes of some instruction sequences are compile-time constants, an additional build configuration would need to be defined to make use of it.
The assembler and disassembler cover every RV32/64GC instruction. The simulator covers all instructions except accessing CSRs and the floating point state accessible through such, include accrued exceptions and dynamic rounding mode.
Quirks:
- RISC-V is a compare-and-branch architecture, but some existing "architecture-independent" parts of the Dart compiler assume a condition code architecture. To avoid rewriting these parts, we use a peephole in the assembler to map to compare-and-branch. See Assembler::BranchIf. Luckily nothing depended on taking multiple branches on the same condition code set.
- There are no hardware overflow checks, so we must use Hacker's Delight style software checks. Often these are very cheap: if the sign of one operand is known, a single branch is needed.
- The ranges of RISC-V branches and jumps are such that we use 3 levels of generation for forward branches, instead of the 2 levels of near and far branches used on ARM[64]. Nearly all code is handled by the first two levels with 20-bits of range, with enormous regex matchers triggering the third level that uses aupic+jalr to get 32-bits of range.
- For PC-relative calls in AOT, we always generate auipc+jalr pairs with 32-bits of range, so we never generate trampolines.
- Only a subset of registers are available in some compressed instructions, so we assign the most popular uses to these registers. In particular, THR, TMP[2], CODE and PP. This has the effect of assigning CODE and PP to volatile registers in the C calling convention, whereas they are assigned preserved registers on the other architectures. As on ARM64, PP is untagged; this is so short indices can be accessed with a compressed instruction.
- There are no push or pop instructions, so combining pushes and pops is preferred so we can update SP once.
- The C calling convention has a strongly aligned stack, but unlike on ARM64 we don't need to use an alternate stack pointer. The author ensured language was added to the RISC-V psABI making the OS responsible for realigning the stack pointer for signal handlers, allowing Dart to leave the stack pointer misaligned from the C calling convention's point of view until a foreign call.
- We don't bother with the link register tracking done on ARM[64]. Instead we make use of an alternate link register to avoid inline spilling in the write barrier.
Unimplemented:
- non-trivial FFI cases
- Compressed pointers - No intention to implement.
- Unboxed SIMD - We might make use of the V extension registers when the V extension is ratified.
- BigInt intrinsics
TEST=existing tests for IL level, new tests for assembler/disassembler/simulator
Bug: https://github.com/dart-lang/sdk/issues/38587
Bug: https://github.com/dart-lang/sdk/issues/48164
Change-Id: I991d1df4be5bf55efec5371b767b332d37dfa3e0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/217289
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2022-01-20 00:57:57 +00:00
|
|
|
if arch in ['riscv32', 'simriscv32']:
|
|
|
|
return 'riscv32'
|
|
|
|
if arch in ['riscv64', 'simriscv64']:
|
|
|
|
return 'riscv64'
|
2019-08-05 20:34:31 +00:00
|
|
|
return arch
|
2017-07-13 21:59:25 +00:00
|
|
|
|
|
|
|
|
2021-01-28 23:15:15 +00:00
|
|
|
def IsCompressedPointerArch(arch):
|
2021-02-04 17:44:37 +00:00
|
|
|
return arch in ['x64c', 'arm64c', 'simarm64c']
|
2021-01-28 23:15:15 +00:00
|
|
|
|
|
|
|
|
2017-05-07 04:44:59 +00:00
|
|
|
def HostOsForGn(host_os):
|
2019-08-05 20:34:31 +00:00
|
|
|
if host_os.startswith('macos'):
|
|
|
|
return 'mac'
|
|
|
|
if host_os.startswith('win'):
|
|
|
|
return 'win'
|
|
|
|
return host_os
|
2016-10-05 02:49:14 +00:00
|
|
|
|
2016-10-04 16:19:07 +00:00
|
|
|
|
2017-01-09 23:53:21 +00:00
|
|
|
# Where string_map is formatted as X1=Y1,X2=Y2 etc.
|
|
|
|
# If key is X1, returns Y1.
|
2017-05-07 04:44:59 +00:00
|
|
|
def ParseStringMap(key, string_map):
|
2019-08-05 20:34:31 +00:00
|
|
|
for m in string_map.split(','):
|
|
|
|
l = m.split('=')
|
|
|
|
if l[0] == key:
|
|
|
|
return l[1]
|
|
|
|
return None
|
2017-01-09 23:53:21 +00:00
|
|
|
|
2020-12-10 12:15:17 +00:00
|
|
|
|
2018-03-09 09:02:05 +00:00
|
|
|
def UseSysroot(args, gn_args):
|
2019-08-05 20:34:31 +00:00
|
|
|
# Don't try to use a Linux sysroot if we aren't on Linux.
|
2020-06-17 06:53:40 +00:00
|
|
|
if gn_args['target_os'] != 'linux' and HOST_OS != 'linux':
|
2019-08-05 20:34:31 +00:00
|
|
|
return False
|
|
|
|
# Don't use the sysroot if we're given another sysroot.
|
|
|
|
if TargetSysroot(args):
|
|
|
|
return False
|
2020-05-07 19:40:18 +00:00
|
|
|
# Our Debian Jesse sysroot doesn't work with GCC 9
|
|
|
|
if not gn_args['is_clang']:
|
|
|
|
return False
|
|
|
|
# Our Debian Jesse sysroot has incorrect annotations on realloc.
|
|
|
|
if gn_args['is_ubsan']:
|
|
|
|
return False
|
[vm] Support RISC-V.
Implements a backend targeting RV32GC and RV64GC, based on Linux standardizing around GC. The assembler is written to make it easy to disable usage of C, but because the sizes of some instruction sequences are compile-time constants, an additional build configuration would need to be defined to make use of it.
The assembler and disassembler cover every RV32/64GC instruction. The simulator covers all instructions except accessing CSRs and the floating point state accessible through such, include accrued exceptions and dynamic rounding mode.
Quirks:
- RISC-V is a compare-and-branch architecture, but some existing "architecture-independent" parts of the Dart compiler assume a condition code architecture. To avoid rewriting these parts, we use a peephole in the assembler to map to compare-and-branch. See Assembler::BranchIf. Luckily nothing depended on taking multiple branches on the same condition code set.
- There are no hardware overflow checks, so we must use Hacker's Delight style software checks. Often these are very cheap: if the sign of one operand is known, a single branch is needed.
- The ranges of RISC-V branches and jumps are such that we use 3 levels of generation for forward branches, instead of the 2 levels of near and far branches used on ARM[64]. Nearly all code is handled by the first two levels with 20-bits of range, with enormous regex matchers triggering the third level that uses aupic+jalr to get 32-bits of range.
- For PC-relative calls in AOT, we always generate auipc+jalr pairs with 32-bits of range, so we never generate trampolines.
- Only a subset of registers are available in some compressed instructions, so we assign the most popular uses to these registers. In particular, THR, TMP[2], CODE and PP. This has the effect of assigning CODE and PP to volatile registers in the C calling convention, whereas they are assigned preserved registers on the other architectures. As on ARM64, PP is untagged; this is so short indices can be accessed with a compressed instruction.
- There are no push or pop instructions, so combining pushes and pops is preferred so we can update SP once.
- The C calling convention has a strongly aligned stack, but unlike on ARM64 we don't need to use an alternate stack pointer. The author ensured language was added to the RISC-V psABI making the OS responsible for realigning the stack pointer for signal handlers, allowing Dart to leave the stack pointer misaligned from the C calling convention's point of view until a foreign call.
- We don't bother with the link register tracking done on ARM[64]. Instead we make use of an alternate link register to avoid inline spilling in the write barrier.
Unimplemented:
- non-trivial FFI cases
- Compressed pointers - No intention to implement.
- Unboxed SIMD - We might make use of the V extension registers when the V extension is ratified.
- BigInt intrinsics
TEST=existing tests for IL level, new tests for assembler/disassembler/simulator
Bug: https://github.com/dart-lang/sdk/issues/38587
Bug: https://github.com/dart-lang/sdk/issues/48164
Change-Id: I991d1df4be5bf55efec5371b767b332d37dfa3e0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/217289
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2022-01-20 00:57:57 +00:00
|
|
|
# Our Debian Jesse sysroot doesn't support RISCV
|
|
|
|
if gn_args['target_cpu'] in ['riscv32', 'riscv64']:
|
|
|
|
return False
|
2019-08-05 20:34:31 +00:00
|
|
|
# Otherwise use the sysroot.
|
|
|
|
return True
|
|
|
|
|
2017-12-02 06:19:33 +00:00
|
|
|
|
2020-07-07 06:08:20 +00:00
|
|
|
def ToGnArgs(args, mode, arch, target_os, sanitizer, verify_sdk_hash):
|
2019-08-05 20:34:31 +00:00
|
|
|
gn_args = {}
|
|
|
|
|
|
|
|
host_os = HostOsForGn(HOST_OS)
|
|
|
|
if target_os == 'host':
|
|
|
|
gn_args['target_os'] = host_os
|
|
|
|
else:
|
|
|
|
gn_args['target_os'] = target_os
|
|
|
|
|
|
|
|
gn_args['host_cpu'] = HostCpuForArch(arch)
|
|
|
|
gn_args['target_cpu'] = TargetCpuForArch(arch, target_os)
|
|
|
|
gn_args['dart_target_arch'] = DartTargetCpuForArch(arch)
|
2021-01-28 23:15:15 +00:00
|
|
|
gn_args['dart_use_compressed_pointers'] = IsCompressedPointerArch(arch)
|
2019-08-05 20:34:31 +00:00
|
|
|
|
|
|
|
# Configure Crashpad library if it is used.
|
|
|
|
gn_args['dart_use_crashpad'] = (args.use_crashpad or
|
|
|
|
DART_USE_CRASHPAD in os.environ)
|
|
|
|
if gn_args['dart_use_crashpad']:
|
|
|
|
# Tell Crashpad's BUILD files which checkout layout to use.
|
|
|
|
gn_args['crashpad_dependencies'] = 'dart'
|
|
|
|
|
2021-04-19 20:18:28 +00:00
|
|
|
if DartTargetCpuForArch(arch) != HostCpuForArch(arch):
|
2019-08-05 20:34:31 +00:00
|
|
|
# Training an app-jit snapshot under a simulator is slow. Use script
|
|
|
|
# snapshots instead.
|
|
|
|
gn_args['dart_snapshot_kind'] = 'kernel'
|
|
|
|
else:
|
|
|
|
gn_args['dart_snapshot_kind'] = 'app-jit'
|
|
|
|
|
|
|
|
# We only want the fallback root certs in the standalone VM on
|
|
|
|
# Linux and Windows.
|
|
|
|
if gn_args['target_os'] in ['linux', 'win']:
|
|
|
|
gn_args['dart_use_fallback_root_certificates'] = True
|
|
|
|
|
2021-05-24 21:31:20 +00:00
|
|
|
gn_args['bssl_use_clang_integrated_as'] = True
|
|
|
|
|
2019-08-05 20:34:31 +00:00
|
|
|
# Use tcmalloc only when targeting Linux and when not using ASAN.
|
|
|
|
gn_args['dart_use_tcmalloc'] = ((gn_args['target_os'] == 'linux') and
|
2021-10-12 18:49:52 +00:00
|
|
|
(gn_args['target_cpu'] != 'arm') and
|
[vm] Support RISC-V.
Implements a backend targeting RV32GC and RV64GC, based on Linux standardizing around GC. The assembler is written to make it easy to disable usage of C, but because the sizes of some instruction sequences are compile-time constants, an additional build configuration would need to be defined to make use of it.
The assembler and disassembler cover every RV32/64GC instruction. The simulator covers all instructions except accessing CSRs and the floating point state accessible through such, include accrued exceptions and dynamic rounding mode.
Quirks:
- RISC-V is a compare-and-branch architecture, but some existing "architecture-independent" parts of the Dart compiler assume a condition code architecture. To avoid rewriting these parts, we use a peephole in the assembler to map to compare-and-branch. See Assembler::BranchIf. Luckily nothing depended on taking multiple branches on the same condition code set.
- There are no hardware overflow checks, so we must use Hacker's Delight style software checks. Often these are very cheap: if the sign of one operand is known, a single branch is needed.
- The ranges of RISC-V branches and jumps are such that we use 3 levels of generation for forward branches, instead of the 2 levels of near and far branches used on ARM[64]. Nearly all code is handled by the first two levels with 20-bits of range, with enormous regex matchers triggering the third level that uses aupic+jalr to get 32-bits of range.
- For PC-relative calls in AOT, we always generate auipc+jalr pairs with 32-bits of range, so we never generate trampolines.
- Only a subset of registers are available in some compressed instructions, so we assign the most popular uses to these registers. In particular, THR, TMP[2], CODE and PP. This has the effect of assigning CODE and PP to volatile registers in the C calling convention, whereas they are assigned preserved registers on the other architectures. As on ARM64, PP is untagged; this is so short indices can be accessed with a compressed instruction.
- There are no push or pop instructions, so combining pushes and pops is preferred so we can update SP once.
- The C calling convention has a strongly aligned stack, but unlike on ARM64 we don't need to use an alternate stack pointer. The author ensured language was added to the RISC-V psABI making the OS responsible for realigning the stack pointer for signal handlers, allowing Dart to leave the stack pointer misaligned from the C calling convention's point of view until a foreign call.
- We don't bother with the link register tracking done on ARM[64]. Instead we make use of an alternate link register to avoid inline spilling in the write barrier.
Unimplemented:
- non-trivial FFI cases
- Compressed pointers - No intention to implement.
- Unboxed SIMD - We might make use of the V extension registers when the V extension is ratified.
- BigInt intrinsics
TEST=existing tests for IL level, new tests for assembler/disassembler/simulator
Bug: https://github.com/dart-lang/sdk/issues/38587
Bug: https://github.com/dart-lang/sdk/issues/48164
Change-Id: I991d1df4be5bf55efec5371b767b332d37dfa3e0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/217289
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2022-01-20 00:57:57 +00:00
|
|
|
(gn_args['target_cpu'] != 'riscv32') and
|
|
|
|
(gn_args['target_cpu'] != 'riscv64') and
|
2019-12-11 18:12:47 +00:00
|
|
|
sanitizer == 'none')
|
2019-08-05 20:34:31 +00:00
|
|
|
|
2021-12-08 00:25:10 +00:00
|
|
|
# Use mallinfo2 if specified on the command line
|
|
|
|
gn_args['dart_use_mallinfo2'] = args.use_mallinfo2
|
|
|
|
|
2019-08-05 20:34:31 +00:00
|
|
|
if gn_args['target_os'] == 'linux':
|
|
|
|
if gn_args['target_cpu'] == 'arm':
|
|
|
|
# Default to -mfloat-abi=hard and -mfpu=neon for arm on Linux as we're
|
|
|
|
# specifying a gnueabihf compiler in //build/toolchain/linux/BUILD.gn.
|
|
|
|
floatabi = 'hard' if args.arm_float_abi == '' else args.arm_float_abi
|
|
|
|
gn_args['arm_version'] = 7
|
|
|
|
gn_args['arm_float_abi'] = floatabi
|
|
|
|
gn_args['arm_use_neon'] = True
|
|
|
|
elif gn_args['target_cpu'] == 'armv6':
|
|
|
|
floatabi = 'softfp' if args.arm_float_abi == '' else args.arm_float_abi
|
|
|
|
gn_args['target_cpu'] = 'arm'
|
|
|
|
gn_args['arm_version'] = 6
|
|
|
|
gn_args['arm_float_abi'] = floatabi
|
|
|
|
|
|
|
|
gn_args['is_debug'] = mode == 'debug'
|
|
|
|
gn_args['is_release'] = mode == 'release'
|
|
|
|
gn_args['is_product'] = mode == 'product'
|
|
|
|
gn_args['dart_debug'] = mode == 'debug'
|
|
|
|
|
|
|
|
# This setting is only meaningful for Flutter. Standalone builds of the VM
|
|
|
|
# should leave this set to 'develop', which causes the build to defer to
|
|
|
|
# 'is_debug', 'is_release' and 'is_product'.
|
|
|
|
if mode == 'product':
|
|
|
|
gn_args['dart_runtime_mode'] = 'release'
|
|
|
|
else:
|
|
|
|
gn_args['dart_runtime_mode'] = 'develop'
|
|
|
|
|
|
|
|
gn_args['exclude_kernel_service'] = args.exclude_kernel_service
|
|
|
|
|
2020-06-25 03:36:41 +00:00
|
|
|
gn_args['is_clang'] = args.clang
|
2019-08-05 20:34:31 +00:00
|
|
|
|
|
|
|
enable_code_coverage = args.code_coverage and gn_args['is_clang']
|
|
|
|
gn_args['dart_vm_code_coverage'] = enable_code_coverage
|
|
|
|
|
2019-12-11 18:12:47 +00:00
|
|
|
gn_args['is_asan'] = sanitizer == 'asan'
|
|
|
|
gn_args['is_lsan'] = sanitizer == 'lsan'
|
|
|
|
gn_args['is_msan'] = sanitizer == 'msan'
|
|
|
|
gn_args['is_tsan'] = sanitizer == 'tsan'
|
|
|
|
gn_args['is_ubsan'] = sanitizer == 'ubsan'
|
2019-11-18 16:58:53 +00:00
|
|
|
gn_args['is_qemu'] = args.use_qemu
|
2019-08-05 20:34:31 +00:00
|
|
|
|
2021-01-20 17:06:25 +00:00
|
|
|
if not args.platform_sdk:
|
2019-08-05 20:34:31 +00:00
|
|
|
gn_args['dart_platform_sdk'] = args.platform_sdk
|
2020-06-17 16:12:26 +00:00
|
|
|
|
|
|
|
# We don't support stripping on Windows
|
|
|
|
if host_os != 'win':
|
|
|
|
gn_args['dart_stripped_binary'] = 'exe.stripped/dart'
|
|
|
|
gn_args['dart_precompiled_runtime_stripped_binary'] = (
|
|
|
|
'exe.stripped/dart_precompiled_runtime_product')
|
|
|
|
gn_args['gen_snapshot_stripped_binary'] = (
|
|
|
|
'exe.stripped/gen_snapshot_product')
|
2019-08-05 20:34:31 +00:00
|
|
|
|
|
|
|
# Setup the user-defined sysroot.
|
|
|
|
if UseSysroot(args, gn_args):
|
|
|
|
gn_args['dart_use_debian_sysroot'] = True
|
|
|
|
else:
|
|
|
|
sysroot = TargetSysroot(args)
|
|
|
|
if sysroot:
|
|
|
|
gn_args['target_sysroot'] = ParseStringMap(arch, sysroot)
|
|
|
|
|
|
|
|
toolchain = ToolchainPrefix(args)
|
|
|
|
if toolchain:
|
|
|
|
gn_args['toolchain_prefix'] = ParseStringMap(arch, toolchain)
|
|
|
|
|
|
|
|
goma_dir = os.environ.get('GOMA_DIR')
|
2020-08-20 08:24:48 +00:00
|
|
|
# Search for goma in depot_tools in path
|
|
|
|
goma_depot_tools_dir = None
|
|
|
|
for path in os.environ.get('PATH', '').split(os.pathsep):
|
|
|
|
if os.path.basename(path) == 'depot_tools':
|
|
|
|
cipd_bin = os.path.join(path, '.cipd_bin')
|
|
|
|
if os.path.isfile(os.path.join(cipd_bin, 'gomacc')):
|
|
|
|
goma_depot_tools_dir = cipd_bin
|
|
|
|
break
|
|
|
|
# Otherwise use goma from home directory.
|
|
|
|
# TODO(whesse): Remove support for goma installed in home directory.
|
|
|
|
# Goma will only be distributed through depot_tools.
|
2019-08-05 20:34:31 +00:00
|
|
|
goma_home_dir = os.path.join(os.getenv('HOME', ''), 'goma')
|
|
|
|
if args.goma and goma_dir:
|
|
|
|
gn_args['use_goma'] = True
|
|
|
|
gn_args['goma_dir'] = goma_dir
|
2020-08-20 08:24:48 +00:00
|
|
|
elif args.goma and goma_depot_tools_dir:
|
|
|
|
gn_args['use_goma'] = True
|
|
|
|
gn_args['goma_dir'] = goma_depot_tools_dir
|
2019-08-05 20:34:31 +00:00
|
|
|
elif args.goma and os.path.exists(goma_home_dir):
|
|
|
|
gn_args['use_goma'] = True
|
|
|
|
gn_args['goma_dir'] = goma_home_dir
|
|
|
|
else:
|
|
|
|
gn_args['use_goma'] = False
|
|
|
|
gn_args['goma_dir'] = None
|
|
|
|
|
2020-10-08 09:44:23 +00:00
|
|
|
if gn_args['target_os'] == 'mac' and gn_args['use_goma']:
|
|
|
|
gn_args['mac_use_goma_rbe'] = True
|
|
|
|
|
2019-08-05 20:34:31 +00:00
|
|
|
# Code coverage requires -O0 to be set.
|
|
|
|
if enable_code_coverage:
|
|
|
|
gn_args['dart_debug_optimization_level'] = 0
|
|
|
|
gn_args['debug_optimization_level'] = 0
|
|
|
|
elif args.debug_opt_level:
|
|
|
|
gn_args['dart_debug_optimization_level'] = args.debug_opt_level
|
|
|
|
gn_args['debug_optimization_level'] = args.debug_opt_level
|
|
|
|
|
2020-07-07 06:08:20 +00:00
|
|
|
gn_args['verify_sdk_hash'] = verify_sdk_hash
|
|
|
|
|
2019-08-05 20:34:31 +00:00
|
|
|
return gn_args
|
2016-09-23 14:47:36 +00:00
|
|
|
|
2016-10-05 02:49:14 +00:00
|
|
|
|
2017-05-07 04:44:59 +00:00
|
|
|
def ProcessOsOption(os_name):
|
2019-08-05 20:34:31 +00:00
|
|
|
if os_name == 'host':
|
|
|
|
return HOST_OS
|
|
|
|
return os_name
|
2016-10-05 02:49:14 +00:00
|
|
|
|
|
|
|
|
2017-05-07 04:44:59 +00:00
|
|
|
def ProcessOptions(args):
|
2019-08-05 20:34:31 +00:00
|
|
|
if args.arch == 'all':
|
2021-02-04 17:44:37 +00:00
|
|
|
args.arch = 'ia32,x64,simarm,simarm64,x64c,simarm64c'
|
2019-08-05 20:34:31 +00:00
|
|
|
if args.mode == 'all':
|
|
|
|
args.mode = 'debug,release,product'
|
|
|
|
if args.os == 'all':
|
2020-06-18 00:24:31 +00:00
|
|
|
args.os = 'host,android,fuchsia'
|
2019-12-11 18:12:47 +00:00
|
|
|
if args.sanitizer == 'all':
|
|
|
|
args.sanitizer = 'none,asan,lsan,msan,tsan,ubsan'
|
2019-08-05 20:34:31 +00:00
|
|
|
args.mode = args.mode.split(',')
|
|
|
|
args.arch = args.arch.split(',')
|
|
|
|
args.os = args.os.split(',')
|
2019-12-11 18:12:47 +00:00
|
|
|
args.sanitizer = args.sanitizer.split(',')
|
2019-08-05 20:34:31 +00:00
|
|
|
for mode in args.mode:
|
|
|
|
if not mode in ['debug', 'release', 'product']:
|
|
|
|
print("Unknown mode %s" % mode)
|
|
|
|
return False
|
2020-07-14 14:10:11 +00:00
|
|
|
for i, arch in enumerate(args.arch):
|
|
|
|
if not arch in AVAILABLE_ARCHS:
|
|
|
|
# Normalise to lower case form to make it less case-picky.
|
|
|
|
arch_lower = arch.lower()
|
|
|
|
if arch_lower in AVAILABLE_ARCHS:
|
|
|
|
args.arch[i] = arch_lower
|
|
|
|
continue
|
2019-08-05 20:34:31 +00:00
|
|
|
print("Unknown arch %s" % arch)
|
|
|
|
return False
|
|
|
|
oses = [ProcessOsOption(os_name) for os_name in args.os]
|
|
|
|
for os_name in oses:
|
2020-06-18 00:24:31 +00:00
|
|
|
if not os_name in [
|
|
|
|
'android', 'freebsd', 'linux', 'macos', 'win32', 'fuchsia'
|
|
|
|
]:
|
2019-08-05 20:34:31 +00:00
|
|
|
print("Unknown os %s" % os_name)
|
|
|
|
return False
|
2020-06-18 00:24:31 +00:00
|
|
|
if os_name == 'android':
|
2019-08-05 20:34:31 +00:00
|
|
|
if not HOST_OS in ['linux', 'macos']:
|
2020-12-10 12:15:17 +00:00
|
|
|
print(
|
|
|
|
"Cross-compilation to %s is not supported on host os %s." %
|
|
|
|
(os_name, HOST_OS))
|
2019-08-05 20:34:31 +00:00
|
|
|
return False
|
2021-03-03 21:51:24 +00:00
|
|
|
if not arch in [
|
[vm] Support RISC-V.
Implements a backend targeting RV32GC and RV64GC, based on Linux standardizing around GC. The assembler is written to make it easy to disable usage of C, but because the sizes of some instruction sequences are compile-time constants, an additional build configuration would need to be defined to make use of it.
The assembler and disassembler cover every RV32/64GC instruction. The simulator covers all instructions except accessing CSRs and the floating point state accessible through such, include accrued exceptions and dynamic rounding mode.
Quirks:
- RISC-V is a compare-and-branch architecture, but some existing "architecture-independent" parts of the Dart compiler assume a condition code architecture. To avoid rewriting these parts, we use a peephole in the assembler to map to compare-and-branch. See Assembler::BranchIf. Luckily nothing depended on taking multiple branches on the same condition code set.
- There are no hardware overflow checks, so we must use Hacker's Delight style software checks. Often these are very cheap: if the sign of one operand is known, a single branch is needed.
- The ranges of RISC-V branches and jumps are such that we use 3 levels of generation for forward branches, instead of the 2 levels of near and far branches used on ARM[64]. Nearly all code is handled by the first two levels with 20-bits of range, with enormous regex matchers triggering the third level that uses aupic+jalr to get 32-bits of range.
- For PC-relative calls in AOT, we always generate auipc+jalr pairs with 32-bits of range, so we never generate trampolines.
- Only a subset of registers are available in some compressed instructions, so we assign the most popular uses to these registers. In particular, THR, TMP[2], CODE and PP. This has the effect of assigning CODE and PP to volatile registers in the C calling convention, whereas they are assigned preserved registers on the other architectures. As on ARM64, PP is untagged; this is so short indices can be accessed with a compressed instruction.
- There are no push or pop instructions, so combining pushes and pops is preferred so we can update SP once.
- The C calling convention has a strongly aligned stack, but unlike on ARM64 we don't need to use an alternate stack pointer. The author ensured language was added to the RISC-V psABI making the OS responsible for realigning the stack pointer for signal handlers, allowing Dart to leave the stack pointer misaligned from the C calling convention's point of view until a foreign call.
- We don't bother with the link register tracking done on ARM[64]. Instead we make use of an alternate link register to avoid inline spilling in the write barrier.
Unimplemented:
- non-trivial FFI cases
- Compressed pointers - No intention to implement.
- Unboxed SIMD - We might make use of the V extension registers when the V extension is ratified.
- BigInt intrinsics
TEST=existing tests for IL level, new tests for assembler/disassembler/simulator
Bug: https://github.com/dart-lang/sdk/issues/38587
Bug: https://github.com/dart-lang/sdk/issues/48164
Change-Id: I991d1df4be5bf55efec5371b767b332d37dfa3e0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/217289
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2022-01-20 00:57:57 +00:00
|
|
|
'ia32',
|
|
|
|
'x64',
|
|
|
|
'arm',
|
|
|
|
'arm_x64',
|
|
|
|
'armv6',
|
|
|
|
'arm64',
|
|
|
|
'x64c',
|
|
|
|
'arm64c',
|
2021-03-03 21:51:24 +00:00
|
|
|
]:
|
2019-08-05 20:34:31 +00:00
|
|
|
print(
|
|
|
|
"Cross-compilation to %s is not supported for architecture %s."
|
|
|
|
% (os_name, arch))
|
|
|
|
return False
|
2020-06-18 00:24:31 +00:00
|
|
|
elif os_name == 'fuchsia':
|
2021-10-13 21:14:56 +00:00
|
|
|
if not HOST_OS in ['linux', 'macos']:
|
2020-12-10 12:15:17 +00:00
|
|
|
print(
|
|
|
|
"Cross-compilation to %s is not supported on host os %s." %
|
|
|
|
(os_name, HOST_OS))
|
2020-06-18 00:24:31 +00:00
|
|
|
return False
|
2021-03-03 21:51:24 +00:00
|
|
|
if not arch in ['x64', 'arm64', 'x64c', 'arm64c']:
|
2020-06-18 00:24:31 +00:00
|
|
|
print(
|
|
|
|
"Cross-compilation to %s is not supported for architecture %s."
|
|
|
|
% (os_name, arch))
|
|
|
|
return False
|
|
|
|
elif os_name != HOST_OS:
|
|
|
|
print("Unsupported target os %s" % os_name)
|
|
|
|
return False
|
2019-08-05 20:34:31 +00:00
|
|
|
if HOST_OS != 'win' and args.use_crashpad:
|
|
|
|
print("Crashpad is only supported on Windows")
|
2016-10-05 02:49:14 +00:00
|
|
|
return False
|
2019-08-05 20:34:31 +00:00
|
|
|
return True
|
2016-10-05 02:49:14 +00:00
|
|
|
|
|
|
|
|
2016-10-05 22:36:46 +00:00
|
|
|
def os_has_ide(host_os):
|
2019-08-05 20:34:31 +00:00
|
|
|
return host_os.startswith('win') or host_os.startswith('mac')
|
2016-10-05 22:36:46 +00:00
|
|
|
|
|
|
|
|
|
|
|
def ide_switch(host_os):
|
2019-08-05 20:34:31 +00:00
|
|
|
if host_os.startswith('win'):
|
|
|
|
return '--ide=vs'
|
|
|
|
elif host_os.startswith('mac'):
|
|
|
|
return '--ide=xcode'
|
|
|
|
else:
|
|
|
|
return '--ide=json'
|
2016-10-05 22:36:46 +00:00
|
|
|
|
|
|
|
|
2020-07-14 14:10:11 +00:00
|
|
|
def AddCommonGnOptionArgs(parser):
|
|
|
|
"""Adds arguments that will change the default GN arguments."""
|
|
|
|
|
|
|
|
parser.add_argument('--goma', help='Use goma', action='store_true')
|
|
|
|
parser.add_argument('--no-goma',
|
|
|
|
help='Disable goma',
|
|
|
|
dest='goma',
|
|
|
|
action='store_false')
|
|
|
|
parser.set_defaults(goma=True)
|
|
|
|
|
|
|
|
parser.add_argument('--verify-sdk-hash',
|
|
|
|
help='Enable SDK hash checks (default)',
|
|
|
|
dest='verify_sdk_hash',
|
|
|
|
action='store_true')
|
|
|
|
parser.add_argument('-nvh',
|
|
|
|
'--no-verify-sdk-hash',
|
|
|
|
help='Disable SDK hash checks',
|
|
|
|
dest='verify_sdk_hash',
|
|
|
|
action='store_false')
|
|
|
|
parser.set_defaults(verify_sdk_hash=True)
|
|
|
|
|
|
|
|
parser.add_argument('--clang', help='Use Clang', action='store_true')
|
|
|
|
parser.add_argument('--no-clang',
|
|
|
|
help='Disable Clang',
|
|
|
|
dest='clang',
|
|
|
|
action='store_false')
|
|
|
|
parser.set_defaults(clang=True)
|
|
|
|
|
|
|
|
parser.add_argument(
|
2019-08-05 20:34:31 +00:00
|
|
|
'--platform-sdk',
|
|
|
|
help='Directs the create_sdk target to create a smaller "Platform" SDK',
|
|
|
|
default=MakePlatformSDK(),
|
|
|
|
action='store_true')
|
2020-07-14 14:10:11 +00:00
|
|
|
parser.add_argument('--use-crashpad',
|
|
|
|
default=False,
|
|
|
|
dest='use_crashpad',
|
|
|
|
action='store_true')
|
|
|
|
parser.add_argument('--use-qemu',
|
|
|
|
default=False,
|
|
|
|
dest='use_qemu',
|
|
|
|
action='store_true')
|
|
|
|
parser.add_argument('--exclude-kernel-service',
|
|
|
|
help='Exclude the kernel service.',
|
|
|
|
default=False,
|
|
|
|
dest='exclude_kernel_service',
|
|
|
|
action='store_true')
|
|
|
|
parser.add_argument('--arm-float-abi',
|
|
|
|
type=str,
|
|
|
|
help='The ARM float ABI (soft, softfp, hard)',
|
|
|
|
metavar='[soft,softfp,hard]',
|
|
|
|
default='')
|
|
|
|
|
|
|
|
parser.add_argument('--code-coverage',
|
|
|
|
help='Enable code coverage for the standalone VM',
|
|
|
|
default=False,
|
|
|
|
dest="code_coverage",
|
|
|
|
action='store_true')
|
|
|
|
parser.add_argument('--debug-opt-level',
|
|
|
|
'-d',
|
|
|
|
help='The optimization level to use for debug builds',
|
|
|
|
type=str)
|
|
|
|
parser.add_argument('--gn-args',
|
|
|
|
help='Set extra GN args',
|
|
|
|
dest='gn_args',
|
|
|
|
action='append')
|
|
|
|
parser.add_argument(
|
2019-08-05 20:34:31 +00:00
|
|
|
'--toolchain-prefix',
|
|
|
|
'-t',
|
|
|
|
type=str,
|
|
|
|
help='Comma-separated list of arch=/path/to/toolchain-prefix mappings')
|
2020-07-14 14:10:11 +00:00
|
|
|
parser.add_argument('--ide',
|
|
|
|
help='Generate an IDE file.',
|
|
|
|
default=os_has_ide(HOST_OS),
|
|
|
|
action='store_true')
|
2021-01-25 10:37:02 +00:00
|
|
|
parser.add_argument('--export-compile-commands',
|
|
|
|
help='Export compile_commands.json database file.',
|
|
|
|
default=False,
|
|
|
|
action='store_true')
|
2020-07-14 14:10:11 +00:00
|
|
|
parser.add_argument(
|
|
|
|
'--target-sysroot',
|
|
|
|
'-s',
|
|
|
|
type=str,
|
|
|
|
help='Comma-separated list of arch=/path/to/sysroot mappings')
|
2021-12-08 00:25:10 +00:00
|
|
|
parser.add_argument('--use-mallinfo2',
|
|
|
|
help='Use mallinfo2 to collect malloc stats.',
|
|
|
|
default=False,
|
|
|
|
dest='use_mallinfo2',
|
|
|
|
action='store_true')
|
2020-07-14 14:10:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
def AddCommonConfigurationArgs(parser):
|
|
|
|
"""Adds arguments that influence which configuration will be built."""
|
|
|
|
parser.add_argument("-a",
|
|
|
|
"--arch",
|
|
|
|
type=str,
|
|
|
|
help='Target architectures (comma-separated).',
|
|
|
|
metavar='[all,' + ','.join(AVAILABLE_ARCHS) + ']',
|
|
|
|
default=utils.GuessArchitecture())
|
|
|
|
parser.add_argument('--mode',
|
|
|
|
'-m',
|
|
|
|
type=str,
|
|
|
|
help='Build variants (comma-separated).',
|
|
|
|
metavar='[all,debug,release,product]',
|
|
|
|
default='debug')
|
|
|
|
parser.add_argument('--os',
|
|
|
|
type=str,
|
|
|
|
help='Target OSs (comma-separated).',
|
|
|
|
metavar='[all,host,android,fuchsia]',
|
|
|
|
default='host')
|
|
|
|
parser.add_argument('--sanitizer',
|
|
|
|
type=str,
|
|
|
|
help='Build variants (comma-separated).',
|
|
|
|
metavar='[all,none,asan,lsan,msan,tsan,ubsan]',
|
|
|
|
default='none')
|
|
|
|
|
|
|
|
|
|
|
|
def AddOtherArgs(parser):
|
|
|
|
"""Adds miscellaneous arguments to the parser."""
|
|
|
|
parser.add_argument("-v",
|
|
|
|
"--verbose",
|
|
|
|
help='Verbose output.',
|
|
|
|
default=False,
|
|
|
|
action="store_true")
|
|
|
|
|
|
|
|
|
|
|
|
def parse_args(args):
|
|
|
|
args = args[1:]
|
|
|
|
parser = argparse.ArgumentParser(
|
|
|
|
description='A script to run `gn gen`.',
|
|
|
|
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
|
|
|
|
|
|
config_group = parser.add_argument_group('Configuration Related Arguments')
|
|
|
|
AddCommonConfigurationArgs(config_group)
|
|
|
|
|
|
|
|
gn_group = parser.add_argument_group('GN Related Arguments')
|
|
|
|
AddCommonGnOptionArgs(gn_group)
|
|
|
|
|
|
|
|
other_group = parser.add_argument_group('Other Arguments')
|
|
|
|
AddOtherArgs(other_group)
|
2019-08-05 20:34:31 +00:00
|
|
|
|
|
|
|
options = parser.parse_args(args)
|
|
|
|
if not ProcessOptions(options):
|
|
|
|
parser.print_help()
|
|
|
|
return None
|
|
|
|
return options
|
2016-09-23 14:47:36 +00:00
|
|
|
|
|
|
|
|
2020-07-14 14:10:11 +00:00
|
|
|
def BuildGnCommand(args, mode, arch, target_os, sanitizer, out_dir):
|
2019-08-05 20:34:31 +00:00
|
|
|
gn = os.path.join(DART_ROOT, 'buildtools',
|
|
|
|
'gn.exe' if utils.IsWindows() else 'gn')
|
|
|
|
if not os.path.isfile(gn):
|
2020-07-14 14:10:11 +00:00
|
|
|
raise Exception("Couldn't find the gn binary at path: " + gn)
|
|
|
|
|
|
|
|
# TODO(infra): Re-enable --check. Many targets fail to use
|
|
|
|
# public_deps to re-expose header files to their dependents.
|
|
|
|
# See dartbug.com/32364
|
|
|
|
command = [gn, 'gen', out_dir]
|
|
|
|
gn_args = ToCommandLine(
|
|
|
|
ToGnArgs(args, mode, arch, target_os, sanitizer, args.verify_sdk_hash))
|
|
|
|
gn_args += GetGNArgs(args)
|
|
|
|
if args.ide:
|
|
|
|
command.append(ide_switch(HOST_OS))
|
2021-01-25 10:37:02 +00:00
|
|
|
if args.export_compile_commands:
|
|
|
|
command.append('--export-compile-commands')
|
2020-07-14 14:10:11 +00:00
|
|
|
command.append('--args=%s' % ' '.join(gn_args))
|
|
|
|
|
|
|
|
return command
|
|
|
|
|
2019-08-05 20:34:31 +00:00
|
|
|
|
2020-07-14 14:10:11 +00:00
|
|
|
def RunGnOnConfiguredConfigurations(args):
|
2019-08-05 20:34:31 +00:00
|
|
|
commands = []
|
|
|
|
for target_os in args.os:
|
|
|
|
for mode in args.mode:
|
|
|
|
for arch in args.arch:
|
2019-12-11 18:12:47 +00:00
|
|
|
for sanitizer in args.sanitizer:
|
2020-06-16 23:37:36 +00:00
|
|
|
out_dir = GetOutDir(mode, arch, target_os, sanitizer)
|
2020-07-14 14:10:11 +00:00
|
|
|
commands.append(
|
|
|
|
BuildGnCommand(args, mode, arch, target_os, sanitizer,
|
|
|
|
out_dir))
|
2019-12-11 18:12:47 +00:00
|
|
|
if args.verbose:
|
|
|
|
print("gn gen --check in %s" % out_dir)
|
2019-08-05 20:34:31 +00:00
|
|
|
|
2020-11-13 12:35:09 +00:00
|
|
|
active_commands = []
|
|
|
|
|
|
|
|
def cleanup(command):
|
|
|
|
print("Command failed: " + ' '.join(command))
|
|
|
|
for (_, process) in active_commands:
|
|
|
|
process.terminate()
|
|
|
|
|
|
|
|
for command in commands:
|
|
|
|
try:
|
|
|
|
process = subprocess.Popen(command, cwd=DART_ROOT)
|
|
|
|
active_commands.append([command, process])
|
|
|
|
except Exception as e:
|
|
|
|
print('Error: %s' % e)
|
|
|
|
cleanup(command)
|
2019-08-05 20:34:31 +00:00
|
|
|
return 1
|
2020-11-13 12:35:09 +00:00
|
|
|
while active_commands:
|
|
|
|
time.sleep(0.1)
|
|
|
|
for active_command in active_commands:
|
|
|
|
(command, process) = active_command
|
|
|
|
if process.poll() is not None:
|
|
|
|
active_commands.remove(active_command)
|
|
|
|
if process.returncode != 0:
|
|
|
|
cleanup(command)
|
|
|
|
return 1
|
|
|
|
return 0
|
2019-08-05 20:34:31 +00:00
|
|
|
|
2020-07-14 14:10:11 +00:00
|
|
|
|
|
|
|
def Main(argv):
|
|
|
|
starttime = time.time()
|
2021-02-26 12:46:57 +00:00
|
|
|
|
2020-07-14 14:10:11 +00:00
|
|
|
args = parse_args(argv)
|
2021-02-26 12:46:57 +00:00
|
|
|
if args is None:
|
|
|
|
return 1
|
2020-07-14 14:10:11 +00:00
|
|
|
|
2020-11-13 12:35:09 +00:00
|
|
|
result = RunGnOnConfiguredConfigurations(args)
|
2020-07-14 14:10:11 +00:00
|
|
|
|
2019-08-05 20:34:31 +00:00
|
|
|
if args.verbose:
|
2021-02-26 12:46:57 +00:00
|
|
|
endtime = time.time()
|
2019-08-05 20:34:31 +00:00
|
|
|
print("GN Time: %.3f seconds" % (endtime - starttime))
|
2021-02-26 12:46:57 +00:00
|
|
|
|
2020-11-13 12:35:09 +00:00
|
|
|
return result
|
2016-10-05 02:49:14 +00:00
|
|
|
|
2016-09-23 14:47:36 +00:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2019-08-05 20:34:31 +00:00
|
|
|
sys.exit(Main(sys.argv))
|