Subversion Repositories Kolibri OS

Rev

Rev 8989 | Rev 9028 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 8989 Rev 8990
1
import re
1
import re
2
import os
2
import os
3
import argparse
3
import argparse
4
import sys
4
import sys
-
 
5
import pickle
5
 
6
 
6
# Parameters
7
# Parameters
7
# Path to doxygen folder to make doxygen files in: -o 
8
# Path to doxygen folder to make doxygen files in: -o 
8
doxygen_src_path = 'docs/doxygen'
9
doxygen_src_path = 'docs/doxygen'
9
# Remove generated doxygen files: --clean
10
# Remove generated doxygen files: --clean
10
clean_generated_stuff = False
11
clean_generated_stuff = False
11
# Dump all defined symbols: --dump
12
# Dump all defined symbols: --dump
12
dump_symbols = False
13
dump_symbols = False
13
# Print symbol stats: --stats
14
# Print symbol stats: --stats
14
print_stats = False
15
print_stats = False
15
# Do not write warnings file: --nowarn
16
# Do not write warnings file: --nowarn
16
enable_warnings = True
17
enable_warnings = True
17
 
18
 
18
# Constants
19
# Constants
19
link_root = "http://websvn.kolibrios.org/filedetails.php?repname=Kolibri+OS&path=/kernel/trunk"
20
link_root = "http://websvn.kolibrios.org/filedetails.php?repname=Kolibri+OS&path=/kernel/trunk"
20
 
21
 
