forked from intelxed/xed
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathxmlToAssembler.py
executable file
·93 lines (78 loc) · 3.42 KB
/
xmlToAssembler.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/usr/bin/env python3
import xml.etree.ElementTree as ET
def main():
root = ET.parse('instructions.xml')
print('.intel_syntax noprefix')
for instrNode in root.iter('instruction'):
# Future instruction set extensions
if instrNode.attrib['extension'] in ['AMD_INVLPGB', 'AMX_BF16', 'AMX_INT8', 'AMX_TILE', 'AVX_IFMA', 'AVX_NE_CONVERT', 'AVX_VNNI', 'AVX_VNNI_INT8', 'CMPCCXADD', 'ENQCMD', 'HRESET', 'ICACHE_PREFETCH', 'KEYLOCKER', 'KEYLOCKER_WIDE', 'MSRLIST', 'RAO_INT', 'SERIALIZE', 'SNP', 'TDX', 'TSX_LDTRK', 'UINTR', 'WRMSRNS']:
continue
if any(x in instrNode.attrib['isa-set'] for x in ['FP16']):
continue
# Deprecated instruction set extensions
if instrNode.attrib['extension'] in ['MPX']:
continue
asm = instrNode.attrib['asm']
first = True
for operandNode in instrNode.iter('operand'):
operandIdx = int(operandNode.attrib['idx'])
if operandNode.attrib.get('suppressed', '0') == '1':
continue;
if not first and not operandNode.attrib.get('opmask', '') == '1':
asm += ', '
else:
asm += ' '
first = False
if operandNode.attrib['type'] == 'reg':
registers = operandNode.text.split(',')
register = registers[min(operandIdx, len(registers)-1)]
if not operandNode.attrib.get('opmask', '') == '1':
asm += register
else:
asm += '{' + register + '}'
if instrNode.attrib.get('zeroing', '') == '1':
asm += '{z}'
elif operandNode.attrib['type'] == 'mem':
memoryPrefix = operandNode.attrib.get('memory-prefix', '')
if memoryPrefix:
asm += memoryPrefix + ' '
if operandNode.attrib.get('VSIB', '0') != '0':
asm += '[' + operandNode.attrib.get('VSIB') + '0]'
elif operandNode.attrib.get('moffs', '0') != '0':
asm += '[0x1111111111111111]'
else:
asm += '[RAX]'
memorySuffix = operandNode.attrib.get('memory-suffix', '')
if memorySuffix:
asm += ' ' + memorySuffix
elif operandNode.attrib['type'] == 'agen':
agen = instrNode.attrib['agen']
address = []
if 'R' in agen: address.append('RIP')
if 'B' in agen: address.append('RAX')
if 'IS' in agen: address.append('2*RBX')
elif 'I' in agen: address.append('1*RBX')
if 'D8' in agen: address.append('8')
if 'D32' in agen: address.append('128')
asm += ' [' + '+'.join(address) + ']'
elif operandNode.attrib['type'] == 'imm':
if instrNode.attrib.get('roundc', '') == '1':
asm += '{rn-sae}, '
elif instrNode.attrib.get('sae', '') == '1':
asm += '{sae}, '
width = int(operandNode.attrib['width'])
if operandNode.text is not None:
imm = operandNode.text
else:
imm = (1 << (width-8)) + 1
asm += str(imm)
elif operandNode.attrib['type'] == 'relbr':
asm = '1: ' + asm + '1b'
if not 'sae' in asm:
if instrNode.attrib.get('roundc', '') == '1':
asm += ', {rn-sae}'
elif instrNode.attrib.get('sae', '') == '1':
asm += ', {sae}'
print(asm)
if __name__ == "__main__":
main()