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>[vShdnwusfDMC]*)(?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']
29 self
._intrinsic
_prefix
= json
['intrinsic_prefix']
31 def intrinsic_prefix(self
):
32 return self
._intrinsic
_prefix
34 class IntrinsicSet(object):
35 def __init__(self
, platform
, json
):
36 self
._llvm
_prefix
= json
['llvm_prefix']
37 self
._type
_info
= json
['number_info']
38 self
._intrinsics
= json
['intrinsics']
39 self
._widths
= json
['width_info']
40 self
._platform
= platform
43 for raw
in self
._intrinsics
:
44 yield GenericIntrinsic(self
,
45 raw
['intrinsic'], raw
['width'], raw
['llvm'],
46 raw
['ret'], raw
['args'])
51 def llvm_prefix(self
):
52 return self
._llvm
_prefix
54 def width_info(self
, bitwidth
):
55 return self
._widths
[str(bitwidth
)]
57 def number_type_info(self
, value
):
58 data
= self
._type
_info
[value
.__class
__.__name
__.lower()]
59 bitwidth
= value
.bitwidth()
61 if not isinstance(raw
, dict):
65 return raw
[str(bitwidth
)]
67 return raw
['pattern'].format(bitwidth
= bitwidth
)
69 return PlatformTypeInfo(value
.llvm_name(),
70 {k
: lookup(v
) for k
, v
in data
.items()})
72 class PlatformTypeInfo(object):
73 def __init__(self
, llvm_name
, properties
, elems
= None):
75 self
.properties
= properties
76 self
.llvm_name
= llvm_name
78 assert properties
is None and llvm_name
is None
83 return '<PlatformTypeInfo {}, {}>'.format(self
.llvm_name
, self
.properties
)
85 def __getattr__(self
, name
):
86 return self
.properties
[name
]
88 def __getitem__(self
, idx
):
89 return self
.elems
[idx
]
91 def vectorize(self
, length
, width_info
):
92 props
= self
.properties
.copy()
93 props
.update(width_info
)
94 return PlatformTypeInfo('v{}{}'.format(length
, self
.llvm_name
), props
)
96 def pointer(self
, llvm_elem
):
97 name
= self
.llvm_name
if llvm_elem
is None else llvm_elem
.llvm_name
98 return PlatformTypeInfo('p0{}'.format(name
), self
.properties
)
100 BITWIDTH_POINTER
= '<pointer>'
103 def __init__(self
, bitwidth
):
104 self
._bitwidth
= bitwidth
107 return self
._bitwidth
109 def modify(self
, spec
, width
, previous
):
110 raise NotImplementedError()
112 def __ne__(self
, other
):
113 return not (self
== other
)
117 Type
.__init
__(self
, 0)
119 def compiler_ctor(self
):
122 def compiler_ctor_ref(self
):
123 return '&' + self
.compiler_ctor()
128 def type_info(self
, platform_info
):
131 def __eq__(self
, other
):
132 return isinstance(other
, Void
)
135 def __init__(self
, bitwidth
):
136 Type
.__init
__(self
, bitwidth
)
138 def modify(self
, spec
, width
, previous
):
140 return Unsigned(self
.bitwidth())
142 return Signed(self
.bitwidth())
144 return Float(self
.bitwidth())
146 return self
.__class
__(self
.bitwidth() * 2)
148 return self
.__class
__(self
.bitwidth() // 2)
150 return Vector(self
, width
// self
.bitwidth())
152 raise ValueError('unknown modification spec {}', spec
)
154 def type_info(self
, platform_info
):
155 return platform_info
.number_type_info(self
)
157 def __eq__(self
, other
):
159 return self
.__class
__ == other
.__class
__ and self
.bitwidth() == other
.bitwidth()
161 class Signed(Number
):
162 def __init__(self
, bitwidth
, llvm_bitwidth
= None):
163 Number
.__init
__(self
, bitwidth
)
164 self
._llvm
_bitwidth
= llvm_bitwidth
167 def compiler_ctor(self
):
168 if self
._llvm
_bitwidth
is None:
169 return '::I{}'.format(self
.bitwidth())
171 return '::I{}_{}'.format(self
.bitwidth(), self
._llvm
_bitwidth
)
173 def compiler_ctor_ref(self
):
174 return '&' + self
.compiler_ctor()
177 bw
= self
._llvm
_bitwidth
or self
.bitwidth()
178 return 'i{}'.format(bw
)
181 return 'i{}'.format(self
.bitwidth())
183 class Unsigned(Number
):
184 def __init__(self
, bitwidth
, llvm_bitwidth
= None):
185 Number
.__init
__(self
, bitwidth
)
186 self
._llvm
_bitwidth
= llvm_bitwidth
188 def compiler_ctor(self
):
189 if self
._llvm
_bitwidth
is None:
190 return '::U{}'.format(self
.bitwidth())
192 return '::U{}_{}'.format(self
.bitwidth(), self
._llvm
_bitwidth
)
194 def compiler_ctor_ref(self
):
195 return '&' + self
.compiler_ctor()
198 bw
= self
._llvm
_bitwidth
or self
.bitwidth()
199 return 'i{}'.format(bw
)
202 return 'u{}'.format(self
.bitwidth())
205 def __init__(self
, bitwidth
):
206 assert bitwidth
in (32, 64)
207 Number
.__init
__(self
, bitwidth
)
209 def compiler_ctor(self
):
210 return '::F{}'.format(self
.bitwidth())
212 def compiler_ctor_ref(self
):
213 return '&' + self
.compiler_ctor()
216 return 'f{}'.format(self
.bitwidth())
219 return 'f{}'.format(self
.bitwidth())
222 def __init__(self
, elem
, length
, bitcast
= None):
223 assert isinstance(elem
, Type
) and not isinstance(elem
, Vector
)
225 elem
.bitwidth() * length
)
226 self
._length
= length
228 assert bitcast
is None or (isinstance(bitcast
, Vector
) and
229 bitcast
._bitcast
is None and
230 bitcast
._elem
.bitwidth() == elem
.bitwidth())
231 if bitcast
is not None and bitcast
._elem
!= elem
:
232 self
._bitcast
= bitcast
._elem
236 def modify(self
, spec
, width
, previous
):
240 return Vector(self
._elem
, self
._length
// 2)
242 return Vector(self
._elem
, self
._length
* 2)
243 elif spec
.startswith('x'):
244 new_bitwidth
= int(spec
[1:])
245 return Vector(self
._elem
, new_bitwidth
// self
._elem
.bitwidth())
246 elif spec
.startswith('->'):
247 bitcast_to
= TypeSpec(spec
[2:])
248 choices
= list(bitcast_to
.enumerate(width
, previous
))
249 assert len(choices
) == 1
250 bitcast_to
= choices
[0]
251 return Vector(self
._elem
, self
._length
, bitcast_to
)
253 return Vector(self
._elem
.modify(spec
, width
, previous
), self
._length
)
255 def compiler_ctor(self
):
256 if self
._bitcast
is None:
257 return '{}x{}'.format(self
._elem
.compiler_ctor(),
260 return '{}x{}_{}'.format(self
._elem
.compiler_ctor(),
262 self
._bitcast
.compiler_ctor()
265 def compiler_ctor_ref(self
):
266 return '&' + self
.compiler_ctor()
269 return '{}x{}'.format(self
._elem
.rust_name(), self
._length
)
271 def type_info(self
, platform_info
):
272 elem_info
= self
._elem
.type_info(platform_info
)
273 return elem_info
.vectorize(self
._length
,
274 platform_info
.width_info(self
.bitwidth()))
276 def __eq__(self
, other
):
277 return isinstance(other
, Vector
) and self
._length
== other
._length
and \
278 self
._elem
== other
._elem
and self
._bitcast
== other
._bitcast
281 def __init__(self
, elem
, llvm_elem
, const
):
283 self
._llvm
_elem
= llvm_elem
285 Type
.__init
__(self
, BITWIDTH_POINTER
)
287 def modify(self
, spec
, width
, previous
):
291 return Pointer(self
._elem
, self
._llvm
_elem
, False)
293 return Pointer(self
._elem
, self
._llvm
_elem
, True)
295 return Pointer(self
._elem
.modify(spec
, width
, previous
), self
._llvm
_elem
, self
._const
)
297 def compiler_ctor(self
):
298 if self
._llvm
_elem
is None:
301 llvm_elem
= 'Some({})'.format(self
._llvm
_elem
.compiler_ctor_ref())
302 return 'Type::Pointer({}, {}, {})'.format(self
._elem
.compiler_ctor_ref(),
304 'true' if self
._const
else 'false')
306 def compiler_ctor_ref(self
):
307 return "{{ static PTR: Type = {}; &PTR }}".format(self
.compiler_ctor())
311 return '*{} {}'.format('const' if self
._const
else 'mut',
312 self
._elem
.rust_name())
314 def type_info(self
, platform_info
):
315 if self
._llvm
_elem
is None:
318 llvm_elem
= self
._llvm
_elem
.type_info(platform_info
)
319 return self
._elem
.type_info(platform_info
).pointer(llvm_elem
)
321 def __eq__(self
, other
):
322 return isinstance(other
, Pointer
) and self
._const
== other
._const \
323 and self
._elem
== other
._elem
and self
._llvm
_elem
== other
._llvm
_elem
325 class Aggregate(Type
):
326 def __init__(self
, flatten
, elems
):
327 self
._flatten
= flatten
329 Type
.__init
__(self
, sum(elem
.bitwidth() for elem
in elems
))
332 return '<Aggregate {}>'.format(self
._elems
)
334 def modify(self
, spec
, width
, previous
):
335 if spec
.startswith('.'):
337 return self
._elems
[num
]
340 raise NotImplementedError()
342 def compiler_ctor(self
):
343 parts
= "{{ static PARTS: [&'static Type; {}] = [{}]; &PARTS }}"
344 elems
= ', '.join(elem
.compiler_ctor_ref() for elem
in self
._elems
)
345 parts
= parts
.format(len(self
._elems
), elems
)
346 return 'Type::Aggregate({}, {})'.format('true' if self
._flatten
else 'false',
349 def compiler_ctor_ref(self
):
350 return "{{ static AGG: Type = {}; &AGG }}".format(self
.compiler_ctor())
353 return '({})'.format(', '.join(elem
.rust_name() for elem
in self
._elems
))
355 def type_info(self
, platform_info
):
356 return PlatformTypeInfo(None, None, [elem
.type_info(platform_info
) for elem
in self
._elems
])
358 def __eq__(self
, other
):
359 return isinstance(other
, Aggregate
) and self
._flatten
== other
._flatten
and \
360 self
._elems
== other
._elems
363 TYPE_ID_LOOKUP
= {'i': [Signed
, Unsigned
],
368 def ptrify(match
, elem
, width
, previous
):
369 ptr
= match
.group('pointer')
373 llvm_ptr
= match
.group('llvm_pointer')
377 assert llvm_ptr
.startswith('/')
378 options
= list(TypeSpec(llvm_ptr
[1:]).enumerate(width
, previous
))
379 assert len(options
) == 1
380 llvm_elem
= options
[0]
381 assert ptr
in ('Pc', 'Pm')
382 return Pointer(elem
, llvm_elem
, ptr
== 'Pc')
384 class TypeSpec(object):
385 def __init__(self
, spec
):
386 if not isinstance(spec
, list):
391 def enumerate(self
, width
, previous
):
392 for spec
in self
.spec
:
393 match
= SPEC
.match(spec
)
394 if match
is not None:
395 id = match
.group('id')
396 reference
= match
.group('reference')
399 index
= match
.group('index')
400 if index
is not None:
401 modifiers
.append(index
)
402 modifiers
+= list(match
.group('modifiers') or '')
403 force
= match
.group('force_width')
404 if force
is not None:
405 modifiers
.append(force
)
406 bitcast
= match
.group('bitcast')
407 if bitcast
is not None:
408 modifiers
.append(bitcast
)
410 if match
.group('void') is not None:
414 is_vector
= id.islower()
415 type_ctors
= TYPE_ID_LOOKUP
[id.lower()]
417 start
= match
.group('start')
418 if start
is not None:
419 end
= match
.group('end')
422 start
= end
= match
.group('width')
423 llvm_width
= match
.group('llvm_width')
428 while bitwidth
<= end
:
429 for ctor
in type_ctors
:
430 if llvm_width
is not None:
432 llvm_width
= int(llvm_width
)
433 assert llvm_width
< bitwidth
434 scalar
= ctor(bitwidth
, llvm_width
)
436 scalar
= ctor(bitwidth
)
439 elem
= Vector(scalar
, width
// bitwidth
)
441 assert bitcast
is None
445 elem
= elem
.modify(x
, width
, previous
)
446 yield ptrify(match
, elem
, width
, previous
)
448 elif reference
is not None:
449 reference
= int(reference
)
450 assert reference
< len(previous
), \
451 'referring to argument {}, but only {} are known'.format(reference
,
453 ret
= previous
[reference
]
455 ret
= ret
.modify(x
, width
, previous
)
456 yield ptrify(match
, ret
, width
, previous
)
458 assert False, 'matched `{}`, but didn\'t understand it?'.format(spec
)
459 elif spec
.startswith('('):
460 if spec
.endswith(')'):
461 true_spec
= spec
[1:-1]
463 elif spec
.endswith(')f'):
464 true_spec
= spec
[1:-2]
467 assert False, 'found unclosed aggregate `{}`'.format(spec
)
469 for elems
in itertools
.product(*(TypeSpec(subspec
).enumerate(width
, previous
)
470 for subspec
in true_spec
.split(','))):
471 yield Aggregate(flatten
, elems
)
472 elif spec
.startswith('['):
473 if spec
.endswith(']'):
474 true_spec
= spec
[1:-1]
476 elif spec
.endswith(']f'):
477 true_spec
= spec
[1:-2]
480 assert False, 'found unclosed aggregate `{}`'.format(spec
)
481 elem_spec
, count
= true_spec
.split(';')
484 for elem
in TypeSpec(elem_spec
).enumerate(width
, previous
):
485 yield Aggregate(flatten
, [elem
] * count
)
487 assert False, 'Failed to parse `{}`'.format(spec
)
489 class GenericIntrinsic(object):
490 def __init__(self
, platform
, intrinsic
, widths
, llvm_name
, ret
, args
):
491 self
._platform
= platform
492 self
.intrinsic
= intrinsic
493 self
.widths
= map(int, widths
)
494 self
.llvm_name
= llvm_name
495 self
.ret
= TypeSpec(ret
)
496 self
.args
= list(map(TypeSpec
, args
))
498 def monomorphise(self
):
499 for width
in self
.widths
:
500 # must be a power of two
501 assert width
& (width
- 1) == 0
502 def recur(processed
, untouched
):
506 yield MonomorphicIntrinsic(self
._platform
, self
.intrinsic
, width
,
510 raw_arg
= untouched
[0]
512 for arg
in raw_arg
.enumerate(width
, processed
):
513 for intr
in recur(processed
+ [arg
], rest
):
516 for x
in recur([], [self
.ret
] + self
.args
):
519 class MonomorphicIntrinsic(object):
520 def __init__(self
, platform
, intrinsic
, width
, llvm_name
, ret
, args
):
521 self
._platform
= platform
522 self
._intrinsic
= intrinsic
523 self
._width
= '' if width
== 64 else 'q'
524 self
._llvm
_name
= llvm_name
526 self
._ret
= ret
.type_info(platform
)
527 self
._args
_raw
= args
528 self
._args
= [arg
.type_info(platform
) for arg
in args
]
531 if self
._llvm
_name
.startswith('!'):
532 return self
._llvm
_name
[1:].format(self
._ret
, *self
._args
)
534 return self
._platform
.llvm_prefix() + self
._llvm
_name
.format(self
._ret
, *self
._args
)
536 def intrinsic_suffix(self
):
537 return self
._intrinsic
.format(self
._ret
,
541 def intrinsic_name(self
):
542 return self
._platform
.platform().intrinsic_prefix() + self
.intrinsic_suffix()
544 def compiler_args(self
):
545 return ', '.join(arg
.compiler_ctor_ref() for arg
in self
._args
_raw
)
547 def compiler_ret(self
):
548 return self
._ret
_raw
.compiler_ctor_ref()
550 def compiler_signature(self
):
551 return '({}) -> {}'.format(self
.compiler_args(), self
.compiler_ret())
553 def intrinsic_signature(self
):
555 return '({}) -> {}'.format(', '.join('{}: {}'.format(name
, arg
.rust_name())
556 for name
, arg
in zip(names
, self
._args
_raw
)),
557 self
._ret
_raw
.rust_name())
560 parser
= argparse
.ArgumentParser(
561 formatter_class
= argparse
.RawDescriptionHelpFormatter
,
562 description
= 'Render an intrinsic definition JSON to various formats.',
563 epilog
= textwrap
.dedent('''\
564 An intrinsic definition consists of a map with fields:
565 - intrinsic: pattern for the name(s) of the vendor's C intrinsic(s)
566 - llvm: pattern for the name(s) of the internal llvm intrinsic(s)
567 - width: a vector of vector bit-widths the pattern works with
568 - ret: type specifier for the return value
569 - arguments: vector of type specifiers for arguments
571 The width and types describe a range of possible intrinsics,
572 and these are fed back into the intrinsic and llvm patterns to
573 create the appropriate definitions.
575 ## Type specifier grammar
578 type := core_type modifier* suffix?
580 core_type := void | vector | scalar | aggregate | reference
582 modifier := 'v' | 'h' | 'd' | 'n' | 'w' | 'u' | 's' |
583 'x' number | '.' number
584 suffix := pointer | bitcast
585 pointer := 'Pm' llvm_pointer? | 'Pc' llvm_pointer?
586 llvm_pointer := '/' type
591 vector := vector_elem width |
592 vector_elem := 'i' | 'u' | 's' | 'f'
594 scalar := scalar_type number llvm_width?
595 scalar_type := 'U' | 'S' | 'F'
596 llvm_width := '/' number
598 aggregate := '(' (type),* ')' 'f'? | '[' type ';' number ']' 'f'?
602 width = number | '(' number '-' number ')'
609 The `V` type corresponds to `void` in LLVM (`()` in
610 Rust). It's likely to only work in return position.
614 The vector grammar is a pattern describing many possibilities
615 for arguments/return value. The `vector_elem` describes the
616 types of elements to use, and the `width` describes the (range
617 of) widths for those elements, which are then placed into a
618 vector with the `width` bitwidth. E.g. if an intrinsic has a
619 `width` that includes 128, and the return value is `i(8-32)`,
620 then some instantiation of that intrinsic will be `u8x16`,
621 `u32x4`, `i32x4`, etc.
625 - i: integer, both signed and unsigned
626 - u: unsigned integer
632 Similar to vectors, but these describe a single concrete type,
633 not a range. The number is the bitwidth. The optional
634 `llvm_width` is the bitwidth of the integer that should be
635 passed to LLVM (by truncating the Rust argument): this only
636 works with scalar integers and the LLVM width must be smaller
641 - U: unsigned integer
647 An aggregate is a collection of multiple types; a tuple in
648 Rust terms, or an unnamed struct in LLVM. The `f` modifiers
649 forces the tuple to be flattened in the LLVM
650 intrinsic. E.g. if `llvm.foo` takes `(F32,S32)`:
652 - no `f` corresponds to `declare ... @llvm.foo({float, i32})`.
653 - having an `f` corresponds to `declare ... @llvm.foo(float, i32)`.
655 The `[type;number]` form is a just shorter way to write
656 `(...)`, except avoids doing a cartesian product of generic
657 types, e.g. `[S32;2]` is the same as `(S32, S32)`, while
658 `[I32;2]` is describing just the two types `(S32,S32)` and
659 `(U32,U32)` (i.e. doesn't include `(S32,U32)`, `(U32,S32)` as
662 (Currently aggregates can not contain other aggregates.)
666 A reference uses the type of another argument, with possible
667 modifications. The number refers to the type to use, starting
668 with 0 == return value, 1 == first argument, 2 == second
673 The `modifier` and `suffix` adaptors change the precise
678 - 'v': put a scalar into a vector of the current width (u32 -> u32x4, when width == 128)
679 - 'S': get the scalar element of a vector (u32x4 -> u32)
680 - 'h': half the length of the vector (u32x4 -> u32x2)
681 - 'd': double the length of the vector (u32x2 -> u32x4)
682 - 'n': narrow the element of the vector (u32x4 -> u16x4)
683 - 'w': widen the element of the vector (u16x4 -> u32x4)
684 - 'u': force a number (vector or scalar) to be unsigned int (f32x4 -> u32x4)
685 - 's': force a number (vector or scalar) to be signed int (u32x4 -> i32x4)
686 - 'f': force a number (vector or scalar) to be float (u32x4 -> f32x4)
687 - 'x' number: force the type to be a vector of bitwidth `number`.
688 - '.' number: get the `number`th element of an aggregate
689 - 'D': dereference a pointer (*mut u32 -> u32)
690 - 'C': make a pointer const (*mut u32 -> *const u32)
691 - 'M': make a pointer mut (*const u32 -> *mut u32)
695 Pointers can be created of any type by appending a `P*`
696 suffix. The `m` vs. `c` chooses mut vs. const. e.g. `S32Pm`
697 corresponds to `*mut i32`, and `i32Pc` corresponds (with width
698 128) to `*const i8x16`, `*const u32x4`, etc.
700 The type after the `/` (optional) represents the type used
701 internally to LLVM, e.g. `S32pm/S8` is exposed as `*mut i32`
702 in Rust, but is `i8*` in LLVM. (This defaults to the main
707 The `'->' type` bitcast suffix will cause the value to be
708 bitcast to the right-hand type when calling the intrinsic,
709 e.g. `s32->f32` will expose the intrinsic as `i32x4` at the
710 Rust level, but will cast that vector to `f32x4` when calling
713 parser
.add_argument('--format', choices
=FORMATS
, required
=True,
714 help = 'Output format.')
715 parser
.add_argument('-o', '--out', type=argparse
.FileType('w'), default
=sys
.stdout
,
716 help = 'File to output to (default stdout).')
717 parser
.add_argument('-i', '--info', type=argparse
.FileType('r'),
718 help = 'File containing platform specific information to merge into '
719 'the input files\' header.')
720 parser
.add_argument('in_', metavar
="FILE", type=argparse
.FileType('r'), nargs
='+',
721 help = 'JSON files to load')
722 return parser
.parse_args()
725 class ExternBlock(object):
729 def open(self
, platform
):
730 return 'extern "platform-intrinsic" {'
732 def render(self
, mono
):
733 return ' fn {}{};'.format(mono
.intrinsic_name(),
734 mono
.intrinsic_signature())
739 class CompilerDefs(object):
743 def open(self
, platform
):
745 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
746 // file at the top-level directory of this distribution and at
747 // http://rust-lang.org/COPYRIGHT.
749 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
750 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
751 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
752 // option. This file may not be copied, modified, or distributed
753 // except according to those terms.
755 // DO NOT EDIT: autogenerated by etc/platform-intrinsics/generator.py
756 // ignore-tidy-linelength
758 #![allow(unused_imports)]
760 use {{Intrinsic, Type}};
761 use IntrinsicDef::Named;
763 // The default inlining settings trigger a pathological behaviour in
764 // LLVM, which causes makes compilation very slow. See #28273.
766 pub fn find(name: &str) -> Option<Intrinsic> {{
767 if !name.starts_with("{0}") {{ return None }}
768 Some(match &name["{0}".len()..] {{'''.format(platform
.intrinsic_prefix())
770 def render(self
, mono
):
773 inputs: {{ static INPUTS: [&'static Type; {}] = [{}]; &INPUTS }},
775 definition: Named("{}")
776 }},'''.format(mono
.intrinsic_suffix(),
778 mono
.compiler_args(),
789 'extern-block': ExternBlock(),
790 'compiler-defs': CompilerDefs(),
798 out_format
= FORMATS
[args
.format
]
800 one_file_no_info
= False
801 if len(ins
) > 1 and info
is None:
802 print('error: cannot have multiple inputs without an info header.', file=sys
.stderr
)
807 one_file_no_info
= True
808 info_json
= json
.load(info
)
809 platform
= PlatformInfo(info_json
)
811 print(out_format
.open(platform
), file=out
)
818 data
= json
.load(in_
)
819 data
.update(info_json
)
821 intrinsics
= IntrinsicSet(platform
, data
)
822 for intr
in intrinsics
.intrinsics():
823 for mono
in intr
.monomorphise():
824 print(out_format
.render(mono
), file=out
)
826 print(out_format
.close(), file=out
)
828 if __name__
== '__main__':