21
# fasm keywords
22
# fasm keywords
22
keywords = [
23
keywords = [
23
	# Generic keywords
24
	# Generic keywords
24
	"align",
25
	"align",
25
	"equ",
26
	"equ",
26
	"org",
27
	"org",
27
	"while",
28
	"while",
28
	"load",
29
	"load",
29
	"store",
30
	"store",
30
	"times",
31
	"times",
31
	"repeat",
32
	"repeat",
32
	"virtual",
33
	"virtual",
33
	"display",
34
	"display",
34
	"err",
35
	"err",
35
	"assert",
36
	"assert",
36
	"if",
37
	"if",
37
	# Instructions
38
	# Instructions
38
	"aaa",
39
	"aaa",
39
	"aad",
40
	"aad",
40
	"aam",
41
	"aam",
41
	"aas",
42
	"aas",
42
	"adc",
43
	"adc",
43
	"adcx",
44
	"adcx",
44
	"add",
45
	"add",
45
	"addpd",
46
	"addpd",
46
	"addps",
47
	"addps",
47
	"addsd",
48
	"addsd",
48
	"addss",
49
	"addss",
49
	"addsubpd",
50
	"addsubpd",
50
	"addsubps",
51
	"addsubps",
51
	"adox",
52
	"adox",
52
	"aesdec",
53
	"aesdec",
53
	"aesdeclast",
54
	"aesdeclast",
54
	"aesenc",
55
	"aesenc",
55
	"aesenclast",
56
	"aesenclast",
56
	"aesimc",
57
	"aesimc",
57
	"aeskeygenassist",
58
	"aeskeygenassist",
58
	"and",
59
	"and",
59
	"andn",
60
	"andn",
60
	"andnpd",
61
	"andnpd",
61
	"andnps",
62
	"andnps",
62
	"andpd",
63
	"andpd",
63
	"andps",
64
	"andps",
64
	"arpl",
65
	"arpl",
65
	"bextr",
66
	"bextr",
66
	"blendpd",
67
	"blendpd",
67
	"blendps",
68
	"blendps",
68
	"blendvpd",
69
	"blendvpd",
69
	"blendvps",
70
	"blendvps",
70
	"blsi",
71
	"blsi",
71
	"blsmsk",
72
	"blsmsk",
72
	"blsr",
73
	"blsr",
73
	"bndcl",
74
	"bndcl",
74
	"bndcn",
75
	"bndcn",
75
	"bndcu",
76
	"bndcu",
76
	"bndldx",
77
	"bndldx",
77
	"bndmk",
78
	"bndmk",
78
	"bndmov",
79
	"bndmov",
79
	"bndstx",
80
	"bndstx",
80
	"bound",
81
	"bound",
81
	"bsf",
82
	"bsf",
82
	"bsr",
83
	"bsr",
83
	"bswap",
84
	"bswap",
84
	"bt",
85
	"bt",
85
	"btc",
86
	"btc",
86
	"btr",
87
	"btr",
87
	"bts",
88
	"bts",
88
	"bzhi",
89
	"bzhi",
89
	"call",
90
	"call",
90
	"cbw",
91
	"cbw",
91
	"cdq",
92
	"cdq",
92
	"cdqe",
93
	"cdqe",
93
	"clac",
94
	"clac",
94
	"clc",
95
	"clc",
95
	"cld",
96
	"cld",
96
	"cldemote",
97
	"cldemote",
97
	"clflush",
98
	"clflush",
98
	"clflushopt",
99
	"clflushopt",
99
	"cli",
100
	"cli",
100
	"clts",
101
	"clts",
101
	"clwb",
102
	"clwb",
102
	"cmc",
103
	"cmc",
103
	"cmova",
104
	"cmova",
104
	"cmovae",
105
	"cmovae",
105
	"cmovb",
106
	"cmovb",
106
	"cmovbe",
107
	"cmovbe",
107
	"cmovc",
108
	"cmovc",
108
	"cmove",
109
	"cmove",
109
	"cmovg",
110
	"cmovg",
110
	"cmovge",
111
	"cmovge",
111
	"cmovl",
112
	"cmovl",
112
	"cmovle",
113
	"cmovle",
113
	"cmovna",
114
	"cmovna",
114
	"cmovnae",
115
	"cmovnae",
115
	"cmovnb",
116
	"cmovnb",
116
	"cmovnbe",
117
	"cmovnbe",
117
	"cmovnc",
118
	"cmovnc",
118
	"cmovne",
119
	"cmovne",
119
	"cmovng",
120
	"cmovng",
120
	"cmovnge",
121
	"cmovnge",
121
	"cmovnl",
122
	"cmovnl",
122
	"cmovnle",
123
	"cmovnle",
123
	"cmovno",
124
	"cmovno",
124
	"cmovnp",
125
	"cmovnp",
125
	"cmovns",
126
	"cmovns",
126
	"cmovnz",
127
	"cmovnz",
127
	"cmovo",
128
	"cmovo",
128
	"cmovp",
129
	"cmovp",
129
	"cmovpe",
130
	"cmovpe",
130
	"cmovpo",
131
	"cmovpo",
131
	"cmovs",
132
	"cmovs",
132
	"cmovz",
133
	"cmovz",
133
	"cmp",
134
	"cmp",
134
	"cmppd",
135
	"cmppd",
135
	"cmpps",
136
	"cmpps",
136
	"cmps",
137
	"cmps",
137
	"cmpsb",
138
	"cmpsb",
138
	"cmpsd",
139
	"cmpsd",
139
	"cmpsd",
140
	"cmpsd",
140
	"cmpsq",
141
	"cmpsq",
141
	"cmpss",
142
	"cmpss",
142
	"cmpsw",
143
	"cmpsw",
143
	"cmpxchg",
144
	"cmpxchg",
144
	"cmpxchg16b",
145
	"cmpxchg16b",
145
	"cmpxchg8b",
146
	"cmpxchg8b",
146
	"comisd",
147
	"comisd",
147
	"comiss",
148
	"comiss",
148
	"cpuid",
149
	"cpuid",
149
	"cqo",
150
	"cqo",
150
	"crc32",
151
	"crc32",
151
	"cvtdq2pd",
152
	"cvtdq2pd",
152
	"cvtdq2ps",
153
	"cvtdq2ps",
153
	"cvtpd2dq",
154
	"cvtpd2dq",
154
	"cvtpd2pi",
155
	"cvtpd2pi",
155
	"cvtpd2ps",
156
	"cvtpd2ps",
156
	"cvtpi2pd",
157
	"cvtpi2pd",
157
	"cvtpi2ps",
158
	"cvtpi2ps",
158
	"cvtps2dq",
159
	"cvtps2dq",
159
	"cvtps2pd",
160
	"cvtps2pd",
160
	"cvtps2pi",
161
	"cvtps2pi",
161
	"cvtsd2si",
162
	"cvtsd2si",
162
	"cvtsd2ss",
163
	"cvtsd2ss",
163
	"cvtsi2sd",
164
	"cvtsi2sd",
164
	"cvtsi2ss",
165
	"cvtsi2ss",
165
	"cvtss2sd",
166
	"cvtss2sd",
166
	"cvtss2si",
167
	"cvtss2si",
167
	"cvttpd2dq",
168
	"cvttpd2dq",
168
	"cvttpd2pi",
169
	"cvttpd2pi",
169
	"cvttps2dq",
170
	"cvttps2dq",
170
	"cvttps2pi",
171
	"cvttps2pi",
171
	"cvttsd2si",
172
	"cvttsd2si",
172
	"cvttss2si",
173
	"cvttss2si",
173
	"cwd",
174
	"cwd",
174
	"cwde",
175
	"cwde",
175
	"daa",
176
	"daa",
176
	"das",
177
	"das",
177
	"dec",
178
	"dec",
178
	"div",
179
	"div",
179
	"divpd",
180
	"divpd",
180
	"divps",
181
	"divps",
181
	"divsd",
182
	"divsd",
182
	"divss",
183
	"divss",
183
	"dppd",
184
	"dppd",
184
	"dpps",
185
	"dpps",
185
	"emms",
186
	"emms",
186
	"enter",
187
	"enter",
187
	"extractps",
188
	"extractps",
188
	"f2xm1",
189
	"f2xm1",
189
	"fabs",
190
	"fabs",
190
	"fadd",
191
	"fadd",
191
	"faddp",
192
	"faddp",
192
	"fbld",
193
	"fbld",
193
	"fbstp",
194
	"fbstp",
194
	"fchs",
195
	"fchs",
195
	"fclex",
196
	"fclex",
196
	"fcmova",
197
	"fcmova",
197
	"fcmovae",
198
	"fcmovae",
198
	"fcmovb",
199
	"fcmovb",
199
	"fcmovbe",
200
	"fcmovbe",
200
	"fcmovc",
201
	"fcmovc",
201
	"fcmove",
202
	"fcmove",
202
	"fcmovg",
203
	"fcmovg",
203
	"fcmovge",
204
	"fcmovge",
204
	"fcmovl",
205
	"fcmovl",
205
	"fcmovle",
206
	"fcmovle",
206
	"fcmovna",
207
	"fcmovna",
207
	"fcmovnae",
208
	"fcmovnae",
208
	"fcmovnb",
209
	"fcmovnb",
209
	"fcmovnbe",
210
	"fcmovnbe",
210
	"fcmovnc",
211
	"fcmovnc",
211
	"fcmovne",
212
	"fcmovne",
212
	"fcmovng",
213
	"fcmovng",
213
	"fcmovnge",
214
	"fcmovnge",
214
	"fcmovnl",
215
	"fcmovnl",
215
	"fcmovnle",
216
	"fcmovnle",
216
	"fcmovno",
217
	"fcmovno",
217
	"fcmovnp",
218
	"fcmovnp",
218
	"fcmovns",
219
	"fcmovns",
219
	"fcmovnz",
220
	"fcmovnz",
220
	"fcmovo",
221
	"fcmovo",
221
	"fcmovp",
222
	"fcmovp",
222
	"fcmovpe",
223
	"fcmovpe",
223
	"fcmovpo",
224
	"fcmovpo",
224
	"fcmovs",
225
	"fcmovs",
225
	"fcmovz",
226
	"fcmovz",
226
	"fcom",
227
	"fcom",
227
	"fcomi",
228
	"fcomi",
228
	"fcomip",
229
	"fcomip",
229
	"fcomp",
230
	"fcomp",
230
	"fcompp",
231
	"fcompp",
231
	"fcos",
232
	"fcos",
232
	"fdecstp",
233
	"fdecstp",
233
	"fdiv",
234
	"fdiv",
234
	"fdivp",
235
	"fdivp",
235
	"fdivr",
236
	"fdivr",
236
	"fdivrp",
237
	"fdivrp",
237
	"ffree",
238
	"ffree",
238
	"fiadd",
239
	"fiadd",
239
	"ficom",
240
	"ficom",
240
	"ficomp",
241
	"ficomp",
241
	"fidiv",
242
	"fidiv",
242
	"fidivr",
243
	"fidivr",
243
	"fild",
244
	"fild",
244
	"fimul",
245
	"fimul",
245
	"fincstp",
246
	"fincstp",
246
	"finit",
247
	"finit",
247
	"fist",
248
	"fist",
248
	"fistp",
249
	"fistp",
249
	"fisttp",
250
	"fisttp",
250
	"fisub",
251
	"fisub",
251
	"fisubr",
252
	"fisubr",
252
	"fld",
253
	"fld",
253
	"fld1",
254
	"fld1",
254
	"fldcw",
255
	"fldcw",
255
	"fldenv",
256
	"fldenv",
256
	"fldl2e",
257
	"fldl2e",
257
	"fldl2t",
258
	"fldl2t",
258
	"fldlg2",
259
	"fldlg2",
259
	"fldln2",
260
	"fldln2",
260
	"fldpi",
261
	"fldpi",
261
	"fldz",
262
	"fldz",
262
	"fmul",
263
	"fmul",
263
	"fmulp",
264
	"fmulp",
264
	"fnclex",
265
	"fnclex",
265
	"fninit",
266
	"fninit",
266
	"fnop",
267
	"fnop",
267
	"fnsave",
268
	"fnsave",
268
	"fnstcw",
269
	"fnstcw",
269
	"fnstenv",
270
	"fnstenv",
270
	"fnstsw",
271
	"fnstsw",
271
	"fpatan",
272
	"fpatan",
272
	"fprem",
273
	"fprem",
273
	"fprem1",
274
	"fprem1",
274
	"fptan",
275
	"fptan",
275
	"frndint",
276
	"frndint",
276
	"frstor",
277
	"frstor",
277
	"fsave",
278
	"fsave",
278
	"fscale",
279
	"fscale",
279
	"fsin",
280
	"fsin",
280
	"fsincos",
281
	"fsincos",
281
	"fsqrt",
282
	"fsqrt",
282
	"fst",
283
	"fst",
283
	"fstcw",
284
	"fstcw",
284
	"fstenv",
285
	"fstenv",
285
	"fstp",
286
	"fstp",
286
	"fstsw",
287
	"fstsw",
287
	"fsub",
288
	"fsub",
288
	"fsubp",
289
	"fsubp",
289
	"fsubr",
290
	"fsubr",
290
	"fsubrp",
291
	"fsubrp",
291
	"ftst",
292
	"ftst",
292
	"fucom",
293
	"fucom",
293
	"fucomi",
294
	"fucomi",
294
	"fucomip",
295
	"fucomip",
295
	"fucomp",
296
	"fucomp",
296
	"fucompp",
297
	"fucompp",
297
	"fwait",
298
	"fwait",
298
	"fxam",
299
	"fxam",
299
	"fxch",
300
	"fxch",
300
	"fxrstor",
301
	"fxrstor",
301
	"fxsave",
302
	"fxsave",
302
	"fxtract",
303
	"fxtract",
303
	"fyl2x",
304
	"fyl2x",
304
	"fyl2xp1",
305
	"fyl2xp1",
305
	"gf2p8affineinvqb",
306
	"gf2p8affineinvqb",
306
	"gf2p8affineqb",
307
	"gf2p8affineqb",
307
	"gf2p8mulb",
308
	"gf2p8mulb",
308
	"haddpd",
309
	"haddpd",
309
	"haddps",
310
	"haddps",
310
	"hlt",
311
	"hlt",
311
	"hsubpd",
312
	"hsubpd",
312
	"hsubps",
313
	"hsubps",
313
	"idiv",
314
	"idiv",
314
	"imul",
315
	"imul",
315
	"in",
316
	"in",
316
	"inc",
317
	"inc",
317
	"ins",
318
	"ins",
318
	"insb",
319
	"insb",
319
	"insd",
320
	"insd",
320
	"insertps",
321
	"insertps",
321
	"insw",
322
	"insw",
322
	"int",
323
	"int",
323
	"int1",
324
	"int1",
324
	"int3",
325
	"int3",
325
	"into",
326
	"into",
326
	"invd",
327
	"invd",
327
	"invlpg",
328
	"invlpg",
328
	"invpcid",
329
	"invpcid",
329
	"iret",
330
	"iret",
330
	"iretd",
331
	"iretd",
331
	"jmp",
332
	"jmp",
332
	"ja",
333
	"ja",
333
	"jae",
334
	"jae",
334
	"jb",
335
	"jb",
335
	"jbe",
336
	"jbe",
336
	"jc",
337
	"jc",
337
	"jcxz",
338
	"jcxz",
338
	"jecxz",
339
	"jecxz",
339
	"je",
340
	"je",
340
	"jg",
341
	"jg",
341
	"jge",
342
	"jge",
342
	"jl",
343
	"jl",
343
	"jle",
344
	"jle",
344
	"jna",
345
	"jna",
345
	"jnae",
346
	"jnae",
346
	"jnb",
347
	"jnb",
347
	"jnbe",
348
	"jnbe",
348
	"jnc",
349
	"jnc",
349
	"jne",
350
	"jne",
350
	"jng",
351
	"jng",
351
	"jnge",
352
	"jnge",
352
	"jnl",
353
	"jnl",
353
	"jnle",
354
	"jnle",
354
	"jno",
355
	"jno",
355
	"jnp",
356
	"jnp",
356
	"jns",
357
	"jns",
357
	"jnz",
358
	"jnz",
358
	"jo",
359
	"jo",
359
	"jp",
360
	"jp",
360
	"jpe",
361
	"jpe",
361
	"jpo",
362
	"jpo",
362
	"js",
363
	"js",
363
	"jz",
364
	"jz",
364
	"kaddb",
365
	"kaddb",
365
	"kaddd",
366
	"kaddd",
366
	"kaddq",
367
	"kaddq",
367
	"kaddw",
368
	"kaddw",
368
	"kandb",
369
	"kandb",
369
	"kandd",
370
	"kandd",
370
	"kandnb",
371
	"kandnb",
371
	"kandnd",
372
	"kandnd",
372
	"kandnq",
373
	"kandnq",
373
	"kandnw",
374
	"kandnw",
374
	"kandq",
375
	"kandq",
375
	"kandw",
376
	"kandw",
376
	"kmovb",
377
	"kmovb",
377
	"kmovd",
378
	"kmovd",
378
	"kmovq",
379
	"kmovq",
379
	"kmovw",
380
	"kmovw",
380
	"knotb",
381
	"knotb",
381
	"knotd",
382
	"knotd",
382
	"knotq",
383
	"knotq",
383
	"knotw",
384
	"knotw",
384
	"korb",
385
	"korb",
385
	"kord",
386
	"kord",
386
	"korq",
387
	"korq",
387
	"kortestb",
388
	"kortestb",
388
	"kortestd",
389
	"kortestd",
389
	"kortestq",
390
	"kortestq",
390
	"kortestw",
391
	"kortestw",
391
	"korw",
392
	"korw",
392
	"kshiftlb",
393
	"kshiftlb",
393
	"kshiftld",
394
	"kshiftld",
394
	"kshiftlq",
395
	"kshiftlq",
395
	"kshiftlw",
396
	"kshiftlw",
396
	"kshiftrb",
397
	"kshiftrb",
397
	"kshiftrd",
398
	"kshiftrd",
398
	"kshiftrq",
399
	"kshiftrq",
399
	"kshiftrw",
400
	"kshiftrw",
400
	"ktestb",
401
	"ktestb",
401
	"ktestd",
402
	"ktestd",
402
	"ktestq",
403
	"ktestq",
403
	"ktestw",
404
	"ktestw",
404
	"kunpckbw",
405
	"kunpckbw",
405
	"kunpckdq",
406
	"kunpckdq",
406
	"kunpckwd",
407
	"kunpckwd",
407
	"kxnorb",
408
	"kxnorb",
408
	"kxnord",
409
	"kxnord",
409
	"kxnorq",
410
	"kxnorq",
410
	"kxnorw",
411
	"kxnorw",
411
	"kxorb",
412
	"kxorb",
412
	"kxord",
413
	"kxord",
413
	"kxorq",
414
	"kxorq",
414
	"kxorw",
415
	"kxorw",
415
	"lahf",
416
	"lahf",
416
	"lar",
417
	"lar",
417
	"lddqu",
418
	"lddqu",
418
	"ldmxcsr",
419
	"ldmxcsr",
419
	"lds",
420
	"lds",
420
	"lea",
421
	"lea",
421
	"leave",
422
	"leave",
422
	"les",
423
	"les",
423
	"lfence",
424
	"lfence",
424
	"lfs",
425
	"lfs",
425
	"lgdt",
426
	"lgdt",
426
	"lgs",
427
	"lgs",
427
	"lidt",
428
	"lidt",
428
	"lldt",
429
	"lldt",
429
	"lmsw",
430
	"lmsw",
430
	"lock",
431
	"lock",
431
	"lods",
432
	"lods",
432
	"lodsb",
433
	"lodsb",
433
	"lodsd",
434
	"lodsd",
434
	"lodsq",
435
	"lodsq",
435
	"lodsw",
436
	"lodsw",
436
	"loop",
437
	"loop",
437
	"loopa",
438
	"loopa",
438
	"loopae",
439
	"loopae",
439
	"loopb",
440
	"loopb",
440
	"loopbe",
441
	"loopbe",
441
	"loopc",
442
	"loopc",
442
	"loope",
443
	"loope",
443
	"loopg",
444
	"loopg",
444
	"loopge",
445
	"loopge",
445
	"loopl",
446
	"loopl",
446
	"loople",
447
	"loople",
447
	"loopna",
448
	"loopna",
448
	"loopnae",
449
	"loopnae",
449
	"loopnb",
450
	"loopnb",
450
	"loopnbe",
451
	"loopnbe",
451
	"loopnc",
452
	"loopnc",
452
	"loopne",
453
	"loopne",
453
	"loopng",
454
	"loopng",
454
	"loopnge",
455
	"loopnge",
455
	"loopnl",
456
	"loopnl",
456
	"loopnle",
457
	"loopnle",
457
	"loopno",
458
	"loopno",
458
	"loopnp",
459
	"loopnp",
459
	"loopns",
460
	"loopns",
460
	"loopnz",
461
	"loopnz",
461
	"loopo",
462
	"loopo",
462
	"loopp",
463
	"loopp",
463
	"looppe",
464
	"looppe",
464
	"looppo",
465
	"looppo",
465
	"loops",
466
	"loops",
466
	"loopz",
467
	"loopz",
467
	"lsl",
468
	"lsl",
468
	"lss",
469
	"lss",
469
	"ltr",
470
	"ltr",
470
	"lzcnt",
471
	"lzcnt",
471
	"maskmovdqu",
472
	"maskmovdqu",
472
	"maskmovq",
473
	"maskmovq",
473
	"maxpd",
474
	"maxpd",
474
	"maxps",
475
	"maxps",
475
	"maxsd",
476
	"maxsd",
476
	"maxss",
477
	"maxss",
477
	"mfence",
478
	"mfence",
478
	"minpd",
479
	"minpd",
479
	"minps",
480
	"minps",
480
	"minsd",
481
	"minsd",
481
	"minss",
482
	"minss",
482
	"monitor",
483
	"monitor",
483
	"mov",
484
	"mov",
484
	"movapd",
485
	"movapd",
485
	"movaps",
486
	"movaps",
486
	"movbe",
487
	"movbe",
487
	"movd",
488
	"movd",
488
	"movddup",
489
	"movddup",
489
	"movdir64b",
490
	"movdir64b",
490
	"movdiri",
491
	"movdiri",
491
	"movdq2q",
492
	"movdq2q",
492
	"movdqa",
493
	"movdqa",
493
	"movdqu",
494
	"movdqu",
494
	"movhlps",
495
	"movhlps",
495
	"movhpd",
496
	"movhpd",
496
	"movhps",
497
	"movhps",
497
	"movlhps",
498
	"movlhps",
498
	"movlpd",
499
	"movlpd",
499
	"movlps",
500
	"movlps",
500
	"movmskpd",
501
	"movmskpd",
501
	"movmskps",
502
	"movmskps",
502
	"movntdq",
503
	"movntdq",
503
	"movntdqa",
504
	"movntdqa",
504
	"movnti",
505
	"movnti",
505
	"movntpd",
506
	"movntpd",
506
	"movntps",
507
	"movntps",
507
	"movntq",
508
	"movntq",
508
	"movq",
509
	"movq",
509
	"movq",
510
	"movq",
510
	"movq2dq",
511
	"movq2dq",
511
	"movs",
512
	"movs",
512
	"movsb",
513
	"movsb",
513
	"movsd",
514
	"movsd",
514
	"movsd",
515
	"movsd",
515
	"movshdup",
516
	"movshdup",
516
	"movsldup",
517
	"movsldup",
517
	"movsq",
518
	"movsq",
518
	"movss",
519
	"movss",
519
	"movsw",
520
	"movsw",
520
	"movsx",
521
	"movsx",
521
	"movsxd",
522
	"movsxd",
522
	"movupd",
523
	"movupd",
523
	"movups",
524
	"movups",
524
	"movzx",
525
	"movzx",
525
	"mpsadbw",
526
	"mpsadbw",
526
	"mul",
527
	"mul",
527
	"mulpd",
528
	"mulpd",
528
	"mulps",
529
	"mulps",
529
	"mulsd",
530
	"mulsd",
530
	"mulss",
531
	"mulss",
531
	"mulx",
532
	"mulx",
532
	"mwait",
533
	"mwait",
533
	"neg",
534
	"neg",
534
	"nop",
535
	"nop",
535
	"not",
536
	"not",
536
	"or",
537
	"or",
537
	"orpd",
538
	"orpd",
538
	"orps",
539
	"orps",
539
	"out",
540
	"out",
540
	"outs",
541
	"outs",
541
	"outsb",
542
	"outsb",
542
	"outsd",
543
	"outsd",
543
	"outsw",
544
	"outsw",
544
	"pabsb",
545
	"pabsb",
545
	"pabsd",
546
	"pabsd",
546
	"pabsq",
547
	"pabsq",
547
	"pabsw",
548
	"pabsw",
548
	"packssdw",
549
	"packssdw",
549
	"packsswb",
550
	"packsswb",
550
	"packusdw",
551
	"packusdw",
551
	"packuswb",
552
	"packuswb",
552
	"paddb",
553
	"paddb",
553
	"paddd",
554
	"paddd",
554
	"paddq",
555
	"paddq",
555
	"paddsb",
556
	"paddsb",
556
	"paddsw",
557
	"paddsw",
557
	"paddusb",
558
	"paddusb",
558
	"paddusw",
559
	"paddusw",
559
	"paddw",
560
	"paddw",
560
	"palignr",
561
	"palignr",
561
	"pand",
562
	"pand",
562
	"pandn",
563
	"pandn",
563
	"pause",
564
	"pause",
564
	"pavgb",
565
	"pavgb",
565
	"pavgw",
566
	"pavgw",
566
	"pblendvb",
567
	"pblendvb",
567
	"pblendw",
568
	"pblendw",
568
	"pclmulqdq",
569
	"pclmulqdq",
569
	"pcmpeqb",
570
	"pcmpeqb",
570
	"pcmpeqd",
571
	"pcmpeqd",
571
	"pcmpeqq",
572
	"pcmpeqq",
572
	"pcmpeqw",
573
	"pcmpeqw",
573
	"pcmpestri",
574
	"pcmpestri",
574
	"pcmpestrm",
575
	"pcmpestrm",
575
	"pcmpgtb",
576
	"pcmpgtb",
576
	"pcmpgtd",
577
	"pcmpgtd",
577
	"pcmpgtq",
578
	"pcmpgtq",
578
	"pcmpgtw",
579
	"pcmpgtw",
579
	"pcmpistri",
580
	"pcmpistri",
580
	"pcmpistrm",
581
	"pcmpistrm",
581
	"pdep",
582
	"pdep",
582
	"pext",
583
	"pext",
583
	"pextrb",
584
	"pextrb",
584
	"pextrd",
585
	"pextrd",
585
	"pextrq",
586
	"pextrq",
586
	"pextrw",
587
	"pextrw",
587
	"phaddd",
588
	"phaddd",
588
	"phaddsw",
589
	"phaddsw",
589
	"phaddw",
590
	"phaddw",
590
	"phminposuw",
591
	"phminposuw",
591
	"phsubd",
592
	"phsubd",
592
	"phsubsw",
593
	"phsubsw",
593
	"phsubw",
594
	"phsubw",
594
	"pinsrb",
595
	"pinsrb",
595
	"pinsrd",
596
	"pinsrd",
596
	"pinsrq",
597
	"pinsrq",
597
	"pinsrw",
598
	"pinsrw",
598
	"pmaddubsw",
599
	"pmaddubsw",
599
	"pmaddwd",
600
	"pmaddwd",
600
	"pmaxsb",
601
	"pmaxsb",
601
	"pmaxsd",
602
	"pmaxsd",
602
	"pmaxsq",
603
	"pmaxsq",
603
	"pmaxsw",
604
	"pmaxsw",
604
	"pmaxub",
605
	"pmaxub",
605
	"pmaxud",
606
	"pmaxud",
606
	"pmaxuq",
607
	"pmaxuq",
607
	"pmaxuw",
608
	"pmaxuw",
608
	"pminsb",
609
	"pminsb",
609
	"pminsd",
610
	"pminsd",
610
	"pminsq",
611
	"pminsq",
611
	"pminsw",
612
	"pminsw",
612
	"pminub",
613
	"pminub",
613
	"pminud",
614
	"pminud",
614
	"pminuq",
615
	"pminuq",
615
	"pminuw",
616
	"pminuw",
616
	"pmovmskb",
617
	"pmovmskb",
617
	"pmovsx",
618
	"pmovsx",
618
	"pmovzx",
619
	"pmovzx",
619
	"pmuldq",
620
	"pmuldq",
620
	"pmulhrsw",
621
	"pmulhrsw",
621
	"pmulhuw",
622
	"pmulhuw",
622
	"pmulhw",
623
	"pmulhw",
623
	"pmulld",
624
	"pmulld",
624
	"pmullq",
625
	"pmullq",
625
	"pmullw",
626
	"pmullw",
626
	"pmuludq",
627
	"pmuludq",
627
	"pop",
628
	"pop",
628
	"popa",
629
	"popa",
629
	"popad",
630
	"popad",
630
	"popcnt",
631
	"popcnt",
631
	"popf",
632
	"popf",
632
	"popfd",
633
	"popfd",
633
	"popfq",
634
	"popfq",
634
	"por",
635
	"por",
635
	"prefetchw",
636
	"prefetchw",
636
	"prefetchh",
637
	"prefetchh",
637
	"psadbw",
638
	"psadbw",
638
	"pshufb",
639
	"pshufb",
639
	"pshufd",
640
	"pshufd",
640
	"pshufhw",
641
	"pshufhw",
641
	"pshuflw",
642
	"pshuflw",
642
	"pshufw",
643
	"pshufw",
643
	"psignb",
644
	"psignb",
644
	"psignd",
645
	"psignd",
645
	"psignw",
646
	"psignw",
646
	"pslld",
647
	"pslld",
647
	"pslldq",
648
	"pslldq",
648
	"psllq",
649
	"psllq",
649
	"psllw",
650
	"psllw",
650
	"psrad",
651
	"psrad",
651
	"psraq",
652
	"psraq",
652
	"psraw",
653
	"psraw",
653
	"psrld",
654
	"psrld",
654
	"psrldq",
655
	"psrldq",
655
	"psrlq",
656
	"psrlq",
656
	"psrlw",
657
	"psrlw",
657
	"psubb",
658
	"psubb",
658
	"psubd",
659
	"psubd",
659
	"psubq",
660
	"psubq",
660
	"psubsb",
661
	"psubsb",
661
	"psubsw",
662
	"psubsw",
662
	"psubusb",
663
	"psubusb",
663
	"psubusw",
664
	"psubusw",
664
	"psubw",
665
	"psubw",
665
	"ptest",
666
	"ptest",
666
	"ptwrite",
667
	"ptwrite",
667
	"punpckhbw",
668
	"punpckhbw",
668
	"punpckhdq",
669
	"punpckhdq",
669
	"punpckhqdq",
670
	"punpckhqdq",
670
	"punpckhwd",
671
	"punpckhwd",
671
	"punpcklbw",
672
	"punpcklbw",
672
	"punpckldq",
673
	"punpckldq",
673
	"punpcklqdq",
674
	"punpcklqdq",
674
	"punpcklwd",
675
	"punpcklwd",
675
	"push",
676
	"push",
676
	"pushw",
677
	"pushw",
677
	"pushd",
678
	"pushd",
678
	"pusha",
679
	"pusha",
679
	"pushad",
680
	"pushad",
680
	"pushf",
681
	"pushf",
681
	"pushfd",
682
	"pushfd",
682
	"pushfq",
683
	"pushfq",
683
	"pxor",
684
	"pxor",
684
	"rcl",
685
	"rcl",
685
	"rcpps",
686
	"rcpps",
686
	"rcpss",
687
	"rcpss",
687
	"rcr",
688
	"rcr",
688
	"rdfsbase",
689
	"rdfsbase",
689
	"rdgsbase",
690
	"rdgsbase",
690
	"rdmsr",
691
	"rdmsr",
691
	"rdpid",
692
	"rdpid",
692
	"rdpkru",
693
	"rdpkru",
693
	"rdpmc",
694
	"rdpmc",
694
	"rdrand",
695
	"rdrand",
695
	"rdseed",
696
	"rdseed",
696
	"rdtsc",
697
	"rdtsc",
697
	"rdtscp",
698
	"rdtscp",
698
	"rep",
699
	"rep",
699
	"repe",
700
	"repe",
700
	"repne",
701
	"repne",
701
	"repnz",
702
	"repnz",
702
	"repz",
703
	"repz",
703
	"ret",
704
	"ret",
704
	"rol",
705
	"rol",
705
	"ror",
706
	"ror",
706
	"rorx",
707
	"rorx",
707
	"roundpd",
708
	"roundpd",
708
	"roundps",
709
	"roundps",
709
	"roundsd",
710
	"roundsd",
710
	"roundss",
711
	"roundss",
711
	"rsm",
712
	"rsm",
712
	"rsqrtps",
713
	"rsqrtps",
713
	"rsqrtss",
714
	"rsqrtss",
714
	"sahf",
715
	"sahf",
715
	"sal",
716
	"sal",
716
	"sar",
717
	"sar",
717
	"sarx",
718
	"sarx",
718
	"sbb",
719
	"sbb",
719
	"scas",
720
	"scas",
720
	"scasb",
721
	"scasb",
721
	"scasd",
722
	"scasd",
722
	"scasw",
723
	"scasw",
723
	"seta",
724
	"seta",
724
	"setae",
725
	"setae",
725
	"setb",
726
	"setb",
726
	"setbe",
727
	"setbe",
727
	"setc",
728
	"setc",
728
	"sete",
729
	"sete",
729
	"setg",
730
	"setg",
730
	"setge",
731
	"setge",
731
	"setl",
732
	"setl",
732
	"setle",
733
	"setle",
733
	"setna",
734
	"setna",
734
	"setnae",
735
	"setnae",
735
	"setnb",
736
	"setnb",
736
	"setnbe",
737
	"setnbe",
737
	"setnc",
738
	"setnc",
738
	"setne",
739
	"setne",
739
	"setng",
740
	"setng",
740
	"setnge",
741
	"setnge",
741
	"setnl",
742
	"setnl",
742
	"setnle",
743
	"setnle",
743
	"setno",
744
	"setno",
744
	"setnp",
745
	"setnp",
745
	"setns",
746
	"setns",
746
	"setnz",
747
	"setnz",
747
	"seto",
748
	"seto",
748
	"setp",
749
	"setp",
749
	"setpe",
750
	"setpe",
750
	"setpo",
751
	"setpo",
751
	"sets",
752
	"sets",
752
	"setz",
753
	"setz",
753
	"sfence",
754
	"sfence",
754
	"sgdt",
755
	"sgdt",
755
	"sha1msg1",
756
	"sha1msg1",
756
	"sha1msg2",
757
	"sha1msg2",
757
	"sha1nexte",
758
	"sha1nexte",
758
	"sha1rnds4",
759
	"sha1rnds4",
759
	"sha256msg1",
760
	"sha256msg1",
760
	"sha256msg2",
761
	"sha256msg2",
761
	"sha256rnds2",
762
	"sha256rnds2",
762
	"shl",
763
	"shl",
763
	"shld",
764
	"shld",
764
	"shlx",
765
	"shlx",
765
	"shr",
766
	"shr",
766
	"shrd",
767
	"shrd",
767
	"shrx",
768
	"shrx",
768
	"shufpd",
769
	"shufpd",
769
	"shufps",
770
	"shufps",
770
	"sidt",
771
	"sidt",
771
	"sldt",
772
	"sldt",
772
	"smsw",
773
	"smsw",
773
	"sqrtpd",
774
	"sqrtpd",
774
	"sqrtps",
775
	"sqrtps",
775
	"sqrtsd",
776
	"sqrtsd",
776
	"sqrtss",
777
	"sqrtss",
777
	"stac",
778
	"stac",
778
	"stc",
779
	"stc",
779
	"std",
780
	"std",
780
	"sti",
781
	"sti",
781
	"stmxcsr",
782
	"stmxcsr",
782
	"stos",
783
	"stos",
783
	"stosb",
784
	"stosb",
784
	"stosd",
785
	"stosd",
785
	"stosq",
786
	"stosq",
786
	"stosw",
787
	"stosw",
787
	"str",
788
	"str",
788
	"sub",
789
	"sub",
789
	"subpd",
790
	"subpd",
790
	"subps",
791
	"subps",
791
	"subsd",
792
	"subsd",
792
	"subss",
793
	"subss",
793
	"swapgs",
794
	"swapgs",
794
	"syscall",
795
	"syscall",
795
	"sysenter",
796
	"sysenter",
796
	"sysexit",
797
	"sysexit",
797
	"sysret",
798
	"sysret",
798
	"test",
799
	"test",
799
	"tpause",
800
	"tpause",
800
	"tzcnt",
801
	"tzcnt",
801
	"ucomisd",
802
	"ucomisd",
802
	"ucomiss",
803
	"ucomiss",
803
	"ud",
804
	"ud",
804
	"umonitor",
805
	"umonitor",
805
	"umwait",
806
	"umwait",
806
	"unpckhpd",
807
	"unpckhpd",
807
	"unpckhps",
808
	"unpckhps",
808
	"unpcklpd",
809
	"unpcklpd",
809
	"unpcklps",
810
	"unpcklps",
810
	"valignd",
811
	"valignd",
811
	"valignq",
812
	"valignq",
812
	"vblendmpd",
813
	"vblendmpd",
813
	"vblendmps",
814
	"vblendmps",
814
	"vbroadcast",
815
	"vbroadcast",
815
	"vcompresspd",
816
	"vcompresspd",
816
	"vcompressps",
817
	"vcompressps",
817
	"vcvtpd2qq",
818
	"vcvtpd2qq",
818
	"vcvtpd2udq",
819
	"vcvtpd2udq",
819
	"vcvtpd2uqq",
820
	"vcvtpd2uqq",
820
	"vcvtph2ps",
821
	"vcvtph2ps",
821
	"vcvtps2ph",
822
	"vcvtps2ph",
822
	"vcvtps2qq",
823
	"vcvtps2qq",
823
	"vcvtps2udq",
824
	"vcvtps2udq",
824
	"vcvtps2uqq",
825
	"vcvtps2uqq",
825
	"vcvtqq2pd",
826
	"vcvtqq2pd",
826
	"vcvtqq2ps",
827
	"vcvtqq2ps",
827
	"vcvtsd2usi",
828
	"vcvtsd2usi",
828
	"vcvtss2usi",
829
	"vcvtss2usi",
829
	"vcvttpd2qq",
830
	"vcvttpd2qq",
830
	"vcvttpd2udq",
831
	"vcvttpd2udq",
831
	"vcvttpd2uqq",
832
	"vcvttpd2uqq",
832
	"vcvttps2qq",
833
	"vcvttps2qq",
833
	"vcvttps2udq",
834
	"vcvttps2udq",
834
	"vcvttps2uqq",
835
	"vcvttps2uqq",
835
	"vcvttsd2usi",
836
	"vcvttsd2usi",
836
	"vcvttss2usi",
837
	"vcvttss2usi",
837
	"vcvtudq2pd",
838
	"vcvtudq2pd",
838
	"vcvtudq2ps",
839
	"vcvtudq2ps",
839
	"vcvtuqq2pd",
840
	"vcvtuqq2pd",
840
	"vcvtuqq2ps",
841
	"vcvtuqq2ps",
841
	"vcvtusi2sd",
842
	"vcvtusi2sd",
842
	"vcvtusi2ss",
843
	"vcvtusi2ss",
843
	"vdbpsadbw",
844
	"vdbpsadbw",
844
	"verr",
845
	"verr",
845
	"verw",
846
	"verw",
846
	"vexpandpd",
847
	"vexpandpd",
847
	"vexpandps",
848
	"vexpandps",
848
	"vextractf128",
849
	"vextractf128",
849
	"vextractf32x4",
850
	"vextractf32x4",
850
	"vextractf32x8",
851
	"vextractf32x8",
851
	"vextractf64x2",
852
	"vextractf64x2",
852
	"vextractf64x4",
853
	"vextractf64x4",
853
	"vextracti128",
854
	"vextracti128",
854
	"vextracti32x4",
855
	"vextracti32x4",
855
	"vextracti32x8",
856
	"vextracti32x8",
856
	"vextracti64x2",
857
	"vextracti64x2",
857
	"vextracti64x4",
858
	"vextracti64x4",
858
	"vfixupimmpd",
859
	"vfixupimmpd",
859
	"vfixupimmps",
860
	"vfixupimmps",
860
	"vfixupimmsd",
861
	"vfixupimmsd",
861
	"vfixupimmss",
862
	"vfixupimmss",
862
	"vfmadd132pd",
863
	"vfmadd132pd",
863
	"vfmadd132ps",
864
	"vfmadd132ps",
864
	"vfmadd132sd",
865
	"vfmadd132sd",
865
	"vfmadd132ss",
866
	"vfmadd132ss",
866
	"vfmadd213pd",
867
	"vfmadd213pd",
867
	"vfmadd213ps",
868
	"vfmadd213ps",
868
	"vfmadd213sd",
869
	"vfmadd213sd",
869
	"vfmadd213ss",
870
	"vfmadd213ss",
870
	"vfmadd231pd",
871
	"vfmadd231pd",
871
	"vfmadd231ps",
872
	"vfmadd231ps",
872
	"vfmadd231sd",
873
	"vfmadd231sd",
873
	"vfmadd231ss",
874
	"vfmadd231ss",
874
	"vfmaddsub132pd",
875
	"vfmaddsub132pd",
875
	"vfmaddsub132ps",
876
	"vfmaddsub132ps",
876
	"vfmaddsub213pd",
877
	"vfmaddsub213pd",
877
	"vfmaddsub213ps",
878
	"vfmaddsub213ps",
878
	"vfmaddsub231pd",
879
	"vfmaddsub231pd",
879
	"vfmaddsub231ps",
880
	"vfmaddsub231ps",
880
	"vfmsub132pd",
881
	"vfmsub132pd",
881
	"vfmsub132ps",
882
	"vfmsub132ps",
882
	"vfmsub132sd",
883
	"vfmsub132sd",
883
	"vfmsub132ss",
884
	"vfmsub132ss",
884
	"vfmsub213pd",
885
	"vfmsub213pd",
885
	"vfmsub213ps",
886
	"vfmsub213ps",
886
	"vfmsub213sd",
887
	"vfmsub213sd",
887
	"vfmsub213ss",
888
	"vfmsub213ss",
888
	"vfmsub231pd",
889
	"vfmsub231pd",
889
	"vfmsub231ps",
890
	"vfmsub231ps",
890
	"vfmsub231sd",
891
	"vfmsub231sd",
891
	"vfmsub231ss",
892
	"vfmsub231ss",
892
	"vfmsubadd132pd",
893
	"vfmsubadd132pd",
893
	"vfmsubadd132ps",
894
	"vfmsubadd132ps",
894
	"vfmsubadd213pd",
895
	"vfmsubadd213pd",
895
	"vfmsubadd213ps",
896
	"vfmsubadd213ps",
896
	"vfmsubadd231pd",
897
	"vfmsubadd231pd",
897
	"vfmsubadd231ps",
898
	"vfmsubadd231ps",
898
	"vfnmadd132pd",
899
	"vfnmadd132pd",
899
	"vfnmadd132ps",
900
	"vfnmadd132ps",
900
	"vfnmadd132sd",
901
	"vfnmadd132sd",
901
	"vfnmadd132ss",
902
	"vfnmadd132ss",
902
	"vfnmadd213pd",
903
	"vfnmadd213pd",
903
	"vfnmadd213ps",
904
	"vfnmadd213ps",
904
	"vfnmadd213sd",
905
	"vfnmadd213sd",
905
	"vfnmadd213ss",
906
	"vfnmadd213ss",
906
	"vfnmadd231pd",
907
	"vfnmadd231pd",
907
	"vfnmadd231ps",
908
	"vfnmadd231ps",
908
	"vfnmadd231sd",
909
	"vfnmadd231sd",
909
	"vfnmadd231ss",
910
	"vfnmadd231ss",
910
	"vfnmsub132pd",
911
	"vfnmsub132pd",
911
	"vfnmsub132ps",
912
	"vfnmsub132ps",
912
	"vfnmsub132sd",
913
	"vfnmsub132sd",
913
	"vfnmsub132ss",
914
	"vfnmsub132ss",
914
	"vfnmsub213pd",
915
	"vfnmsub213pd",
915
	"vfnmsub213ps",
916
	"vfnmsub213ps",
916
	"vfnmsub213sd",
917
	"vfnmsub213sd",
917
	"vfnmsub213ss",
918
	"vfnmsub213ss",
918
	"vfnmsub231pd",
919
	"vfnmsub231pd",
919
	"vfnmsub231ps",
920
	"vfnmsub231ps",
920
	"vfnmsub231sd",
921
	"vfnmsub231sd",
921
	"vfnmsub231ss",
922
	"vfnmsub231ss",
922
	"vfpclasspd",
923
	"vfpclasspd",
923
	"vfpclassps",
924
	"vfpclassps",
924
	"vfpclasssd",
925
	"vfpclasssd",
925
	"vfpclassss",
926
	"vfpclassss",
926
	"vgatherdpd",
927
	"vgatherdpd",
927
	"vgatherdpd",
928
	"vgatherdpd",
928
	"vgatherdps",
929
	"vgatherdps",
929
	"vgatherdps",
930
	"vgatherdps",
930
	"vgatherqpd",
931
	"vgatherqpd",
931
	"vgatherqpd",
932
	"vgatherqpd",
932
	"vgatherqps",
933
	"vgatherqps",
933
	"vgatherqps",
934
	"vgatherqps",
934
	"vgetexppd",
935
	"vgetexppd",
935
	"vgetexpps",
936
	"vgetexpps",
936
	"vgetexpsd",
937
	"vgetexpsd",
937
	"vgetexpss",
938
	"vgetexpss",
938
	"vgetmantpd",
939
	"vgetmantpd",
939
	"vgetmantps",
940
	"vgetmantps",
940
	"vgetmantsd",
941
	"vgetmantsd",
941
	"vgetmantss",
942
	"vgetmantss",
942
	"vinsertf128",
943
	"vinsertf128",
943
	"vinsertf32x4",
944
	"vinsertf32x4",
944
	"vinsertf32x8",
945
	"vinsertf32x8",
945
	"vinsertf64x2",
946
	"vinsertf64x2",
946
	"vinsertf64x4",
947
	"vinsertf64x4",
947
	"vinserti128",
948
	"vinserti128",
948
	"vinserti32x4",
949
	"vinserti32x4",
949
	"vinserti32x8",
950
	"vinserti32x8",
950
	"vinserti64x2",
951
	"vinserti64x2",
951
	"vinserti64x4",
952
	"vinserti64x4",
952
	"vmaskmov",
953
	"vmaskmov",
953
	"vmovdqa32",
954
	"vmovdqa32",
954
	"vmovdqa64",
955
	"vmovdqa64",
955
	"vmovdqu16",
956
	"vmovdqu16",
956
	"vmovdqu32",
957
	"vmovdqu32",
957
	"vmovdqu64",
958
	"vmovdqu64",
958
	"vmovdqu8",
959
	"vmovdqu8",
959
	"vpblendd",
960
	"vpblendd",
960
	"vpblendmb",
961
	"vpblendmb",
961
	"vpblendmd",
962
	"vpblendmd",
962
	"vpblendmq",
963
	"vpblendmq",
963
	"vpblendmw",
964
	"vpblendmw",
964
	"vpbroadcast",
965
	"vpbroadcast",
965
	"vpbroadcastb",
966
	"vpbroadcastb",
966
	"vpbroadcastd",
967
	"vpbroadcastd",
967
	"vpbroadcastm",
968
	"vpbroadcastm",
968
	"vpbroadcastq",
969
	"vpbroadcastq",
969
	"vpbroadcastw",
970
	"vpbroadcastw",
970
	"vpcmpb",
971
	"vpcmpb",
971
	"vpcmpd",
972
	"vpcmpd",
972
	"vpcmpq",
973
	"vpcmpq",
973
	"vpcmpub",
974
	"vpcmpub",
974
	"vpcmpud",
975
	"vpcmpud",
975
	"vpcmpuq",
976
	"vpcmpuq",
976
	"vpcmpuw",
977
	"vpcmpuw",
977
	"vpcmpw",
978
	"vpcmpw",
978
	"vpcompressd",
979
	"vpcompressd",
979
	"vpcompressq",
980
	"vpcompressq",
980
	"vpconflictd",
981
	"vpconflictd",
981
	"vpconflictq",
982
	"vpconflictq",
982
	"vperm2f128",
983
	"vperm2f128",
983
	"vperm2i128",
984
	"vperm2i128",
984
	"vpermb",
985
	"vpermb",
985
	"vpermd",
986
	"vpermd",
986
	"vpermi2b",
987
	"vpermi2b",
987
	"vpermi2d",
988
	"vpermi2d",
988
	"vpermi2pd",
989
	"vpermi2pd",
989
	"vpermi2ps",
990
	"vpermi2ps",
990
	"vpermi2q",
991
	"vpermi2q",
991
	"vpermi2w",
992
	"vpermi2w",
992
	"vpermilpd",
993
	"vpermilpd",
993
	"vpermilps",
994
	"vpermilps",
994
	"vpermpd",
995
	"vpermpd",
995
	"vpermps",
996
	"vpermps",
996
	"vpermq",
997
	"vpermq",
997
	"vpermt2b",
998
	"vpermt2b",
998
	"vpermt2d",
999
	"vpermt2d",
999
	"vpermt2pd",
1000
	"vpermt2pd",
1000
	"vpermt2ps",
1001
	"vpermt2ps",
1001
	"vpermt2q",
1002
	"vpermt2q",
1002
	"vpermt2w",
1003
	"vpermt2w",
1003
	"vpermw",
1004
	"vpermw",
1004
	"vpexpandd",
1005
	"vpexpandd",
1005
	"vpexpandq",
1006
	"vpexpandq",
1006
	"vpgatherdd",
1007
	"vpgatherdd",
1007
	"vpgatherdd",
1008
	"vpgatherdd",
1008
	"vpgatherdq",
1009
	"vpgatherdq",
1009
	"vpgatherdq",
1010
	"vpgatherdq",
1010
	"vpgatherqd",
1011
	"vpgatherqd",
1011
	"vpgatherqd",
1012
	"vpgatherqd",
1012
	"vpgatherqq",
1013
	"vpgatherqq",
1013
	"vpgatherqq",
1014
	"vpgatherqq",
1014
	"vplzcntd",
1015
	"vplzcntd",
1015
	"vplzcntq",
1016
	"vplzcntq",
1016
	"vpmadd52huq",
1017
	"vpmadd52huq",
1017
	"vpmadd52luq",
1018
	"vpmadd52luq",
1018
	"vpmaskmov",
1019
	"vpmaskmov",
1019
	"vpmovb2m",
1020
	"vpmovb2m",
1020
	"vpmovd2m",
1021
	"vpmovd2m",
1021
	"vpmovdb",
1022
	"vpmovdb",
1022
	"vpmovdw",
1023
	"vpmovdw",
1023
	"vpmovm2b",
1024
	"vpmovm2b",
1024
	"vpmovm2d",
1025
	"vpmovm2d",
1025
	"vpmovm2q",
1026
	"vpmovm2q",
1026
	"vpmovm2w",
1027
	"vpmovm2w",
1027
	"vpmovq2m",
1028
	"vpmovq2m",
1028
	"vpmovqb",
1029
	"vpmovqb",
1029
	"vpmovqd",
1030
	"vpmovqd",
1030
	"vpmovqw",
1031
	"vpmovqw",
1031
	"vpmovsdb",
1032
	"vpmovsdb",
1032
	"vpmovsdw",
1033
	"vpmovsdw",
1033
	"vpmovsqb",
1034
	"vpmovsqb",
1034
	"vpmovsqd",
1035
	"vpmovsqd",
1035
	"vpmovsqw",
1036
	"vpmovsqw",
1036
	"vpmovswb",
1037
	"vpmovswb",
1037
	"vpmovusdb",
1038
	"vpmovusdb",
1038
	"vpmovusdw",
1039
	"vpmovusdw",
1039
	"vpmovusqb",
1040
	"vpmovusqb",
1040
	"vpmovusqd",
1041
	"vpmovusqd",
1041
	"vpmovusqw",
1042
	"vpmovusqw",
1042
	"vpmovuswb",
1043
	"vpmovuswb",
1043
	"vpmovw2m",
1044
	"vpmovw2m",
1044
	"vpmovwb",
1045
	"vpmovwb",
1045
	"vpmultishiftqb",
1046
	"vpmultishiftqb",
1046
	"vprold",
1047
	"vprold",
1047
	"vprolq",
1048
	"vprolq",
1048
	"vprolvd",
1049
	"vprolvd",
1049
	"vprolvq",
1050
	"vprolvq",
1050
	"vprord",
1051
	"vprord",
1051
	"vprorq",
1052
	"vprorq",
1052
	"vprorvd",
1053
	"vprorvd",
1053
	"vprorvq",
1054
	"vprorvq",
1054
	"vpscatterdd",
1055
	"vpscatterdd",
1055
	"vpscatterdq",
1056
	"vpscatterdq",
1056
	"vpscatterqd",
1057
	"vpscatterqd",
1057
	"vpscatterqq",
1058
	"vpscatterqq",
1058
	"vpsllvd",
1059
	"vpsllvd",
1059
	"vpsllvq",
1060
	"vpsllvq",
1060
	"vpsllvw",
1061
	"vpsllvw",
1061
	"vpsravd",
1062
	"vpsravd",
1062
	"vpsravq",
1063
	"vpsravq",
1063
	"vpsravw",
1064
	"vpsravw",
1064
	"vpsrlvd",
1065
	"vpsrlvd",
1065
	"vpsrlvq",
1066
	"vpsrlvq",
1066
	"vpsrlvw",
1067
	"vpsrlvw",
1067
	"vpternlogd",
1068
	"vpternlogd",
1068
	"vpternlogq",
1069
	"vpternlogq",
1069
	"vptestmb",
1070
	"vptestmb",
1070
	"vptestmd",
1071
	"vptestmd",
1071
	"vptestmq",
1072
	"vptestmq",
1072
	"vptestmw",
1073
	"vptestmw",
1073
	"vptestnmb",
1074
	"vptestnmb",
1074
	"vptestnmd",
1075
	"vptestnmd",
1075
	"vptestnmq",
1076
	"vptestnmq",
1076
	"vptestnmw",
1077
	"vptestnmw",
1077
	"vrangepd",
1078
	"vrangepd",
1078
	"vrangeps",
1079
	"vrangeps",
1079
	"vrangesd",
1080
	"vrangesd",
1080
	"vrangess",
1081
	"vrangess",
1081
	"vrcp14pd",
1082
	"vrcp14pd",
1082
	"vrcp14ps",
1083
	"vrcp14ps",
1083
	"vrcp14sd",
1084
	"vrcp14sd",
1084
	"vrcp14ss",
1085
	"vrcp14ss",
1085
	"vreducepd",
1086
	"vreducepd",
1086
	"vreduceps",
1087
	"vreduceps",
1087
	"vreducesd",
1088
	"vreducesd",
1088
	"vreducess",
1089
	"vreducess",
1089
	"vrndscalepd",
1090
	"vrndscalepd",
1090
	"vrndscaleps",
1091
	"vrndscaleps",
1091
	"vrndscalesd",
1092
	"vrndscalesd",
1092
	"vrndscaless",
1093
	"vrndscaless",
1093
	"vrsqrt14pd",
1094
	"vrsqrt14pd",
1094
	"vrsqrt14ps",
1095
	"vrsqrt14ps",
1095
	"vrsqrt14sd",
1096
	"vrsqrt14sd",
1096
	"vrsqrt14ss",
1097
	"vrsqrt14ss",
1097
	"vscalefpd",
1098
	"vscalefpd",
1098
	"vscalefps",
1099
	"vscalefps",
1099
	"vscalefsd",
1100
	"vscalefsd",
1100
	"vscalefss",
1101
	"vscalefss",
1101
	"vscatterdpd",
1102
	"vscatterdpd",
1102
	"vscatterdps",
1103
	"vscatterdps",
1103
	"vscatterqpd",
1104
	"vscatterqpd",
1104
	"vscatterqps",
1105
	"vscatterqps",
1105
	"vshuff32x4",
1106
	"vshuff32x4",
1106
	"vshuff64x2",
1107
	"vshuff64x2",
1107
	"vshufi32x4",
1108
	"vshufi32x4",
1108
	"vshufi64x2",
1109
	"vshufi64x2",
1109
	"vtestpd",
1110
	"vtestpd",
1110
	"vtestps",
1111
	"vtestps",
1111
	"vzeroall",
1112
	"vzeroall",
1112
	"vzeroupper",
1113
	"vzeroupper",
1113
	"wait",
1114
	"wait",
1114
	"wbinvd",
1115
	"wbinvd",
1115
	"wrfsbase",
1116
	"wrfsbase",
1116
	"wrgsbase",
1117
	"wrgsbase",
1117
	"wrmsr",
1118
	"wrmsr",
1118
	"wrpkru",
1119
	"wrpkru",
1119
	"xabort",
1120
	"xabort",
1120
	"xacquire",
1121
	"xacquire",
1121
	"xadd",
1122
	"xadd",
1122
	"xbegin",
1123
	"xbegin",
1123
	"xchg",
1124
	"xchg",
1124
	"xend",
1125
	"xend",
1125
	"xgetbv",
1126
	"xgetbv",
1126
	"xlat",
1127
	"xlat",
1127
	"xlatb",
1128
	"xlatb",
1128
	"xor",
1129
	"xor",
1129
	"xorpd",
1130
	"xorpd",
1130
	"xorps",
1131
	"xorps",
1131
	"xrelease",
1132
	"xrelease",
1132
	"xrstor",
1133
	"xrstor",
1133
	"xrstors",
1134
	"xrstors",
1134
	"xsave",
1135
	"xsave",
1135
	"xsavec",
1136
	"xsavec",
1136
	"xsaveopt",
1137
	"xsaveopt",
1137
	"xsaves",
1138
	"xsaves",
1138
	"xsetbv",
1139
	"xsetbv",
1139
	"xtest"
1140
	"xtest"
1140
]
1141
]
1141
 
