comparison cpu_dsl.py @ 1838:0c1491818f4b

WIP new 68K core using CPU DSL
author Michael Pavone <pavone@retrodev.com>
date Thu, 18 Apr 2019 19:47:50 -0700
parents 7b6831305a6a
children 9ab5184811ea
comparison
equal deleted inserted replaced
1837:f6ee0df6bb48 1838:0c1491818f4b
46 self.implementation = [] 46 self.implementation = []
47 self.locals = {} 47 self.locals = {}
48 self.regValues = {} 48 self.regValues = {}
49 self.varyingBits = 0 49 self.varyingBits = 0
50 self.invalidFieldValues = {} 50 self.invalidFieldValues = {}
51 self.invalidCombos = []
51 self.newLocals = [] 52 self.newLocals = []
52 for field in fields: 53 for field in fields:
53 self.varyingBits += fields[field][1] 54 self.varyingBits += fields[field][1]
54 55
55 def addOp(self, op): 56 def addOp(self, op):
56 if op.op == 'local': 57 if op.op == 'local':
57 name = op.params[0] 58 name = op.params[0]
58 size = int(op.params[1]) 59 size = int(op.params[1])
59 self.locals[name] = size 60 self.locals[name] = size
60 elif op.op == 'invalid': 61 elif op.op == 'invalid':
61 name = op.params[0] 62 if len(op.params) < 3:
62 value = int(op.params[1]) 63 name = op.params[0]
63 self.invalidFieldValues.setdefault(name, set()).add(value) 64 value = int(op.params[1])
65 self.invalidFieldValues.setdefault(name, set()).add(value)
66 else:
67 vmap = {}
68 for i in range(0, len(op.params), 2):
69 name = op.params[i]
70 value = int(op.params[i+1])
71 vmap[name] = value
72 self.invalidCombos.append(vmap)
64 else: 73 else:
65 self.implementation.append(op) 74 self.implementation.append(op)
66 75
67 def resolveLocal(self, name): 76 def resolveLocal(self, name):
68 if name in self.locals: 77 if name in self.locals:
87 def allValues(self): 96 def allValues(self):
88 values = [] 97 values = []
89 for i in range(0, 1 << self.varyingBits): 98 for i in range(0, 1 << self.varyingBits):
90 iword = self.value 99 iword = self.value
91 doIt = True 100 doIt = True
101 combos = []
102 for combo in self.invalidCombos:
103 combos.append(dict(combo))
92 for field in self.fields: 104 for field in self.fields:
93 shift,bits = self.fields[field] 105 shift,bits = self.fields[field]
94 val = i & ((1 << bits) - 1) 106 val = i & ((1 << bits) - 1)
95 if field in self.invalidFieldValues and val in self.invalidFieldValues[field]: 107 if field in self.invalidFieldValues and val in self.invalidFieldValues[field]:
96 doIt = False 108 doIt = False
109 break
110 nextcombos = []
111 for combo in combos:
112 if field in combo:
113 if combo[field] == val:
114 del combo[field]
115 if not combo:
116 doIt = False
117 break
118 else:
119 continue
120 nextcombos.append(combo)
121 combos = nextcombos
122 if not doIt:
97 break 123 break
98 i >>= bits 124 i >>= bits
99 iword |= val << shift 125 iword |= val << shift
100 if doIt: 126 if doIt:
101 values.append(iword) 127 values.append(iword)
130 self.newLocals = [] 156 self.newLocals = []
131 fieldVals,_ = self.getFieldVals(value) 157 fieldVals,_ = self.getFieldVals(value)
132 self.processOps(prog, fieldVals, output, otype, self.implementation) 158 self.processOps(prog, fieldVals, output, otype, self.implementation)
133 159
134 if prog.dispatch == 'call': 160 if prog.dispatch == 'call':
135 begin = '\nvoid ' + self.generateName(value) + '(' + prog.context_type + ' *context)\n{' 161 begin = '\nvoid ' + self.generateName(value) + '(' + prog.context_type + ' *context, uint32_t target_cycle)\n{'
136 elif prog.dispatch == 'goto': 162 elif prog.dispatch == 'goto':
137 begin = '\n' + self.generateName(value) + ': {' 163 begin = '\n' + self.generateName(value) + ': {'
138 else: 164 else:
139 raise Exception('Unsupported dispatch type ' + prog.dispatch) 165 raise Exception('Unsupported dispatch type ' + prog.dispatch)
140 if prog.needFlagCoalesce: 166 if prog.needFlagCoalesce:
141 begin += prog.flags.coalesceFlags(prog, otype) 167 begin += prog.flags.coalesceFlags(prog, otype)
142 if prog.needFlagDisperse: 168 if prog.needFlagDisperse:
143 output.append(prog.flags.disperseFlags(prog, otype)) 169 output.append(prog.flags.disperseFlags(prog, otype))
144 for var in self.newLocals: 170 for var in self.newLocals:
145 begin += '\n\tuint{sz}_t {name};'.format(sz=self.locals[var], name=var) 171 begin += '\n\tuint{sz}_t {name};'.format(sz=self.locals[var], name=var)
172 for size in prog.temp:
173 begin += '\n\tuint{sz}_t gen_tmp{sz}__;'.format(sz=size)
146 prog.popScope() 174 prog.popScope()
147 if prog.dispatch == 'goto': 175 if prog.dispatch == 'goto':
148 output += prog.nextInstruction(otype) 176 output += prog.nextInstruction(otype)
149 return begin + ''.join(output) + '\n}' 177 return begin + ''.join(output) + '\n}'
150 178
235 a = params[1] 263 a = params[1]
236 b = params[0] 264 b = params[0]
237 else: 265 else:
238 a = params[0] 266 a = params[0]
239 b = params[1] 267 b = params[1]
268 needsSizeAdjust = False
269 if len(params) > 3:
270 size = params[3]
271 if size == 0:
272 size = 8
273 elif size == 1:
274 size = 16
275 else:
276 size = 32
277 prog.lastSize = size
278 destSize = prog.paramSize(rawParams[2])
279 if destSize > size:
280 needsSizeAdjust = True
281 prog.sizeAdjust = size
240 needsCarry = needsOflow = needsHalf = False 282 needsCarry = needsOflow = needsHalf = False
241 if flagUpdates: 283 if flagUpdates:
242 for flag in flagUpdates: 284 for flag in flagUpdates:
243 calc = prog.flags.flagCalc[flag] 285 calc = prog.flags.flagCalc[flag]
244 if calc == 'carry': 286 if calc == 'carry':
246 elif calc == 'half-carry': 288 elif calc == 'half-carry':
247 needsHalf = True 289 needsHalf = True
248 elif calc == 'overflow': 290 elif calc == 'overflow':
249 needsOflow = True 291 needsOflow = True
250 decl = '' 292 decl = ''
251 if needsCarry or needsOflow or needsHalf: 293 if needsCarry or needsOflow or needsHalf or (flagUpdates and needsSizeAdjust):
252 size = prog.paramSize(rawParams[2]) 294 if len(params) <= 3:
295 size = prog.paramSize(rawParams[2])
253 if needsCarry and op != 'lsr': 296 if needsCarry and op != 'lsr':
254 size *= 2 297 size *= 2
255 decl,name = prog.getTemp(size) 298 decl,name = prog.getTemp(size)
256 dst = prog.carryFlowDst = name 299 dst = prog.carryFlowDst = name
257 prog.lastA = a 300 prog.lastA = a
258 prog.lastB = b 301 prog.lastB = b
302 if size == 64:
303 a = '((uint64_t){a})'.format(a=a)
304 b = '((uint64_t){b})'.format(b=b)
259 prog.lastBFlow = b if op == '-' else '(~{b})'.format(b=b) 305 prog.lastBFlow = b if op == '-' else '(~{b})'.format(b=b)
260 else: 306 elif needsSizeAdjust:
307 decl,name = prog.getTemp(size)
261 dst = params[2] 308 dst = params[2]
262 return decl + '\n\t{dst} = {a} {op} {b};'.format( 309 return '{decl}\n\t{tmp} = ({a} & {mask}) {op} ({b} & {mask});\n\t{dst} = ({dst} & ~{mask}) | {tmp};'.format(
263 dst = dst, a = a, b = b, op = op 310 decl = decl, tmp = name, a = a, b = b, op = op, dst = dst, mask = ((1 << size) - 1)
264 ) 311 )
312 else:
313 dst = params[2]
314 if needsSizeAdjust:
315 return decl + '\n\t{dst} = ({a} & {mask}) {op} ({b} & {mask});'.format(
316 dst = dst, a = a, b = b, op = op, mask = (1 << prog.sizeAdjust) - 1
317 )
318 else:
319 return decl + '\n\t{dst} = {a} {op} {b};'.format(
320 dst = dst, a = a, b = b, op = op
321 )
265 self.impls['c'] = _impl 322 self.impls['c'] = _impl
266 self.outOp = (2,) 323 self.outOp = (2,)
267 return self 324 return self
268 def cUnaryOperator(self, op): 325 def cUnaryOperator(self, op):
269 def _impl(prog, params, rawParams, flagUpdates): 326 def _impl(prog, params, rawParams, flagUpdates):
270 dst = params[1] 327 dst = params[1]
271 decl = '' 328 decl = ''
329 needsSizeAdjust = False
330 if len(params) > 2:
331 size = params[2]
332 if size == 0:
333 size = 8
334 elif size == 1:
335 size = 16
336 else:
337 size = 32
338 prog.lastSize = size
339 destSize = prog.paramSize(rawParams[1])
340 if destSize > size:
341 needsSizeAdjust = True
342 prog.sizeAdjust = size
272 if op == '-': 343 if op == '-':
273 if flagUpdates: 344 if flagUpdates:
274 for flag in flagUpdates: 345 for flag in flagUpdates:
275 calc = prog.flags.flagCalc[flag] 346 calc = prog.flags.flagCalc[flag]
276 if calc == 'carry': 347 if calc == 'carry':
277 needsCarry = True 348 needsCarry = True
278 elif calc == 'half-carry': 349 elif calc == 'half-carry':
279 needsHalf = True 350 needsHalf = True
280 elif calc == 'overflow': 351 elif calc == 'overflow':
281 needsOflow = True 352 needsOflow = True
282 if needsCarry or needsOflow or needsHalf: 353 if needsCarry or needsOflow or needsHalf or (flagUpdates and needsSizeAdjust):
283 size = prog.paramSize(rawParams[1]) 354 size = prog.paramSize(rawParams[1])
284 if needsCarry: 355 if needsCarry:
285 size *= 2 356 size *= 2
286 decl,name = prog.getTemp(size) 357 decl,name = prog.getTemp(size)
287 dst = prog.carryFlowDst = name 358 dst = prog.carryFlowDst = name
288 prog.lastA = 0 359 prog.lastA = 0
289 prog.lastB = params[0] 360 prog.lastB = params[0]
290 prog.lastBFlow = params[0] 361 prog.lastBFlow = params[0]
291 return decl + '\n\t{dst} = {op}{a};'.format( 362 if needsSizeAdjust:
292 dst = dst, a = params[0], op = op 363 return decl + '\n\t{dst} = ({dst} & ~{mask}) | (({op}{a}) & {mask});'.format(
293 ) 364 dst = dst, a = params[0], op = op, mask = (1 << prog.sizeAdjust) - 1
365 )
366 else:
367 return decl + '\n\t{dst} = {op}{a};'.format(
368 dst = dst, a = params[0], op = op
369 )
294 self.impls['c'] = _impl 370 self.impls['c'] = _impl
295 self.outOp = (1,) 371 self.outOp = (1,)
296 return self 372 return self
297 def addImplementation(self, lang, outOp, impl): 373 def addImplementation(self, lang, outOp, impl):
298 self.impls[lang] = impl 374 self.impls[lang] = impl
334 if len(params) == 1: 410 if len(params) == 1:
335 table = 'main' 411 table = 'main'
336 else: 412 else:
337 table = params[1] 413 table = params[1]
338 if prog.dispatch == 'call': 414 if prog.dispatch == 'call':
339 return '\n\timpl_{tbl}[{op}](context);'.format(tbl = table, op = params[0]) 415 return '\n\timpl_{tbl}[{op}](context, target_cycle);'.format(tbl = table, op = params[0])
340 elif prog.dispatch == 'goto': 416 elif prog.dispatch == 'goto':
341 return '\n\tgoto *impl_{tbl}[{op}];'.format(tbl = table, op = params[0]) 417 return '\n\tgoto *impl_{tbl}[{op}];'.format(tbl = table, op = params[0])
342 else: 418 else:
343 raise Exception('Unsupported dispatch type ' + prog.dispatch) 419 raise Exception('Unsupported dispatch type ' + prog.dispatch)
344 420
356 lastDst = prog.resolveParam(prog.lastDst, prog.currentScope, {}) 432 lastDst = prog.resolveParam(prog.lastDst, prog.currentScope, {})
357 storage = prog.flags.getStorage(flag) 433 storage = prog.flags.getStorage(flag)
358 if calc == 'bit' or calc == 'sign' or calc == 'carry' or calc == 'half' or calc == 'overflow': 434 if calc == 'bit' or calc == 'sign' or calc == 'carry' or calc == 'half' or calc == 'overflow':
359 myRes = lastDst 435 myRes = lastDst
360 if calc == 'sign': 436 if calc == 'sign':
361 resultBit = prog.paramSize(prog.lastDst) - 1 437 resultBit = prog.getLastSize() - 1
362 elif calc == 'carry': 438 elif calc == 'carry':
363 if prog.lastOp.op in ('asr', 'lsr'): 439 if prog.lastOp.op in ('asr', 'lsr'):
364 resultBit = 0 440 resultBit = 0
365 myRes = prog.lastA 441 myRes = prog.lastA
366 else: 442 else:
367 resultBit = prog.paramSize(prog.lastDst) 443 resultBit = prog.getLastSize()
368 if prog.lastOp.op == 'ror': 444 if prog.lastOp.op == 'ror':
369 resultBit -= 1 445 resultBit -= 1
370 elif calc == 'half': 446 elif calc == 'half':
371 resultBit = prog.paramSize(prog.lastDst) - 4 447 resultBit = prog.getLastSize() - 4
372 myRes = '({a} ^ {b} ^ {res})'.format(a = prog.lastA, b = prog.lastB, res = lastDst) 448 myRes = '({a} ^ {b} ^ {res})'.format(a = prog.lastA, b = prog.lastB, res = lastDst)
373 elif calc == 'overflow': 449 elif calc == 'overflow':
374 resultBit = prog.paramSize(prog.lastDst) - 1 450 resultBit = prog.getLastSize() - 1
375 myRes = '((({a} ^ {b})) & ({a} ^ {res}))'.format(a = prog.lastA, b = prog.lastBFlow, res = lastDst) 451 myRes = '((({a} ^ {b})) & ({a} ^ {res}))'.format(a = prog.lastA, b = prog.lastBFlow, res = lastDst)
376 else: 452 else:
377 #Note: offsetting this by the operation size - 8 makes sense for the Z80 453 #Note: offsetting this by the operation size - 8 makes sense for the Z80
378 #but might not for other CPUs with this kind of fixed bit flag behavior 454 #but might not for other CPUs with this kind of fixed bit flag behavior
379 resultBit = int(resultBit) + prog.paramSize(prog.lastDst) - 8 455 resultBit = int(resultBit) + prog.getLastSize() - 8
380 if type(storage) is tuple: 456 if type(storage) is tuple:
381 reg,storageBit = storage 457 reg,storageBit = storage
382 if storageBit == resultBit: 458 if storageBit == resultBit:
383 directFlags.setdefault((reg, myRes), []).append(resultBit) 459 directFlags.setdefault((reg, myRes), []).append(resultBit)
384 else: 460 else:
399 output.append('\n\t{reg} = {res} >> {shift} & {mask}U;'.format(reg=reg, res=myRes, shift = resultBit - maxBit, mask = 1 << maxBit)) 475 output.append('\n\t{reg} = {res} >> {shift} & {mask}U;'.format(reg=reg, res=myRes, shift = resultBit - maxBit, mask = 1 << maxBit))
400 else: 476 else:
401 output.append('\n\t{reg} = {res} & {mask}U;'.format(reg=reg, res=myRes, mask = 1 << resultBit)) 477 output.append('\n\t{reg} = {res} & {mask}U;'.format(reg=reg, res=myRes, mask = 1 << resultBit))
402 elif calc == 'zero': 478 elif calc == 'zero':
403 if prog.carryFlowDst: 479 if prog.carryFlowDst:
404 realSize = prog.paramSize(prog.lastDst) 480 realSize = prog.getLastSize()
405 if realSize != prog.paramSize(prog.carryFlowDst): 481 if realSize != prog.paramSize(prog.carryFlowDst):
406 lastDst = '({res} & {mask})'.format(res=lastDst, mask = (1 << realSize) - 1) 482 lastDst = '({res} & {mask})'.format(res=lastDst, mask = (1 << realSize) - 1)
407 if type(storage) is tuple: 483 if type(storage) is tuple:
408 reg,storageBit = storage 484 reg,storageBit = storage
409 reg = prog.resolveParam(reg, None, {}) 485 reg = prog.resolveParam(reg, None, {})
415 output.append('\n\t{reg} = {res} == 0;'.format( 491 output.append('\n\t{reg} = {res} == 0;'.format(
416 reg = reg, res = lastDst 492 reg = reg, res = lastDst
417 )) 493 ))
418 elif calc == 'parity': 494 elif calc == 'parity':
419 parity = storage 495 parity = storage
420 paritySize = prog.paramSize(prog.lastDst) 496 paritySize = prog.getLastSize()
421 if prog.carryFlowDst: 497 if prog.carryFlowDst:
422 parityDst = paritySrc = prog.carryFlowDst 498 parityDst = paritySrc = prog.carryFlowDst
423 else: 499 else:
424 paritySrc = lastDst 500 paritySrc = lastDst
425 decl,name = prog.getTemp(paritySize) 501 decl,name = prog.getTemp(paritySize)
439 output.append('\n\t{reg} = ({reg} & ~{mask}U) | ({res} & {mask}U);'.format( 515 output.append('\n\t{reg} = ({reg} & ~{mask}U) | ({res} & {mask}U);'.format(
440 reg = resolved, mask = mask, res = myRes 516 reg = resolved, mask = mask, res = myRes
441 )) 517 ))
442 if prog.carryFlowDst: 518 if prog.carryFlowDst:
443 if prog.lastOp.op != 'cmp': 519 if prog.lastOp.op != 'cmp':
444 output.append('\n\t{dst} = {tmpdst};'.format(dst = prog.resolveParam(prog.lastDst, prog.currentScope, {}), tmpdst = prog.carryFlowDst)) 520 if prog.sizeAdjust:
521 output.append('\n\t{dst} = ({dst} & ~{mask}) | ({tmpdst} & {mask});'.format(
522 dst = prog.resolveParam(prog.lastDst, prog.currentScope, {}), tmpdst = prog.carryFlowDst, mask = ((1 << prog.sizeAdjust) - 1)
523 ))
524 prog.sizeAdjust = None
525 else:
526 output.append('\n\t{dst} = {tmpdst};'.format(dst = prog.resolveParam(prog.lastDst, prog.currentScope, {}), tmpdst = prog.carryFlowDst))
445 prog.carryFlowDst = None 527 prog.carryFlowDst = None
446 if parity: 528 if parity:
447 if paritySize > 8: 529 if paritySize > 8:
448 if paritySize > 16: 530 if paritySize > 16:
449 output.append('\n\t{dst} = {src} ^ ({src} >> 16);'.format(dst=parityDst, src=paritySrc)) 531 output.append('\n\t{dst} = {src} ^ ({src} >> 16);'.format(dst=parityDst, src=paritySrc))
498 prog.lastBFlow = params[0] 580 prog.lastBFlow = params[0]
499 scope = prog.getRootScope() 581 scope = prog.getRootScope()
500 if not scope.resolveLocal(tmpvar): 582 if not scope.resolveLocal(tmpvar):
501 scope.addLocal(tmpvar, size) 583 scope.addLocal(tmpvar, size)
502 prog.lastDst = rawParams[1] 584 prog.lastDst = rawParams[1]
585 if len(params) > 2:
586 size = params[2]
587 if size == 0:
588 size = 8
589 elif size == 1:
590 size = 16
591 else:
592 size = 32
593 prog.lastSize = size
594 else:
595 prog.lastSize = None
503 return '\n\t{var} = {b} - {a};'.format(var = tmpvar, a = params[0], b = params[1]) 596 return '\n\t{var} = {b} - {a};'.format(var = tmpvar, a = params[0], b = params[1])
504 597
505 def _asrCImpl(prog, params, rawParams, flagUpdates): 598 def _asrCImpl(prog, params, rawParams, flagUpdates):
506 needsCarry = False 599 needsCarry = False
507 if flagUpdates: 600 if flagUpdates:
521 return decl + '\n\t{dst} = ({a} >> {b}) | ({a} & {mask} ? 0xFFFFFFFFU << ({size} - {b}) : 0);'.format( 614 return decl + '\n\t{dst} = ({a} >> {b}) | ({a} & {mask} ? 0xFFFFFFFFU << ({size} - {b}) : 0);'.format(
522 a = params[0], b = params[1], dst = dst, mask = mask, size=size) 615 a = params[0], b = params[1], dst = dst, mask = mask, size=size)
523 616
524 def _sext(size, src): 617 def _sext(size, src):
525 if size == 16: 618 if size == 16:
526 return src | 0xFF00 if src & 0x80 else src 619 return src | 0xFF00 if src & 0x80 else src & 0x7F
527 else: 620 else:
528 return src | 0xFFFF0000 if src & 0x8000 else src 621 return src | 0xFFFF0000 if src & 0x8000 else src & 0x7FFF
529 622
530 def _sextCImpl(prog, params, rawParms): 623 def _sextCImpl(prog, params, rawParms):
531 if params[0] == 16: 624 if params[0] == 16:
532 fmt = '\n\t{dst} = {src} & 0x80 ? {src} | 0xFF00 : {src};' 625 fmt = '\n\t{dst} = {src} & 0x80 ? {src} | 0xFF00 : {src} & 0x7F;'
533 else: 626 else:
534 fmt = '\n\t{dst} = {src} & 0x8000 ? {src} | 0xFFFF0000 : {src};' 627 fmt = '\n\t{dst} = {src} & 0x8000 ? {src} | 0xFFFF0000 : {src} & 0x7FFF;'
535 return fmt.format(src=params[1], dst=params[2]) 628 return fmt.format(src=params[1], dst=params[2])
536 629
537 def _getCarryCheck(prog): 630 def _getCarryCheck(prog):
538 carryFlag = None 631 carryFlag = None
539 for flag in prog.flags.flagCalc: 632 for flag in prog.flags.flagOrder:
540 if prog.flags.flagCalc[flag] == 'carry': 633 if prog.flags.flagCalc[flag] == 'carry':
541 carryFlag = flag 634 carryFlag = flag
635 break
542 if carryFlag is None: 636 if carryFlag is None:
543 raise Exception('adc requires a defined carry flag') 637 raise Exception('adc requires a defined carry flag')
544 carryStorage = prog.flags.getStorage(carryFlag) 638 carryStorage = prog.flags.getStorage(carryFlag)
545 if type(carryStorage) is tuple: 639 if type(carryStorage) is tuple:
546 reg,bit = carryStorage 640 reg,bit = carryStorage
548 return '({reg} & 1 << {bit})'.format(reg=reg, bit=bit) 642 return '({reg} & 1 << {bit})'.format(reg=reg, bit=bit)
549 else: 643 else:
550 return prog.resolveReg(carryStorage, None, (), False) 644 return prog.resolveReg(carryStorage, None, (), False)
551 645
552 def _adcCImpl(prog, params, rawParams, flagUpdates): 646 def _adcCImpl(prog, params, rawParams, flagUpdates):
647 needsSizeAdjust = False
648 if len(params) > 3:
649 size = params[3]
650 if size == 0:
651 size = 8
652 elif size == 1:
653 size = 16
654 else:
655 size = 32
656 prog.lastSize = size
657 destSize = prog.paramSize(rawParams[2])
658 if destSize > size:
659 needsSizeAdjust = True
660 prog.sizeAdjust = size
553 needsCarry = needsOflow = needsHalf = False 661 needsCarry = needsOflow = needsHalf = False
554 if flagUpdates: 662 if flagUpdates:
555 for flag in flagUpdates: 663 for flag in flagUpdates:
556 calc = prog.flags.flagCalc[flag] 664 calc = prog.flags.flagCalc[flag]
557 if calc == 'carry': 665 if calc == 'carry':
560 needsHalf = True 668 needsHalf = True
561 elif calc == 'overflow': 669 elif calc == 'overflow':
562 needsOflow = True 670 needsOflow = True
563 decl = '' 671 decl = ''
564 carryCheck = _getCarryCheck(prog) 672 carryCheck = _getCarryCheck(prog)
565 if needsCarry or needsOflow or needsHalf: 673 vals = '1 : 0'
566 size = prog.paramSize(rawParams[2]) 674 if needsCarry or needsOflow or needsHalf or (flagUpdates and needsSizeAdjust):
675 if len(params) <= 3:
676 size = prog.paramSize(rawParams[2])
567 if needsCarry: 677 if needsCarry:
568 size *= 2 678 size *= 2
569 decl,name = prog.getTemp(size) 679 decl,name = prog.getTemp(size)
570 dst = prog.carryFlowDst = name 680 dst = prog.carryFlowDst = name
571 prog.lastA = params[0] 681 prog.lastA = params[0]
572 prog.lastB = params[1] 682 prog.lastB = params[1]
573 prog.lastBFlow = '(~{b})'.format(b=params[1]) 683 prog.lastBFlow = '(~{b})'.format(b=params[1])
684 if size == 64:
685 params[0] = '((uint64_t){a})'.format(a=params[0])
686 params[1] = '((uint64_t){b})'.format(b=params[1])
687 vals = '((uint64_t)1) : ((uint64_t)0)'
688 elif needsSizeAdjust:
689 decl,name = prog.getTemp(size)
690 dst = params[2]
691 return '{decl}\n\t{tmp} = ({a} & {mask}) + ({b} & {mask}) + ({check} ? 1 : 0);\n\t{dst} = ({dst} & ~{mask}) | {tmp};'.format(
692 decl = decl, tmp = name, a = a, b = b, op = op, dst = dst, mask = ((1 << size) - 1), check = carryCheck
693 )
574 else: 694 else:
575 dst = params[2] 695 dst = params[2]
576 return decl + '\n\t{dst} = {a} + {b} + ({check} ? 1 : 0);'.format(dst = dst, 696 return decl + '\n\t{dst} = {a} + {b} + ({check} ? {vals});'.format(dst = dst,
577 a = params[0], b = params[1], check = carryCheck 697 a = params[0], b = params[1], check = carryCheck, vals = vals
578 ) 698 )
579 699
580 def _sbcCImpl(prog, params, rawParams, flagUpdates): 700 def _sbcCImpl(prog, params, rawParams, flagUpdates):
701 needsSizeAdjust = False
702 if len(params) > 3:
703 size = params[3]
704 if size == 0:
705 size = 8
706 elif size == 1:
707 size = 16
708 else:
709 size = 32
710 prog.lastSize = size
711 destSize = prog.paramSize(rawParams[2])
712 if destSize > size:
713 needsSizeAdjust = True
714 prog.sizeAdjust = size
581 needsCarry = needsOflow = needsHalf = False 715 needsCarry = needsOflow = needsHalf = False
582 if flagUpdates: 716 if flagUpdates:
583 for flag in flagUpdates: 717 for flag in flagUpdates:
584 calc = prog.flags.flagCalc[flag] 718 calc = prog.flags.flagCalc[flag]
585 if calc == 'carry': 719 if calc == 'carry':
588 needsHalf = True 722 needsHalf = True
589 elif calc == 'overflow': 723 elif calc == 'overflow':
590 needsOflow = True 724 needsOflow = True
591 decl = '' 725 decl = ''
592 carryCheck = _getCarryCheck(prog) 726 carryCheck = _getCarryCheck(prog)
593 if needsCarry or needsOflow or needsHalf: 727 vals = '1 : 0'
728 if needsCarry or needsOflow or needsHalf or (flagUpdates and needsSizeAdjust):
594 size = prog.paramSize(rawParams[2]) 729 size = prog.paramSize(rawParams[2])
595 if needsCarry: 730 if needsCarry:
596 size *= 2 731 size *= 2
597 decl,name = prog.getTemp(size) 732 decl,name = prog.getTemp(size)
598 dst = prog.carryFlowDst = name 733 dst = prog.carryFlowDst = name
599 prog.lastA = params[1] 734 prog.lastA = params[1]
600 prog.lastB = params[0] 735 prog.lastB = params[0]
601 prog.lastBFlow = params[0] 736 prog.lastBFlow = params[0]
737 if size == 64:
738 params[1] = '((uint64_t){a})'.format(a=params[1])
739 params[0] = '((uint64_t){b})'.format(b=params[0])
740 vals = '((uint64_t)1) : ((uint64_t)0)'
741 elif needsSizeAdjust:
742 decl,name = prog.getTemp(size)
743 dst = params[2]
744 return '{decl}\n\t{tmp} = ({b} & {mask}) - ({a} & {mask}) - ({check} ? 1 : 0);\n\t{dst} = ({dst} & ~{mask}) | {tmp};'.format(
745 decl = decl, tmp = name, a = params[0], b = params[1], op = op, dst = dst, mask = ((1 << size) - 1), check = carryCheck
746 )
602 else: 747 else:
603 dst = params[2] 748 dst = params[2]
604 return decl + '\n\t{dst} = {b} - {a} - ({check} ? 1 : 0);'.format(dst = dst, 749 return decl + '\n\t{dst} = {b} - {a} - ({check} ? {vals});'.format(dst = dst,
605 a = params[0], b = params[1], check=_getCarryCheck(prog) 750 a = params[0], b = params[1], check=_getCarryCheck(prog), vals = vals
606 ) 751 )
607 752
608 def _rolCImpl(prog, params, rawParams, flagUpdates): 753 def _rolCImpl(prog, params, rawParams, flagUpdates):
609 needsCarry = False 754 needsCarry = False
610 if flagUpdates: 755 if flagUpdates:
695 'cmp': Op().addImplementation('c', None, _cmpCImpl), 840 'cmp': Op().addImplementation('c', None, _cmpCImpl),
696 'sext': Op(_sext).addImplementation('c', 2, _sextCImpl), 841 'sext': Op(_sext).addImplementation('c', 2, _sextCImpl),
697 'ocall': Op().addImplementation('c', None, lambda prog, params: '\n\t{pre}{fun}({args});'.format( 842 'ocall': Op().addImplementation('c', None, lambda prog, params: '\n\t{pre}{fun}({args});'.format(
698 pre = prog.prefix, fun = params[0], args = ', '.join(['context'] + [str(p) for p in params[1:]]) 843 pre = prog.prefix, fun = params[0], args = ', '.join(['context'] + [str(p) for p in params[1:]])
699 )), 844 )),
845 'pcall': Op().addImplementation('c', None, lambda prog, params: '\n\t(({typ}){fun})({args});'.format(
846 typ = params[1], fun = params[0], args = ', '.join([str(p) for p in params[2:]])
847 )),
700 'cycles': Op().addImplementation('c', None, 848 'cycles': Op().addImplementation('c', None,
701 lambda prog, params: '\n\tcontext->cycles += context->opts->gen.clock_divider * {0};'.format( 849 lambda prog, params: '\n\tcontext->cycles += context->opts->gen.clock_divider * {0};'.format(
702 params[0] 850 params[0]
703 ) 851 )
704 ), 852 ),
705 'addsize': Op( 853 'addsize': Op(
706 lambda a, b: b + (2 * a if a else 1) 854 lambda a, b: b + (2 * a if a else 1)
707 ).addImplementation('c', 2, lambda prog, params: '\n\t{dst} = {val} + {sz} ? {sz} * 2 : 1;'.format( 855 ).addImplementation('c', 2, lambda prog, params: '\n\t{dst} = {val} + ({sz} ? {sz} * 2 : 1);'.format(
708 dst = params[2], sz = params[0], val = params[1] 856 dst = params[2], sz = params[0], val = params[1]
709 )), 857 )),
710 'decsize': Op( 858 'decsize': Op(
711 lambda a, b: b - (2 * a if a else 1) 859 lambda a, b: b - (2 * a if a else 1)
712 ).addImplementation('c', 2, lambda prog, params: '\n\t{dst} = {val} - {sz} ? {sz} * 2 : 1;'.format( 860 ).addImplementation('c', 2, lambda prog, params: '\n\t{dst} = {val} - ({sz} ? {sz} * 2 : 1);'.format(
713 dst = params[2], sz = params[0], val = params[1] 861 dst = params[2], sz = params[0], val = params[1]
714 )), 862 )),
715 'xchg': Op().addImplementation('c', (0,1), _xchgCImpl), 863 'xchg': Op().addImplementation('c', (0,1), _xchgCImpl),
716 'dispatch': Op().addImplementation('c', None, _dispatchCImpl), 864 'dispatch': Op().addImplementation('c', None, _dispatchCImpl),
717 'update_flags': Op().addImplementation('c', None, _updateFlagsCImpl), 865 'update_flags': Op().addImplementation('c', None, _updateFlagsCImpl),
727 def generate(self, prog, parent, fieldVals, output, otype, flagUpdates): 875 def generate(self, prog, parent, fieldVals, output, otype, flagUpdates):
728 procParams = [] 876 procParams = []
729 allParamsConst = flagUpdates is None and not prog.conditional 877 allParamsConst = flagUpdates is None and not prog.conditional
730 opDef = _opMap.get(self.op) 878 opDef = _opMap.get(self.op)
731 for param in self.params: 879 for param in self.params:
732 allowConst = (self.op in prog.subroutines or len(procParams) != len(self.params) - 1) and param in parent.regValues
733 isDst = (not opDef is None) and len(procParams) in opDef.outOp 880 isDst = (not opDef is None) and len(procParams) in opDef.outOp
881 allowConst = (self.op in prog.subroutines or not isDst) and param in parent.regValues
734 if isDst and self.op == 'xchg': 882 if isDst and self.op == 'xchg':
735 #xchg uses its regs as both source and destination 883 #xchg uses its regs as both source and destination
736 #we need to resolve as both so that disperse/coalesce flag stuff gets done 884 #we need to resolve as both so that disperse/coalesce flag stuff gets done
737 prog.resolveParam(param, parent, fieldVals, allowConst, False) 885 prog.resolveParam(param, parent, fieldVals, allowConst, False)
738 param = prog.resolveParam(param, parent, fieldVals, allowConst, isDst) 886 param = prog.resolveParam(param, parent, fieldVals, allowConst, isDst)
792 if end in fieldVals: 940 if end in fieldVals:
793 param = begin + '.' + str(fieldVals[end]) 941 param = begin + '.' + str(fieldVals[end])
794 else: 942 else:
795 if param in fieldVals: 943 if param in fieldVals:
796 param = fieldVals[param] 944 param = fieldVals[param]
945 else:
946 maybeLocal = parent.resolveLocal(param)
947 if maybeLocal and maybeLocal in parent.regValues:
948 param = parent.regValues[maybeLocal]
797 procParams.append(param) 949 procParams.append(param)
798 prog.subroutines[self.op].inline(prog, procParams, output, otype, parent) 950 prog.subroutines[self.op].inline(prog, procParams, output, otype, parent)
799 else: 951 else:
800 output.append('\n\t' + self.op + '(' + ', '.join([str(p) for p in procParams]) + ');') 952 output.append('\n\t' + self.op + '(' + ', '.join([str(p) for p in procParams]) + ');')
801 prog.lastOp = self 953 prog.lastOp = self
870 oldCond = prog.conditional 1022 oldCond = prog.conditional
871 prog.conditional = True 1023 prog.conditional = True
872 output.append('\n\tswitch(' + param + ')') 1024 output.append('\n\tswitch(' + param + ')')
873 output.append('\n\t{') 1025 output.append('\n\t{')
874 for case in self.cases: 1026 for case in self.cases:
875 temp = prog.temp.copy() 1027 #temp = prog.temp.copy()
876 self.current_locals = self.case_locals[case] 1028 self.current_locals = self.case_locals[case]
877 self.regValues = dict(self.parent.regValues) 1029 self.regValues = dict(self.parent.regValues)
878 output.append('\n\tcase {0}U: '.format(case) + '{') 1030 output.append('\n\tcase {0}U: '.format(case) + '{')
879 for local in self.case_locals[case]: 1031 for local in self.case_locals[case]:
880 output.append('\n\tuint{0}_t {1};'.format(self.case_locals[case][local], local)) 1032 output.append('\n\tuint{0}_t {1};'.format(self.case_locals[case][local], local))
881 self.processOps(prog, fieldVals, output, otype, self.cases[case]) 1033 self.processOps(prog, fieldVals, output, otype, self.cases[case])
882 output.append('\n\tbreak;') 1034 output.append('\n\tbreak;')
883 output.append('\n\t}') 1035 output.append('\n\t}')
884 prog.temp = temp 1036 #prog.temp = temp
885 if self.default: 1037 if self.default:
886 temp = prog.temp.copy() 1038 #temp = prog.temp.copy()
887 self.current_locals = self.default_locals 1039 self.current_locals = self.default_locals
888 self.regValues = dict(self.parent.regValues) 1040 self.regValues = dict(self.parent.regValues)
889 output.append('\n\tdefault: {') 1041 output.append('\n\tdefault: {')
890 for local in self.default_locals: 1042 for local in self.default_locals:
891 output.append('\n\tuint{0}_t {1};'.format(self.default_locals[local], local)) 1043 output.append('\n\tuint{0}_t {1};'.format(self.default_locals[local], local))
892 self.processOps(prog, fieldVals, output, otype, self.default) 1044 self.processOps(prog, fieldVals, output, otype, self.default)
893 prog.temp = temp 1045 #prog.temp = temp
894 output.append('\n\t}') 1046 output.append('\n\t}')
895 prog.conditional = oldCond 1047 prog.conditional = oldCond
896 prog.popScope() 1048 prog.popScope()
897 1049
898 def __str__(self): 1050 def __str__(self):
913 return '\n\tif ({a} >= {b}) '.format(a=params[1], b = params[0]) + '{' 1065 return '\n\tif ({a} >= {b}) '.format(a=params[1], b = params[0]) + '{'
914 else: 1066 else:
915 raise Exception(">=U not implemented in the general case yet") 1067 raise Exception(">=U not implemented in the general case yet")
916 1068
917 def _eqCImpl(prog, parent, fieldVals, output): 1069 def _eqCImpl(prog, parent, fieldVals, output):
918 return '\n\tif (!{a}) {'.format(a=prog.resolveParam(prog.lastDst, None, {})) 1070 if prog.lastOp.op == 'cmp':
1071 output.pop()
1072 params = [prog.resolveParam(p, parent, fieldVals) for p in prog.lastOp.params]
1073 return '\n\tif ({a} == {b}) '.format(a=params[1], b = params[0]) + '{'
1074 else:
1075 return '\n\tif (!{a}) {{'.format(a=prog.resolveParam(prog.lastDst, None, {}))
919 1076
920 def _neqCImpl(prog, parent, fieldVals, output): 1077 def _neqCImpl(prog, parent, fieldVals, output):
921 return '\n\tif ({a}) {'.format(a=prog.resolveParam(prog.lastDst, None, {})) 1078 return '\n\tif ({a}) {{'.format(a=prog.resolveParam(prog.lastDst, None, {}))
922 1079
923 _ifCmpImpl = { 1080 _ifCmpImpl = {
924 'c': { 1081 'c': {
925 '>=U': _geuCImpl, 1082 '>=U': _geuCImpl,
926 '=': _eqCImpl, 1083 '=': _eqCImpl,
984 else: 1141 else:
985 self._genFalseBody(prog, fieldVals, output, otype) 1142 self._genFalseBody(prog, fieldVals, output, otype)
986 1143
987 def generate(self, prog, parent, fieldVals, output, otype, flagUpdates): 1144 def generate(self, prog, parent, fieldVals, output, otype, flagUpdates):
988 self.regValues = parent.regValues 1145 self.regValues = parent.regValues
989 try: 1146 if self.cond in prog.booleans:
990 self._genConstParam(prog.checkBool(self.cond), prog, fieldVals, output, otype) 1147 self._genConstParam(prog.checkBool(self.cond), prog, fieldVals, output, otype)
991 except Exception: 1148 else:
992 if self.cond in _ifCmpImpl[otype]: 1149 if self.cond in _ifCmpImpl[otype]:
993 oldCond = prog.conditional 1150 oldCond = prog.conditional
994 prog.conditional = True 1151 prog.conditional = True
995 temp = prog.temp.copy() 1152 #temp = prog.temp.copy()
996 output.append(_ifCmpImpl[otype][self.cond](prog, parent, fieldVals, output)) 1153 output.append(_ifCmpImpl[otype][self.cond](prog, parent, fieldVals, output))
997 self._genTrueBody(prog, fieldVals, output, otype) 1154 self._genTrueBody(prog, fieldVals, output, otype)
998 prog.temp = temp 1155 #prog.temp = temp
999 if self.elseBody: 1156 if self.elseBody:
1000 temp = prog.temp.copy() 1157 #temp = prog.temp.copy()
1001 output.append('\n\t} else {') 1158 output.append('\n\t} else {')
1002 self._genFalseBody(prog, fieldVals, output, otype) 1159 self._genFalseBody(prog, fieldVals, output, otype)
1003 prog.temp = temp 1160 #prog.temp = temp
1004 output.append('\n\t}') 1161 output.append('\n\t}')
1005 prog.conditional = oldCond 1162 prog.conditional = oldCond
1006 else: 1163 else:
1007 cond = prog.resolveParam(self.cond, parent, fieldVals) 1164 cond = prog.resolveParam(self.cond, parent, fieldVals)
1008 if type(cond) is int: 1165 if type(cond) is int:
1009 self._genConstParam(cond, prog, fieldVals, output, otype) 1166 self._genConstParam(cond, prog, fieldVals, output, otype)
1010 else: 1167 else:
1011 temp = prog.temp.copy() 1168 #temp = prog.temp.copy()
1012 output.append('\n\tif ({cond}) '.format(cond=cond) + '{') 1169 output.append('\n\tif ({cond}) '.format(cond=cond) + '{')
1013 oldCond = prog.conditional 1170 oldCond = prog.conditional
1014 prog.conditional = True 1171 prog.conditional = True
1015 self._genTrueBody(prog, fieldVals, output, otype) 1172 self._genTrueBody(prog, fieldVals, output, otype)
1016 prog.temp = temp 1173 #prog.temp = temp
1017 if self.elseBody: 1174 if self.elseBody:
1018 temp = prog.temp.copy() 1175 #temp = prog.temp.copy()
1019 output.append('\n\t} else {') 1176 output.append('\n\t} else {')
1020 self._genFalseBody(prog, fieldVals, output, otype) 1177 self._genFalseBody(prog, fieldVals, output, otype)
1021 prog.temp = temp 1178 #prog.temp = temp
1022 output.append('\n\t}') 1179 output.append('\n\t}')
1023 prog.conditional = oldCond 1180 prog.conditional = oldCond
1024 1181
1025 1182
1026 def __str__(self): 1183 def __str__(self):
1127 class Flags: 1284 class Flags:
1128 def __init__(self): 1285 def __init__(self):
1129 self.flagBits = {} 1286 self.flagBits = {}
1130 self.flagCalc = {} 1287 self.flagCalc = {}
1131 self.flagStorage = {} 1288 self.flagStorage = {}
1289 self.flagOrder = []
1132 self.flagReg = None 1290 self.flagReg = None
1133 self.storageToFlags = {} 1291 self.storageToFlags = {}
1134 self.maxBit = -1 1292 self.maxBit = -1
1135 1293
1136 def processLine(self, parts): 1294 def processLine(self, parts):
1151 self.flagBits[flag] = bit 1309 self.flagBits[flag] = bit
1152 self.flagCalc[flag] = calc 1310 self.flagCalc[flag] = calc
1153 self.flagStorage[flag] = storage 1311 self.flagStorage[flag] = storage
1154 storage,_,storebit = storage.partition('.') 1312 storage,_,storebit = storage.partition('.')
1155 self.storageToFlags.setdefault(storage, []).append((storebit, flag)) 1313 self.storageToFlags.setdefault(storage, []).append((storebit, flag))
1314 self.flagOrder.append(flag)
1156 return self 1315 return self
1157 1316
1158 def getStorage(self, flag): 1317 def getStorage(self, flag):
1159 if not flag in self.flagStorage: 1318 if not flag in self.flagStorage:
1160 raise Exception('Undefined flag ' + flag) 1319 raise Exception('Undefined flag ' + flag)
1310 self.lastOp = None 1469 self.lastOp = None
1311 self.carryFlowDst = None 1470 self.carryFlowDst = None
1312 self.lastA = None 1471 self.lastA = None
1313 self.lastB = None 1472 self.lastB = None
1314 self.lastBFlow = None 1473 self.lastBFlow = None
1474 self.sizeAdjust = None
1315 self.conditional = False 1475 self.conditional = False
1316 self.declares = [] 1476 self.declares = []
1477 self.lastSize = None
1317 1478
1318 def __str__(self): 1479 def __str__(self):
1319 pieces = [] 1480 pieces = []
1320 for reg in self.regs: 1481 for reg in self.regs:
1321 pieces.append(str(self.regs[reg])) 1482 pieces.append(str(self.regs[reg]))
1409 body = [] 1570 body = []
1410 pieces = [] 1571 pieces = []
1411 for include in self.includes: 1572 for include in self.includes:
1412 body.append('#include "{0}"\n'.format(include)) 1573 body.append('#include "{0}"\n'.format(include))
1413 if self.dispatch == 'call': 1574 if self.dispatch == 'call':
1414 body.append('\nstatic void unimplemented({pre}context *context)'.format(pre = self.prefix)) 1575 body.append('\nstatic void unimplemented({pre}context *context, uint32_t target_cycle)'.format(pre = self.prefix))
1415 body.append('\n{') 1576 body.append('\n{')
1416 body.append('\n\tfatal_error("Unimplemented instruction\\n");') 1577 body.append('\n\tfatal_error("Unimplemented instruction\\n");')
1417 body.append('\n}\n') 1578 body.append('\n}\n')
1418 body.append('\ntypedef void (*impl_fun)({pre}context *context);'.format(pre=self.prefix)) 1579 body.append('\ntypedef void (*impl_fun)({pre}context *context, uint32_t target_cycle);'.format(pre=self.prefix))
1419 for table in self.extra_tables: 1580 for table in self.extra_tables:
1420 body.append('\nstatic impl_fun impl_{name}[{sz}];'.format(name = table, sz=(1 << self.opsize))) 1581 body.append('\nstatic impl_fun impl_{name}[{sz}];'.format(name = table, sz=(1 << self.opsize)))
1421 body.append('\nstatic impl_fun impl_main[{sz}];'.format(sz=(1 << self.opsize))) 1582 body.append('\nstatic impl_fun impl_main[{sz}];'.format(sz=(1 << self.opsize)))
1422 elif self.dispatch == 'goto': 1583 elif self.dispatch == 'goto':
1423 body.append('\nvoid {pre}execute({type} *context, uint32_t target_cycle)'.format(pre = self.prefix, type = self.context_type)) 1584 body.append('\nvoid {pre}execute({type} *context, uint32_t target_cycle)'.format(pre = self.prefix, type = self.context_type))
1453 1614
1454 def getTemp(self, size): 1615 def getTemp(self, size):
1455 if size in self.temp: 1616 if size in self.temp:
1456 return ('', self.temp[size]) 1617 return ('', self.temp[size])
1457 self.temp[size] = 'gen_tmp{sz}__'.format(sz=size); 1618 self.temp[size] = 'gen_tmp{sz}__'.format(sz=size);
1458 return ('\n\tuint{sz}_t gen_tmp{sz}__;'.format(sz=size), self.temp[size]) 1619 return ('', self.temp[size])
1459 1620
1460 def resolveParam(self, param, parent, fieldVals, allowConstant=True, isdst=False): 1621 def resolveParam(self, param, parent, fieldVals, allowConstant=True, isdst=False):
1461 keepGoing = True 1622 keepGoing = True
1462 while keepGoing: 1623 while keepGoing:
1463 keepGoing = False 1624 keepGoing = False
1475 return parent.regValues[param] 1636 return parent.regValues[param]
1476 maybeLocal = parent.resolveLocal(param) 1637 maybeLocal = parent.resolveLocal(param)
1477 if maybeLocal: 1638 if maybeLocal:
1478 if isdst: 1639 if isdst:
1479 self.lastDst = param 1640 self.lastDst = param
1641 self.lastSize = None
1480 return maybeLocal 1642 return maybeLocal
1481 if param in fieldVals: 1643 if param in fieldVals:
1482 param = fieldVals[param] 1644 param = fieldVals[param]
1483 fieldVals = {} 1645 fieldVals = {}
1484 keepGoing = True 1646 keepGoing = True
1485 elif param in self.meta: 1647 elif param in self.meta:
1486 param = self.meta[param] 1648 param = self.meta[param]
1487 keepGoing = True 1649 keepGoing = True
1488 elif self.isReg(param): 1650 elif self.isReg(param):
1489 return self.resolveReg(param, parent, fieldVals, isdst) 1651 return self.resolveReg(param, parent, fieldVals, isdst)
1652 elif param in self.regs.pointers:
1653 return 'context->' + param
1490 if isdst: 1654 if isdst:
1491 self.lastDst = param 1655 self.lastDst = param
1656 self.lastSize = None
1492 return param 1657 return param
1493 1658
1494 def isReg(self, name): 1659 def isReg(self, name):
1495 if not type(name) is str: 1660 if not type(name) is str:
1496 return False 1661 return False
1548 if sep and self.regs.isRegArray(begin): 1713 if sep and self.regs.isRegArray(begin):
1549 return self.regs.regArrays[begin][0] 1714 return self.regs.regArrays[begin][0]
1550 if self.regs.isReg(name): 1715 if self.regs.isReg(name):
1551 return self.regs.regs[name] 1716 return self.regs.regs[name]
1552 return 32 1717 return 32
1718
1719 def getLastSize(self):
1720 if self.lastSize:
1721 return self.lastSize
1722 return self.paramSize(self.lastDst)
1553 1723
1554 def pushScope(self, scope): 1724 def pushScope(self, scope):
1555 self.scopes.append(scope) 1725 self.scopes.append(scope)
1556 self.currentScope = scope 1726 self.currentScope = scope
1557 1727