comparison cpu_dsl.py @ 1618:5dbc453cd345

Getting SVP core closer to compiling
author Michael Pavone <pavone@retrodev.com>
date Mon, 01 Oct 2018 19:11:17 -0700
parents 8c78543c4783
children 0e8438a4c76f
comparison
equal deleted inserted replaced
1617:5e04f9f8bd85 1618:5dbc453cd345
38 self.implementation = [] 38 self.implementation = []
39 self.locals = {} 39 self.locals = {}
40 self.regValues = {} 40 self.regValues = {}
41 self.varyingBits = 0 41 self.varyingBits = 0
42 self.invalidFieldValues = {} 42 self.invalidFieldValues = {}
43 self.newLocals = []
43 for field in fields: 44 for field in fields:
44 self.varyingBits += fields[field][1] 45 self.varyingBits += fields[field][1]
45 46
46 def addOp(self, op): 47 def addOp(self, op):
47 if op.op == 'local': 48 if op.op == 'local':
60 return name 61 return name
61 return None 62 return None
62 63
63 def addLocal(self, name, size): 64 def addLocal(self, name, size):
64 self.locals[name] = size 65 self.locals[name] = size
66 self.newLocals.append(name)
65 67
66 def localSize(self, name): 68 def localSize(self, name):
67 return self.locals.get(name) 69 return self.locals.get(name)
68 70
69 def __lt__(self, other): 71 def __lt__(self, other):
111 return funName 113 return funName
112 114
113 def generateBody(self, value, prog, otype): 115 def generateBody(self, value, prog, otype):
114 output = [] 116 output = []
115 prog.meta = {} 117 prog.meta = {}
116 prog.currentScope = self 118 prog.pushScope(self)
117 self.regValues = {} 119 self.regValues = {}
118 for var in self.locals: 120 for var in self.locals:
119 output.append('\n\tuint{sz}_t {name};'.format(sz=self.locals[var], name=var)) 121 output.append('\n\tuint{sz}_t {name};'.format(sz=self.locals[var], name=var))
122 self.newLocals = []
120 fieldVals,_ = self.getFieldVals(value) 123 fieldVals,_ = self.getFieldVals(value)
121 for op in self.implementation: 124 for op in self.implementation:
122 op.generate(prog, self, fieldVals, output, otype) 125 op.generate(prog, self, fieldVals, output, otype)
123 begin = '\nvoid ' + self.generateName(value) + '(' + prog.context_type + ' *context)\n{' 126 begin = '\nvoid ' + self.generateName(value) + '(' + prog.context_type + ' *context)\n{'
124 if prog.needFlagCoalesce: 127 if prog.needFlagCoalesce:
125 begin += prog.flags.coalesceFlags(prog, otype) 128 begin += prog.flags.coalesceFlags(prog, otype)
126 if prog.needFlagDisperse: 129 if prog.needFlagDisperse:
127 output.append(prog.flags.disperseFlags(prog, otype)) 130 output.append(prog.flags.disperseFlags(prog, otype))
131 for var in self.newLocals:
132 begin += '\n\tuint{sz}_t {name};'.format(sz=self.locals[var], name=var)
133 prog.popScope()
128 return begin + ''.join(output) + '\n}' 134 return begin + ''.join(output) + '\n}'
129 135
130 def __str__(self): 136 def __str__(self):
131 pieces = [self.name + ' ' + hex(self.value) + ' ' + str(self.fields)] 137 pieces = [self.name + ' ' + hex(self.value) + ' ' + str(self.fields)]
132 for name in self.locals: 138 for name in self.locals:
173 if len(params) != len(self.args): 179 if len(params) != len(self.args):
174 raise Exception('{0} expects {1} arguments, but was called with {2}'.format(self.name, len(self.args), len(params))) 180 raise Exception('{0} expects {1} arguments, but was called with {2}'.format(self.name, len(self.args), len(params)))
175 argValues = {} 181 argValues = {}
176 if parent: 182 if parent:
177 self.regValues = parent.regValues 183 self.regValues = parent.regValues
178 oldScope = prog.currentScope 184 prog.pushScope(self)
179 prog.currentScope = self
180 i = 0 185 i = 0
181 for name,size in self.args: 186 for name,size in self.args:
182 argValues[name] = params[i] 187 argValues[name] = params[i]
183 i += 1 188 i += 1
184 for name in self.locals: 189 for name in self.locals:
185 size = self.locals[name] 190 size = self.locals[name]
186 output.append('\n\tuint{size}_t {sub}_{local};'.format(size=size, sub=self.name, local=name)) 191 output.append('\n\tuint{size}_t {sub}_{local};'.format(size=size, sub=self.name, local=name))
187 for op in self.implementation: 192 for op in self.implementation:
188 op.generate(prog, self, argValues, output, otype) 193 op.generate(prog, self, argValues, output, otype)
189 prog.currentScope = oldScope 194 prog.popScope()
190 195
191 def __str__(self): 196 def __str__(self):
192 pieces = [self.name] 197 pieces = [self.name]
193 for name,size in self.args: 198 for name,size in self.args:
194 pieces.append('\n\targ {0} {1}'.format(name, size)) 199 pieces.append('\n\targ {0} {1}'.format(name, size))
282 output = [] 287 output = []
283 #TODO: handle autoUpdate flags 288 #TODO: handle autoUpdate flags
284 for flag in autoUpdate: 289 for flag in autoUpdate:
285 calc = prog.flags.flagCalc[flag] 290 calc = prog.flags.flagCalc[flag]
286 calc,_,resultBit = calc.partition('-') 291 calc,_,resultBit = calc.partition('-')
287 lastDst = prog.resolveReg(prog.lastDst, None, {}) 292 lastDst = prog.resolveParam(prog.lastDst, None, {})
288 storage = prog.flags.getStorage(flag) 293 storage = prog.flags.getStorage(flag)
289 if calc == 'bit' or calc == 'sign': 294 if calc == 'bit' or calc == 'sign':
290 if calc == 'sign': 295 if calc == 'sign':
291 resultBit = prog.paramSize(prog.lastDst) - 1 296 resultBit = prog.paramSize(prog.lastDst) - 1
292 else: 297 else:
293 resultBit = int(resultBit) 298 resultBit = int(resultBit)
294 if type(storage) is tuple: 299 if type(storage) is tuple:
295 reg,storageBit = storage 300 reg,storageBit = storage
296 reg = prog.resolveReg(reg, None, {}) 301 reg = prog.resolveParam(reg, None, {})
297 if storageBit == resultBit: 302 if storageBit == resultBit:
298 #TODO: optimize this case 303 #TODO: optimize this case
299 output.append('\n\t{reg} = ({reg} & ~{mask}) | ({res} & {mask});'.format( 304 output.append('\n\t{reg} = ({reg} & ~{mask}U) | ({res} & {mask}U);'.format(
300 reg = reg, mask = 1 << resultBit, res = lastDst 305 reg = reg, mask = 1 << resultBit, res = lastDst
301 )) 306 ))
302 else: 307 else:
303 if resultBit > storageBit: 308 if resultBit > storageBit:
304 op = '>>' 309 op = '>>'
305 shift = resultBit - storageBit 310 shift = resultBit - storageBit
306 else: 311 else:
307 op = '<<' 312 op = '<<'
308 shift = storageBit - resultBit 313 shift = storageBit - resultBit
309 output.append('\n\t{reg} = ({reg} & ~{mask}) | ({res} {op} {shift} & {mask});'.format( 314 output.append('\n\t{reg} = ({reg} & ~{mask}U) | ({res} {op} {shift}U & {mask}U);'.format(
310 reg = reg, mask = 1 << storageBit, res = lastDst, op = op, shift = shift 315 reg = reg, mask = 1 << storageBit, res = lastDst, op = op, shift = shift
311 )) 316 ))
312 else: 317 else:
313 reg = prog.resolveReg(storage, None, {}) 318 reg = prog.resolveParam(storage, None, {})
314 output.append('\n\t{reg} = {res} & {mask};'.format(reg=reg, res=lastDst, mask = 1 << resultBit)) 319 output.append('\n\t{reg} = {res} & {mask}U;'.format(reg=reg, res=lastDst, mask = 1 << resultBit))
315 elif calc == 'zero': 320 elif calc == 'zero':
316 if type(storage) is tuple: 321 if type(storage) is tuple:
317 reg,storageBit = storage 322 reg,storageBit = storage
318 reg = prog.resolveReg(reg, None, {}) 323 reg = prog.resolveParam(reg, None, {})
319 output.append('\n\t{reg} = {res} ? ({reg} & {mask}) : ({reg} | {bit});'.format( 324 output.append('\n\t{reg} = {res} ? ({reg} & {mask}U) : ({reg} | {bit}U);'.format(
320 reg = reg, mask = ~(1 << storageBit), res = lastDst, bit = 1 << storageBit 325 reg = reg, mask = ~(1 << storageBit), res = lastDst, bit = 1 << storageBit
321 )) 326 ))
322 elif prog.paramSize(prog.lastDst) > prog.paramSize(storage): 327 elif prog.paramSize(prog.lastDst) > prog.paramSize(storage):
323 reg = prog.resolveReg(storage, None, {}) 328 reg = prog.resolveParam(storage, None, {})
324 output.append('\n\t{reg} = {res} != 0;'.format( 329 output.append('\n\t{reg} = {res} != 0;'.format(
325 reg = reg, res = lastDst 330 reg = reg, res = lastDst
326 )) 331 ))
327 else: 332 else:
328 reg = prog.resolveReg(storage, None, {}) 333 reg = prog.resolveParam(storage, None, {})
329 output.append('\n\t{reg} = {res};'.format(reg = reg, res = lastDst)) 334 output.append('\n\t{reg} = {res};'.format(reg = reg, res = lastDst))
330 elif calc == 'half-carry': 335 elif calc == 'half-carry':
331 pass 336 pass
332 elif calc == 'carry': 337 elif calc == 'carry':
333 pass 338 pass
355 360
356 def _cmpCImpl(prog, params): 361 def _cmpCImpl(prog, params):
357 size = prog.paramSize(params[1]) 362 size = prog.paramSize(params[1])
358 tmpvar = 'cmp_tmp{sz}__'.format(sz=size) 363 tmpvar = 'cmp_tmp{sz}__'.format(sz=size)
359 typename = '' 364 typename = ''
360 if not prog.currentScope.resolveLocal(tmpvar): 365 scope = prog.getRootScope()
361 prog.currentScope.addLocal(tmpvar, size) 366 if not scope.resolveLocal(tmpvar):
362 typename = 'uint{sz}_t '.format(sz=size) 367 scope.addLocal(tmpvar, size)
363 prog.lastDst = tmpvar 368 prog.lastDst = tmpvar
364 return '\n\t{tp}{var} = {b} - {a};'.format(tp = typename, var = tmpvar, a = params[0], b = params[1]) 369 return '\n\t{var} = {b} - {a};'.format(var = tmpvar, a = params[0], b = params[1])
365 370
366 def _asrCImpl(prog, params, rawParams): 371 def _asrCImpl(prog, params, rawParams):
367 shiftSize = prog.paramSize(rawParams[0]) 372 shiftSize = prog.paramSize(rawParams[0])
368 mask = 1 << (shiftSize - 1) 373 mask = 1 << (shiftSize - 1)
369 return '\n\t{dst} = ({a} >> {b}) | ({a} & {mask}'.format(a = params[0], b = params[1], dst = params[2], mask = mask) 374 return '\n\t{dst} = ({a} >> {b}) | ({a} & {mask});'.format(a = params[0], b = params[1], dst = params[2], mask = mask)
370 375
371 _opMap = { 376 _opMap = {
372 'mov': Op(lambda val: val).cUnaryOperator(''), 377 'mov': Op(lambda val: val).cUnaryOperator(''),
373 'not': Op(lambda val: ~val).cUnaryOperator('~'), 378 'not': Op(lambda val: ~val).cUnaryOperator('~'),
374 'lnot': Op(lambda val: 0 if val else 1).cUnaryOperator('!'), 379 'lnot': Op(lambda val: 0 if val else 1).cUnaryOperator('!'),
379 'lsr': Op(lambda a, b: a >> b).cBinaryOperator('>>'), 384 'lsr': Op(lambda a, b: a >> b).cBinaryOperator('>>'),
380 'asr': Op(lambda a, b: a >> b).addImplementation('c', 2, _asrCImpl), 385 'asr': Op(lambda a, b: a >> b).addImplementation('c', 2, _asrCImpl),
381 'and': Op(lambda a, b: a & b).cBinaryOperator('&'), 386 'and': Op(lambda a, b: a & b).cBinaryOperator('&'),
382 'or': Op(lambda a, b: a | b).cBinaryOperator('|'), 387 'or': Op(lambda a, b: a | b).cBinaryOperator('|'),
383 'xor': Op(lambda a, b: a ^ b).cBinaryOperator('^'), 388 'xor': Op(lambda a, b: a ^ b).cBinaryOperator('^'),
389 'abs': Op(lambda val: abs(val)).addImplementation(
390 'c', 1, lambda prog, params: '\n\t{dst} = abs({src});'.format(dst=params[1], src=params[0])
391 ),
384 'cmp': Op().addImplementation('c', None, _cmpCImpl), 392 'cmp': Op().addImplementation('c', None, _cmpCImpl),
385 'ocall': Op().addImplementation('c', None, lambda prog, params: '\n\t{pre}{fun}({args});'.format( 393 'ocall': Op().addImplementation('c', None, lambda prog, params: '\n\t{pre}{fun}({args});'.format(
386 pre = prog.prefix, fun = params[0], args = ', '.join(['context'] + [str(p) for p in params[1:]]) 394 pre = prog.prefix, fun = params[0], args = ', '.join(['context'] + [str(p) for p in params[1:]])
387 )), 395 )),
388 'cycles': Op().addImplementation('c', None, 396 'cycles': Op().addImplementation('c', None,
389 lambda prog, params: '\n\tcontext->current_cycle += context->opts->gen.clock_divider * {0};'.format( 397 lambda prog, params: '\n\tcontext->cycles += context->opts->gen.clock_divider * {0};'.format(
390 params[0] 398 params[0]
391 ) 399 )
392 ), 400 ),
393 'addsize': Op( 401 'addsize': Op(
394 lambda a, b: b + (2 * a if a else 1) 402 lambda a, b: b + (2 * a if a else 1)
395 ).addImplementation('c', 2, lambda prog, params: '\n\t{dst} = {val} + {sz} ? {sz} * 2 : 1;'.format( 403 ).addImplementation('c', 2, lambda prog, params: '\n\t{dst} = {val} + {sz} ? {sz} * 2 : 1;'.format(
396 dst = params[1], sz = params[0], val = params[1] 404 dst = params[2], sz = params[0], val = params[1]
397 )), 405 )),
398 'decsize': Op( 406 'decsize': Op(
399 lambda a, b: b - (2 * a if a else 1) 407 lambda a, b: b - (2 * a if a else 1)
400 ).addImplementation('c', 2, lambda prog, params: '\n\t{dst} = {val} - {sz} ? {sz} * 2 : 1;'.format( 408 ).addImplementation('c', 2, lambda prog, params: '\n\t{dst} = {val} - {sz} ? {sz} * 2 : 1;'.format(
401 dst = params[2], sz = params[0], val = params[1] 409 dst = params[2], sz = params[0], val = params[1]
507 if name in self.current_locals: 515 if name in self.current_locals:
508 return self.current_locals[name] 516 return self.current_locals[name]
509 return self.parent.localSize(name) 517 return self.parent.localSize(name)
510 518
511 def generate(self, prog, parent, fieldVals, output, otype): 519 def generate(self, prog, parent, fieldVals, output, otype):
512 oldScope = prog.currentScope 520 prog.pushScope(self)
513 prog.currentScope = self
514 param = prog.resolveParam(self.param, parent, fieldVals) 521 param = prog.resolveParam(self.param, parent, fieldVals)
515 if type(param) is int: 522 if type(param) is int:
516 self.regValues = self.parent.regValues 523 self.regValues = self.parent.regValues
517 if param in self.cases: 524 if param in self.cases:
518 if self.case_locals[param]: 525 self.current_locals = self.case_locals[param]
519 output.append('\n\t{') 526 output.append('\n\t{')
520 for local in self.case_locals[param]: 527 for local in self.case_locals[param]:
521 output.append('\n\tuint{0}_t {1};'.format(self.case_locals[param][local], local)) 528 output.append('\n\tuint{0}_t {1};'.format(self.case_locals[param][local], local))
522 for op in self.cases[param]: 529 for op in self.cases[param]:
523 op.generate(prog, self, fieldVals, output, otype) 530 op.generate(prog, self, fieldVals, output, otype)
524 if self.case_locals[param]: 531 output.append('\n\t}')
525 output.append('\n\t}')
526 elif self.default: 532 elif self.default:
527 if self.default_locals: 533 self.current_locals = self.default_locals
528 output.append('\n\t{') 534 output.append('\n\t{')
529 for local in self.default: 535 for local in self.default_locals:
530 output.append('\n\tuint{0}_t {1};'.format(self.default[local], local)) 536 output.append('\n\tuint{0}_t {1};'.format(self.default[local], local))
531 for op in self.default: 537 for op in self.default:
532 op.generate(prog, self, fieldVals, output, otype) 538 op.generate(prog, self, fieldVals, output, otype)
539 output.append('\n\t}')
533 else: 540 else:
534 output.append('\n\tswitch(' + param + ')') 541 output.append('\n\tswitch(' + param + ')')
535 output.append('\n\t{') 542 output.append('\n\t{')
536 for case in self.cases: 543 for case in self.cases:
544 self.current_locals = self.case_locals[case]
537 self.regValues = dict(self.parent.regValues) 545 self.regValues = dict(self.parent.regValues)
538 output.append('\n\tcase {0}: '.format(case) + '{') 546 output.append('\n\tcase {0}: '.format(case) + '{')
539 for local in self.case_locals[case]: 547 for local in self.case_locals[case]:
540 output.append('\n\tuint{0}_t {1};'.format(self.case_locals[case][local], local)) 548 output.append('\n\tuint{0}_t {1};'.format(self.case_locals[case][local], local))
541 for op in self.cases[case]: 549 for op in self.cases[case]:
542 op.generate(prog, self, fieldVals, output, otype) 550 op.generate(prog, self, fieldVals, output, otype)
543 output.append('\n\tbreak;') 551 output.append('\n\tbreak;')
544 output.append('\n\t}') 552 output.append('\n\t}')
545 if self.default: 553 if self.default:
554 self.current_locals = self.default_locals
546 self.regValues = dict(self.parent.regValues) 555 self.regValues = dict(self.parent.regValues)
547 output.append('\n\tdefault: {') 556 output.append('\n\tdefault: {')
548 for local in self.default_locals: 557 for local in self.default_locals:
549 output.append('\n\tuint{0}_t {1};'.format(self.default_locals[local], local)) 558 output.append('\n\tuint{0}_t {1};'.format(self.default_locals[local], local))
550 for op in self.default: 559 for op in self.default:
551 op.generate(prog, self, fieldVals, output, otype) 560 op.generate(prog, self, fieldVals, output, otype)
552 output.append('\n\t}') 561 output.append('\n\t}')
553 prog.currentScope = oldScope 562 prog.popScope()
554 563
555 def __str__(self): 564 def __str__(self):
556 keys = self.cases.keys() 565 keys = self.cases.keys()
557 keys.sort() 566 keys.sort()
558 lines = ['\n\tswitch'] 567 lines = ['\n\tswitch']
607 return self.curLocals.get(name) 616 return self.curLocals.get(name)
608 617
609 def resolveLocal(self, name): 618 def resolveLocal(self, name):
610 if name in self.locals: 619 if name in self.locals:
611 return name 620 return name
612 return None 621 return self.parent.resolveLocal(name)
613 622
614 def _genTrueBody(self): 623 def _genTrueBody(self, prog, fieldVals, output, otype):
615 self.curLocals = self.locals 624 self.curLocals = self.locals
625 for local in self.locals:
626 output.append('\n\tuint{sz}_t {nm};'.format(sz=self.locals[local], nm=local))
616 for op in self.body: 627 for op in self.body:
617 op.generate(prog, self, fieldVals, output, otype) 628 op.generate(prog, self, fieldVals, output, otype)
618 629
619 def _genFalseBody(self): 630 def _genFalseBody(self, prog, fieldVals, output, otype):
620 self.curLocals = self.elseLocals 631 self.curLocals = self.elseLocals
621 for op in self.body: 632 for local in self.elseLocals:
633 output.append('\n\tuint{sz}_t {nm};'.format(sz=self.elseLocals[local], nm=local))
634 for op in self.elseBody:
622 op.generate(prog, self, fieldVals, output, otype) 635 op.generate(prog, self, fieldVals, output, otype)
623 636
624 def _genConstParam(self, param): 637 def _genConstParam(self, param, prog, fieldVals, output, otype):
625 if param: 638 if param:
626 self._genTrueBody() 639 self._genTrueBody(prog, fieldVals, output, otype)
627 else: 640 else:
628 self._genFalseBody() 641 self._genFalseBody(prog, fieldVals, output, otype)
629 642
630 def generate(self, prog, parent, fieldVals, output, otype): 643 def generate(self, prog, parent, fieldVals, output, otype):
631 self.regValues = parent.regValues 644 self.regValues = parent.regValues
632 try: 645 try:
633 self._genConstParam(prog.checkBool(self.cond)) 646 self._genConstParam(prog.checkBool(self.cond), prog, fieldVals, output, otype)
634 except Exception: 647 except Exception:
635 if self.cond in _ifCmpImpl[otype]: 648 if self.cond in _ifCmpImpl[otype]:
636 output.append(_ifCmpImpl[otype][self.cond](prog, parent, fieldVals, output)) 649 output.append(_ifCmpImpl[otype][self.cond](prog, parent, fieldVals, output))
637 for op in self.body: 650 self._genTrueBody(prog, fieldVals, output, otype)
638 op.generate(prog, self, fieldVals, output, otype)
639 if self.elseBody: 651 if self.elseBody:
640 output.append('\n\t} else {') 652 output.append('\n\t} else {')
641 for op in self.elseBody: 653 self._genFalseBody(prog, fieldVals, output, otype)
642 op.generate(prog, self, fieldVals, output, otype)
643 output.append('\n\t}') 654 output.append('\n\t}')
644 else: 655 else:
645 cond = prog.resolveParam(self.cond, parent, fieldVals) 656 cond = prog.resolveParam(self.cond, parent, fieldVals)
646 if type(cond) is int: 657 if type(cond) is int:
647 if cond: 658 self._genConstParam(cond, prog, fieldVals, output, otype)
648 for op in self.body:
649 op.generate(prog, self, fieldVals, output, otype)
650 else:
651 for op in self.elseBody:
652 op.generate(prog, self, fieldVals, output, otype)
653 else: 659 else:
654 output.append('\n\tif ({cond}) '.format(cond=cond) + '{') 660 output.append('\n\tif ({cond}) '.format(cond=cond) + '{')
655 for op in self.body: 661 self._genTrueBody(prog, fieldVals, output, otype)
656 op.generate(prog, self, fieldVals, output, otype)
657 if self.elseBody: 662 if self.elseBody:
658 output.append('\n\t} else {') 663 output.append('\n\t} else {')
659 for op in self.elseBody: 664 self._genFalseBody(prog, fieldVals, output, otype)
660 op.generate(prog, self, fieldVals, output, otype)
661 output.append('\n\t}') 665 output.append('\n\t}')
662 666
663 667
664 def __str__(self): 668 def __str__(self):
665 lines = ['\n\tif'] 669 lines = ['\n\tif']
716 elif len(parts) > 2: 720 elif len(parts) > 2:
717 self.addRegArray(parts[0], int(parts[1]), parts[2:]) 721 self.addRegArray(parts[0], int(parts[1]), parts[2:])
718 else: 722 else:
719 self.addReg(parts[0], int(parts[1])) 723 self.addReg(parts[0], int(parts[1]))
720 return self 724 return self
725
726 def writeHeader(self, otype, hFile):
727 fieldList = []
728 for reg in self.regs:
729 if not self.isRegArrayMember(reg):
730 fieldList.append((self.regs[reg], 1, reg))
731 for arr in self.regArrays:
732 size,regs = self.regArrays[arr]
733 if not type(regs) is int:
734 regs = len(regs)
735 fieldList.append((size, regs, arr))
736 fieldList.sort()
737 fieldList.reverse()
738 for size, count, name in fieldList:
739 if count > 1:
740 hFile.write('\n\tuint{sz}_t {nm}[{ct}];'.format(sz=size, nm=name, ct=count))
741 else:
742 hFile.write('\n\tuint{sz}_t {nm};'.format(sz=size, nm=name))
721 743
722 class Flags: 744 class Flags:
723 def __init__(self): 745 def __init__(self):
724 self.flagBits = {} 746 self.flagBits = {}
725 self.flagCalc = {} 747 self.flagCalc = {}
752 raise Exception('Undefined flag ' + flag) 774 raise Exception('Undefined flag ' + flag)
753 loc,_,bit = self.flagStorage[flag].partition('.') 775 loc,_,bit = self.flagStorage[flag].partition('.')
754 if bit: 776 if bit:
755 return (loc, int(bit)) 777 return (loc, int(bit))
756 else: 778 else:
757 return loc 779 return loc
758 780
759 def disperseFlags(self, prog, otype): 781 def disperseFlags(self, prog, otype):
760 bitToFlag = [None] * (self.maxBit+1) 782 bitToFlag = [None] * (self.maxBit+1)
761 src = prog.resolveReg(self.flagReg, None, {}) 783 src = prog.resolveReg(self.flagReg, None, {})
762 output = [] 784 output = []
870 self.extra_tables = info.get('extra_tables', []) 892 self.extra_tables = info.get('extra_tables', [])
871 self.context_type = self.prefix + 'context' 893 self.context_type = self.prefix + 'context'
872 self.body = info.get('body', [None])[0] 894 self.body = info.get('body', [None])[0]
873 self.flags = flags 895 self.flags = flags
874 self.lastDst = None 896 self.lastDst = None
897 self.scopes = []
875 self.currentScope = None 898 self.currentScope = None
876 self.lastOp = None 899 self.lastOp = None
877 900
878 def __str__(self): 901 def __str__(self):
879 pieces = [] 902 pieces = []
883 pieces.append('\n'+str(self.subroutines[name])) 906 pieces.append('\n'+str(self.subroutines[name]))
884 for instruction in self.instructions: 907 for instruction in self.instructions:
885 pieces.append('\n'+str(instruction)) 908 pieces.append('\n'+str(instruction))
886 return ''.join(pieces) 909 return ''.join(pieces)
887 910
911 def writeHeader(self, otype, header):
912 hFile = open(header, 'w')
913 macro = header.upper().replace('.', '_')
914 hFile.write('#ifndef {0}_'.format(macro))
915 hFile.write('\n#define {0}_'.format(macro))
916 hFile.write('\n#include "backend.h"')
917 hFile.write('\n\ntypedef struct {')
918 hFile.write('\n\tcpu_options gen;')
919 hFile.write('\n}} {0}options;'.format(self.prefix))
920 hFile.write('\n\ntypedef struct {')
921 hFile.write('\n\t{0}options *opts;'.format(self.prefix))
922 hFile.write('\n\tuint32_t cycles;')
923 self.regs.writeHeader(otype, hFile)
924 hFile.write('\n}} {0}context;'.format(self.prefix))
925 hFile.write('\n')
926 hFile.write('\n#endif //{0}_'.format(macro))
927 hFile.write('\n')
928 hFile.close()
888 def build(self, otype): 929 def build(self, otype):
889 body = [] 930 body = []
890 pieces = [] 931 pieces = []
891 for table in self.instructions: 932 for table in self.instructions:
892 opmap = [None] * (1 << self.opsize) 933 opmap = [None] * (1 << self.opsize)
902 self.needFlagDisperse = False 943 self.needFlagDisperse = False
903 self.lastOp = None 944 self.lastOp = None
904 opmap[val] = inst.generateName(val) 945 opmap[val] = inst.generateName(val)
905 bodymap[val] = inst.generateBody(val, self, otype) 946 bodymap[val] = inst.generateBody(val, self, otype)
906 947
907 pieces.append('\nstatic void *impl_{name}[{sz}] = {{'.format(name = table, sz=len(opmap))) 948 pieces.append('\ntypedef void (*impl_fun)({pre}context *context);'.format(pre=self.prefix))
949 pieces.append('\nstatic impl_fun impl_{name}[{sz}] = {{'.format(name = table, sz=len(opmap)))
908 for inst in range(0, len(opmap)): 950 for inst in range(0, len(opmap)):
909 op = opmap[inst] 951 op = opmap[inst]
910 if op is None: 952 if op is None:
911 pieces.append('\n\tunimplemented,') 953 pieces.append('\n\tunimplemented,')
912 else: 954 else:
914 body.append(bodymap[inst]) 956 body.append(bodymap[inst])
915 pieces.append('\n};') 957 pieces.append('\n};')
916 if self.body in self.subroutines: 958 if self.body in self.subroutines:
917 pieces.append('\nvoid {pre}execute({type} *context, uint32_t target_cycle)'.format(pre = self.prefix, type = self.context_type)) 959 pieces.append('\nvoid {pre}execute({type} *context, uint32_t target_cycle)'.format(pre = self.prefix, type = self.context_type))
918 pieces.append('\n{') 960 pieces.append('\n{')
919 pieces.append('\n\twhile (context->current_cycle < target_cycle)') 961 pieces.append('\n\twhile (context->cycles < target_cycle)')
920 pieces.append('\n\t{') 962 pieces.append('\n\t{')
921 self.meta = {} 963 self.meta = {}
922 self.temp = {} 964 self.temp = {}
923 self.subroutines[self.body].inline(self, [], pieces, otype, None) 965 self.subroutines[self.body].inline(self, [], pieces, otype, None)
924 pieces.append('\n\t}') 966 pieces.append('\n\t}')
925 pieces.append('\n}') 967 pieces.append('\n}')
968 body.append('\nstatic void unimplemented({pre}context *context)'.format(pre = self.prefix))
969 body.append('\n{')
970 body.append('\n\tfatal_error("Unimplemented instruction");')
971 body.append('\n}\n')
926 return ''.join(body) + ''.join(pieces) 972 return ''.join(body) + ''.join(pieces)
927 973
928 def checkBool(self, name): 974 def checkBool(self, name):
929 if not name in self.booleans: 975 if not name in self.booleans:
930 raise Exception(name + ' is not a defined boolean flag') 976 raise Exception(name + ' is not a defined boolean flag')
1018 if sep and self.regs.isRegArray(begin): 1064 if sep and self.regs.isRegArray(begin):
1019 return self.regs.regArrays[begin][0] 1065 return self.regs.regArrays[begin][0]
1020 if self.regs.isReg(name): 1066 if self.regs.isReg(name):
1021 return self.regs.regs[name] 1067 return self.regs.regs[name]
1022 return 32 1068 return 32
1069
1070 def pushScope(self, scope):
1071 self.scopes.append(scope)
1072 self.currentScope = scope
1073
1074 def popScope(self):
1075 ret = self.scopes.pop()
1076 self.currentScope = self.scopes[-1] if self.scopes else None
1077 return ret
1078
1079 def getRootScope(self):
1080 return self.scopes[0]
1023 1081
1024 def parse(f): 1082 def parse(f):
1025 instructions = {} 1083 instructions = {}
1026 subroutines = {} 1084 subroutines = {}
1027 registers = None 1085 registers = None
1105 else: 1163 else:
1106 p = Program(registers, instructions, subroutines, info, flags) 1164 p = Program(registers, instructions, subroutines, info, flags)
1107 p.booleans['dynarec'] = False 1165 p.booleans['dynarec'] = False
1108 p.booleans['interp'] = True 1166 p.booleans['interp'] = True
1109 1167
1110 print('#include "m68k_prefix.c"') 1168 if 'header' in info:
1169 print('#include "{0}"'.format(info['header'][0]))
1170 p.writeHeader('c', info['header'][0])
1171 print('#include "util.h"')
1172 print('#include <stdlib.h>')
1111 print(p.build('c')) 1173 print(p.build('c'))
1112 1174
1113 def main(argv): 1175 def main(argv):
1114 f = open(argv[1]) 1176 f = open(argv[1])
1115 parse(f) 1177 parse(f)