20
20
r'|(?P<reference>\d+)(?P<modifiers>[vShdnwus]*)(?P<force_width>x\d+)?)$'
21
21
)
22
22
23
- class IntrinsicSet (object ):
23
+ class PlatformInfo (object ):
24
24
def __init__ (self , json ):
25
25
self ._platform = json ['platform' ]
26
26
self ._intrinsic_prefix = json ['intrinsic_prefix' ]
27
+ def intrinsic_prefix (self ):
28
+ return self ._intrinsic_prefix
29
+
30
+
31
+ class IntrinsicSet (object ):
32
+ def __init__ (self , platform , json ):
27
33
self ._llvm_prefix = json ['llvm_prefix' ]
28
- self ._intrinsics = json ['intrinsics' ]
29
34
self ._type_info = json ['number_info' ]
30
- self ._widths = json ['widths' ]
35
+ self ._intrinsics = json ['intrinsics' ]
36
+ self ._widths = json ['width_info' ]
37
+ self ._platform = platform
31
38
32
39
def intrinsics (self ):
33
40
for raw in self ._intrinsics :
34
41
yield GenericIntrinsic (self ,
35
42
raw ['intrinsic' ], raw ['width' ], raw ['llvm' ],
36
43
raw ['ret' ], raw ['args' ])
44
+ def platform (self ):
45
+ return self ._platform
37
46
def llvm_prefix (self ):
38
47
return self ._llvm_prefix
39
- def intrinsic_prefix (self ):
40
- return self ._intrinsic_prefix
41
-
42
- def width_name (self , bitwidth ):
48
+ def width_info (self , bitwidth ):
43
49
return self ._widths [str (bitwidth )]
44
50
45
51
def number_type_info (self , value ):
46
52
data = self ._type_info [value .__class__ .__name__ .lower ()]
47
53
bitwidth = value .bitwidth ()
48
- raw_dtype = data ['data_type' ]
49
- try :
50
- dtype = raw_dtype [str (bitwidth )]
51
- except KeyError :
52
- dtype = raw_dtype ['pattern' ].format (bitwidth = bitwidth )
53
- return PlatformTypeInfo (data ['kind' ],
54
- dtype ,
55
- value .llvm_name ())
54
+ def lookup (raw ):
55
+ if not isinstance (raw , dict ):
56
+ return raw
57
+
58
+ try :
59
+ return raw [str (bitwidth )]
60
+ except KeyError :
61
+ return raw ['pattern' ].format (bitwidth = bitwidth )
62
+
63
+ return PlatformTypeInfo (value .llvm_name (),
64
+ {k : lookup (v ) for k , v in data .items ()})
56
65
57
66
class PlatformTypeInfo (object ):
58
- def __init__ (self , kind , data_type , llvm_name , width = None ):
59
- self .kind = kind
60
- self .data_type = data_type
67
+ def __init__ (self , llvm_name , properties ):
68
+ self .properties = properties
61
69
self .llvm_name = llvm_name
62
- if width is not None :
63
- self .width = width
64
- def vectorize (self , length , width ):
65
- return PlatformTypeInfo ( self . kind , self .data_type ,
66
- 'v{}{}' . format ( length , self . llvm_name ),
67
- width )
70
+ def __getattr__ ( self , name ) :
71
+ return self .properties [ name ]
72
+ def vectorize (self , length , width_info ):
73
+ props = self .properties . copy ()
74
+ props . update ( width_info )
75
+ return PlatformTypeInfo ( 'v{}{}' . format ( length , self . llvm_name ), props )
68
76
69
77
class Type (object ):
70
78
def __init__ (self , bitwidth ):
@@ -79,7 +87,11 @@ class Number(Type):
79
87
def __init__ (self , bitwidth ):
80
88
Type .__init__ (self , bitwidth )
81
89
def modify (self , spec , width ):
82
- if spec == 'w' :
90
+ if spec == 'u' :
91
+ return Unsigned (self .bitwidth ())
92
+ elif spec == 's' :
93
+ return Signed (self .bitwidth ())
94
+ elif spec == 'w' :
83
95
return self .__class__ (self .bitwidth () * 2 )
84
96
elif spec == 'n' :
85
97
return self .__class__ (self .bitwidth () // 2 )
@@ -94,13 +106,6 @@ def type_info(self, platform_info):
94
106
class Signed (Number ):
95
107
def __init__ (self , bitwidth ):
96
108
Number .__init__ (self , bitwidth )
97
- def modify (self , spec , width ):
98
- if spec == 'u' :
99
- return Unsigned (self .bitwidth ())
100
- elif spec == 's' :
101
- return Signed (self .bitwidth ())
102
- else :
103
- return Number .modify (self , spec , width )
104
109
def compiler_ctor (self ):
105
110
return 'i({})' .format (self .bitwidth ())
106
111
def llvm_name (self ):
@@ -111,13 +116,6 @@ def rust_name(self):
111
116
class Unsigned (Number ):
112
117
def __init__ (self , bitwidth ):
113
118
Number .__init__ (self , bitwidth )
114
- def modify (self , spec , width ):
115
- if spec == 'u' :
116
- return Unsigned (self .bitwidth ())
117
- elif spec == 's' :
118
- return Signed (self .bitwidth ())
119
- else :
120
- return Number .modify (self , spec , width )
121
119
def compiler_ctor (self ):
122
120
return 'u({})' .format (self .bitwidth ())
123
121
def llvm_name (self ):
@@ -159,7 +157,7 @@ def rust_name(self):
159
157
def type_info (self , platform_info ):
160
158
elem_info = self ._elem .type_info (platform_info )
161
159
return elem_info .vectorize (self ._length ,
162
- platform_info .width_name (self .bitwidth ()))
160
+ platform_info .width_info (self .bitwidth ()))
163
161
164
162
class Aggregate (Type ):
165
163
def __init__ (self , flatten , elems ):
@@ -216,7 +214,7 @@ def enumerate(self, width):
216
214
yield scalar
217
215
bitwidth *= 2
218
216
else :
219
- print ('Failed to parse: {} ' .format (spec ), file = sys .stderr )
217
+ print ('Failed to parse: `{}` ' .format (spec ), file = sys .stderr )
220
218
def resolve (self , width , zero ):
221
219
assert len (self .spec ) == 1
222
220
spec = self .spec [0 ]
@@ -257,7 +255,8 @@ def __init__(self, platform, intrinsic, widths, llvm_name, ret, args):
257
255
258
256
def monomorphise (self ):
259
257
for width in self .widths :
260
- assert width in (64 , 128 )
258
+ # must be a power of two
259
+ assert width & (width - 1 ) == 0
261
260
for ret in self .ret .enumerate (width ):
262
261
args = [arg .resolve (width , ret ) for arg in self .args ]
263
262
yield MonomorphicIntrinsic (self ._platform , self .intrinsic , width , self .llvm_name ,
@@ -283,7 +282,7 @@ def intrinsic_suffix(self):
283
282
* self ._args ,
284
283
width = self ._width )
285
284
def intrinsic_name (self ):
286
- return self ._platform .intrinsic_prefix () + self .intrinsic_suffix ()
285
+ return self ._platform .platform (). intrinsic_prefix () + self .intrinsic_suffix ()
287
286
def compiler_args (self ):
288
287
return ', ' .join (arg .compiler_ctor () for arg in self ._args_raw )
289
288
def compiler_ret (self ):
@@ -294,7 +293,7 @@ def intrinsic_signature(self):
294
293
names = 'xyzwabcdef'
295
294
return '({}) -> {}' .format (', ' .join ('{}: {}' .format (name , arg .rust_name ())
296
295
for name , arg in zip (names , self ._args_raw )),
297
- self ._ret .rust_name ())
296
+ self ._ret_raw .rust_name ())
298
297
299
298
def parse_args ():
300
299
parser = argparse .ArgumentParser (
@@ -400,8 +399,11 @@ def parse_args():
400
399
help = 'Output format.' )
401
400
parser .add_argument ('-o' , '--out' , type = argparse .FileType ('w' ), default = sys .stdout ,
402
401
help = 'File to output to (default stdout).' )
403
- parser .add_argument ('in_' , metavar = "FILE" , type = argparse .FileType ('r' ),
404
- help = 'JSON file to load' )
402
+ parser .add_argument ('-i' , '--info' , type = argparse .FileType ('r' ),
403
+ help = 'File containing platform specific information to merge into'
404
+ 'the input files\' header.' )
405
+ parser .add_argument ('in_' , metavar = "FILE" , type = argparse .FileType ('r' ), nargs = '+' ,
406
+ help = 'JSON files to load' )
405
407
return parser .parse_args ()
406
408
407
409
@@ -466,16 +468,35 @@ def close(self):
466
468
467
469
def main ():
468
470
args = parse_args ()
469
- in_ = args .in_
471
+ ins = args .in_
470
472
out = args .out
471
473
out_format = FORMATS [args .format ]
474
+ info = args .info
475
+ one_file_no_info = False
476
+ if len (ins ) > 1 and info is None :
477
+ print ('error: cannot have multiple inputs without an info header.' , file = sys .stderr )
478
+ sys .exit (1 )
472
479
473
- intrinsics = IntrinsicSet (json .load (in_ ))
480
+ elif info is None :
481
+ info = ins [0 ]
482
+ one_file_no_info = True
483
+ info_json = json .load (info )
484
+ platform = PlatformInfo (info_json )
485
+
486
+ print (out_format .open (platform ), file = out )
487
+
488
+ for in_ in ins :
489
+
490
+ if one_file_no_info :
491
+ data = info_json
492
+ else :
493
+ data = json .load (in_ )
494
+ data .update (info_json )
474
495
475
- print ( out_format . open ( intrinsics ), file = out )
476
- for intr in intrinsics .intrinsics ():
477
- for mono in intr .monomorphise ():
478
- print (out_format .render (mono ), file = out )
496
+ intrinsics = IntrinsicSet ( platform , data )
497
+ for intr in intrinsics .intrinsics ():
498
+ for mono in intr .monomorphise ():
499
+ print (out_format .render (mono ), file = out )
479
500
print (out_format .close (), file = out )
480
501
481
502
if __name__ == '__main__' :
0 commit comments