Set up crosstest to run simple loop in Om1 on ARM.
We can't run O2 yet because some of the advanced Phi lowering
hooks aren't implemented for O2 yet.
BUG= https://code.google.com/p/nativeclient/issues/detail?id=4076
R=stichnot@chromium.org
Review URL: https://codereview.chromium.org/1160873006.
diff --git a/Makefile.standalone b/Makefile.standalone
index 708c91f..5f2686b 100644
--- a/Makefile.standalone
+++ b/Makefile.standalone
@@ -22,10 +22,13 @@
NACL_ROOT ?= $(shell python -c "import sys; sys.path.insert(0, 'pydir'); \
import utils; print utils.FindBaseNaCl()")
+# TOOLCHAIN_ROOT is the location of NaCl/PNaCl toolchains and other
+# tools like qemu.
+TOOLCHAIN_ROOT ?= $(shell readlink -e $(NACL_ROOT)/toolchain/linux_x86)
+
# PNACL_TOOLCHAIN_ROOT is the location of the PNaCl toolchain.
# This is used as the default root for finding binutils, libcxx, etc.
-PNACL_TOOLCHAIN_ROOT ?= $(shell readlink -e \
- $(NACL_ROOT)/toolchain/linux_x86/pnacl_newlib_raw)
+PNACL_TOOLCHAIN_ROOT ?= $(shell readlink -e $(TOOLCHAIN_ROOT)/pnacl_newlib_raw)
# The location of PNaCl tools (e.g., binutils objdump, pnacl-clang++, etc.).
PNACL_BIN_PATH ?= $(shell readlink -e $(PNACL_TOOLCHAIN_ROOT)/bin)
@@ -105,6 +108,7 @@
$(info Using LLVM_SRC_PATH = $(LLVM_SRC_PATH))
$(info Using SB_LLVM_PATH = $(SB_LLVM_PATH))
$(info Using NACL_ROOT = $(NACL_ROOT))
+$(info Using TOOLCHAIN_ROOT = $(TOOLCHAIN_ROOT))
$(info Using PNACL_TOOLCHAIN_ROOT = $(PNACL_TOOLCHAIN_ROOT))
$(info Using PNACL_BIN_PATH = $(PNACL_BIN_PATH))
$(info Using CLANG_PATH = $(CLANG_PATH))
@@ -303,8 +307,10 @@
# Do all native/sse2 tests, but only test_vector_ops for native/sse4.1.
# For (slow) sandboxed tests, limit to Om1/sse4.1.
./pydir/crosstest_generator.py -v --lit \
- -i native,sse2 -i native,sse4.1,test_vector_ops \
- -i sandbox,sse4.1,Om1
+ --toolchain-root $(TOOLCHAIN_ROOT) \
+ -i x8632,native,sse2 -i x8632,native,sse4.1,test_vector_ops \
+ -i x8632,sandbox,sse4.1,Om1 \
+ -i arm32,native,neon,Om1,simple_loop
PNACL_BIN_PATH=$(PNACL_BIN_PATH) \
$(LLVM_SRC_PATH)/utils/lit/lit.py -sv crosstest/Output
endif
diff --git a/pydir/build-runtime.py b/pydir/build-runtime.py
index cc1054f..4010b51 100755
--- a/pydir/build-runtime.py
+++ b/pydir/build-runtime.py
@@ -1,13 +1,15 @@
#!/usr/bin/env python2
import argparse
-from collections import namedtuple
import os
import shutil
import tempfile
+
+import targets
from utils import shellcmd
from utils import FindBaseNaCl
+
def Translate(ll_files, extra_args, obj, verbose):
"""Translate a set of input bitcode files into a single object file.
@@ -29,6 +31,7 @@
obj
], echo=verbose)
+
def PartialLink(obj_files, extra_args, lib, verbose):
"""Partially links a set of obj files into a final obj library."""
shellcmd(['le32-nacl-ld',
@@ -37,10 +40,6 @@
] + extra_args + obj_files, echo=verbose)
-TargetInfo = namedtuple('TargetInfo',
- ['target', 'triple', 'llc_flags', 'ld_emu'])
-
-
def MakeRuntimesForTarget(target_info, ll_files,
srcdir, tempdir, rtdir, verbose):
def TmpFile(template):
@@ -72,7 +71,7 @@
# The sandboxed library does not get the profiler helper function as the
# binaries are linked with -nostdlib.
Translate(ll_files,
- ['-mtriple=' + target_info.triple.replace('linux', 'nacl')] +
+ ['-mtriple=' + targets.ConvertTripleToNaCl(target_info.triple)] +
target_info.llc_flags,
OutFile('{rtdir}/szrt_sb_{target}.o'),
verbose)
@@ -123,19 +122,9 @@
ll_files = ['{dir}/szrt.ll'.format(dir=tempdir),
'{srcdir}/szrt_ll.ll'.format(srcdir=srcdir)]
- x8632_target = TargetInfo(target='x8632',
- triple='i686-none-linux',
- llc_flags=['-mcpu=pentium4m'],
- ld_emu='elf_i386_nacl')
- MakeRuntimesForTarget(x8632_target, ll_files,
+ MakeRuntimesForTarget(targets.X8632Target, ll_files,
srcdir, tempdir, rtdir, args.verbose)
- arm32_target = TargetInfo(target='arm32',
- triple='armv7a-none-linux-gnueabihf',
- llc_flags=['-mcpu=cortex-a9',
- '-float-abi=hard',
- '-mattr=+neon'],
- ld_emu='armelf_nacl')
- MakeRuntimesForTarget(arm32_target, ll_files,
+ MakeRuntimesForTarget(targets.ARM32Target, ll_files,
srcdir, tempdir, rtdir, args.verbose)
finally:
diff --git a/pydir/crosstest.py b/pydir/crosstest.py
index ca7e242..ebc33f8 100755
--- a/pydir/crosstest.py
+++ b/pydir/crosstest.py
@@ -6,6 +6,7 @@
import sys
import tempfile
+import targets
from utils import shellcmd
from utils import FindBaseNaCl
@@ -22,8 +23,23 @@
results.
"""
- # arch_map maps a Subzero target string to an llvm-mc -triple string.
- arch_map = { 'x8632':'i686', 'x8664':'x86_64', 'arm':'armv7a' }
+ # arch_map maps a Subzero target string to TargetInfo (e.g., triple).
+ arch_map = { 'x8632': targets.X8632Target,
+ 'x8664': targets.X8664Target,
+ 'arm32': targets.ARM32Target }
+ arch_sz_flags = { 'x8632': [],
+ 'x8664': [],
+ # TODO(jvoung): remove skip-unimplemented when implemented
+ 'arm32': ['--skip-unimplemented']
+ }
+ arch_llc_flags_extra = {
+ # Use sse2 instructions regardless of input -mattr
+ # argument to avoid differences in (undefined) behavior of
+ # converting NaN to int.
+ 'x8632': ['-mattr=sse2'],
+ 'x8664': ['-mattr=sse2'],
+ 'arm32': [],
+ }
desc = 'Build a cross-test that compares Subzero and llc translation.'
argparser = argparse.ArgumentParser(description=desc)
argparser.add_argument('--test', required=True, action='append',
@@ -46,7 +62,8 @@
argparser.add_argument('--clang-opt', required=False, default=True,
dest='clang_opt')
argparser.add_argument('--mattr', required=False, default='sse2',
- dest='attr', choices=['sse2', 'sse4.1'],
+ dest='attr', choices=['sse2', 'sse4.1',
+ 'neon', 'hwdiv-arm'],
metavar='ATTRIBUTE',
help='Target attribute. Default %(default)s.')
argparser.add_argument('--sandbox', required=False, default=0, type=int,
@@ -76,7 +93,11 @@
nacl_root = FindBaseNaCl()
bindir = ('{root}/toolchain/linux_x86/pnacl_newlib_raw/bin'
.format(root=nacl_root))
- triple = arch_map[args.target] + ('-nacl' if args.sandbox else '')
+ target_info = arch_map[args.target]
+ triple = target_info.triple
+ if args.sandbox:
+ triple = targets.ConvertTripleToNaCl(triple)
+ llc_flags = target_info.llc_flags + arch_llc_flags_extra[args.target]
mypath = os.path.abspath(os.path.dirname(sys.argv[0]))
objs = []
@@ -116,7 +137,7 @@
'-externalize',
'-filetype=' + args.filetype,
'-o=' + (obj_sz if args.filetype == 'obj' else asm_sz),
- bitcode])
+ bitcode] + arch_sz_flags[args.target])
if args.filetype != 'obj':
shellcmd(['{bin}/llvm-mc'.format(bin=bindir),
'-triple=' + triple,
@@ -137,14 +158,10 @@
if args.crosstest_bitcode:
shellcmd(['{bin}/pnacl-llc'.format(bin=bindir),
'-mtriple=' + triple,
- # Use sse2 instructions regardless of input -mattr
- # argument to avoid differences in (undefined) behavior of
- # converting NaN to int.
- '-mattr=sse2',
'-externalize',
'-filetype=obj',
'-o=' + obj_llc,
- bitcode])
+ bitcode] + llc_flags)
objs.append(obj_llc)
else:
objs.append(arg)
@@ -162,7 +179,8 @@
sb_native_args = (['-O0', '--pnacl-allow-native', '-arch', 'x8632',
'-Wn,-defsym=__Sz_AbsoluteZero=0']
if args.sandbox else
- ['-g', '-m32', '-lm', '-lpthread',
+ ['-g', '-target=' + triple,
+ '-lm', '-lpthread',
'-Wl,--defsym=__Sz_AbsoluteZero=0'])
shellcmd([compiler, args.driver] + objs +
['-o', os.path.join(args.dir, args.output)] + sb_native_args)
diff --git a/pydir/crosstest_generator.py b/pydir/crosstest_generator.py
index 945ad00..e79657f 100755
--- a/pydir/crosstest_generator.py
+++ b/pydir/crosstest_generator.py
@@ -27,6 +27,22 @@
return True
return default_match
+
+def RunNativePrefix(toolchain_root, target, run_cmd):
+ """Returns a prefix for running an executable for the target.
+
+ For example, we may be running an ARM or MIPS target executable on an
+ x86 machine and need to use an emulator.
+ """
+ arch_map = { 'x8632' : '',
+ 'x8664' : '',
+ 'arm32' : os.path.join(toolchain_root, 'arm_trusted',
+ 'run_under_qemu_arm'),
+ }
+ prefix = arch_map[target]
+ return (prefix + ' ' + run_cmd) if prefix else run_cmd
+
+
def main():
"""Framework for cross test generation and execution.
@@ -39,13 +55,20 @@
root = FindBaseNaCl()
# The rest of the attribute sets.
- targets = [ 'x8632' ]
+ targets = [ 'x8632', 'arm32' ]
sandboxing = [ 'native', 'sandbox' ]
opt_levels = [ 'Om1', 'O2' ]
- arch_attrs = [ 'sse2', 'sse4.1' ]
+ arch_attrs = { 'x8632': [ 'sse2', 'sse4.1' ],
+ 'arm32': [ 'neon', 'hwdiv-arm' ] }
+ flat_attrs = []
+ for v in arch_attrs.values():
+ flat_attrs += v
+ arch_flags = { 'x8632': [],
+ # ARM doesn't have an integrated assembler yet.
+ 'arm32': ['--filetype=asm'] }
# all_keys is only used in the help text.
all_keys = '; '.join([' '.join(targets), ' '.join(sandboxing),
- ' '.join(opt_levels), ' '.join(arch_attrs)])
+ ' '.join(opt_levels), ' '.join(flat_attrs)])
argparser = argparse.ArgumentParser(
description=' ' + main.__doc__ +
@@ -76,6 +99,8 @@
help='Output directory')
argparser.add_argument('--lit', default=False, action='store_true',
help='Generate files for lit testing')
+ argparser.add_argument('--toolchain-root', dest='toolchain_root',
+ help='Path to toolchain binaries.')
args = argparser.parse_args()
# Run from the crosstest directory to make it easy to grab inputs.
@@ -113,7 +138,7 @@
for target in targets:
for sb in sandboxing:
for opt in opt_levels:
- for attr in arch_attrs:
+ for attr in arch_attrs[target]:
desc = [ test, target, sb, opt, attr ]
if Match(set(desc), includes, excludes, default_match):
exe = '{test}_{target}_{sb}_{opt}_{attr}'.format(
@@ -122,24 +147,27 @@
extra = (tests.get(test, 'flags').split(' ')
if tests.has_option(test, 'flags') else [])
# Generate the compile command.
- cmp_cmd = ['{path}/crosstest.py'.format(path=pypath),
- '-{opt}'.format(opt=opt),
- '--mattr={attr}'.format(attr=attr),
- '--prefix=Subzero_',
- '--target={target}'.format(target=target),
- '--sandbox={sb}'.format(sb='1' if sb=='sandbox'
- else '0'),
- '--dir={dir}'.format(dir=args.dir),
- '--output={exe}'.format(exe=exe),
- '--driver={drv}'.format(drv=tests.get(test, 'driver')),
- ] + extra + \
- [ '--test=' + t
- for t in tests.get(test, 'test').split(' ') ]
+ cmp_cmd = (
+ ['{path}/crosstest.py'.format(path=pypath),
+ '-{opt}'.format(opt=opt),
+ '--mattr={attr}'.format(attr=attr),
+ '--prefix=Subzero_',
+ '--target={target}'.format(target=target),
+ '--sandbox={sb}'.format(sb='1' if sb=='sandbox' else '0'),
+ '--dir={dir}'.format(dir=args.dir),
+ '--output={exe}'.format(exe=exe),
+ '--driver={drv}'.format(drv=tests.get(test, 'driver'))] +
+ extra +
+ ['--test=' + t
+ for t in tests.get(test, 'test').split(' ')] +
+ arch_flags[target])
run_cmd_base = os.path.join(args.dir, exe)
# Generate the run command.
run_cmd = run_cmd_base
if sb == 'sandbox':
run_cmd = '{root}/run.py -q '.format(root=root) + run_cmd
+ else:
+ run_cmd = RunNativePrefix(args.toolchain_root, target, run_cmd)
if args.lit:
# Create a file to drive the lit test.
with open(run_cmd_base + '.xtest', 'w') as f:
diff --git a/pydir/targets.py b/pydir/targets.py
new file mode 100644
index 0000000..0f6433c
--- /dev/null
+++ b/pydir/targets.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python2
+
+from collections import namedtuple
+
+TargetInfo = namedtuple('TargetInfo',
+ ['target', 'triple', 'llc_flags', 'ld_emu'])
+
+X8632Target = TargetInfo(target='x8632',
+ triple='i686-none-linux',
+ llc_flags=['-mcpu=pentium4m'],
+ ld_emu='elf_i386_nacl')
+
+X8664Target = TargetInfo(target='x8664',
+ triple='x86_64-none-linux',
+ llc_flags=['-mcpu=x86-64'],
+ ld_emu='elf_x86_64_nacl')
+
+ARM32Target = TargetInfo(target='arm32',
+ triple='armv7a-none-linux-gnueabihf',
+ llc_flags=['-mcpu=cortex-a9',
+ '-float-abi=hard',
+ '-mattr=+neon'],
+ ld_emu='armelf_nacl')
+
+
+def ConvertTripleToNaCl(nonsfi_triple):
+ return nonsfi_triple.replace('linux', 'nacl')