1142
 
1142
fasm_types = [
1143
fasm_types = [
1143
	"db", "rb",
1144
	"db", "rb",
1144
	"dw", "rw",
1145
	"dw", "rw",
1145
	"dd", "rd",
1146
	"dd", "rd",
1146
	"dp", "rp",
1147
	"dp", "rp",
1147
	"df", "rf",
1148
	"df", "rf",
1148
	"dq", "rq",
1149
	"dq", "rq",
1149
	"dt", "rt",
1150
	"dt", "rt",
1150
	"du",
1151
	"du",
1151
]
1152
]
1152
 
1153
 
1153
# Dict where an identifier is assicoated with a string
1154
# Dict where an identifier is assicoated with a string
1154
# The string contains characters specifying flags
1155
# The string contains characters specifying flags
1155
# Available flags:
1156
# Available flags:
1156
#  k - Keyword
1157
#  k - Keyword
1157
#  m - Macro name
1158
#  m - Macro name
1158
#  t - fasm data Type name (db, rq, etc.)
1159
#  t - fasm data Type name (db, rq, etc.)
1159
#  s - Struct type name
1160
#  s - Struct type name
1160
#  e - equated constant (name equ value)
1161
#  e - equated constant (name equ value)
1161
#  = - set constants (name = value)
1162
#  = - set constants (name = value)
1162
ID_KIND_KEYWORD = 'k'
1163
ID_KIND_KEYWORD = 'k'
1163
ID_KIND_MACRO_NAME = 'm'
1164
ID_KIND_MACRO_NAME = 'm'
1164
ID_KIND_FASM_TYPE = 't'
1165
ID_KIND_FASM_TYPE = 't'
1165
ID_KIND_STRUCT_NAME = 's'
1166
ID_KIND_STRUCT_NAME = 's'
1166
ID_KIND_EQUATED_CONSTANT = 'e'
1167
ID_KIND_EQUATED_CONSTANT = 'e'
1167
ID_KIND_SET_CONSTANT = '='
1168
ID_KIND_SET_CONSTANT = '='
1168
id2kind = {}
1169
id2kind = {}
1169
 
