annotate gentests.py @ 989:d70000fdff0b

Implemented IR and undefined bits of info word for address error exception frames
author Michael Pavone <pavone@retrodev.com>
date Wed, 27 Apr 2016 21:39:17 -0700
parents 097c172839d4
children 188a60def81f
rev   line source
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