pavone@214
|
1 #!/usr/bin/env python
|
pavone@214
|
2
|
pavone@214
|
3 def split_fields(line):
|
pavone@214
|
4 parts = []
|
pavone@214
|
5 while line:
|
pavone@214
|
6 field,_,line = line.partition('\t')
|
pavone@214
|
7 parts.append(field.strip())
|
pavone@214
|
8 while line.startswith('\t'):
|
pavone@214
|
9 line = line[1:]
|
pavone@214
|
10 return parts
|
pavone@214
|
11
|
pavone@214
|
12 class Program(object):
|
pavone@214
|
13 def __init__(self, instruction):
|
pavone@214
|
14 self.avail_dregs = {0,1,2,3,4,5,6,7}
|
pavone@214
|
15 self.avail_aregs = {0,1,2,3,4,5,6,7}
|
pavone@214
|
16 instruction.consume_regs(self)
|
pavone@214
|
17 self.inst = instruction
|
pavone@214
|
18
|
pavone@224
|
19 def dirname(self):
|
pavone@224
|
20 return self.inst.name + '_' + self.inst.size
|
pavone@214
|
21 def name(self):
|
pavone@214
|
22 return str(self.inst).replace('.', '_').replace('#', '_').replace(',', '_').replace(' ', '_').replace('(', '[').replace(')', ']')
|
pavone@214
|
23
|
pavone@214
|
24 def write_rom_test(self, outfile):
|
pavone@214
|
25 outfile.write('\tdc.l $0, start\n')
|
pavone@227
|
26 needdivzero = self.inst.name.startswith('div')
|
pavone@325
|
27 needchk = self.inst.name.startswith('chk')
|
pavone@214
|
28 for i in xrange(0x8, 0x100, 0x4):
|
pavone@227
|
29 if needdivzero and i == 0x14:
|
pavone@227
|
30 outfile.write('\tdc.l div_zero_handler\n')
|
pavone@325
|
31 elif needchk and i == 0x18:
|
pavone@325
|
32 outfile.write('\tdc.l chk_handler\n')
|
pavone@227
|
33 else:
|
pavone@227
|
34 outfile.write('\tdc.l empty_handler\n')
|
pavone@227
|
35 outfile.write('\tdc.b "SEGA"\nempty_handler:\n\trte\n')
|
pavone@227
|
36 if needdivzero:
|
pavone@227
|
37 outfile.write('div_zero_handler:\n')
|
pavone@227
|
38 div_zero_count = self.get_dreg()
|
pavone@227
|
39 outfile.write('\taddq #1, ' + str(div_zero_count) + '\n')
|
pavone@227
|
40 outfile.write('\trte\n')
|
pavone@325
|
41 if needchk:
|
pavone@325
|
42 outfile.write('chk_handler:\n')
|
pavone@325
|
43 chk_count = self.get_dreg()
|
pavone@325
|
44 outfile.write('\taddq #1, ' + str(chk_count) + '\n')
|
pavone@325
|
45 outfile.write('\trte\n')
|
pavone@227
|
46 outfile.write('start:\n\tmove #0, CCR\n')
|
pavone@227
|
47 if needdivzero:
|
pavone@227
|
48 outfile.write('\tmoveq #0, ' + str(div_zero_count) + '\n')
|
pavone@214
|
49 already = {}
|
pavone@214
|
50 self.inst.write_init(outfile, already)
|
pavone@214
|
51 if 'label' in already:
|
pavone@214
|
52 outfile.write('lbl_' + str(already['label']) + ':\n')
|
pavone@214
|
53 outfile.write('\t'+str(self.inst)+'\n')
|
pavone@214
|
54 outfile.write('\t'+self.inst.save_result(self.get_dreg(), True) + '\n')
|
pavone@214
|
55 save_ccr = self.get_dreg()
|
pavone@214
|
56 outfile.write('\tmove SR, ' + str(save_ccr) + '\n')
|
pavone@214
|
57 outfile.write('\tmove #$1F, CCR\n')
|
pavone@214
|
58 self.inst.invalidate_dest(already)
|
pavone@214
|
59 self.inst.write_init(outfile, already)
|
pavone@214
|
60 if 'label' in already:
|
pavone@214
|
61 outfile.write('lbl_' + str(already['label']) + ':\n')
|
pavone@214
|
62 outfile.write('\t'+str(self.inst)+'\n')
|
pavone@214
|
63 outfile.write('\t'+self.inst.save_result(self.get_dreg(), False) + '\n')
|
pavone@214
|
64 outfile.write('\treset\n')
|
pavone@214
|
65
|
pavone@214
|
66 def consume_dreg(self, num):
|
pavone@214
|
67 self.avail_dregs.discard(num)
|
pavone@214
|
68
|
pavone@214
|
69 def consume_areg(self, num):
|
pavone@214
|
70 self.avail_aregs.discard(num)
|
pavone@214
|
71
|
pavone@214
|
72 def get_dreg(self):
|
pavone@214
|
73 return Register('d', self.avail_dregs.pop())
|
pavone@214
|
74
|
pavone@439
|
75 class Dummy(object):
|
pavone@439
|
76 def __str__(self):
|
pavone@439
|
77 return ''
|
pavone@439
|
78 def write_init(self, outfile, size, already):
|
pavone@439
|
79 pass
|
pavone@439
|
80 def consume_regs(self, program):
|
pavone@439
|
81 pass
|
pavone@439
|
82
|
pavone@439
|
83 dummy_op = Dummy()
|
pavone@439
|
84
|
pavone@214
|
85 class Register(object):
|
pavone@214
|
86 def __init__(self, kind, num):
|
pavone@214
|
87 self.kind = kind
|
pavone@214
|
88 self.num = num
|
pavone@214
|
89
|
pavone@214
|
90 def __str__(self):
|
pavone@214
|
91 if self.kind == 'd' or self.kind == 'a':
|
pavone@214
|
92 return self.kind + str(self.num)
|
pavone@214
|
93 return self.kind
|
pavone@214
|
94
|
pavone@214
|
95 def write_init(self, outfile, size, already):
|
pavone@214
|
96 if not str(self) in already:
|
pavone@214
|
97 minv,maxv = get_size_range(size)
|
pavone@214
|
98 val = randint(minv,maxv)
|
pavone@214
|
99 already[str(self)] = val
|
pavone@214
|
100 outfile.write('\tmove.'+size+' #'+str(val)+', ' + str(self) + '\n')
|
pavone@214
|
101
|
pavone@214
|
102 def consume_regs(self, program):
|
pavone@214
|
103 if self.kind == 'd':
|
pavone@214
|
104 program.consume_dreg(self.num)
|
pavone@214
|
105 elif self.kind == 'a':
|
pavone@214
|
106 program.consume_areg(self.num)
|
pavone@214
|
107
|
pavone@214
|
108 def valid_ram_address(address, size='b'):
|
pavone@214
|
109 return address >= 0xE00000 and address <= 0xFFFFFFFC and (address & 0xE00000) == 0xE00000 and (size == 'b' or not address & 1)
|
pavone@214
|
110
|
pavone@214
|
111 def random_ram_address(mina=0xE00000, maxa=0xFFFFFFFC):
|
pavone@214
|
112 return randint(mina, maxa) | 0xE00000
|
pavone@214
|
113
|
pavone@214
|
114 class Indexed(object):
|
pavone@214
|
115 def __init__(self, base, index, index_size, disp):
|
pavone@214
|
116 self.base = base
|
pavone@214
|
117 self.index = index
|
pavone@214
|
118 self.index_size = index_size
|
pavone@214
|
119 self.disp = disp
|
pavone@214
|
120
|
pavone@214
|
121 def write_init(self, outfile, size, already):
|
pavone@214
|
122 if self.base.kind == 'pc':
|
pavone@214
|
123 if str(self.index) in already:
|
pavone@214
|
124 index = already[str(self.index)]
|
pavone@214
|
125 if self.index_size == 'w':
|
pavone@214
|
126 index = index & 0xFFFF
|
pavone@214
|
127 #sign extend index
|
pavone@214
|
128 if index & 0x8000:
|
pavone@214
|
129 index -= 65536
|
pavone@214
|
130 if index > -1024:
|
pavone@214
|
131 index = already[str(self.index)] = randint(-32768, -1024)
|
pavone@214
|
132 outfile.write('\tmove.l #' + str(index) + ', ' + str(self.index) + '\n')
|
pavone@214
|
133 else:
|
pavone@214
|
134 index = already[str(self.index)] = randint(-32768, -1024)
|
pavone@214
|
135 outfile.write('\tmove.l #' + str(index) + ', ' + str(self.index) + '\n')
|
pavone@214
|
136 num = already.get('label', 0)+1
|
pavone@214
|
137 already['label'] = num
|
pavone@214
|
138 address = 'lbl_' + str(num) + ' + 2 + ' + str(self.disp) + ' + ' + str(index)
|
pavone@214
|
139 else:
|
pavone@217
|
140 if self.base == self.index:
|
pavone@217
|
141 if str(self.base) in already:
|
pavone@217
|
142 if not valid_ram_address(already[str(self.base)]*2):
|
pavone@217
|
143 del already[str(self.base)]
|
pavone@217
|
144 self.write_init(outfile, size, already)
|
pavone@217
|
145 return
|
pavone@217
|
146 else:
|
pavone@217
|
147 base = index = already[str(self.base)]
|
pavone@214
|
148 else:
|
pavone@217
|
149 base = index = already[str(self.base)] = random_ram_address()/2
|
pavone@217
|
150 outfile.write('\tmove.l #' + str(base) + ', ' + str(self.base) + '\n')
|
pavone@214
|
151 else:
|
pavone@217
|
152 if str(self.base) in already:
|
pavone@217
|
153 if not valid_ram_address(already[str(self.base)]):
|
pavone@217
|
154 del already[str(self.base)]
|
pavone@217
|
155 self.write_init(outfile, size, already)
|
pavone@217
|
156 return
|
pavone@217
|
157 else:
|
pavone@217
|
158 base = already[str(self.base)]
|
pavone@217
|
159 else:
|
pavone@217
|
160 base = already[str(self.base)] = random_ram_address()
|
pavone@217
|
161 outfile.write('\tmove.l #' + str(base) + ', ' + str(self.base) + '\n')
|
pavone@217
|
162 if str(self.index) in already:
|
pavone@217
|
163 index = already[str(self.index)]
|
pavone@217
|
164 if self.index_size == 'w':
|
pavone@217
|
165 index = index & 0xFFFF
|
pavone@217
|
166 #sign extend index
|
pavone@217
|
167 if index & 0x8000:
|
pavone@217
|
168 index -= 65536
|
pavone@217
|
169 if not valid_ram_address(base + index):
|
pavone@217
|
170 index = already[str(self.index)] = randint(-64, 63)
|
pavone@217
|
171 outfile.write('\tmove.l #' + str(index) + ', ' + str(self.index) + '\n')
|
pavone@217
|
172 else:
|
pavone@214
|
173 index = already[str(self.index)] = randint(-64, 63)
|
pavone@214
|
174 outfile.write('\tmove.l #' + str(index) + ', ' + str(self.index) + '\n')
|
pavone@214
|
175 address = base + index + self.disp
|
pavone@214
|
176 if (address & 0xFFFFFF) < 0xE00000:
|
pavone@214
|
177 if (address & 0xFFFFFF) < 128:
|
pavone@214
|
178 self.disp -= (address & 0xFFFFFF)
|
pavone@214
|
179 else:
|
pavone@214
|
180 self.disp += 0xE00000-(address & 0xFFFFFF)
|
pavone@608
|
181 if self.disp > 127:
|
pavone@608
|
182 self.disp = 127
|
pavone@608
|
183 elif self.disp < -128:
|
pavone@608
|
184 self.disp = -128
|
pavone@214
|
185 address = base + index + self.disp
|
pavone@214
|
186 elif (address & 0xFFFFFF) > 0xFFFFFC:
|
pavone@214
|
187 self.disp -= (address & 0xFFFFFF) - 0xFFFFFC
|
pavone@608
|
188 if self.disp > 127:
|
pavone@608
|
189 self.disp = 127
|
pavone@608
|
190 elif self.disp < -128:
|
pavone@608
|
191 self.disp = -128
|
pavone@214
|
192 address = base + index + self.disp
|
pavone@214
|
193 if size != 'b' and address & 1:
|
pavone@214
|
194 self.disp = self.disp ^ 1
|
pavone@214
|
195 address = base + index + self.disp
|
pavone@214
|
196 minv,maxv = get_size_range(size)
|
pavone@214
|
197 outfile.write('\tmove.' + size + ' #' + str(randint(minv, maxv)) + ', (' + str(address) + ').l\n')
|
pavone@214
|
198
|
pavone@214
|
199 def __str__(self):
|
pavone@214
|
200 return '(' + str(self.disp) + ', ' + str(self.base) + ', ' + str(self.index) + '.' + self.index_size + ')'
|
pavone@214
|
201
|
pavone@214
|
202 def consume_regs(self, program):
|
pavone@214
|
203 self.base.consume_regs(program)
|
pavone@214
|
204 self.index.consume_regs(program)
|
pavone@214
|
205
|
pavone@214
|
206 class Displacement(object):
|
pavone@214
|
207 def __init__(self, base, disp):
|
pavone@214
|
208 self.base = base
|
pavone@214
|
209 self.disp = disp
|
pavone@214
|
210
|
pavone@214
|
211 def write_init(self, outfile, size, already):
|
pavone@214
|
212 if self.base.kind == 'pc':
|
pavone@214
|
213 num = already.get('label', 0)+1
|
pavone@214
|
214 already['label'] = num
|
pavone@214
|
215 address = 'lbl_' + str(num) + ' + 2 + ' + str(self.disp)
|
pavone@214
|
216 else:
|
pavone@214
|
217 if str(self.base) in already:
|
pavone@214
|
218 if not valid_ram_address(already[str(self.base)]):
|
pavone@214
|
219 del already[str(self.base)]
|
pavone@214
|
220 self.write_init(outfile, size, already)
|
pavone@214
|
221 return
|
pavone@214
|
222 else:
|
pavone@214
|
223 base = already[str(self.base)]
|
pavone@214
|
224 else:
|
pavone@214
|
225 base = already[str(self.base)] = random_ram_address()
|
pavone@214
|
226 outfile.write('\tmove.l #' + str(base) + ', ' + str(self.base) + '\n')
|
pavone@214
|
227 address = base + self.disp
|
pavone@214
|
228 if (address & 0xFFFFFF) < 0xE00000:
|
pavone@214
|
229 if (address & 0xFFFFFF) < 0x10000:
|
pavone@214
|
230 self.disp -= (address & 0xFFFFFF)
|
pavone@214
|
231 else:
|
pavone@214
|
232 self.disp += 0xE00000-(address & 0xFFFFFF)
|
pavone@214
|
233 address = base + self.disp
|
pavone@214
|
234 elif (address & 0xFFFFFF) > 0xFFFFFC:
|
pavone@214
|
235 self.disp -= (address & 0xFFFFFF) - 0xFFFFFC
|
pavone@214
|
236 address = base + self.disp
|
pavone@214
|
237 if size != 'b' and address & 1:
|
pavone@214
|
238 self.disp = self.disp ^ 1
|
pavone@214
|
239 address = base + self.disp
|
pavone@214
|
240 minv,maxv = get_size_range(size)
|
pavone@214
|
241 outfile.write('\tmove.' + size + ' #' + str(randint(minv, maxv)) + ', (' + str(address) + ').l\n')
|
pavone@214
|
242
|
pavone@214
|
243 def __str__(self):
|
pavone@214
|
244 return '(' + str(self.disp) + ', ' + str(self.base) + ')'
|
pavone@214
|
245
|
pavone@214
|
246 def consume_regs(self, program):
|
pavone@214
|
247 self.base.consume_regs(program)
|
pavone@214
|
248
|
pavone@214
|
249 class Indirect(object):
|
pavone@214
|
250 def __init__(self, reg):
|
pavone@214
|
251 self.reg = reg
|
pavone@214
|
252
|
pavone@214
|
253 def __str__(self):
|
pavone@214
|
254 return '(' + str(self.reg) + ')'
|
pavone@214
|
255
|
pavone@214
|
256 def write_init(self, outfile, size, already):
|
pavone@214
|
257 if str(self.reg) in already:
|
pavone@214
|
258 if not valid_ram_address(already[str(self.reg)], size):
|
pavone@214
|
259 del already[str(self.reg)]
|
pavone@214
|
260 self.write_init(outfile, size, already)
|
pavone@214
|
261 return
|
pavone@214
|
262 else:
|
pavone@214
|
263 address = already[str(self.reg)]
|
pavone@214
|
264 else:
|
pavone@214
|
265 address = random_ram_address()
|
pavone@214
|
266 if size != 'b':
|
pavone@214
|
267 address = address & 0xFFFFFFFE
|
pavone@214
|
268 outfile.write('\tmove.l #' + str(address) + ', ' + str(self.reg) + '\n')
|
pavone@214
|
269 already[str(self.reg)] = address
|
pavone@214
|
270 minv,maxv = get_size_range(size)
|
pavone@214
|
271 outfile.write('\tmove.' + size + ' #' + str(randint(minv, maxv)) + ', (' + str(address) + ').l\n')
|
pavone@214
|
272
|
pavone@214
|
273 def consume_regs(self, program):
|
pavone@214
|
274 self.reg.consume_regs(program)
|
pavone@214
|
275
|
pavone@214
|
276 class Increment(object):
|
pavone@214
|
277 def __init__(self, reg):
|
pavone@214
|
278 self.reg = reg
|
pavone@214
|
279
|
pavone@214
|
280 def __str__(self):
|
pavone@214
|
281 return '(' + str(self.reg) + ')+'
|
pavone@214
|
282
|
pavone@214
|
283 def write_init(self, outfile, size, already):
|
pavone@214
|
284 if str(self.reg) in already:
|
pavone@214
|
285 if not valid_ram_address(already[str(self.reg)], size):
|
pavone@214
|
286 del already[str(self.reg)]
|
pavone@214
|
287 self.write_init(outfile, size, already)
|
pavone@214
|
288 return
|
pavone@214
|
289 else:
|
pavone@214
|
290 address = already[str(self.reg)]
|
pavone@214
|
291 else:
|
pavone@214
|
292 address = random_ram_address()
|
pavone@214
|
293 if size != 'b':
|
pavone@214
|
294 address = address & 0xFFFFFFFE
|
pavone@214
|
295 outfile.write('\tmove.l #' + str(address) + ', ' + str(self.reg) + '\n')
|
pavone@214
|
296 already[str(self.reg)] = address
|
pavone@214
|
297 minv,maxv = get_size_range(size)
|
pavone@214
|
298 outfile.write('\tmove.' + size + ' #' + str(randint(minv, maxv)) + ', (' + str(address) + ').l\n')
|
pavone@214
|
299
|
pavone@214
|
300 def consume_regs(self, program):
|
pavone@214
|
301 self.reg.consume_regs(program)
|
pavone@214
|
302
|
pavone@214
|
303 class Decrement(object):
|
pavone@214
|
304 def __init__(self, reg):
|
pavone@214
|
305 self.reg = reg
|
pavone@214
|
306
|
pavone@214
|
307 def __str__(self):
|
pavone@214
|
308 return '-(' + str(self.reg) + ')'
|
pavone@214
|
309
|
pavone@214
|
310 def write_init(self, outfile, size, already):
|
pavone@214
|
311 if str(self.reg) in already:
|
pavone@214
|
312 if not valid_ram_address(already[str(self.reg)]- 4 if size == 'l' else 2 if size == 'w' else 1, size):
|
pavone@214
|
313 del already[str(self.reg)]
|
pavone@214
|
314 self.write_init(outfile, size, already)
|
pavone@214
|
315 return
|
pavone@214
|
316 else:
|
pavone@214
|
317 address = already[str(self.reg)]
|
pavone@214
|
318 else:
|
pavone@214
|
319 address = random_ram_address(mina=0xE00004)
|
pavone@214
|
320 if size != 'b':
|
pavone@214
|
321 address = address & 0xFFFFFFFE
|
pavone@214
|
322 outfile.write('\tmove.l #' + str(address) + ', ' + str(self.reg) + '\n')
|
pavone@214
|
323 already[str(self.reg)] = address
|
pavone@214
|
324 minv,maxv = get_size_range(size)
|
pavone@214
|
325 outfile.write('\tmove.' + size + ' #' + str(randint(minv, maxv)) + ', (' + str(address) + ').l\n')
|
pavone@214
|
326
|
pavone@214
|
327 def consume_regs(self, program):
|
pavone@214
|
328 self.reg.consume_regs(program)
|
pavone@214
|
329
|
pavone@214
|
330 class Absolute(object):
|
pavone@214
|
331 def __init__(self, address, size):
|
pavone@214
|
332 self.address = address
|
pavone@214
|
333 self.size = size
|
pavone@214
|
334
|
pavone@214
|
335 def __str__(self):
|
pavone@214
|
336 return '(' + str(self.address) + ').' + self.size
|
pavone@214
|
337
|
pavone@214
|
338 def write_init(self, outfile, size, already):
|
pavone@214
|
339 minv,maxv = get_size_range(size)
|
pavone@214
|
340 outfile.write('\tmove.' + size + ' #' + str(randint(minv, maxv)) + ', '+str(self)+'\n')
|
pavone@214
|
341
|
pavone@214
|
342 def consume_regs(self, program):
|
pavone@214
|
343 pass
|
pavone@214
|
344
|
pavone@214
|
345 class Immediate(object):
|
pavone@214
|
346 def __init__(self, value):
|
pavone@214
|
347 self.value = value
|
pavone@214
|
348
|
pavone@214
|
349 def __str__(self):
|
pavone@214
|
350 return '#' + str(self.value)
|
pavone@214
|
351
|
pavone@214
|
352 def write_init(self, outfile, size, already):
|
pavone@214
|
353 pass
|
pavone@214
|
354
|
pavone@214
|
355 def consume_regs(self, program):
|
pavone@214
|
356 pass
|
pavone@214
|
357
|
pavone@214
|
358 all_dregs = [Register('d', i) for i in range(0, 8)]
|
pavone@214
|
359 all_aregs = [Register('a', i) for i in range(0, 8)]
|
pavone@214
|
360 all_indirect = [Indirect(reg) for reg in all_aregs]
|
pavone@214
|
361 all_predec = [Decrement(reg) for reg in all_aregs]
|
pavone@214
|
362 all_postinc = [Increment(reg) for reg in all_aregs]
|
pavone@214
|
363 from random import randint
|
pavone@214
|
364 def all_indexed():
|
pavone@214
|
365 return [Indexed(base, index, index_size, randint(-128, 127)) for base in all_aregs for index in all_dregs + all_aregs for index_size in ('w','l')]
|
pavone@214
|
366
|
pavone@214
|
367 def all_disp():
|
pavone@214
|
368 return [Displacement(base, randint(-32768, 32767)) for base in all_aregs]
|
pavone@214
|
369
|
pavone@214
|
370 def rand_pc_disp():
|
pavone@214
|
371 return [Displacement(Register('pc', 0), randint(-32768, -1024)) for x in xrange(0, 8)]
|
pavone@214
|
372
|
pavone@214
|
373 def all_pc_indexed():
|
pavone@214
|
374 return [Indexed(Register('pc', 0), index, index_size, randint(-128, 127)) for index in all_dregs + all_aregs for index_size in ('w','l')]
|
pavone@214
|
375
|
pavone@214
|
376 def rand_abs_short():
|
pavone@214
|
377 return [Absolute(0xFFFF8000 + randint(0, 32767), 'w') for x in xrange(0, 8)]
|
pavone@214
|
378
|
pavone@214
|
379 def rand_abs_long():
|
pavone@214
|
380 return [Absolute(0xFF0000 + randint(0, 65535), 'l') for x in xrange(0, 8)]
|
pavone@214
|
381
|
pavone@214
|
382 def get_size_range(size):
|
pavone@214
|
383 if size == 'b':
|
pavone@214
|
384 return (-128, 127)
|
pavone@214
|
385 elif size == 'w':
|
pavone@214
|
386 return (-32768, 32767)
|
pavone@214
|
387 else:
|
pavone@214
|
388 return (-2147483648, 2147483647)
|
pavone@214
|
389
|
pavone@214
|
390 def rand_immediate(size):
|
pavone@214
|
391 minv,maxv = get_size_range(size)
|
pavone@214
|
392
|
pavone@214
|
393 return [Immediate(randint(minv, maxv)) for x in xrange(0,8)]
|
pavone@214
|
394
|
pavone@214
|
395 def get_variations(mode, size):
|
pavone@214
|
396 mapping = {
|
pavone@214
|
397 'd':all_dregs,
|
pavone@214
|
398 'a':all_aregs,
|
pavone@214
|
399 '(a)':all_indirect,
|
pavone@214
|
400 '-(a)':all_predec,
|
pavone@214
|
401 '(a)+':all_postinc,
|
pavone@214
|
402 '(n,a)':all_disp,
|
pavone@214
|
403 '(n,a,x)':all_indexed,
|
pavone@214
|
404 '(n,pc)':rand_pc_disp,
|
pavone@214
|
405 '(n,pc,x)':all_pc_indexed,
|
pavone@214
|
406 '(n).w':rand_abs_short,
|
pavone@214
|
407 '(n).l':rand_abs_long
|
pavone@214
|
408 }
|
pavone@214
|
409 if mode in mapping:
|
pavone@214
|
410 ret = mapping[mode]
|
pavone@214
|
411 if type(ret) != list:
|
pavone@214
|
412 ret = ret()
|
pavone@214
|
413 return ret
|
pavone@214
|
414 elif mode == '#n':
|
pavone@214
|
415 return rand_immediate(size)
|
pavone@214
|
416 elif mode.startswith('#(') and mode.endswith(')'):
|
pavone@214
|
417 inner = mode[2:-1]
|
pavone@224
|
418 start,sep,end = inner.rpartition('-')
|
pavone@220
|
419 start,end = int(start),int(end)
|
pavone@220
|
420 if end-start > 16:
|
pavone@220
|
421 return [Immediate(randint(start, end)) for x in range(0,8)]
|
pavone@220
|
422 else:
|
pavone@220
|
423 return [Immediate(num) for num in range(start, end+1)]
|
pavone@217
|
424 else:
|
pavone@217
|
425 print "Don't know what to do with source type", mode
|
pavone@217
|
426 return None
|
pavone@214
|
427
|
pavone@214
|
428 class Inst2Op(object):
|
pavone@214
|
429 def __init__(self, name, size, src, dst):
|
pavone@214
|
430 self.name = name
|
pavone@214
|
431 self.size = size
|
pavone@214
|
432 self.src = src
|
pavone@214
|
433 self.dst = dst
|
pavone@214
|
434
|
pavone@214
|
435 def __str__(self):
|
pavone@214
|
436 return self.name + '.' + self.size + ' ' + str(self.src) + ', ' + str(self.dst)
|
pavone@214
|
437
|
pavone@214
|
438 def write_init(self, outfile, already):
|
pavone@214
|
439 self.src.write_init(outfile, self.size, already)
|
pavone@214
|
440 self.dst.write_init(outfile, self.size, already)
|
pavone@214
|
441
|
pavone@214
|
442 def invalidate_dest(self, already):
|
pavone@214
|
443 if type(self.dst) == Register:
|
pavone@214
|
444 del already[str(self.dst)]
|
pavone@214
|
445
|
pavone@214
|
446 def save_result(self, reg, always):
|
pavone@214
|
447 if always or type(self.dst) != Register:
|
pavone@217
|
448 if type(self.dst) == Decrement:
|
pavone@217
|
449 src = Increment(self.dst.reg)
|
pavone@217
|
450 elif type(self.dst) == Increment:
|
pavone@217
|
451 src = Decrement(self.dst.reg)
|
pavone@217
|
452 else:
|
pavone@217
|
453 src = self.dst
|
pavone@217
|
454 return 'move.' + self.size + ' ' + str(src) + ', ' + str(reg)
|
pavone@214
|
455 else:
|
pavone@214
|
456 return ''
|
pavone@214
|
457
|
pavone@214
|
458 def consume_regs(self, program):
|
pavone@214
|
459 self.src.consume_regs(program)
|
pavone@214
|
460 self.dst.consume_regs(program)
|
pavone@214
|
461
|
pavone@439
|
462 class Inst1Op(Inst2Op):
|
pavone@439
|
463 def __init__(self, name, size, dst):
|
pavone@439
|
464 super(Inst1Op, self).__init__(name, size, dummy_op, dst)
|
pavone@439
|
465
|
pavone@439
|
466 def __str__(self):
|
pavone@439
|
467 return self.name + '.' + self.size + ' ' + str(self.dst)
|
pavone@439
|
468
|
pavone@214
|
469 class Entry(object):
|
pavone@214
|
470 def __init__(self, line):
|
pavone@214
|
471 fields = split_fields(line)
|
pavone@214
|
472 self.name = fields[0]
|
pavone@214
|
473 sizes = fields[1]
|
pavone@214
|
474 sources = fields[2].split(';')
|
pavone@439
|
475 if len(fields) > 3:
|
pavone@439
|
476 dests = fields[3].split(';')
|
pavone@439
|
477 else:
|
pavone@439
|
478 dests = None
|
pavone@214
|
479 combos = []
|
pavone@214
|
480 for size in sizes:
|
pavone@214
|
481 for source in sources:
|
pavone@214
|
482 if size != 'b' or source != 'a':
|
pavone@439
|
483 if dests:
|
pavone@439
|
484 for dest in dests:
|
pavone@439
|
485 if size != 'b' or dest != 'a':
|
pavone@439
|
486 combos.append((size, source, dest))
|
pavone@439
|
487 else:
|
pavone@439
|
488 combos.append((size, None, source))
|
pavone@214
|
489 self.cases = combos
|
pavone@214
|
490
|
pavone@214
|
491 def programs(self):
|
pavone@214
|
492 res = []
|
pavone@214
|
493 for (size, src, dst) in self.cases:
|
pavone@214
|
494 dests = get_variations(dst, size)
|
pavone@439
|
495 if src:
|
pavone@439
|
496 sources = get_variations(src, size)
|
pavone@439
|
497 for source in sources:
|
pavone@439
|
498 for dest in dests:
|
pavone@439
|
499 res.append(Program(Inst2Op(self.name, size, source, dest)))
|
pavone@439
|
500 else:
|
pavone@214
|
501 for dest in dests:
|
pavone@439
|
502 res.append(Program(Inst1Op(self.name, size, dest)))
|
pavone@214
|
503 return res
|
pavone@214
|
504
|
pavone@214
|
505 def process_entries(f):
|
pavone@214
|
506 entries = []
|
pavone@214
|
507 for line in f:
|
pavone@214
|
508 if not line.startswith('Name') and not line.startswith('#') and len(line.strip()) > 0:
|
pavone@214
|
509 entries.append(Entry(line))
|
pavone@214
|
510 return entries
|
pavone@214
|
511
|
pavone@224
|
512 from os import path, mkdir
|
pavone@214
|
513 def main(args):
|
pavone@214
|
514 entries = process_entries(open('testcases.txt'))
|
pavone@214
|
515 for entry in entries:
|
pavone@214
|
516 programs = entry.programs()
|
pavone@214
|
517 for program in programs:
|
pavone@224
|
518 dname = program.dirname()
|
pavone@224
|
519 if not path.exists('generated_tests/' + dname):
|
pavone@224
|
520 mkdir('generated_tests/' + dname)
|
pavone@224
|
521 f = open('generated_tests/' + dname + '/' + program.name() + '.s68', 'w')
|
pavone@214
|
522 program.write_rom_test(f)
|
pavone@214
|
523 f.close()
|
pavone@214
|
524
|
pavone@214
|
525 if __name__ == '__main__':
|
pavone@214
|
526 import sys
|
pavone@214
|
527 main(sys.argv)
|
pavone@214
|
528
|