1170
 
1170
# Add kind flag to identifier in id2kind
1171
# Add kind flag to identifier in id2kind
1171
def id_add_kind(identifier, kind):
1172
def id_add_kind(identifier, kind):
1172
	if identifier not in id2kind:
1173
	if identifier not in id2kind:
1173
		id2kind[identifier] = ''
1174
		id2kind[identifier] = ''
1174
	id2kind[identifier] += kind
1175
	id2kind[identifier] += kind
1175
 
1176
 
1176
# Remove kind flag of identifier in id2kind
1177
# Remove kind flag of identifier in id2kind
1177
def id_remove_kind(identifier, kind):
1178
def id_remove_kind(identifier, kind):
1178
	if identifier in id2kind:
1179
	if identifier in id2kind:
1179
		if kind in id2kind[identifier]:
1180
		if kind in id2kind[identifier]:
1180
			id2kind[identifier] = id2kind[identifier].replace(kind, '')
1181
			id2kind[identifier] = id2kind[identifier].replace(kind, '')
1181
 
1182
 
1182
# Get kind of an identifier
1183
# Get kind of an identifier
1183
def id_get_kind(identifier):
1184
def id_get_kind(identifier):
1184
	if identifier in id2kind:
1185
	if identifier in id2kind:
1185
		return id2kind[identifier]
1186
		return id2kind[identifier]
1186
	else:
1187
	else:
1187
		return ''
1188
		return ''
1188
 
1189
 
1189
for keyword in keywords:
1190
for keyword in keywords:
1190
	id_add_kind(keyword, ID_KIND_KEYWORD)
1191
	id_add_kind(keyword, ID_KIND_KEYWORD)
1191
 
1192
 
