-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathassembler.py
117 lines (109 loc) · 4.15 KB
/
assembler.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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
opcode = {
'add' : 0,'sub' : 1,'inc' : 2,'dec' : 3,'and' : 4,'or' : 5,
'neg' : 6,'ldi' : 7,'nand': 8,'nor' : 9,'xor' : 10,
'xnor': 11,'lshl': 12,'lshr': 13,'ashl': 14,'ashr': 15,
}
def binf(N:int, length:int)->str:
'''Convert a number to binary string of given width'''
Nbin = bin(N)[2:] if N>=0 else bin(N & (2**16-1))[2:]
Nbin = '0'*(length - len(Nbin)) + Nbin if len(Nbin) <= 16 else Nbin[:16]
return Nbin
def assemble(instr:str)->str:
instr = ''.join(filter(lambda ch:ch.isalnum() or ch==' ', instr))
instr = instr.lower().split()
res = ""
res += binf(opcode[instr[0]], 4)
if instr[1][0] == 'r':
res += binf(int(instr[1][1:]), 4)
else:
raise ValueError("Expected register")
if len(instr) == 2:
res += '0'*16
else:
if instr[2][0] == 'r':
res += binf(int(instr[2][1:]), 16)
else:
res += binf(int(instr[2], 16), 16)
return res
def mkcoe(code:str)->str:
coe = "memory_initialization_radix=2;\n" + "memory_initialization_vector=\n"
code = filter(None, code.splitlines())
for i, instr in enumerate(code):
coe += assemble(instr) if i==0 else ',\n' + assemble(instr)
coe += ";\n"
return coe
def interpret(code:str)->str:
regbank = [0 for _ in range(16)]
coe = "memory_initialization_radix=2;\n" + "memory_initialization_vector=\n"
code = filter(None, code.splitlines())
for i, instr in enumerate(code):
instr = assemble(instr)
opcode = int(instr[:4], 2)
op1 = int(instr[4:8], 2)
op2 = int(instr[8:], 2)
if i!=0:
coe += ",\n"
if opcode == 0:
regbank[op1] = int(binf(regbank[op1] + regbank[op2], 16), 2)
coe += binf(regbank[op1], 16)
elif opcode == 1:
regbank[op1] = int(binf(regbank[op1] - regbank[op2], 16), 2)
coe += binf(regbank[op1], 16)
elif opcode == 2:
regbank[op1] = int(binf(regbank[op1] + 1, 16), 2)
coe += binf(regbank[op1], 16)
elif opcode == 3:
regbank[op1] = int(binf(regbank[op1] - 1, 16), 2)
coe += binf(regbank[op1], 16)
elif opcode == 4:
regbank[op1] = int(binf(regbank[op1] & regbank[op2], 16), 2)
coe += binf(regbank[op1], 16)
elif opcode == 5:
regbank[op1] = int(binf(regbank[op1] | regbank[op2], 16), 2)
coe += binf(regbank[op1], 16)
elif opcode == 6:
regbank[op1] = int(binf(~regbank[op1], 16), 2)
coe += binf(regbank[op1], 16)
elif opcode == 7:
regbank[op1] = op2
coe += binf(0, 16)
elif opcode == 8:
regbank[op1] = int(binf(~(regbank[op1] & regbank[op2]), 16), 2)
coe += binf(regbank[op1], 16)
elif opcode == 9:
regbank[op1] = int(binf(~(regbank[op1] | regbank[op2]), 16), 2)
coe += binf(regbank[op1], 16)
elif opcode == 10:
regbank[op1] = int(binf((regbank[op1] ^ regbank[op2]), 16), 2)
coe += binf(regbank[op1], 16)
elif opcode == 11:
regbank[op1] = int(binf(~(regbank[op1] ^ regbank[op2]), 16), 2)
coe += binf(regbank[op1], 16)
elif opcode == 12:
regbank[op1] = int(binf((regbank[op1] << regbank[op2]), 16), 2)
coe += binf(regbank[op1], 16)
elif opcode == 13:
regbank[op1] = int(binf((regbank[op1] >> regbank[op2]), 16), 2)
coe += binf(regbank[op1], 16)
elif opcode == 14:
regbank[op1] = int(binf((regbank[op1] << regbank[op2]), 16), 2)
coe += binf(regbank[op1], 16)
elif opcode == 15:
regbank[op1] = int(binf(((regbank[op1] >> regbank[op2]) | (2**15 & regbank[op1]) ), 16), 2)
coe += binf(regbank[op1], 16)
else:
raise ValueError("wtf")
coe += ';\n'
return coe
code = '''
ldi r0, 0xf00f
ldi r1, 0x002
add r0, r1
sub r0, r1
add r0, r1
add r2, r0
dec r3
inc r4
'''
#print(interpret(code))
print(mkcoe(code))