-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
compile_arm.py
160 lines (118 loc) · 4.42 KB
/
compile_arm.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# Written by Folkert van Heusden
# Released in the public domain
import sys
from compile_x86 import CompileToX86
class CompileToARM(CompileToX86):
loopNr = 0
lnrs = []
functionsFirst = False
def header(self):
print('Brainfuck to ARM ASM compiler.', file=sys.stderr)
def get_name():
return ('arm', 'ARM assembly, Raspberry PI target')
def genindent(self, level):
return ' ' * (level * 4)
def invokeFunction(self, funcNr):
self.addComment('invoke function')
print('%sbl f%d' % (self.genindent(1), funcNr))
def addToDataPtr(self, n, dot, position):
ind = self.genindent(1)
self.addComment('add value to data pointer')
print('%sadd r0, r0, #%d' % (ind, n))
def subFromDataPtr(self, n, dot, position):
ind = self.genindent(1)
self.addComment('sub value from data pointer')
print('%ssub r0, r0, #%d' % (ind, n))
def addToData(self, n, dot, position):
ind = self.genindent(1)
self.addComment('add to data')
print('%sldrb r1,[r0]' % ind)
print('%sadd r1, r1, #%d' % (ind, n))
print('%sstrb r1,[r0]' % ind)
def subFromData(self, n, dot, position):
ind = self.genindent(1)
self.addComment('sub from data')
print('%sldrb r1,[r0]' % ind)
print('%ssub r1, r1, #%d' % (ind, n))
print('%sstrb r1,[r0]' % ind)
def emitCharacter(self, n, dot):
self.addComment('emit character(s)')
for i in range(0, n):
print('%sbl prtchr' % self.genindent(1))
print('')
def startLoop(self, n, position):
for j in range(0, n):
self.addComment('start of while loop')
loopName = 'wloop_%d' % self.loopNr
self.loopNr += 1
self.lnrs.append(loopName)
print('%s%s:' % (self.genindent(0), loopName))
ind = self.genindent(1)
print('%sldrb r1,[r0]' % ind)
print('%stst r1,r1' % ind)
print('%sbeq %s_e' % (ind, loopName))
self.lindentlevel += 1
def finishLoop(self, n, dot, position):
for j in range(0, n):
self.addComment('end of while loop')
jb_label = self.lnrs.pop(-1) # jump bakc label
print('%sb %s' % (self.genindent(1), jb_label))
jb_label_e = jb_label + "_e" # break out of while label
print('%s:' % jb_label_e)
def addComment(self, s):
print('// %s' % s)
def multilineCommentStart(self):
print('//')
def multilineCommentLine(self, s):
print('// %s' % s)
def multilineCommentEnd(self):
print('//')
def emitFunctions(self):
self.lindentlevel += 1
for blkLoop in range(0, len(self.blocks)):
self.addComment('function')
print('f%d:' % blkLoop)
i = self.genindent(1)
print('%spush { lr }' % i)
self.translate(self.blocks[blkLoop][0], self.blocks[blkLoop][1])
print('%spop { lr }' % i)
print('%sbx lr' % i)
print('.ltorg')
self.lindentlevel -= 1
def emitProgramTail(self):
print('.bss')
ind = self.genindent(1)
print('%s.lcomm buffer, 2' % ind)
print('%s.lcomm data_mem, 32000' % ind)
def emitMainFunction(self):
ind = self.genindent(1)
print('.global _start')
print('')
self.addComments(self.copyrightNotice)
print('.text')
print('_start:')
print('%sbl init' % ind)
# initialize print-buffer
print('%smov r1,#0' % ind)
print('%sstrb r1,[r2]' % ind)
self.translate(0, len(self.allCode))
print('')
print('%smov r0, $0' %ind)
print('%smov r7, $1' % ind) # sys_exit
print('%sswi $0' % ind)
ind = self.genindent(1)
print('prtchr:')
print('%spush { r0, r1, r2 }' % ind)
print('%sldrb r1,[r0]' % ind)
print('%sstrb r1,[r2]' % ind)
print('%smov r0, #1 ' % ind) # fd: STDOUT
print('%sldr r1,=buffer' % ind) # msg
print('%smov r2, #1 ' % ind) # count
print('%smov r7, #4 ' % ind) # write is syscall #4
print('%sswi $0 ' % ind) # syscall
print('%spop { r0, r1, r2 }' % ind)
print('%sbx lr' % ind)
print('init:')
print('%sldr r0,=data_mem' % ind)
print('%sldr r2,=buffer' % ind)
print('%sbx lr' % ind)