1192
for fasm_type in fasm_types:
1193
for fasm_type in fasm_types:
1193
	id_add_kind(fasm_type, ID_KIND_FASM_TYPE)
1194
	id_add_kind(fasm_type, ID_KIND_FASM_TYPE)
1194
 
1195
 
1195
# Warning list
1196
# Warning list
1196
warnings = ""
1197
warnings = ""
1197
 
1198
 
1198
# Parse arguments
1199
# Parse arguments
1199
parser = argparse.ArgumentParser()
1200
parser = argparse.ArgumentParser()
1200
parser.add_argument("-o", help="Doxygen output folder")
1201
parser.add_argument("-o", help="Doxygen output folder")
1201
parser.add_argument("--clean", help="Remove generated files", action="store_true")
1202
parser.add_argument("--clean", help="Remove generated files", action="store_true")
1202
parser.add_argument("--dump", help="Dump all defined symbols", action="store_true")
1203
parser.add_argument("--dump", help="Dump all defined symbols", action="store_true")
1203
parser.add_argument("--stats", help="Print symbol stats", action="store_true")
1204
parser.add_argument("--stats", help="Print symbol stats", action="store_true")
1204
parser.add_argument("--nowarn", help="Do not write warnings file", action="store_true")
1205
parser.add_argument("--nowarn", help="Do not write warnings file", action="store_true")
1205
parser.add_argument("--noemit", help="Do not emit doxygen files (for testing)", action="store_true")
1206
parser.add_argument("--noemit", help="Do not emit doxygen files (for testing)", action="store_true")
1206
args = parser.parse_args()
1207
args = parser.parse_args()
1207
doxygen_src_path = args.o if args.o else 'docs/doxygen'
1208
doxygen_src_path = args.o if args.o else 'docs/doxygen'
1208
clean_generated_stuff = args.clean
1209
clean_generated_stuff = args.clean
1209
dump_symbols = args.dump
1210
dump_symbols = args.dump
1210
print_stats = args.stats
1211
print_stats = args.stats
1211
enable_warnings = not args.nowarn
1212
enable_warnings = not args.nowarn
1212
noemit = args.noemit
1213
noemit = args.noemit
1213
 
1214
 
1214
# Variables, functions, labels, macros, structure types
1215
# Variables, functions, labels, macros, structure types
1215
elements = []
1216
elements = []
1216
 
1217
 
1217
class LegacyAsmReader:
1218
class LegacyAsmReader:
1218
	def __init__(self, file):
1219
	def __init__(self, file):
1219
		self.file = file
1220
		self.file = file
1220
		self.lines = open(file, "r", encoding="utf-8").readlines()
1221
		self.lines = open(file, "r", encoding="utf-8").readlines()
1221
		self.line_idx = 0
1222
		self.line_idx = 0
1222
		self.i = 0
1223
		self.i = 0
1223
 
1224
 
1224
	def curr(self):
1225
	def curr(self):
1225
		try: return self.lines[self.line_idx][self.i]
1226
		try: return self.lines[self.line_idx][self.i]
1226
		except: return ''
1227
		except: return ''
1227
 
1228
 
1228
	def step(self):
1229
	def step(self):
1229
		c = self.curr()
1230
		c = self.curr()
1230
		self.i += 1
1231
		self.i += 1
1231
		# Wrap the line if '\\' followed by whitespaces and/or comment
1232
		# Wrap the line if '\\' followed by whitespaces and/or comment
1232
		while self.curr() == '\\':
1233
		while self.curr() == '\\':
1233
			i_of_backslash = self.i
1234
			i_of_backslash = self.i
1234
			self.i += 1
1235
			self.i += 1
1235
			while self.curr().isspace():
1236
			while self.curr().isspace():
1236
				self.i += 1
1237
				self.i += 1
1237
			if self.curr() == ';' or self.curr() == '':
1238
			if self.curr() == ';' or self.curr() == '':
1238
				self.line_idx += 1
1239
				self.line_idx += 1
1239
				self.i = 0
1240
				self.i = 0
1240
			else:
1241
			else:
1241
				# There's something other than a comment after the backslash
1242
				# There's something other than a comment after the backslash
1242
				# So don't interpret the backslash as a line wrap
1243
				# So don't interpret the backslash as a line wrap
1243
				self.i = i_of_backslash
1244
				self.i = i_of_backslash
1244
				break
1245
				break
1245
		return c
1246
		return c
1246
 
1247
 
1247
	def nextline(self):
1248
	def nextline(self):
1248
		c = self.curr()
1249
		c = self.curr()
1249
		while c != '':
1250
		while c != '':
1250
			c = self.step()
1251
			c = self.step()
1251
		self.line_idx += 1
1252
		self.line_idx += 1
1252
		self.i = 0
1253
		self.i = 0
1253
 
1254
 
1254
	def no_lines(self):
1255
	def no_lines(self):
1255
		if self.line_idx >= len(self.lines):
1256
		if self.line_idx >= len(self.lines):
1256
			return True
1257
			return True
1257
		return False
1258
		return False
1258
 
1259
 
1259
	def location(self):	
1260
	def location(self):	
1260
		return f"{self.file}:{self.line_idx + 1}"
1261
		return f"{self.file}:{self.line_idx + 1}"
1261
 
1262
 
1262
	def skip_spaces(self):
1263
	def skip_spaces(self):
1263
		while self.curr().isspace():
1264
		while self.curr().isspace():
1264
			self.step()
1265
			self.step()
1265
 
1266
 
1266
class AsmReaderRecognizingStrings(LegacyAsmReader):
1267
class AsmReaderRecognizingStrings(LegacyAsmReader):
1267
	def __init__(self, file):
1268
	def __init__(self, file):
1268
		super().__init__(file)
1269
		super().__init__(file)
1269
		self.in_string = None
1270
		self.in_string = None
1270
		self.should_recognize_strings = True
1271
		self.should_recognize_strings = True
1271
 
1272
 
1272
	def step(self):
1273
	def step(self):
1273
		c = super().step()
1274
		c = super().step()
1274
		if self.should_recognize_strings and (c == '"' or c == "'"):
1275
		if self.should_recognize_strings and (c == '"' or c == "'"):
1275
			# If just now we was at the double or single quotation mark
1276
			# If just now we was at the double or single quotation mark
1276
			# and we aren't in a string yet
1277
			# and we aren't in a string yet
1277
			# then say "we are in a string openned with this quotation mark now"
1278
			# then say "we are in a string openned with this quotation mark now"
1278
			if self.in_string == None:
1279
			if self.in_string == None:
1279
				self.in_string = c
1280
				self.in_string = c
1280
			# If just now we was at the double or single quotation mark
1281
			# If just now we was at the double or single quotation mark
1281
			# and we are in the string entered with the same quotation mark
1282
			# and we are in the string entered with the same quotation mark
1282
			# then say "we aren't in a string anymore"
1283
			# then say "we aren't in a string anymore"
1283
			elif self.in_string == c:
1284
			elif self.in_string == c:
1284
				self.in_string = None
1285
				self.in_string = None
1285
		return c
1286
		return c
1286
 
1287
 
1287
class AsmReaderReadingComments(AsmReaderRecognizingStrings):
1288
class AsmReaderReadingComments(AsmReaderRecognizingStrings):
1288
	def __init__(self, file):
1289
	def __init__(self, file):
1289
		super().__init__(file)
1290
		super().__init__(file)
1290
		self.status = dict()
1291
		self.status = dict()
1291
		self.status_reset()
1292
		self.status_reset()
1292
		self.comment = ''
1293
		self.comment = ''
1293
 
1294
 
1294
	def status_reset(self):
1295
	def status_reset(self):
1295
		# If the line has non-comment code
1296
		# If the line has non-comment code
1296
		self.status_has_code = False
1297
		self.status_has_code = False
1297
		# If the line has a comment at the end
1298
		# If the line has a comment at the end
1298
		self.status_has_comment = False
1299
		self.status_has_comment = False
1299
		# Let it recognize strings further, we are definitely out of a comment
1300
		# Let it recognize strings further, we are definitely out of a comment
1300
		self.should_recognize_strings = True
1301
		self.should_recognize_strings = True
1301
 
1302
 
1302
	def status_set_has_comment(self):
1303
	def status_set_has_comment(self):
1303
		self.status_has_comment = True
1304
		self.status_has_comment = True
1304
		# Don't let it recognize strings cause we are in a comment now
1305
		# Don't let it recognize strings cause we are in a comment now
1305
		self.should_recognize_strings = False
1306
		self.should_recognize_strings = False
1306
 
1307
 
1307
	def status_set_has_code(self):
1308
	def status_set_has_code(self):
1308
		self.status_has_code = True
1309
		self.status_has_code = True
1309
 
1310
 
1310
	def update_status(self):
1311
	def update_status(self):
1311
		# If we aren't in a comment and we aren't in a string - say we are now in a comment if ';' met
1312
		# If we aren't in a comment and we aren't in a string - say we are now in a comment if ';' met
1312
		if not self.status_has_comment and not self.in_string and self.curr() == ';':
1313
		if not self.status_has_comment and not self.in_string and self.curr() == ';':
1313
			self.status_set_has_comment()
1314
			self.status_set_has_comment()
1314
		# Else if we are in a comment - collect the comment
1315
		# Else if we are in a comment - collect the comment
1315
		elif self.status_has_comment:
1316
		elif self.status_has_comment:
1316
			self.comment += self.curr()
1317
			self.comment += self.curr()
1317
		# Else if there's some non-whitespace character out of a comment
1318
		# Else if there's some non-whitespace character out of a comment
1318
		# then the line has code
1319
		# then the line has code
1319
		elif not self.status_has_comment and not self.curr().isspace():
1320
		elif not self.status_has_comment and not self.curr().isspace():
1320
			self.status_set_has_code()
1321
			self.status_set_has_code()
1321
 
1322
 
1322
	def step(self):
1323
	def step(self):
1323
		# Get to the next character
1324
		# Get to the next character
1324
		c = super().step()
1325
		c = super().step()
1325
		# Update status of the line according to the next character
1326
		# Update status of the line according to the next character
1326
		self.update_status()
1327
		self.update_status()
1327
		return c
1328
		return c
1328
 
1329
 
1329
	def nextline(self):
1330
	def nextline(self):
1330
		super().nextline()
1331
		super().nextline()
1331
		# If the line we leave was not a comment-only line
1332
		# If the line we leave was not a comment-only line
1332
		# then forget the collected comment
1333
		# then forget the collected comment
1333
		# Otherwise the collected comment should be complemented by comment from next line in step()
1334
		# Otherwise the collected comment should be complemented by comment from next line in step()
1334
		if self.status_has_code:
1335
		if self.status_has_code:
1335
			self.comment = ''
1336
			self.comment = ''
1336
		# Reset the line status (now it's the status of the new line)
1337
		# Reset the line status (now it's the status of the new line)
1337
		self.status_reset()
1338
		self.status_reset()
1338
		# Set new status for this line according to the first character in the line
1339
		# Set new status for this line according to the first character in the line
1339
		self.update_status()
1340
		self.update_status()
1340
 
1341
 
1341
class AsmReaderFetchingIdentifiers(AsmReaderReadingComments):
1342
class AsmReaderFetchingIdentifiers(AsmReaderReadingComments):
1342
	def __init__(self, file):
1343
	def __init__(self, file):
1343
		super().__init__(file)
1344
		super().__init__(file)
1344
 
1345
 
1345
	def fetch_identifier(self):
1346
	def fetch_identifier(self):
1346
		self.skip_spaces()
1347
		self.skip_spaces()
1347
		result = ''
1348
		result = ''
1348
		while is_id(self.curr()):
1349
		while is_id(self.curr()):
1349
			result += self.step()
1350
			result += self.step()
1350
		return result
1351
		return result
1351
 
1352
 
1352
class AsmReader(AsmReaderFetchingIdentifiers):
1353
class AsmReader(AsmReaderFetchingIdentifiers):
1353
	def __init__(self, file):
1354
	def __init__(self, file):
1354
		super().__init__(file)
1355
		super().__init__(file)
1355
 
1356
 
1356
created_files = []
1357
created_files = []
1357
 
1358
 
1358
class AsmElement:
1359
class AsmElement:
1359
	def __init__(self, location, name, comment):
1360
	def __init__(self, location, name, comment):
1360
		global warnings
1361
		global warnings
-
 
1362
 
-
 
1363
		# If the element was constructed during this execution then the element is new
1361
 
1364
		self.new = True
1362
		self.location = location
1365
		self.location = location
1363
		self.file = self.location.split(':')[0].replace('\\', '/')
1366
		self.file = self.location.split(':')[0].replace('\\', '/')
1364
		self.line = self.location.split(':')[1]
1367
		self.line = self.location.split(':')[1]
1365
		self.name = name
1368
		self.name = name
1366
		self.comment = comment
1369
		self.comment = comment
1367
 
1370
 
1368
		if self.comment == '':
1371
		if self.comment == '':
1369
			warnings += f'{self.location}: Undocumented element\n'
1372
			warnings += f'{self.location}: Undocumented element\n'
1370
 
1373
 
1371
	def dump(self):
1374
	def dump(self):
1372
		print(f"{self.comment}")
1375
		print(f"{self.comment}")
1373
		print(f"{self.location}: {self.name}")
1376
		print(f"{self.location}: {self.name}")
1374
 
1377
 
1375
	def emit(self, dest, doxycomment = '', declaration = ''):
1378
	def emit(self, dest, doxycomment = '', declaration = ''):
1376
		# Do not emit anything if the symbol is marked as hidden in its comment
1379
		# Do not emit anything if the symbol is marked as hidden in its comment
1377
		if '@dont_give_a_doxygen' in self.comment:
1380
		if '@dont_give_a_doxygen' in self.comment:
1378
			return
1381
			return
1379
 
1382
 
1380
		global warnings
1383
		global warnings
1381
		# Redefine default declaration
1384
		# Redefine default declaration
1382
		if declaration == '':
1385
		if declaration == '':
1383
			declaration = f'#define {self.name}'
1386
			declaration = f'#define {self.name}'
1384
		# Check doxycomment
1387
		# Check doxycomment
1385
		if not doxycomment.endswith('\n'):
1388
		if not doxycomment.endswith('\n'):
1386
			doxycomment += '\n'
1389
			doxycomment += '\n'
1387
		if doxycomment.split('@brief ')[1][0].islower():
1390
		if doxycomment.split('@brief ')[1][0].islower():
1388
			warnings += f"{self.location}: Brief comment starting from lowercase\n"
1391
			warnings += f"{self.location}: Brief comment starting from lowercase\n"
1389
		# Build contents to emit
1392
		# Build contents to emit
1390
		contents = ''
1393
		contents = ''
1391
		contents += '/**\n'
1394
		contents += '/**\n'
1392
		contents += doxycomment
1395
		contents += doxycomment
1393
		contents += (f"@par Source\n" +
1396
		contents += (f"@par Source\n" +
1394
		             f"{self.file}:{self.line}\n")
1397
		             f"{self.file}:{self.line}\n")
1395
		contents += '*/\n'
1398
		contents += '*/\n'
1396
		contents += declaration
1399
		contents += declaration
1397
		contents += '\n\n'
1400
		contents += '\n\n'
1398
		# Get path to file to emit this
1401
		# Get path to file to emit this
1399
		full_path = dest + '/' + self.file
1402
		full_path = dest + '/' + self.file
1400
		# Remove the file on first access if it was created by previous generation
1403
		# Remove the file on first access if it was created by previous generation
1401
		if full_path not in created_files:
1404
		if full_path not in created_files:
1402
			if os.path.isfile(full_path):
1405
			if os.path.isfile(full_path):
1403
				os.remove(full_path)
1406
				os.remove(full_path)
1404
			created_files.append(full_path)
1407
			created_files.append(full_path)
1405
		# Create directories need for the file
1408
		# Create directories need for the file
1406
		os.makedirs(os.path.dirname(full_path), exist_ok=True)
1409
		os.makedirs(os.path.dirname(full_path), exist_ok=True)
1407
		f = open(full_path, "a")
