1
+ import json
1
2
import os
2
3
import re
3
4
import sys
@@ -35,6 +36,10 @@ def clone_repository(repo_name, path, repo_url, sub_path=None):
35
36
run_command (["git" , "checkout" ], cwd = path )
36
37
37
38
39
+ def append_intrinsic (array , intrinsic_name , translation ):
40
+ array .append ((intrinsic_name , translation ))
41
+
42
+
38
43
def extract_instrinsics (intrinsics , file ):
39
44
print ("Extracting intrinsics from `{}`..." .format (file ))
40
45
with open (file , "r" , encoding = "utf8" ) as f :
@@ -70,25 +75,85 @@ def extract_instrinsics(intrinsics, file):
70
75
if current_arch not in intrinsics :
71
76
intrinsics [current_arch ] = []
72
77
for entry in entries :
73
- intrinsics [current_arch ]. append ( '"{}" => "{}",' . format ( intrinsic , entry ) )
78
+ append_intrinsic ( intrinsics [current_arch ], intrinsic , entry )
74
79
continue
75
80
pos += 1
76
81
continue
77
82
print ("Done!" )
78
83
79
84
80
- def update_intrinsics (llvm_path ):
85
+ def extract_instrinsics_from_llvm (llvm_path , intrinsics ):
81
86
files = []
82
87
intrinsics_path = os .path .join (llvm_path , "llvm/include/llvm/IR" )
83
88
for (dirpath , dirnames , filenames ) in walk (intrinsics_path ):
84
89
files .extend ([os .path .join (intrinsics_path , f ) for f in filenames if f .endswith (".td" )])
85
90
86
- intrinsics = {}
87
91
for file in files :
88
92
extract_instrinsics (intrinsics , file )
89
93
94
+
95
+ def append_translation (json_data , p , array ):
96
+ it = json_data ["index" ][p ]
97
+ content = it ["docs" ].split ('`' )
98
+ if len (content ) != 5 :
99
+ return
100
+ append_intrinsic (array , content [1 ], content [3 ])
101
+
102
+
103
+ def extract_instrinsics_from_llvmint (llvmint , intrinsics ):
104
+ archs = [
105
+ "AMDGPU" ,
106
+ "aarch64" ,
107
+ "arm" ,
108
+ "cuda" ,
109
+ "hexagon" ,
110
+ "mips" ,
111
+ "nvvm" ,
112
+ "ppc" ,
113
+ "ptx" ,
114
+ "x86" ,
115
+ "xcore" ,
116
+ ]
117
+
118
+ json_file = os .path .join (llvmint , "target/doc/llvmint.json" )
119
+ if not os .path .exists (json_file ):
120
+ # We need to regenerate the documentation!
121
+ run_command (
122
+ ["cargo" , "rustdoc" , "--" , "-Zunstable-options" , "--output-format" , "json" ],
123
+ cwd = llvmint ,
124
+ )
125
+ with open (json_file , "r" , encoding = "utf8" ) as f :
126
+ json_data = json .loads (f .read ())
127
+ for p in json_data ["paths" ]:
128
+ it = json_data ["paths" ][p ]
129
+ if it ["crate_id" ] != 0 :
130
+ # This is from an external crate.
131
+ continue
132
+ if it ["kind" ] != "function" :
133
+ # We're only looking for functions.
134
+ continue
135
+ # if len(it["path"]) == 2:
136
+ # # This is a "general" intrinsic, not bound to a specific arch.
137
+ # append_translation(json_data, p, general)
138
+ # continue
139
+ if len (it ["path" ]) != 3 or it ["path" ][1 ] not in archs :
140
+ continue
141
+ arch = it ["path" ][1 ]
142
+ if arch not in intrinsics :
143
+ intrinsics [arch ] = []
144
+ append_translation (json_data , p , intrinsics [arch ])
145
+
146
+
147
+ def update_intrinsics (llvm_path , llvmint ):
148
+ intrinsics = {}
149
+ all_intrinsics = {}
150
+
151
+ extract_instrinsics_from_llvm (llvm_path , intrinsics )
152
+ extract_instrinsics_from_llvmint (llvmint , intrinsics )
153
+
90
154
archs = [arch for arch in intrinsics ]
91
155
archs .sort ()
156
+
92
157
output_file = os .path .join (
93
158
os .path .dirname (os .path .abspath (__file__ )),
94
159
"../src/intrinsic/archs.rs" ,
@@ -103,8 +168,16 @@ def update_intrinsics(llvm_path):
103
168
continue
104
169
intrinsics [arch ].sort ()
105
170
out .write (' // {}\n ' .format (arch ))
106
- out .write ('\n ' .join ([' {}' .format (x ) for x in intrinsics [arch ]]))
107
- out .write ('\n ' )
171
+ for entry in intrinsics [arch ]:
172
+ if entry [0 ] in all_intrinsics :
173
+ if all_intrinsics [entry [0 ]] == entry [1 ]:
174
+ # This is a "full" duplicate, both the LLVM instruction and the GCC
175
+ # translation are the same.
176
+ continue
177
+ out .write (' // [DUPLICATE]: "{}" => "{}",\n ' .format (entry [0 ], entry [1 ]))
178
+ else :
179
+ out .write (' "{}" => "{}",\n ' .format (entry [0 ], entry [1 ]))
180
+ all_intrinsics [entry [0 ]] = entry [1 ]
108
181
out .write (' _ => unimplemented!("***** unsupported LLVM intrinsic {}", name),\n ' )
109
182
out .write ("}\n " )
110
183
print ("Done!" )
@@ -115,14 +188,24 @@ def main():
115
188
os .path .dirname (os .path .abspath (__file__ )),
116
189
"llvm-project" ,
117
190
)
191
+ llvmint_path = os .path .join (
192
+ os .path .dirname (os .path .abspath (__file__ )),
193
+ "llvmint" ,
194
+ )
118
195
119
196
# First, we clone the LLVM repository if it's not already here.
120
197
clone_repository (
121
198
"llvm-project" ,
122
199
llvm_path ,
123
200
"https://github.com/llvm/llvm-project" ,
124
- sub_path = "llvm/include/llvm/IR" )
125
- update_intrinsics (llvm_path )
201
+ sub_path = "llvm/include/llvm/IR" ,
202
+ )
203
+ clone_repository (
204
+ "llvmint" ,
205
+ llvmint_path ,
206
+ "https://github.com/GuillaumeGomez/llvmint" ,
207
+ )
208
+ update_intrinsics (llvm_path , llvmint_path )
126
209
127
210
128
211
if __name__ == "__main__" :
0 commit comments