Subversion Repositories Kolibri OS

Rev

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

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