1410
		f = open(full_path, "a")
1408
		contents = ''.join([i if ord(i) < 128 else '?' for i in contents])
1411
		contents = ''.join([i if ord(i) < 128 else '?' for i in contents])
1409
		f.write(contents)
1412
		f.write(contents)
1410
		f.close()
1413
		f.close()
1411
 
1414
 
1412
class AsmVariable(AsmElement):
1415
class AsmVariable(AsmElement):
1413
	def __init__(self, location, name, comment, type, init):
1416
	def __init__(self, location, name, comment, type, init):
1414
		super().__init__(location, name, comment)
1417
		super().__init__(location, name, comment)
1415
		self.type = type
1418
		self.type = type
1416
		self.init = init
1419
		self.init = init
1417
 
1420
 
1418
	def dump(self):
1421
	def dump(self):
1419
		super().dump()
1422
		super().dump()
1420
		print(f"Variable")
1423
		print(f"Variable")
1421
 
1424
 
1422
	def emit(self, dest):
1425
	def emit(self, dest):
1423
		# Build doxycomment specific for the variable
1426
		# Build doxycomment specific for the variable
1424
		doxycomment = ''
1427
		doxycomment = ''
1425
		doxycomment += self.comment
1428
		doxycomment += self.comment
1426
		if '@brief' not in doxycomment:
1429
		if '@brief' not in doxycomment:
1427
			doxycomment = '@brief ' + doxycomment
1430
			doxycomment = '@brief ' + doxycomment
1428
		doxycomment += (f"@par Initial value\n" +
1431
		doxycomment += (f"@par Initial value\n" +
1429
		                f"{self.init}\n")
1432
		                f"{self.init}\n")
1430
		# Build the declaration
1433
		# Build the declaration
1431
		name = self.name.replace(".", "_")
1434
		name = self.name.replace(".", "_")
1432
		var_type = self.type.replace(".", "_")
1435
		var_type = self.type.replace(".", "_")
1433
		declaration = f"{var_type} {name};"
1436
		declaration = f"{var_type} {name};"
1434
		# Emit this
1437
		# Emit this
1435
		super().emit(dest, doxycomment, declaration)
1438
		super().emit(dest, doxycomment, declaration)
1436
 
1439
 
1437
class AsmFunction(AsmElement):
1440
class AsmFunction(AsmElement):
1438
	def __init__(self, location, name, comment, calling_convention, args, used_regs):
1441
	def __init__(self, location, name, comment, calling_convention, args, used_regs):
1439
		super().__init__(location, name, comment)
1442
		super().__init__(location, name, comment)
1440
		self.calling_convention = calling_convention
1443
		self.calling_convention = calling_convention
1441
		self.args = args
1444
		self.args = args
1442
		self.used_regs = used_regs
1445
		self.used_regs = used_regs
1443
 
1446
 
1444
	def dump(self):
1447
	def dump(self):
1445
		super().dump()
1448
		super().dump()
1446
		print(f"Function")
1449
		print(f"Function")
1447
 
1450
 
1448
	def emit(self, dest):
1451
	def emit(self, dest):
1449
		# Build doxycomment specific for the variable
1452
		# Build doxycomment specific for the variable
1450
		doxycomment = ''
1453
		doxycomment = ''
1451
		doxycomment += self.comment
1454
		doxycomment += self.comment
1452
		if '@brief' not in doxycomment:
1455
		if '@brief' not in doxycomment:
1453
			doxycomment = '@brief ' + doxycomment
1456
			doxycomment = '@brief ' + doxycomment
1454
		# Build the arg list for declaration
1457
		# Build the arg list for declaration
1455
		arg_list = '('
1458
		arg_list = '('
1456
		if len(self.args) > 0:
1459
		if len(self.args) > 0:
1457
			argc = 0
1460
			argc = 0
1458
			for arg in self.args:
1461
			for arg in self.args:
1459
				if argc != 0:
1462
				if argc != 0:
1460
					arg_list += ", "
1463
					arg_list += ", "
1461
				arg_list += f"{arg[1]} {arg[0]}"
1464
				arg_list += f"{arg[1]} {arg[0]}"
1462
				argc += 1
1465
				argc += 1
1463
		arg_list += ')'
1466
		arg_list += ')'
1464
		# Build the declaration
1467
		# Build the declaration
1465
		name = self.name.replace(".", "_")
1468
		name = self.name.replace(".", "_")
1466
		declaration = f"void {name}{arg_list};"
1469
		declaration = f"void {name}{arg_list};"
1467
		# Emit this
1470
		# Emit this
1468
		super().emit(dest, doxycomment, declaration)
1471
		super().emit(dest, doxycomment, declaration)
1469
 
1472
 
1470
class AsmLabel(AsmElement):
1473
class AsmLabel(AsmElement):
1471
	def __init__(self, location, name, comment):
1474
	def __init__(self, location, name, comment):
1472
		super().__init__(location, name, comment)
1475
		super().__init__(location, name, comment)
1473
 
1476
 
1474
	def dump(self):
1477
	def dump(self):
1475
		super().dump()
1478
		super().dump()
1476
		print(f"Label")
1479
		print(f"Label")
1477
 
1480
 
1478
	def emit(self, dest):
1481
	def emit(self, dest):
1479
		# Build doxycomment specific for the variable
1482
		# Build doxycomment specific for the variable
1480
		doxycomment = ''
1483
		doxycomment = ''
1481
		doxycomment += self.comment
1484
		doxycomment += self.comment
1482
		if '@brief' not in doxycomment:
1485
		if '@brief' not in doxycomment:
1483
			doxycomment = '@brief ' + doxycomment
1486
			doxycomment = '@brief ' + doxycomment
1484
		# Build the declaration
1487
		# Build the declaration
1485
		name = self.name.replace(".", "_")
1488
		name = self.name.replace(".", "_")
1486
		declaration = f"label {name};"
1489
		declaration = f"label {name};"
1487
		# Emit this
1490
		# Emit this
1488
		super().emit(dest, doxycomment, declaration)
1491
		super().emit(dest, doxycomment, declaration)
1489
 
1492
 
1490
class AsmMacro(AsmElement):
1493
class AsmMacro(AsmElement):
1491
	def __init__(self, location, name, comment, args):
1494
	def __init__(self, location, name, comment, args):
1492
		super().__init__(location, name, comment)
1495
		super().__init__(location, name, comment)
1493
		self.args = args
1496
		self.args = args
1494
 
1497
 
1495
	def dump(self):
1498
	def dump(self):
1496
		super().dump()
1499
		super().dump()
1497
		print(f"Macro")
1500
		print(f"Macro")
1498
		print(f"Parameters: {self.args}")
1501
		print(f"Parameters: {self.args}")
1499
 
1502
 
1500
	def emit(self, dest):
1503
	def emit(self, dest):
1501
		# Construct arg list without '['s, ']'s and '*'s
1504
		# Construct arg list without '['s, ']'s and '*'s
1502
		args = [arg for arg in self.args if arg not in "[]*"]
1505
		args = [arg for arg in self.args if arg not in "[]*"]
1503
		# Construct C-like arg list
1506
		# Construct C-like arg list
1504
		arg_list = ""
1507
		arg_list = ""
1505
		if len(args) > 0:
1508
		if len(args) > 0:
1506
			arg_list += '('
1509
			arg_list += '('
1507
			argc = 0
1510
			argc = 0
1508
			for arg in args:
1511
			for arg in args:
1509
				if argc != 0:
1512
				if argc != 0:
1510
					arg_list += ", "
1513
					arg_list += ", "
1511
				arg_list += arg
1514
				arg_list += arg
1512
				argc += 1
1515
				argc += 1
1513
			arg_list += ')'
1516
			arg_list += ')'
1514
		# Build doxycomment
1517
		# Build doxycomment
1515
		doxycomment = ''
1518
		doxycomment = ''
1516
		doxycomment += self.comment
1519
		doxycomment += self.comment
1517
		if '@brief' not in doxycomment:
1520
		if '@brief' not in doxycomment:
1518
			doxycomment = '@brief ' + doxycomment
1521
			doxycomment = '@brief ' + doxycomment
1519
		# Build declaration
1522
		# Build declaration
1520
		declaration = f"#define {self.name}{arg_list}"
1523
		declaration = f"#define {self.name}{arg_list}"
1521
		# Emit this
1524
		# Emit this
1522
		super().emit(dest, doxycomment, declaration)
1525
		super().emit(dest, doxycomment, declaration)
1523
 
1526
 
1524
class AsmStruct(AsmElement):
1527
class AsmStruct(AsmElement):
1525
	def __init__(self, location, name, comment, members):
1528
	def __init__(self, location, name, comment, members):
1526
		super().__init__(location, name, comment)
1529
		super().__init__(location, name, comment)
1527
		self.members = members
1530
		self.members = members
1528
 
1531
 
1529
	def dump(self):
1532
	def dump(self):
1530
		super().dump()
1533
		super().dump()
1531
		print(f"Struct")
1534
		print(f"Struct")
1532
 
1535
 
1533
	def emit(self, dest):
1536
	def emit(self, dest):
1534
		# Build doxycomment
1537
		# Build doxycomment
1535
		doxycomment = ''
1538
		doxycomment = ''
1536
		doxycomment += self.comment
1539
		doxycomment += self.comment
1537
		if '@brief' not in doxycomment:
1540
		if '@brief' not in doxycomment:
1538
			doxycomment = '@brief ' + doxycomment
1541
			doxycomment = '@brief ' + doxycomment
1539
		doxycomment += '\n'
1542
		doxycomment += '\n'
1540
		# Build declaration
1543
		# Build declaration
1541
		declaration = f"struct {self.name}" + " {\n"
1544
		declaration = f"struct {self.name}" + " {\n"
1542
		for member in self.members:
1545
		for member in self.members:
1543
			if type(member) == AsmVariable:
1546
			if type(member) == AsmVariable:
1544
				declaration += f'\t{member.type} {member.name}; /**< {member.comment} */\n'
1547
				declaration += f'\t{member.type} {member.name}; /**< {member.comment} */\n'
1545
		declaration += '};'
1548
		declaration += '};'
1546
		# Emit this
1549
		# Emit this
1547
		super().emit(dest, doxycomment, declaration)
1550
		super().emit(dest, doxycomment, declaration)
1548
 
1551
 
1549
class AsmUnion(AsmElement):
1552
class AsmUnion(AsmElement):
1550
	def __init__(self, location, name, comment, members):
1553
	def __init__(self, location, name, comment, members):
1551
		super().__init__(location, name, comment)
1554
		super().__init__(location, name, comment)
1552
		self.members = members
1555
		self.members = members
1553
 
1556
 
1554
	def dump(self):
1557
	def dump(self):
1555
		super().dump()
1558
		super().dump()
1556
		print(f"Union")
1559
		print(f"Union")
1557
 
1560
 
1558
	def emit(self, dest):
1561
	def emit(self, dest):
1559
		# Build doxycomment
1562
		# Build doxycomment
1560
		doxycomment = ''
1563
		doxycomment = ''
1561
		doxycomment += self.comment
1564
		doxycomment += self.comment
1562
		if '@brief' not in doxycomment:
1565
		if '@brief' not in doxycomment:
1563
			doxycomment = '@brief ' + doxycomment
1566
			doxycomment = '@brief ' + doxycomment
1564
		# Build declaration
1567
		# Build declaration
1565
		declaration = f"union {self.name}" + " {};"
1568
		declaration = f"union {self.name}" + " {};"
1566
		# Emit this
1569
		# Emit this
1567
		super().emit(dest, doxycomment, declaration)
1570
		super().emit(dest, doxycomment, declaration)
1568
 
1571
 
1569
class VariableNameIsMacroName:
1572
class VariableNameIsMacroName:
1570
	def __init__(self, name):
1573
	def __init__(self, name):
1571
		self.name = name
1574
		self.name = name
1572
 
1575
 
1573
def is_id(c):
1576
def is_id(c):
1574
	return c.isprintable() and c not in "+-/*=<>()[]{};:,|&~#`'\" \n\r\t\v"
1577
	return c.isprintable() and c not in "+-/*=<>()[]{};:,|&~#`'\" \n\r\t\v"
1575
 
1578
 
1576
def is_starts_as_id(s):
1579
def is_starts_as_id(s):
1577
	return not s[0].isdigit()
1580
	return not s[0].isdigit()
1578
 
1581
 
1579
def parse_after_macro(r):
1582
def parse_after_macro(r):
1580
	location = r.location()
1583
	location = r.location()
1581
 
1584
 
1582
	# Skip spaces after the "macro" keyword
1585
	# Skip spaces after the "macro" keyword
1583
	r.skip_spaces()
1586
	r.skip_spaces()
1584
	# Read macro name
1587
	# Read macro name
1585
	name = ""
1588
	name = ""
1586
	while is_id(r.curr()) or r.curr() == '#':
1589
	while is_id(r.curr()) or r.curr() == '#':
1587
		name += r.step()
1590
		name += r.step()
1588
	# Skip spaces after macro name
1591
	# Skip spaces after macro name
1589
	r.skip_spaces()
1592
	r.skip_spaces()
1590
	# Find all arguments
1593
	# Find all arguments
1591
	args = []
1594
	args = []
1592
	arg = ''
1595
	arg = ''
1593
	while r.curr() and r.curr() != ';' and r.curr() != '{':
1596
	while r.curr() and r.curr() != ';' and r.curr() != '{':
1594
		# Collect identifier
1597
		# Collect identifier
1595
		if is_id(r.curr()):
1598
		if is_id(r.curr()):
1596
			arg += r.step()
1599
			arg += r.step()
1597
		# Save the collected identifier
1600
		# Save the collected identifier
1598
		elif r.curr() == ',':
1601
		elif r.curr() == ',':
1599
			args.append(arg)
1602
			args.append(arg)
1600
			arg = ''
1603
			arg = ''
1601
			r.step()
1604
			r.step()
1602
		# Just push the '['
1605
		# Just push the '['
1603
		elif r.curr() == '[':
1606
		elif r.curr() == '[':
1604
			args.append(r.step())
1607
			args.append(r.step())
1605
		# Just push the identifier and get ']' ready to be pushed on next comma
1608
		# Just push the identifier and get ']' ready to be pushed on next comma
1606
		elif r.curr() == ']':
1609
		elif r.curr() == ']':
1607
			args.append(arg)
1610
			args.append(arg)
1608
			arg = r.step()
1611
			arg = r.step()
1609
		# Just push the identifier and get '*' ready to be pushed on next comma
1612
		# Just push the identifier and get '*' ready to be pushed on next comma
1610
		elif r.curr() == '*':
1613
		elif r.curr() == '*':
1611
			args.append(arg)
1614
			args.append(arg)
1612
			arg = r.step()
1615
			arg = r.step()
1613
		# Just skip whitespaces
1616
		# Just skip whitespaces
1614
		elif r.curr().isspace():
1617
		elif r.curr().isspace():
1615
			r.step()
1618
			r.step()
1616
		# Something unexpected
1619
		# Something unexpected
1617
		else:
1620
		else:
1618
			raise Exception(f"Unexpected symbol '{r.curr()}' at index #{r.i} " + 
1621
			raise Exception(f"Unexpected symbol '{r.curr()}' at index #{r.i} " + 
1619
			                f"in the macro declaration at {location} " +
1622
			                f"in the macro declaration at {location} " +
1620
			                f"(line: {r.lines[r.line_idx]})\n''")
1623
			                f"(line: {r.lines[r.line_idx]})\n''")
1621
	# Append the last argument
1624
	# Append the last argument
1622
	if arg != '':
1625
	if arg != '':
1623
		args.append(arg)
1626
		args.append(arg)
1624
	# Skip t spaces after the argument list
1627
	# Skip t spaces after the argument list
1625
	r.skip_spaces()
1628
	r.skip_spaces()
1626
	# Get a comment if it is: read till the end of the line and get the comment from the reader
1629
	# Get a comment if it is: read till the end of the line and get the comment from the reader
1627
	while r.curr() != '':
1630
	while r.curr() != '':
