diff options
| author | Huon Wilson <dbau.pp+github@gmail.com> | 2015-08-29 20:01:33 -0700 |
|---|---|---|
| committer | Huon Wilson <dbau.pp+github@gmail.com> | 2015-08-29 20:11:23 -0700 |
| commit | 29dcff3aa2ca3d867bc83cb555271de7ba7ac5a5 (patch) | |
| tree | ccddef79ca16069c5fb2dc0ed89a35afa4c1f6ac /src/etc | |
| parent | daf8bdca57d0a099f955a33c2f9552b335d06ff6 (diff) | |
| download | rust-29dcff3aa2ca3d867bc83cb555271de7ba7ac5a5.tar.gz rust-29dcff3aa2ca3d867bc83cb555271de7ba7ac5a5.zip | |
Support different scalar integer widths in Rust v. LLVM.
Some x86 C intrinsics are declared to take `int ...` (i.e. exposed in Rust as `i32`), but LLVM implements them by taking `i8` instead.
Diffstat (limited to 'src/etc')
| -rw-r--r-- | src/etc/platform-intrinsics/generator.py | 50 | ||||
| -rw-r--r-- | src/etc/platform-intrinsics/x86/avx.json | 2 | ||||
| -rw-r--r-- | src/etc/platform-intrinsics/x86/avx2.json | 14 | ||||
| -rw-r--r-- | src/etc/platform-intrinsics/x86/sse41.json | 4 | ||||
| -rw-r--r-- | src/etc/platform-intrinsics/x86/sse42.json | 28 |
5 files changed, 70 insertions, 28 deletions
diff --git a/src/etc/platform-intrinsics/generator.py b/src/etc/platform-intrinsics/generator.py index 7f5a737e33e..97b2f57010b 100644 --- a/src/etc/platform-intrinsics/generator.py +++ b/src/etc/platform-intrinsics/generator.py @@ -16,7 +16,8 @@ import re import textwrap SPEC = re.compile( - r'^(?:(?P<id>[iusfIUSF])(?:\((?P<start>\d*)-(?P<end>\d*)\)|(?P<width>\d*))' + + r'^(?:(?P<id>[iusfIUSF])(?:\((?P<start>\d+)-(?P<end>\d+)\)|' + r'(?P<width>\d+)(:?/(?P<llvm_width>\d+))?)' r'|(?P<reference>\d+)(?P<modifiers>[vShdnwus]*)(?P<force_width>x\d+)?)$' ) @@ -111,27 +112,39 @@ class Number(Type): return platform_info.number_type_info(self) class Signed(Number): - def __init__(self, bitwidth): + def __init__(self, bitwidth, llvm_bitwidth = None): Number.__init__(self, bitwidth) + self._llvm_bitwidth = llvm_bitwidth def compiler_ctor(self): - return 'i({})'.format(self.bitwidth()) + if self._llvm_bitwidth is None: + return 'i({})'.format(self.bitwidth()) + else: + return 'i_({}, {})'.format(self.bitwidth(), + self._llvm_bitwidth) def llvm_name(self): - return 'i{}'.format(self.bitwidth()) + bw = self._llvm_bitwidth or self.bitwidth() + return 'i{}'.format(bw) def rust_name(self): return 'i{}'.format(self.bitwidth()) class Unsigned(Number): - def __init__(self, bitwidth): + def __init__(self, bitwidth, llvm_bitwidth = None): Number.__init__(self, bitwidth) + self._llvm_bitwidth = llvm_bitwidth def compiler_ctor(self): - return 'u({})'.format(self.bitwidth()) + if self._llvm_bitwidth is None: + return 'u({})'.format(self.bitwidth()) + else: + return 'u_({}, {})'.format(self.bitwidth(), + self._llvm_bitwidth) def llvm_name(self): - return 'i{}'.format(self.bitwidth()) + bw = self._llvm_bitwidth or self.bitwidth() + return 'i{}'.format(bw) def rust_name(self): return 'u{}'.format(self.bitwidth()) @@ -220,18 +233,28 @@ class TypeSpec(object): id = match.group('id') is_vector = id.islower() type_ctors = TYPE_ID_LOOKUP[id.lower()] + start = match.group('start') if start is not None: end = match.group('end') + llvm_width = None else: start = end = match.group('width') + llvm_width = match.group('llvm_width') start = int(start) end = int(end) bitwidth = start while bitwidth <= end: for ctor in type_ctors: - scalar = ctor(bitwidth) + if llvm_width is not None: + assert not is_vector + llvm_width = int(llvm_width) + assert llvm_width < bitwidth + scalar = ctor(bitwidth, llvm_width) + else: + scalar = ctor(bitwidth) + if is_vector: yield Vector(scalar, width // bitwidth) else: @@ -351,8 +374,9 @@ def parse_args(): vector := vector_elem width | vector_elem := 'i' | 'u' | 's' | 'f' - scalar := scalar_type number + scalar := scalar_type number llvm_width? scalar_type := 'U' | 'S' | 'F' + llvm_width := '/' number aggregate := '(' (type),* ')' 'f'? @@ -387,7 +411,11 @@ def parse_args(): ## Scalars Similar to vectors, but these describe a single concrete type, - not a range. The number is the bitwidth. + not a range. The number is the bitwidth. The optional + `llvm_width` is the bitwidth of the integer that should be + passed to LLVM (by truncating the Rust argument): this only + works with scalar integers and the LLVM width must be smaller + than the Rust width. ### Types @@ -474,7 +502,7 @@ class CompilerDefs(object): #![allow(unused_imports)] -use {{Intrinsic, i, u, f, v, agg}}; +use {{Intrinsic, i, i_, u, u_, f, v, agg}}; use IntrinsicDef::Named; use rustc::middle::ty; diff --git a/src/etc/platform-intrinsics/x86/avx.json b/src/etc/platform-intrinsics/x86/avx.json index 7d6a07f7550..4ac82fb90e9 100644 --- a/src/etc/platform-intrinsics/x86/avx.json +++ b/src/etc/platform-intrinsics/x86/avx.json @@ -13,7 +13,7 @@ "width": [256], "llvm": "dp.ps.256", "ret": "f32", - "args": ["0", "0", "S32"] + "args": ["0", "0", "S32/8"] }, { "intrinsic": "256_hadd_{0.data_type}", diff --git a/src/etc/platform-intrinsics/x86/avx2.json b/src/etc/platform-intrinsics/x86/avx2.json index 8b0e53e48cf..bd260ec02e9 100644 --- a/src/etc/platform-intrinsics/x86/avx2.json +++ b/src/etc/platform-intrinsics/x86/avx2.json @@ -79,6 +79,20 @@ "args": ["0", "0"] }, { + "intrinsic": "256_movemask_epi8", + "width": [256], + "llvm": "pmovmskb", + "ret": "S32", + "args": ["s8"] + }, + { + "intrinsic": "256_mpsadbw_epu8", + "width": [256], + "llvm": "mpsadbw", + "ret": "u16", + "args": ["u8", "u8", "S32/8"] + }, + { "intrinsic": "256_mul_{0.data_type}", "width": [256], "llvm": "pmul{0.data_type_short}.dq", diff --git a/src/etc/platform-intrinsics/x86/sse41.json b/src/etc/platform-intrinsics/x86/sse41.json index 8610dc83bd6..e835320e5cd 100644 --- a/src/etc/platform-intrinsics/x86/sse41.json +++ b/src/etc/platform-intrinsics/x86/sse41.json @@ -6,7 +6,7 @@ "width": [128], "llvm": "dp{0.data_type}", "ret": "f(32-64)", - "args": ["0", "0", "S32"] + "args": ["0", "0", "S32/8"] }, { "intrinsic": "_max_{0.data_type}", @@ -34,7 +34,7 @@ "width": [128], "llvm": "mpsadbw", "ret": "u16", - "args": ["u8", "u8", "S32"] + "args": ["u8", "u8", "S32/8"] }, { "intrinsic": "_mul_epi32", diff --git a/src/etc/platform-intrinsics/x86/sse42.json b/src/etc/platform-intrinsics/x86/sse42.json index e63182d4857..c43ffef0dc5 100644 --- a/src/etc/platform-intrinsics/x86/sse42.json +++ b/src/etc/platform-intrinsics/x86/sse42.json @@ -6,98 +6,98 @@ "width": [128], "llvm": "pcmpestria128", "ret": "S32", - "args": ["s8", "S32", "s8", "S32", "S32"] + "args": ["s8", "S32", "s8", "S32", "S32/8"] }, { "intrinsic": "_cmpestrc", "width": [128], "llvm": "pcmpestric128", "ret": "S32", - "args": ["s8", "S32", "s8", "S32", "S32"] + "args": ["s8", "S32", "s8", "S32", "S32/8"] }, { "intrinsic": "_cmpestri", "width": [128], "llvm": "pcmpestri128", "ret": "S32", - "args": ["s8", "S32", "s8", "S32", "S32"] + "args": ["s8", "S32", "s8", "S32", "S32/8"] }, { "intrinsic": "_cmpestrm", "width": [128], "llvm": "pcmpestrm128", "ret": "s8", - "args": ["s8", "S32", "s8", "S32", "S32"] + "args": ["s8", "S32", "s8", "S32", "S32/8"] }, { "intrinsic": "_cmpestro", "width": [128], "llvm": "pcmpestrio128", "ret": "S32", - "args": ["s8", "S32", "s8", "S32", "S32"] + "args": ["s8", "S32", "s8", "S32", "S32/8"] }, { "intrinsic": "_cmpestrs", "width": [128], "llvm": "pcmpestris128", "ret": "S32", - "args": ["s8", "S32", "s8", "S32", "S32"] + "args": ["s8", "S32", "s8", "S32", "S32/8"] }, { "intrinsic": "_cmpestrz", "width": [128], "llvm": "pcmpestriz128", "ret": "S32", - "args": ["s8", "S32", "s8", "S32", "S32"] + "args": ["s8", "S32", "s8", "S32", "S32/8"] }, { "intrinsic": "_cmpistra", "width": [128], "llvm": "pcmpistria128", "ret": "S32", - "args": ["s8", "s8", "S32"] + "args": ["s8", "s8", "S32/8"] }, { "intrinsic": "_cmpistrc", "width": [128], "llvm": "pcmpistric128", "ret": "S32", - "args": ["s8", "s8", "S32"] + "args": ["s8", "s8", "S32/8"] }, { "intrinsic": "_cmpistri", "width": [128], "llvm": "pcmpistri128", "ret": "S32", - "args": ["s8", "s8", "S32"] + "args": ["s8", "s8", "S32/8"] }, { "intrinsic": "_cmpistrm", "width": [128], "llvm": "pcmpistrm128", "ret": "s8", - "args": ["s8", "s8", "S32"] + "args": ["s8", "s8", "S32/8"] }, { "intrinsic": "_cmpistro", "width": [128], "llvm": "pcmpistrio128", "ret": "S32", - "args": ["s8", "s8", "S32"] + "args": ["s8", "s8", "S32/8"] }, { "intrinsic": "_cmpistrs", "width": [128], "llvm": "pcmpistris128", "ret": "S32", - "args": ["s8", "s8", "S32"] + "args": ["s8", "s8", "S32/8"] }, { "intrinsic": "_cmpistrz", "width": [128], "llvm": "pcmpistriz128", "ret": "S32", - "args": ["s8", "s8", "S32"] + "args": ["s8", "s8", "S32/8"] } ] } |
