1 # Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 # file at the top-level directory of this distribution and at
3 # http://rust-lang.org/COPYRIGHT.
5 # Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 # http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 # <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 # option. This file may not be copied, modified, or distributed
9 # except according to those terms.
11 from __future__
import division
, print_function
20 r
'^(?:(?P<void>V)|(?P<id>[iusfIUSF])(?:\((?P<start>\d+)-(?P<end>\d+)\)|'
21 r
'(?P<width>\d+)(:?/(?P<llvm_width>\d+))?)'
22 r
'|(?P<reference>\d+))(?P<index>\.\d+)?(?P<modifiers>[vShdnwusfDMCNW]*)(?P<force_width>x\d+)?'
23 r
'(?:(?P<pointer>Pm|Pc)(?P<llvm_pointer>/.*)?|(?P<bitcast>->.*))?$'
26 class PlatformInfo(object):
27 def __init__(self
, json
):
28 self
._platform
= json
['platform']
30 def platform_prefix(self
):
33 class IntrinsicSet(object):
34 def __init__(self
, platform
, json
):
35 self
._llvm
_prefix
= json
['llvm_prefix']
36 self
._type
_info
= json
['number_info']
37 self
._intrinsics
= json
['intrinsics']
38 self
._widths
= json
['width_info']
39 self
._platform
= platform
40 self
._intrinsic
_prefix
= json
['intrinsic_prefix']
43 for raw
in self
._intrinsics
:
44 yield GenericIntrinsic(self
,
45 raw
['intrinsic'], raw
['width'], raw
['llvm'],
46 raw
['ret'], raw
['args'])
51 def intrinsic_prefix(self
):
52 return self
._intrinsic
_prefix
54 def llvm_prefix(self
):
55 return self
._llvm
_prefix
57 def width_info(self
, bitwidth
):
58 return self
._widths
[str(bitwidth
)]
60 def number_type_info(self
, value
):
61 data
= self
._type
_info
[value
.__class
__.__name
__.lower()]
62 bitwidth
= value
.bitwidth()
64 if not isinstance(raw
, dict):
68 return raw
[str(bitwidth
)]
70 return raw
['pattern'].format(bitwidth
= bitwidth
)
72 return PlatformTypeInfo(value
.llvm_name(),
73 {k
: lookup(v
) for k
, v
in data
.items()})
75 class PlatformTypeInfo(object):
76 def __init__(self
, llvm_name
, properties
, elems
= None):
78 self
.properties
= properties
79 self
.llvm_name
= llvm_name
81 assert properties
is None and llvm_name
is None
86 return '<PlatformTypeInfo {}, {}>'.format(self
.llvm_name
, self
.properties
)
88 def __getattr__(self
, name
):
89 return self
.properties
[name
]
91 def __getitem__(self
, idx
):
92 return self
.elems
[idx
]
94 def vectorize(self
, length
, width_info
):
95 props
= self
.properties
.copy()
96 props
.update(width_info
)
97 return PlatformTypeInfo('v{}{}'.format(length
, self
.llvm_name
), props
)
99 def pointer(self
, llvm_elem
):
100 name
= self
.llvm_name
if llvm_elem
is None else llvm_elem
.llvm_name
101 return PlatformTypeInfo('p0{}'.format(name
), self
.properties
)
103 BITWIDTH_POINTER
= '<pointer>'
106 def __init__(self
, bitwidth
):
107 self
._bitwidth
= bitwidth
110 return self
._bitwidth
112 def modify(self
, spec
, width
, previous
):
113 raise NotImplementedError()
115 def __ne__(self
, other
):
116 return not (self
== other
)
120 Type
.__init
__(self
, 0)
126 def compiler_ctor_ref(self
):
127 return '&' + self
.compiler_ctor()
134 def type_info(platform_info
):
137 def __eq__(self
, other
):
138 return isinstance(other
, Void
)
141 def __init__(self
, bitwidth
):
142 Type
.__init
__(self
, bitwidth
)
144 def modify(self
, spec
, width
, previous
):
146 return Unsigned(self
.bitwidth())
148 return Signed(self
.bitwidth())
150 return Float(self
.bitwidth())
152 return self
.__class
__(self
.bitwidth() * 2)
154 return self
.__class
__(self
.bitwidth() // 2)
156 return Vector(self
, width
// self
.bitwidth())
158 raise ValueError('unknown modification spec {}', spec
)
160 def type_info(self
, platform_info
):
161 return platform_info
.number_type_info(self
)
163 def __eq__(self
, other
):
165 return self
.__class
__ == other
.__class
__ and self
.bitwidth() == other
.bitwidth()
167 class Signed(Number
):
168 def __init__(self
, bitwidth
, llvm_bitwidth
= None):
169 Number
.__init
__(self
, bitwidth
)
170 self
._llvm
_bitwidth
= llvm_bitwidth
173 def compiler_ctor(self
):
174 if self
._llvm
_bitwidth
is None:
175 return '::I{}'.format(self
.bitwidth())
177 return '::I{}_{}'.format(self
.bitwidth(), self
._llvm
_bitwidth
)
179 def compiler_ctor_ref(self
):
180 return '&' + self
.compiler_ctor()
183 bw
= self
._llvm
_bitwidth
or self
.bitwidth()
184 return 'i{}'.format(bw
)
187 return 'i{}'.format(self
.bitwidth())
189 class Unsigned(Number
):
190 def __init__(self
, bitwidth
, llvm_bitwidth
= None):
191 Number
.__init
__(self
, bitwidth
)
192 self
._llvm
_bitwidth
= llvm_bitwidth
194 def compiler_ctor(self
):
195 if self
._llvm
_bitwidth
is None:
196 return '::U{}'.format(self
.bitwidth())
198 return '::U{}_{}'.format(self
.bitwidth(), self
._llvm
_bitwidth
)
200 def compiler_ctor_ref(self
):
201 return '&' + self
.compiler_ctor()
204 bw
= self
._llvm
_bitwidth
or self
.bitwidth()
205 return 'i{}'.format(bw
)
208 return 'u{}'.format(self
.bitwidth())
211 def __init__(self
, bitwidth
):
212 assert bitwidth
in (32, 64)
213 Number
.__init
__(self
, bitwidth
)
215 def compiler_ctor(self
):
216 return '::F{}'.format(self
.bitwidth())
218 def compiler_ctor_ref(self
):
219 return '&' + self
.compiler_ctor()
222 return 'f{}'.format(self
.bitwidth())
225 return 'f{}'.format(self
.bitwidth())
228 def __init__(self
, elem
, length
, bitcast
= None):
229 assert isinstance(elem
, Type
) and not isinstance(elem
, Vector
)
231 elem
.bitwidth() * length
)
232 self
._length
= length
234 assert bitcast
is None or (isinstance(bitcast
, Vector
) and
235 bitcast
._bitcast
is None and
236 bitcast
._elem
.bitwidth() == elem
.bitwidth())
237 if bitcast
is not None and bitcast
._elem
!= elem
:
238 self
._bitcast
= bitcast
._elem
242 def modify(self
, spec
, width
, previous
):
246 return Vector(self
._elem
, self
._length
// 2)
248 return Vector(self
._elem
, self
._length
* 2)
250 elem
= self
._elem
.__class
__(self
._elem
.bitwidth() // 2)
251 return Vector(elem
, self
._length
* 2)
253 elem
= self
._elem
.__class
__(self
._elem
.bitwidth() * 2)
254 return Vector(elem
, self
._length
// 2)
255 elif spec
.startswith('x'):
256 new_bitwidth
= int(spec
[1:])
257 return Vector(self
._elem
, new_bitwidth
// self
._elem
.bitwidth())
258 elif spec
.startswith('->'):
259 bitcast_to
= TypeSpec(spec
[2:])
260 choices
= list(bitcast_to
.enumerate(width
, previous
))
261 assert len(choices
) == 1
262 bitcast_to
= choices
[0]
263 return Vector(self
._elem
, self
._length
, bitcast_to
)
265 return Vector(self
._elem
.modify(spec
, width
, previous
), self
._length
)
267 def compiler_ctor(self
):
268 if self
._bitcast
is None:
269 return '{}x{}'.format(self
._elem
.compiler_ctor(),
272 return '{}x{}_{}'.format(self
._elem
.compiler_ctor(),
274 self
._bitcast
.compiler_ctor()
277 def compiler_ctor_ref(self
):
278 return '&' + self
.compiler_ctor()
281 return '{}x{}'.format(self
._elem
.rust_name(), self
._length
)
283 def type_info(self
, platform_info
):
284 elem_info
= self
._elem
.type_info(platform_info
)
285 return elem_info
.vectorize(self
._length
,
286 platform_info
.width_info(self
.bitwidth()))
288 def __eq__(self
, other
):
289 return isinstance(other
, Vector
) and self
._length
== other
._length
and \
290 self
._elem
== other
._elem
and self
._bitcast
== other
._bitcast
293 def __init__(self
, elem
, llvm_elem
, const
):
295 self
._llvm
_elem
= llvm_elem
297 Type
.__init
__(self
, BITWIDTH_POINTER
)
299 def modify(self
, spec
, width
, previous
):
303 return Pointer(self
._elem
, self
._llvm
_elem
, False)
305 return Pointer(self
._elem
, self
._llvm
_elem
, True)
307 return Pointer(self
._elem
.modify(spec
, width
, previous
), self
._llvm
_elem
, self
._const
)
309 def compiler_ctor(self
):
310 if self
._llvm
_elem
is None:
313 llvm_elem
= 'Some({})'.format(self
._llvm
_elem
.compiler_ctor_ref())
314 return 'Type::Pointer({}, {}, {})'.format(self
._elem
.compiler_ctor_ref(),
316 'true' if self
._const
else 'false')
318 def compiler_ctor_ref(self
):
319 return "{{ static PTR: Type = {}; &PTR }}".format(self
.compiler_ctor())
323 return '*{} {}'.format('const' if self
._const
else 'mut',
324 self
._elem
.rust_name())
326 def type_info(self
, platform_info
):
327 if self
._llvm
_elem
is None:
330 llvm_elem
= self
._llvm
_elem
.type_info(platform_info
)
331 return self
._elem
.type_info(platform_info
).pointer(llvm_elem
)
333 def __eq__(self
, other
):
334 return isinstance(other
, Pointer
) and self
._const
== other
._const \
335 and self
._elem
== other
._elem
and self
._llvm
_elem
== other
._llvm
_elem
337 class Aggregate(Type
):
338 def __init__(self
, flatten
, elems
):
339 self
._flatten
= flatten
341 Type
.__init
__(self
, sum(elem
.bitwidth() for elem
in elems
))
344 return '<Aggregate {}>'.format(self
._elems
)
346 def modify(self
, spec
, width
, previous
):
347 if spec
.startswith('.'):
349 return self
._elems
[num
]
352 raise NotImplementedError()
354 def compiler_ctor(self
):
355 parts
= "{{ static PARTS: [&'static Type; {}] = [{}]; &PARTS }}"
356 elems
= ', '.join(elem
.compiler_ctor_ref() for elem
in self
._elems
)
357 parts
= parts
.format(len(self
._elems
), elems
)
358 return 'Type::Aggregate({}, {})'.format('true' if self
._flatten
else 'false',
361 def compiler_ctor_ref(self
):
362 return "{{ static AGG: Type = {}; &AGG }}".format(self
.compiler_ctor())
365 return '({})'.format(', '.join(elem
.rust_name() for elem
in self
._elems
))
367 def type_info(self
, platform_info
):
368 return PlatformTypeInfo(None, None, [elem
.type_info(platform_info
) for elem
in self
._elems
])
370 def __eq__(self
, other
):
371 return isinstance(other
, Aggregate
) and self
._flatten
== other
._flatten
and \
372 self
._elems
== other
._elems
375 TYPE_ID_LOOKUP
= {'i': [Signed
, Unsigned
],
380 def ptrify(match
, elem
, width
, previous
):
381 ptr
= match
.group('pointer')
385 llvm_ptr
= match
.group('llvm_pointer')
389 assert llvm_ptr
.startswith('/')
390 options
= list(TypeSpec(llvm_ptr
[1:]).enumerate(width
, previous
))
391 assert len(options
) == 1
392 llvm_elem
= options
[0]
393 assert ptr
in ('Pc', 'Pm')
394 return Pointer(elem
, llvm_elem
, ptr
== 'Pc')
396 class TypeSpec(object):
397 def __init__(self
, spec
):
398 if not isinstance(spec
, list):
403 def enumerate(self
, width
, previous
):
404 for spec
in self
.spec
:
405 match
= SPEC
.match(spec
)
406 if match
is not None:
407 id = match
.group('id')
408 reference
= match
.group('reference')
411 index
= match
.group('index')
412 if index
is not None:
413 modifiers
.append(index
)
414 modifiers
+= list(match
.group('modifiers') or '')
415 force
= match
.group('force_width')
416 if force
is not None:
417 modifiers
.append(force
)
418 bitcast
= match
.group('bitcast')
419 if bitcast
is not None:
420 modifiers
.append(bitcast
)
422 if match
.group('void') is not None:
426 is_vector
= id.islower()
427 type_ctors
= TYPE_ID_LOOKUP
[id.lower()]
429 start
= match
.group('start')
430 if start
is not None:
431 end
= match
.group('end')
434 start
= end
= match
.group('width')
435 llvm_width
= match
.group('llvm_width')
440 while bitwidth
<= end
:
441 for ctor
in type_ctors
:
442 if llvm_width
is not None:
444 llvm_width
= int(llvm_width
)
445 assert llvm_width
< bitwidth
446 scalar
= ctor(bitwidth
, llvm_width
)
448 scalar
= ctor(bitwidth
)
451 elem
= Vector(scalar
, width
// bitwidth
)
453 assert bitcast
is None
457 elem
= elem
.modify(x
, width
, previous
)
458 yield ptrify(match
, elem
, width
, previous
)
460 elif reference
is not None:
461 reference
= int(reference
)
462 assert reference
< len(previous
), \
463 'referring to argument {}, but only {} are known'.format(reference
,
465 ret
= previous
[reference
]
467 ret
= ret
.modify(x
, width
, previous
)
468 yield ptrify(match
, ret
, width
, previous
)
470 assert False, 'matched `{}`, but didn\'t understand it?'.format(spec
)
471 elif spec
.startswith('('):
472 if spec
.endswith(')'):
473 true_spec
= spec
[1:-1]
475 elif spec
.endswith(')f'):
476 true_spec
= spec
[1:-2]
479 assert False, 'found unclosed aggregate `{}`'.format(spec
)
481 for elems
in itertools
.product(*(TypeSpec(subspec
).enumerate(width
, previous
)
482 for subspec
in true_spec
.split(','))):
483 yield Aggregate(flatten
, elems
)
484 elif spec
.startswith('['):
485 if spec
.endswith(']'):
486 true_spec
= spec
[1:-1]
488 elif spec
.endswith(']f'):
489 true_spec
= spec
[1:-2]
492 assert False, 'found unclosed aggregate `{}`'.format(spec
)
493 elem_spec
, count
= true_spec
.split(';')
496 for elem
in TypeSpec(elem_spec
).enumerate(width
, previous
):
497 yield Aggregate(flatten
, [elem
] * count
)
499 assert False, 'Failed to parse `{}`'.format(spec
)
501 class GenericIntrinsic(object):
502 def __init__(self
, platform
, intrinsic
, widths
, llvm_name
, ret
, args
):
503 self
._platform
= platform
504 self
.intrinsic
= intrinsic
505 self
.widths
= map(int, widths
)
506 self
.llvm_name
= llvm_name
507 self
.ret
= TypeSpec(ret
)
508 self
.args
= list(map(TypeSpec
, args
))
510 def monomorphise(self
):
511 for width
in self
.widths
:
512 # must be a power of two
513 assert width
& (width
- 1) == 0
514 def recur(processed
, untouched
):
518 yield MonomorphicIntrinsic(self
._platform
, self
.intrinsic
, width
,
522 raw_arg
= untouched
[0]
524 for arg
in raw_arg
.enumerate(width
, processed
):
525 for intr
in recur(processed
+ [arg
], rest
):
528 for x
in recur([], [self
.ret
] + self
.args
):
531 class MonomorphicIntrinsic(object):
532 def __init__(self
, platform
, intrinsic
, width
, llvm_name
, ret
, args
):
533 self
._platform
= platform
534 self
._intrinsic
= intrinsic
535 self
._width
= '' if width
== 64 else 'q'
536 self
._llvm
_name
= llvm_name
538 self
._ret
= ret
.type_info(platform
)
539 self
._args
_raw
= args
540 self
._args
= [arg
.type_info(platform
) for arg
in args
]
543 if self
._llvm
_name
.startswith('!'):
544 return self
._llvm
_name
[1:].format(self
._ret
, *self
._args
)
546 return self
._platform
.llvm_prefix() + self
._llvm
_name
.format(self
._ret
, *self
._args
)
548 def intrinsic_suffix(self
):
549 return self
._intrinsic
.format(self
._ret
,
553 def platform_prefix(self
):
554 return self
._platform
.platform().platform_prefix()
556 def intrinsic_set_name(self
):
557 return self
._platform
.intrinsic_prefix()
559 def intrinsic_name(self
):
560 return self
._platform
.intrinsic_prefix() + self
.intrinsic_suffix()
562 def compiler_args(self
):
563 return ', '.join(arg
.compiler_ctor_ref() for arg
in self
._args
_raw
)
565 def compiler_ret(self
):
566 return self
._ret
_raw
.compiler_ctor_ref()
568 def compiler_signature(self
):
569 return '({}) -> {}'.format(self
.compiler_args(), self
.compiler_ret())
571 def intrinsic_signature(self
):
573 return '({}) -> {}'.format(', '.join('{}: {}'.format(name
, arg
.rust_name())
574 for name
, arg
in zip(names
, self
._args
_raw
)),
575 self
._ret
_raw
.rust_name())
578 parser
= argparse
.ArgumentParser(
579 formatter_class
= argparse
.RawDescriptionHelpFormatter
,
580 description
= 'Render an intrinsic definition JSON to various formats.',
581 epilog
= textwrap
.dedent('''\
584 There are two operating modes: single file and multiple files.
586 For example, ARM is specified as a single file. To generate the
587 compiler-definitions for ARM just pass the script the "arm.json" file:
589 python generator.py --format compiler-defs arm.json
591 The X86 architecture is specified as multiple files (for the different
592 instruction sets that x86 supports). To generate the compiler
593 definitions one needs to pass the script a "platform information file"
594 (with the -i flag) next to the files of the different instruction sets.
595 For example, to generate the X86 compiler-definitions for SSE4.2, just:
597 python generator.py --format compiler-defs -i x86/info.json sse42.json
599 And to generate the compiler-definitions for SSE4.1 and SSE4.2, just:
601 python generator.py --format compiler-defs -i x86/info.json sse41.json sse42.json
603 An intrinsic definition consists of a map with fields:
604 - intrinsic: pattern for the name(s) of the vendor's C intrinsic(s)
605 - llvm: pattern for the name(s) of the internal llvm intrinsic(s)
606 - width: a vector of vector bit-widths the pattern works with
607 - ret: type specifier for the return value
608 - arguments: vector of type specifiers for arguments
610 The width and types describe a range of possible intrinsics,
611 and these are fed back into the intrinsic and llvm patterns to
612 create the appropriate definitions.
614 ## Type specifier grammar
617 type := core_type modifier* suffix?
619 core_type := void | vector | scalar | aggregate | reference
621 modifier := 'v' | 'h' | 'd' | 'n' | 'w' | 'u' | 's' |
622 'x' number | '.' number
623 suffix := pointer | bitcast
624 pointer := 'Pm' llvm_pointer? | 'Pc' llvm_pointer?
625 llvm_pointer := '/' type
630 vector := vector_elem width |
631 vector_elem := 'i' | 'u' | 's' | 'f'
633 scalar := scalar_type number llvm_width?
634 scalar_type := 'U' | 'S' | 'F'
635 llvm_width := '/' number
637 aggregate := '(' (type),* ')' 'f'? | '[' type ';' number ']' 'f'?
641 width = number | '(' number '-' number ')'
648 The `V` type corresponds to `void` in LLVM (`()` in
649 Rust). It's likely to only work in return position.
653 The vector grammar is a pattern describing many possibilities
654 for arguments/return value. The `vector_elem` describes the
655 types of elements to use, and the `width` describes the (range
656 of) widths for those elements, which are then placed into a
657 vector with the `width` bitwidth. E.g. if an intrinsic has a
658 `width` that includes 128, and the return value is `i(8-32)`,
659 then some instantiation of that intrinsic will be `u8x16`,
660 `u32x4`, `i32x4`, etc.
664 - i: integer, both signed and unsigned
665 - u: unsigned integer
671 Similar to vectors, but these describe a single concrete type,
672 not a range. The number is the bitwidth. The optional
673 `llvm_width` is the bitwidth of the integer that should be
674 passed to LLVM (by truncating the Rust argument): this only
675 works with scalar integers and the LLVM width must be smaller
680 - U: unsigned integer
686 An aggregate is a collection of multiple types; a tuple in
687 Rust terms, or an unnamed struct in LLVM. The `f` modifiers
688 forces the tuple to be flattened in the LLVM
689 intrinsic. E.g. if `llvm.foo` takes `(F32,S32)`:
691 - no `f` corresponds to `declare ... @llvm.foo({float, i32})`.
692 - having an `f` corresponds to `declare ... @llvm.foo(float, i32)`.
694 The `[type;number]` form is a just shorter way to write
695 `(...)`, except avoids doing a cartesian product of generic
696 types, e.g. `[S32;2]` is the same as `(S32, S32)`, while
697 `[I32;2]` is describing just the two types `(S32,S32)` and
698 `(U32,U32)` (i.e. doesn't include `(S32,U32)`, `(U32,S32)` as
701 (Currently aggregates can not contain other aggregates.)
705 A reference uses the type of another argument, with possible
706 modifications. The number refers to the type to use, starting
707 with 0 == return value, 1 == first argument, 2 == second
712 The `modifier` and `suffix` adaptors change the precise
717 - 'v': put a scalar into a vector of the current width (u32 -> u32x4, when width == 128)
718 - 'S': get the scalar element of a vector (u32x4 -> u32)
719 - 'h': half the length of the vector (u32x4 -> u32x2)
720 - 'd': double the length of the vector (u32x2 -> u32x4)
721 - 'n': narrow the element of the vector (u32x4 -> u16x4)
722 - 'w': widen the element of the vector (u16x4 -> u32x4)
723 - 'N': half the length of the vector element (u32x4 -> u16x8)
724 - 'W': double the length of the vector element (u16x8 -> u32x4)
725 - 'u': force a number (vector or scalar) to be unsigned int (f32x4 -> u32x4)
726 - 's': force a number (vector or scalar) to be signed int (u32x4 -> i32x4)
727 - 'f': force a number (vector or scalar) to be float (u32x4 -> f32x4)
728 - 'x' number: force the type to be a vector of bitwidth `number`.
729 - '.' number: get the `number`th element of an aggregate
730 - 'D': dereference a pointer (*mut u32 -> u32)
731 - 'C': make a pointer const (*mut u32 -> *const u32)
732 - 'M': make a pointer mut (*const u32 -> *mut u32)
736 Pointers can be created of any type by appending a `P*`
737 suffix. The `m` vs. `c` chooses mut vs. const. e.g. `S32Pm`
738 corresponds to `*mut i32`, and `i32Pc` corresponds (with width
739 128) to `*const i8x16`, `*const u32x4`, etc.
741 The type after the `/` (optional) represents the type used
742 internally to LLVM, e.g. `S32pm/S8` is exposed as `*mut i32`
743 in Rust, but is `i8*` in LLVM. (This defaults to the main
748 The `'->' type` bitcast suffix will cause the value to be
749 bitcast to the right-hand type when calling the intrinsic,
750 e.g. `s32->f32` will expose the intrinsic as `i32x4` at the
751 Rust level, but will cast that vector to `f32x4` when calling
754 parser
.add_argument('--format', choices
=FORMATS
, required
=True,
755 help = 'Output format.')
756 parser
.add_argument('-o', '--out', type=argparse
.FileType('w'), default
=sys
.stdout
,
757 help = 'File to output to (default stdout).')
758 parser
.add_argument('-i', '--info', type=argparse
.FileType('r'),
759 help = 'File containing platform specific information to merge into '
760 'the input files\' header.')
761 parser
.add_argument('in_', metavar
="FILE", type=argparse
.FileType('r'), nargs
='+',
762 help = 'JSON files to load')
763 return parser
.parse_args()
766 class ExternBlock(object):
772 return 'extern "platform-intrinsic" {'
776 return ' fn {}{}{};'.format(mono
.platform_prefix(),
777 mono
.intrinsic_name(),
778 mono
.intrinsic_signature())
784 class CompilerDefs(object):
791 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
792 // file at the top-level directory of this distribution and at
793 // http://rust-lang.org/COPYRIGHT.
795 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
796 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
797 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
798 // option. This file may not be copied, modified, or distributed
799 // except according to those terms.
801 // DO NOT EDIT: autogenerated by etc/platform-intrinsics/generator.py
802 // ignore-tidy-linelength
804 #![allow(unused_imports)]
806 use {{Intrinsic, Type}};
807 use IntrinsicDef::Named;
809 pub fn find(name: &str) -> Option<Intrinsic> {{
810 if !name.starts_with("{0}") {{ return None }}
811 Some(match &name["{0}".len()..] {{'''.format(platform
.platform_prefix())
817 inputs: {{ static INPUTS: [&'static Type; {}] = [{}]; &INPUTS }},
819 definition: Named("{}")
820 }},'''.format(mono
.intrinsic_set_name() + mono
.intrinsic_suffix(),
822 mono
.compiler_args(),
834 'extern-block': ExternBlock(),
835 'compiler-defs': CompilerDefs(),
843 out_format
= FORMATS
[args
.format
]
845 one_file_no_info
= False
846 if len(ins
) > 1 and info
is None:
847 print('error: cannot have multiple inputs without an info header.', file=sys
.stderr
)
852 one_file_no_info
= True
853 info_json
= json
.load(info
)
854 platform
= PlatformInfo(info_json
)
856 print(out_format
.open(platform
), file=out
)
863 data
= json
.load(in_
)
864 data
.update(info_json
)
866 intrinsics
= IntrinsicSet(platform
, data
)
867 for intr
in intrinsics
.intrinsics():
868 for mono
in intr
.monomorphise():
869 print(out_format
.render(mono
), file=out
)
871 print(out_format
.close(), file=out
)
873 if __name__
== '__main__':