1628
		r.step()
1631
		r.step()
1629
	comment = r.comment
1632
	comment = r.comment
1630
	# Find end of the macro
1633
	# Find end of the macro
1631
	prev = ''
1634
	prev = ''
1632
	while True:
1635
	while True:
1633
		if r.curr() == '}' and prev != '\\':
1636
		if r.curr() == '}' and prev != '\\':
1634
			break
1637
			break
1635
		elif r.curr() == '':
1638
		elif r.curr() == '':
1636
			prev = ''
1639
			prev = ''
1637
			r.nextline()
1640
			r.nextline()
1638
			continue
1641
			continue
1639
		prev = r.step()
1642
		prev = r.step()
1640
	# Build the output
1643
	# Build the output
1641
	return AsmMacro(location, name, comment, args)
1644
	return AsmMacro(location, name, comment, args)
1642
 
1645
 
1643
def parse_variable(r, first_word = None):
1646
def parse_variable(r, first_word = None):
1644
	global warnings
1647
	global warnings
1645
	location = r.location()
1648
	location = r.location()
1646
 
1649
 
1647
	# Skip spaces before variable name
1650
	# Skip spaces before variable name
1648
	r.skip_spaces()
1651
	r.skip_spaces()
1649
	# Get variable name
1652
	# Get variable name
1650
	name = ""
1653
	name = ""
1651
	# Read it if it was not supplied
1654
	# Read it if it was not supplied
1652
	if first_word == None:
1655
	if first_word == None:
1653
		while is_id(r.curr()):
1656
		while is_id(r.curr()):
1654
			name += r.step()
1657
			name += r.step()
1655
	# Or use the supplied one instead
1658
	# Or use the supplied one instead
1656
	else:
1659
	else:
1657
		name = first_word
1660
		name = first_word
1658
	# Check the name
1661
	# Check the name
1659
	# If it's 0 len, that means threr's something else than an identifier at the beginning
1662
	# If it's 0 len, that means threr's something else than an identifier at the beginning
1660
	if len(name) == 0:
1663
	if len(name) == 0:
1661
		return None
1664
		return None
1662
	# If it starts from digit or othervice illegally it's illegal
1665
	# If it starts from digit or othervice illegally it's illegal
1663
	if not is_starts_as_id(name):
1666
	if not is_starts_as_id(name):
1664
		return None
1667
		return None
1665
	# Get kind of the identifier from id2kind table
1668
	# Get kind of the identifier from id2kind table
1666
	kind = id_get_kind(name)
1669
	kind = id_get_kind(name)
1667
	# If it's a keyword, that's not a variable declaration
1670
	# If it's a keyword, that's not a variable declaration
1668
	if ID_KIND_KEYWORD in kind:
1671
	if ID_KIND_KEYWORD in kind:
1669
		return None
1672
		return None
1670
	# If it's a macro name, that's not a variable declaration
1673
	# If it's a macro name, that's not a variable declaration
1671
	if ID_KIND_MACRO_NAME in kind:
1674
	if ID_KIND_MACRO_NAME in kind:
1672
		return VariableNameIsMacroName(name)
1675
		return VariableNameIsMacroName(name)
1673
	# If it's a datatype or a structure name that's not a variable declaration: that's just a data
1676
	# If it's a datatype or a structure name that's not a variable declaration: that's just a data
1674
	# don't document just a data for now
1677
	# don't document just a data for now
1675
	if ID_KIND_STRUCT_NAME in kind or ID_KIND_FASM_TYPE in kind:
1678
	if ID_KIND_STRUCT_NAME in kind or ID_KIND_FASM_TYPE in kind:
1676
		return None
1679
		return None
1677
	# Skip spaces before type name
1680
	# Skip spaces before type name
1678
	r.skip_spaces()
1681
	r.skip_spaces()
1679
	# Read type name
1682
	# Read type name
1680
	var_type = ""
1683
	var_type = ""
1681
	while is_id(r.curr()):
1684
	while is_id(r.curr()):
1682
		var_type += r.step()
1685
		var_type += r.step()
1683
	# Check the type name
1686
	# Check the type name
1684
	if len(var_type) == 0:
1687
	if len(var_type) == 0:
1685
		# If there's no type identifier after the name
1688
		# If there's no type identifier after the name
1686
		# maybe the name is something meaningful for the next parser
1689
		# maybe the name is something meaningful for the next parser
1687
		# return it
1690
		# return it
1688
		return name
1691
		return name
1689
	# If it starts from digit or othervice illegally it's illegal
1692
	# If it starts from digit or othervice illegally it's illegal
1690
	if not is_starts_as_id(var_type):
1693
	if not is_starts_as_id(var_type):
1691
		return None
1694
		return None
1692
	# Get kind of type identifier
1695
	# Get kind of type identifier
1693
	type_kind = id_get_kind(var_type)
1696
	type_kind = id_get_kind(var_type)
1694
	# If it's a keyword, that's not a variable declaration
1697
	# If it's a keyword, that's not a variable declaration
1695
	# return the two words of the lexical structure
1698
	# return the two words of the lexical structure
1696
	if ID_KIND_KEYWORD in type_kind:
1699
	if ID_KIND_KEYWORD in type_kind:
1697
		return (name, var_type)
1700
		return (name, var_type)
1698
	# Skip spaces before the value
1701
	# Skip spaces before the value
1699
	r.skip_spaces()
1702
	r.skip_spaces()
1700
	# Read the value until the comment or end of the line
1703
	# Read the value until the comment or end of the line
1701
	value = ""
1704
	value = ""
1702
	while r.curr() != ';' and r.curr() != '' and r.curr() != '\n':
1705
	while r.curr() != ';' and r.curr() != '' and r.curr() != '\n':
1703
		value += r.step()
1706
		value += r.step()
1704
	# Skip spaces after the value
1707
	# Skip spaces after the value
1705
	r.skip_spaces()
1708
	r.skip_spaces()
1706
	# Read till end of the line to get a comment from the reader
1709
	# Read till end of the line to get a comment from the reader
1707
	while r.curr() != '':
1710
	while r.curr() != '':
1708
		r.step()
1711
		r.step()
1709
	# Build the result
1712
	# Build the result
1710
	return AsmVariable(location, name, r.comment, var_type, value)
1713
	return AsmVariable(location, name, r.comment, var_type, value)
1711
 
1714
 
1712
def parse_after_struct(r, as_union = True):
1715
def parse_after_struct(r, as_union = True):
1713
	global warnings
1716
	global warnings
1714
	location = r.location()
1717
	location = r.location()
1715
 
1718
 
1716
	# Skip spaces after "struct" keyword
1719
	# Skip spaces after "struct" keyword
1717
	r.skip_spaces()
1720
	r.skip_spaces()
1718
	# Read struct name
1721
	# Read struct name
1719
	name = ""
1722
	name = ""
1720
	while is_id(r.curr()):
1723
	while is_id(r.curr()):
1721
		name += r.step()
1724
		name += r.step()
1722
	# Read till end of the line and get the comment from the reader
1725
	# Read till end of the line and get the comment from the reader
1723
	while r.curr() != '':
1726
	while r.curr() != '':
1724
		r.step()
1727
		r.step()
1725
	comment = r.comment
1728
	comment = r.comment
1726
	# Get to the next line to parse struct members
1729
	# Get to the next line to parse struct members
1727
	r.nextline()
1730
	r.nextline()
1728
	# Parse struct members
1731
	# Parse struct members
1729
	members = []
1732
	members = []
1730
	while True:
1733
	while True:
1731
		r.skip_spaces()
1734
		r.skip_spaces()
1732
		var = parse_variable(r)
1735
		var = parse_variable(r)
1733
		if type(var) == AsmVariable:
1736
		if type(var) == AsmVariable:
1734
			members.append(var)
1737
			members.append(var)
1735
		elif type(var) == str:
1738
		elif type(var) == str:
1736
			if var == 'union':
1739
			if var == 'union':
1737
				# Parse the union as a struct
1740
				# Parse the union as a struct
1738
				union = parse_after_struct(r, as_union = True)
1741
				union = parse_after_struct(r, as_union = True)
1739
				members.append(union)
1742
				members.append(union)
1740
				# Skip the ends of the union
1743
				# Skip the ends of the union
1741
				r.nextline()
1744
				r.nextline()
1742
			elif r.curr() == ':':
1745
			elif r.curr() == ':':
1743
				warnings += f"{r.location()}: Skept the label in the struct\n"
1746
				warnings += f"{r.location()}: Skept the label in the struct\n"
1744
			else:
1747
			else:
1745
				raise Exception(f"Garbage in struct member at {location} (got '{var}' identifier)")
1748
				raise Exception(f"Garbage in struct member at {location} (got '{var}' identifier)")
1746
		elif type(var) == VariableNameIsMacroName:
1749
		elif type(var) == VariableNameIsMacroName:
1747
			if var.name == 'ends':
1750
			if var.name == 'ends':
1748
				break
1751
				break
1749
		r.nextline()
1752
		r.nextline()
1750
	# Return the result
1753
	# Return the result
1751
	if as_union:
1754
	if as_union:
1752
		return AsmStruct(location, name, comment, members)
1755
		return AsmStruct(location, name, comment, members)
1753
	else:
1756
	else:
1754
		return AsmUnion(location, name, comment, members)
1757
		return AsmUnion(location, name, comment, members)
1755
 
1758
 
1756
def parse_after_proc(r):
1759
def parse_after_proc(r):
1757
	# Get proc name
1760
	# Get proc name
1758
	name = r.fetch_identifier()
1761
	name = r.fetch_identifier()
1759
	# Next identifier after the proc name
1762
	# Next identifier after the proc name
1760
	identifier = r.fetch_identifier()
1763
	identifier = r.fetch_identifier()
1761
	# Check if the id is 'stdcall' or 'c' (calling convention specifier)
1764
	# Check if the id is 'stdcall' or 'c' (calling convention specifier)
1762
	# and if so - save the convention and lookup the next identifier
1765
	# and if so - save the convention and lookup the next identifier
1763
	calling_convention = ''
1766
	calling_convention = ''
1764
	if identifier == 'stdcall' or identifier == 'c':
1767
	if identifier == 'stdcall' or identifier == 'c':
1765
		calling_convention = identifier
1768
		calling_convention = identifier
1766
		# If next is a comma, just skip it
1769
		# If next is a comma, just skip it
1767
		if r.curr() == ',':
1770
		if r.curr() == ',':
1768
			r.step()
1771
			r.step()
1769
		# Read the next identifier
1772
		# Read the next identifier
1770
		identifier = r.fetch_identifier()
1773
		identifier = r.fetch_identifier()
1771
	# Check if the id is 'uses' (used register list specifier)
1774
	# Check if the id is 'uses' (used register list specifier)
1772
	# and if so save the used register list
1775
	# and if so save the used register list
1773
	used_regs = []
1776
	used_regs = []
1774
	if identifier == 'uses':
1777
	if identifier == 'uses':
1775
		# Read the registers
1778
		# Read the registers
1776
		while True:
1779
		while True:
1777
			reg_name = r.fetch_identifier()
1780
			reg_name = r.fetch_identifier()
1778
			if reg_name != '':
1781
			if reg_name != '':
1779
				used_regs.append(reg_name)
1782
				used_regs.append(reg_name)
1780
			else:
1783
			else:
1781
				break
1784
				break
1782
		# If next is a comma, just skip it
1785
		# If next is a comma, just skip it
1783
		if r.curr() == ',':
1786
		if r.curr() == ',':
1784
			r.step()
1787
			r.step()
1785
		# Read the next identifier
1788
		# Read the next identifier
1786
		identifier = r.fetch_identifier()
1789
		identifier = r.fetch_identifier()
1787
	# Check if there are argument identifiers
1790
	# Check if there are argument identifiers
1788
	args = []
1791
	args = []
1789
	while identifier != '':
1792
	while identifier != '':
1790
		arg_name = identifier
1793
		arg_name = identifier
1791
		arg_type = 'arg_t'
1794
		arg_type = 'arg_t'
1792
		# Skip spaces after argument name
1795
		# Skip spaces after argument name
1793
		r.skip_spaces()
1796
		r.skip_spaces()
1794
		# If there's a ':' after the name - the next identifier is type
1797
		# If there's a ':' after the name - the next identifier is type
1795
		if r.curr() == ':':
1798
		if r.curr() == ':':
1796
			r.step()
1799
			r.step()
1797
			arg_type = r.fetch_identifier()
1800
			arg_type = r.fetch_identifier()
1798
		# If there's a comma - there's one more argument
1801
		# If there's a comma - there's one more argument
1799
		# else no arguments anymore
1802
		# else no arguments anymore
1800
		if r.curr() == ',':
1803
		if r.curr() == ',':
1801
			r.step()
1804
			r.step()
1802
			identifier = r.fetch_identifier()
1805
			identifier = r.fetch_identifier()
1803
		else:
1806
		else:
1804
			identifier = ''
1807
			identifier = ''
1805
		args.append((arg_name, arg_type))
1808
		args.append((arg_name, arg_type))
1806
	# Get to the end of the line and get a comment from the reader
1809
	# Get to the end of the line and get a comment from the reader
1807
	while r.curr() != '':
1810
	while r.curr() != '':
1808
		r.step()
1811
		r.step()
1809
	comment = r.comment
1812
	comment = r.comment
1810
	# Build the element
1813
	# Build the element
1811
	return AsmFunction(r.location(), name, comment, calling_convention, args, used_regs)
1814
	return AsmFunction(r.location(), name, comment, calling_convention, args, used_regs)
1812
 
1815
 
1813
def get_declarations(asm_file_contents, asm_file_name):
1816
def get_declarations(asm_file_contents, asm_file_name):
1814
	r = AsmReader(asm_file_name)
1817
	r = AsmReader(asm_file_name)
1815
 
1818
 
1816
	while not r.no_lines():
1819
	while not r.no_lines():
1817
		# Skip leading spaces
1820
		# Skip leading spaces
1818
		r.skip_spaces()
1821
		r.skip_spaces()
1819
		# Skip the line if it's starting with a comment
1822
		# Skip the line if it's starting with a comment
1820
		if r.curr() == ';':
1823
		if r.curr() == ';':
1821
			r.nextline()
1824
			r.nextline()
1822
			continue
1825
			continue
1823
		# Get first word
1826
		# Get first word
1824
		first_word = ""
1827
		first_word = ""
1825
		while is_id(r.curr()):
1828
		while is_id(r.curr()):
1826
			first_word += r.step()
1829
			first_word += r.step()
1827
		# Match macro declaration
1830
		# Match macro declaration
1828
		if first_word == "macro":
1831
		if first_word == "macro":
1829
			macro = parse_after_macro(r)
1832
			macro = parse_after_macro(r)
1830
			elements.append(macro)
1833
			elements.append(macro)
1831
			id_add_kind(macro.name, ID_KIND_MACRO_NAME)
1834
			id_add_kind(macro.name, ID_KIND_MACRO_NAME)
1832
		# Match structure declaration
1835
		# Match structure declaration
1833
		elif first_word == "struct":
1836
		elif first_word == "struct":
1834
			struct = parse_after_struct(r)
1837
			struct = parse_after_struct(r)
1835
			elements.append(struct)
1838
			elements.append(struct)
1836
			id_add_kind(struct.name, ID_KIND_STRUCT_NAME)
1839
			id_add_kind(struct.name, ID_KIND_STRUCT_NAME)
1837
		# Match function definition
1840
		# Match function definition
1838
		elif first_word == "proc":
1841
		elif first_word == "proc":
1839
			proc = parse_after_proc(r)
1842
			proc = parse_after_proc(r)
1840
			elements.append(proc)
1843
			elements.append(proc)
1841
		elif first_word == 'format':
1844
		elif first_word == 'format':
1842
			# Skip the format directive
1845
			# Skip the format directive
1843
			pass
1846
			pass
1844
		elif first_word == 'include':
1847
		elif first_word == 'include':
1845
			# Skip the include directive
1848
			# Skip the include directive
1846
			pass
1849
			pass
1847
		elif first_word == 'if':
1850
		elif first_word == 'if':
1848
			# Skip the conditional directive
1851
			# Skip the conditional directive
1849
			pass
1852
			pass
1850
		elif first_word == 'repeat':
1853
		elif first_word == 'repeat':
1851
			# Skip the repeat directive
1854
			# Skip the repeat directive
1852
			pass
1855
			pass
1853
		elif first_word == 'purge':
1856
		elif first_word == 'purge':
1854
			while True:
1857
			while True:
1855
				# Skip spaces after the 'purge' keyword or after the comma what separated the previous macro name
1858
				# Skip spaces after the 'purge' keyword or after the comma what separated the previous macro name
1856
				r.skip_spaces()
1859
				r.skip_spaces()
1857
				# Get the purged macro name
1860
				# Get the purged macro name
1858
				name = ''
1861
				name = ''
1859
				while is_id(r.curr()):
1862
				while is_id(r.curr()):
1860
					name += r.step()
1863
					name += r.step()
1861
				# Remove the purged macro from the macro names list
1864
				# Remove the purged macro from the macro names list
1862
				try:
1865
				try:
1863
					id_remove_kind(name, ID_KIND_MACRO_NAME)
1866
					id_remove_kind(name, ID_KIND_MACRO_NAME)
1864
				except:
1867
				except:
1865
					pass
1868
					pass
1866
				# Skip spaces after the name
1869
				# Skip spaces after the name
1867
				r.skip_spaces()
1870
				r.skip_spaces()
1868
				# If it's comma (',') after then that's not the last purged macro, continue purging
1871
				# If it's comma (',') after then that's not the last purged macro, continue purging
1869
				if r.curr() == ',':
1872
				if r.curr() == ',':
1870
					r.step()
1873
					r.step()
1871
					continue
1874
					continue
1872
				# Here we purged all the macros should be purged
1875
				# Here we purged all the macros should be purged
1873
				break
1876
				break
1874
		# Match label or a variable
1877
		# Match label or a variable
1875
		elif len(first_word) != 0:
1878
		elif len(first_word) != 0:
1876
			# Skip spaces after the identifier
1879
			# Skip spaces after the identifier
1877
			r.skip_spaces()
1880
			r.skip_spaces()
1878
			# Match a variable
1881
			# Match a variable
1879
			var = parse_variable(r, first_word)
1882
			var = parse_variable(r, first_word)
1880
			if type(var) == AsmVariable:
1883
			if type(var) == AsmVariable:
1881
				elements.append(var)
1884
				elements.append(var)
1882
			# If it wasn't a variable but there was an identifier
1885
			# If it wasn't a variable but there was an identifier
1883
			# Maybe that's a label and the identifier is the label name
1886
			# Maybe that's a label and the identifier is the label name
1884
			# The parse_variable returns the first found or supplied identifier
1887
			# The parse_variable returns the first found or supplied identifier
1885
			# In this case it returns the first_word which is supplied
1888
			# In this case it returns the first_word which is supplied
1886
			# If it didn't match a type identifier after the word
1889
			# If it didn't match a type identifier after the word
1887
			elif type(var) == str:
1890
			elif type(var) == str:
1888
				name = var
1891
				name = var
1889
				# Match label beginning (':' after name)
1892
				# Match label beginning (':' after name)
1890
				if r.curr() == ':':
1893
				if r.curr() == ':':
1891
					# Get to the end of the line and get the coment from the reader
1894
					# Get to the end of the line and get the coment from the reader
1892
					while r.curr() != '':
1895
					while r.curr() != '':
1893
						r.step()
1896
						r.step()
1894
					comment = r.comment
1897
					comment = r.comment
1895
					# Only handle non-local labels
1898
					# Only handle non-local labels
1896
					if name[0] != '.' and name != "@@" and name != "$Revision":
1899
					if name[0] != '.' and name != "@@" and name != "$Revision":
1897
						if '@return' in comment or '@param' in comment:
1900
						if '@return' in comment or '@param' in comment:
1898
							element = AsmFunction(r.location(), name, comment, '', [], [])
1901
							element = AsmFunction(r.location(), name, comment, '', [], [])
1899
						else:
1902
						else:
1900
							element = AsmLabel(r.location(), name, comment)
1903
							element = AsmLabel(r.location(), name, comment)
1901
						elements.append(element)
1904
						elements.append(element)
1902
				elif r.curr() == '=':
1905
				elif r.curr() == '=':
1903
					# Save the identifier as a set constant
1906
					# Save the identifier as a set constant
1904
					id_add_kind(first_word, ID_KIND_SET_CONSTANT)
1907
					id_add_kind(first_word, ID_KIND_SET_CONSTANT)
1905
			elif type(var) == tuple:
1908
			elif type(var) == tuple:
1906
				(word_one, word_two) = var
1909
				(word_one, word_two) = var
1907
				if word_two == 'equ':
1910
				if word_two == 'equ':
1908
					# Save the identifier as an equated constant
1911
					# Save the identifier as an equated constant
1909
					id_add_kind(word_one, ID_KIND_EQUATED_CONSTANT)
1912
					id_add_kind(word_one, ID_KIND_EQUATED_CONSTANT)
1910
		r.nextline()
1913
		r.nextline()
1911
 
1914
 
1912
def it_neds_to_be_parsed(source_file):
1915
def it_neds_to_be_parsed(source_file):
-
 
1916
	# If there's no symbols file saved - parse it anyway
-
 
1917
	# cause we need to create the symbols file and use it
-
 
1918
	# if we gonna generate proper doxygen
-
 
1919
	if not os.path.isfile('asmxygen.elements.pickle'):
-
 
1920
		return True
1913
	dest = doxygen_src_path + '/' + source_file
1921
	dest = doxygen_src_path + '/' + source_file
1914
	# If there's no the doxygen file it should be compiled to
1922
	# If there's no the doxygen file it should be compiled to
1915
	# then yes, we should compile it to doxygen
1923
	# then yes, we should compile it to doxygen
1916
	if not os.path.isfile(dest):
1924
	if not os.path.isfile(dest):
1917
		return True
1925
		return True
1918
	source_change_time = os.path.getmtime(source_file)
1926
	source_change_time = os.path.getmtime(source_file)
1919
	dest_change_file = os.path.getmtime(dest)
1927
	dest_change_file = os.path.getmtime(dest)
1920
	# If the source is newer than the doxygen it was compiled to
1928
	# If the source is newer than the doxygen it was compiled to
1921
	# then the source should be recompiled (existing doxygen is old)
1929
	# then the source should be recompiled (existing doxygen is old)
1922
	if source_change_time > dest_change_file:
1930
	if source_change_time > dest_change_file:
1923
		return True
1931
		return True
1924
	return False
1932
	return False
1925
 
1933
 
1926
def handle_file(handled_files, asm_file_name, subdir = "."):
1934
def handle_file(handled_files, asm_file_name, subdir = "."):
-
 
1935
	global elements
1927
	# Canonicalize the file path and get it relative to cwd
1936
	# Canonicalize the file path and get it relative to cwd
1928
	cwd = os.path.abspath(os.path.dirname(sys.argv[0]))
1937
	cwd = os.path.abspath(os.path.dirname(sys.argv[0]))
1929
	asm_file_name = os.path.realpath(asm_file_name)
1938
	asm_file_name = os.path.realpath(asm_file_name)
1930
	asm_file_name = asm_file_name[len(cwd) + 1:]
1939
	asm_file_name = asm_file_name[len(cwd) + 1:]
1931
	# If it's lang.inc - skip it
1940
	# If it's lang.inc - skip it
1932
	if asm_file_name == 'lang.inc':
1941
	if asm_file_name == 'lang.inc':
1933
		return
1942
		return
1934
	# If the file was handled in this execution before - skip it
1943
	# If the file was handled in this execution before - skip it
1935
	if asm_file_name in handled_files:
1944
	if asm_file_name in handled_files:
1936
		return
1945
		return
1937
	# Say that the file was handled in this execution
1946
	# Say that the file was handled in this execution
1938
	handled_files.append(asm_file_name)
1947
	handled_files.append(asm_file_name)
1939
	# Check if the file should be parsed (if it was modified or wasn't parsed yet)
1948
	# Check if the file should be parsed (if it was modified or wasn't parsed yet)
1940
	should_get_declarations = True
1949
	should_get_declarations = True
1941
	if not it_neds_to_be_parsed(asm_file_name):
1950
	if not it_neds_to_be_parsed(asm_file_name):
1942
		print(f"Skipping {asm_file_name} (already newest)")
1951
		print(f"Skipping {asm_file_name} (already newest)")
1943
		should_get_declarations = False
1952
		should_get_declarations = False
1944
	else:
1953
	else:
1945
		print(f"Handling {asm_file_name}")
1954
		print(f"Handling {asm_file_name}")
-
 
1955
		# Remove elements parsed from this file before if any
-
 
1956
		elements_to_remove = [x for x in elements if x.location.split(':')[0] == asm_file_name]
-
 
1957
		elements = [x for x in elements if x.location.split(':')[0] != asm_file_name]
-
 
1958
		# Forget types of identifiers of names of the removed elements
-
 
1959
		for element in elements_to_remove:
-
 
1960
			if type(element) == AsmStruct:
-
 
1961
				id_remove_kind(element.name, ID_KIND_STRUCT_NAME)
-
 
1962
			elif type(element) == AsmMacro:
-
 
1963
				id_remove_kind(element.name, ID_KIND_MACRO_NAME)
1946
	# Read the source
1964
	# Read the source
1947
	asm_file_contents = open(asm_file_name, "r", encoding="utf-8").read()
1965
	asm_file_contents = open(asm_file_name, "r", encoding="utf-8").read()
1948
	# Find includes, fix their paths and handle em recoursively
1966
	# Find includes, fix their paths and handle em recoursively
1949
	includes = re.findall(r'^include (["\'])(.*)\1', asm_file_contents, flags=re.MULTILINE)
1967
	includes = re.findall(r'^include (["\'])(.*)\1', asm_file_contents, flags=re.MULTILINE)
1950
	for include in includes:
1968
	for include in includes:
1951
		include = include[1].replace('\\', '/');
1969
		include = include[1].replace('\\', '/');
1952
		full_path = subdir + '/' + include;
1970
		full_path = subdir + '/' + include;
1953
		# If the path isn't valid, maybe that's not relative path
1971
		# If the path isn't valid, maybe that's not relative path
1954
		if not os.path.isfile(full_path):
1972
		if not os.path.isfile(full_path):
1955
			full_path = include
1973
			full_path = include
1956
		new_subdir = full_path.rsplit('/', 1)[0]
1974
		new_subdir = full_path.rsplit('/', 1)[0]
1957
		handle_file(handled_files, full_path, new_subdir)
1975
		handle_file(handled_files, full_path, new_subdir)
1958
	# Only collect declarations from the file if it wasn't parsed before
1976
	# Only collect declarations from the file if it wasn't parsed before
1959
	if should_get_declarations and not clean_generated_stuff:
1977
	if should_get_declarations and not clean_generated_stuff:
1960
		get_declarations(asm_file_contents, asm_file_name)
1978
		get_declarations(asm_file_contents, asm_file_name)
1961
 
1979
 
1962
kernel_files = []
1980
kernel_files = []
-
 
1981
 
-
 
1982
# Load remembered list of symbols
-
 
1983
if os.path.isfile('asmxygen.elements.pickle'):
-
 
1984
	print('Reading existing dump of symbols')
-
 
1985
	(elements, id2kind) = pickle.load(open('asmxygen.elements.pickle', 'rb'))
1963
 
1986
 
1964
handle_file(kernel_files, "./kernel.asm");
1987
handle_file(kernel_files, "./kernel.asm");
1965
 
1988
 
1966
if dump_symbols:
1989
if dump_symbols:
1967
	for asm_element in elements:
1990
	for asm_element in elements:
1968
		asm_element.dump()
1991
		asm_element.dump()
1969
 
1992
 
1970
if clean_generated_stuff:
1993
if clean_generated_stuff:
1971
	kernel_files_set = set(kernel_files)
1994
	kernel_files_set = set(kernel_files)
1972
	for file in kernel_files:
1995
	for file in kernel_files:
1973
		doxygen_file = f"{doxygen_src_path}/{file}"
1996
		doxygen_file = f"{doxygen_src_path}/{file}"
1974
		if (os.path.isfile(doxygen_file)):
1997
		if (os.path.isfile(doxygen_file)):
1975
			print(f"Removing {file}... ", end = '')
1998
			print(f"Removing {file}... ", end = '')
1976
			os.remove(doxygen_file)
1999
			os.remove(doxygen_file)
1977
			print("Done.")
2000
			print("Done.")
1978
elif not noemit:
2001
elif not noemit:
1979
	print(f"Writing doumented sources to {doxygen_src_path}")
2002
	print(f"Writing doumented sources to {doxygen_src_path}")
1980
 
2003
 
1981
	i = 0
2004
	i = 0
-
 
2005
	new_elements = [x for x in elements if x.new]
1982
	for element in elements:
2006
	for element in new_elements:
1983
		print(f"[{i + 1}/{len(elements)}] Emitting {element.name} from {element.location}")
2007
		print(f"[{i + 1}/{len(new_elements)}] Emitting {element.name} from {element.location}")
1984
		element.emit(doxygen_src_path)
2008
		element.emit(doxygen_src_path)
1985
		i += 1
2009
		i += 1
-
 
2010
 
-
 
2011
	print(f"Writing dump of symbols to asmxygen.elements.pickle")
-
 
2012
 
-
 
2013
	# Now when the new elements already was written, there's no new elements anymore
-
 
2014
	for element in elements:
-
 
2015
		element.new = False
-
 
2016
	pickle.dump((elements, id2kind), open('asmxygen.elements.pickle', 'wb'))
1986
 
2017
 
1987
if print_stats:
2018
if print_stats:
1988
	var_count = 0
2019
	var_count = 0
1989
	mac_count = 0
2020
	mac_count = 0
1990
	lab_count = 0
2021
	lab_count = 0
1991
	fun_count = 0
2022
	fun_count = 0
1992
	uni_count = 0
2023
	uni_count = 0
1993
	str_count = 0
2024
	str_count = 0
1994
	for element in elements:
2025
	for element in elements:
1995
		if type(element) == AsmVariable:
2026
		if type(element) == AsmVariable:
1996
			var_count += 1
2027
			var_count += 1
1997
		elif type(element) == AsmMacro:
2028
		elif type(element) == AsmMacro:
1998
			mac_count += 1
2029
			mac_count += 1
1999
		elif type(element) == AsmLabel:
2030
		elif type(element) == AsmLabel:
2000
			lab_count += 1
2031
			lab_count += 1
2001
		elif type(element) == AsmFunction:
2032
		elif type(element) == AsmFunction:
2002
			fun_count += 1
2033
			fun_count += 1
2003
		elif type(element) == AsmUnion:
2034
		elif type(element) == AsmUnion:
2004
			uni_count += 1
2035
			uni_count += 1
2005
		elif type(element) == AsmStruct:
2036
		elif type(element) == AsmStruct:
2006
			str_count += 1
2037
			str_count += 1
2007
	print(f'Parsed variable count: {var_count}')
2038
	print(f'Parsed variable count: {var_count}')
2008
	print(f'Parsed macro count: {mac_count}')
2039
	print(f'Parsed macro count: {mac_count}')
2009
	print(f'Parsed label count: {lab_count}')
2040
	print(f'Parsed label count: {lab_count}')
2010
	print(f'Parsed function count: {fun_count}')
2041
	print(f'Parsed function count: {fun_count}')
2011
	print(f'Parsed union type count: {uni_count}')
2042
	print(f'Parsed union type count: {uni_count}')
2012
	print(f'Parsed structure type count: {str_count}')
2043
	print(f'Parsed structure type count: {str_count}')
2013
 
2044
 
2014
if enable_warnings:
2045
if enable_warnings:
2015
	open('asmxygen.txt', "w", encoding = "utf-8").write(warnings)
2046
	open('asmxygen.txt', "w", encoding = "utf-8").write(warnings)