git @ Cat's Eye Technologies SixtyPical / 5fcbfa1
Analyze reads and updates of tables. Chris Pressey 4 years ago
2 changed file(s) with 89 addition(s) and 34 deletion(s). Raw diff Collapse all Expand all
278278 def encountered_gotos(self):
279279 return self._gotos_encountered
280280
281 def assert_types_for_read_table(self, instr, src, dest, type_):
282 if (not TableType.is_a_table_type(src.ref.type, type_)) or (not dest.type == type_):
283 raise TypeMismatchError(instr, '{} and {}'.format(src.ref.name, dest.name))
284 self.assert_meaningful(src, src.index)
285 self.assert_in_range(src.index, src.ref)
286
287 def assert_types_for_update_table(self, instr, dest, type_):
288 if not TableType.is_a_table_type(dest.ref.type, type_):
289 raise TypeMismatchError(instr, '{}'.format(dest.ref.name))
290 self.assert_meaningful(dest.index)
291 self.assert_in_range(dest.index, dest.ref)
292 self.set_written(dest.ref)
293
281294
282295 class Analyzer(object):
283296
385398
386399 if opcode == 'ld':
387400 if isinstance(src, IndexedRef):
388 if TableType.is_a_table_type(src.ref.type, TYPE_BYTE) and dest.type == TYPE_BYTE:
389 pass
390 else:
391 raise TypeMismatchError(instr, '{} and {}'.format(src.ref.name, dest.name))
392 context.assert_meaningful(src, src.index)
393 context.assert_in_range(src.index, src.ref)
401 context.assert_types_for_read_table(instr, src, dest, TYPE_BYTE)
394402 elif isinstance(src, IndirectRef):
395403 # copying this analysis from the matching branch in `copy`, below
396404 if isinstance(src.ref.type, PointerType) and dest.type == TYPE_BYTE:
406414 context.set_written(dest, FLAG_Z, FLAG_N)
407415 elif opcode == 'st':
408416 if isinstance(dest, IndexedRef):
409 if src.type == TYPE_BYTE and TableType.is_a_table_type(dest.ref.type, TYPE_BYTE):
410 pass
411 else:
412 raise TypeMismatchError(instr, (src, dest))
413 context.assert_meaningful(dest.index)
414 context.assert_in_range(dest.index, dest.ref)
415 context.set_written(dest.ref)
417 if src.type != TYPE_BYTE:
418 raise TypeMismatchError(instr, (src, dest))
419 context.assert_types_for_update_table(instr, dest, TYPE_BYTE)
416420 elif isinstance(dest, IndirectRef):
417421 # copying this analysis from the matching branch in `copy`, below
418422 if isinstance(dest.ref.type, PointerType) and src.type == TYPE_BYTE:
429433 context.assert_meaningful(src)
430434 elif opcode == 'add':
431435 context.assert_meaningful(src, dest, FLAG_C)
432 if src.type == TYPE_BYTE:
436 if isinstance(src, IndexedRef):
437 context.assert_types_for_read_table(instr, src, dest, TYPE_BYTE)
438 elif src.type == TYPE_BYTE:
433439 self.assert_type(TYPE_BYTE, src, dest)
434 context.set_written(dest, FLAG_Z, FLAG_N, FLAG_C, FLAG_V)
435440 else:
436441 self.assert_type(TYPE_WORD, src)
437442 if dest.type == TYPE_WORD:
438 context.set_written(dest, FLAG_Z, FLAG_N, FLAG_C, FLAG_V)
439443 context.set_touched(REG_A)
440444 context.set_unmeaningful(REG_A)
441445 elif isinstance(dest.type, PointerType):
442 context.set_written(dest, FLAG_Z, FLAG_N, FLAG_C, FLAG_V)
443446 context.set_touched(REG_A)
444447 context.set_unmeaningful(REG_A)
445448 else:
446449 self.assert_type(TYPE_WORD, dest)
450 context.set_written(dest, FLAG_Z, FLAG_N, FLAG_C, FLAG_V)
447451 context.invalidate_range(dest)
448452 elif opcode == 'sub':
449453 context.assert_meaningful(src, dest, FLAG_C)
450 if src.type == TYPE_BYTE:
454 if isinstance(src, IndexedRef):
455 context.assert_types_for_read_table(instr, src, dest, TYPE_BYTE)
456 elif src.type == TYPE_BYTE:
451457 self.assert_type(TYPE_BYTE, src, dest)
452 context.set_written(dest, FLAG_Z, FLAG_N, FLAG_C, FLAG_V)
453458 else:
454459 self.assert_type(TYPE_WORD, src, dest)
455 context.set_written(dest, FLAG_Z, FLAG_N, FLAG_C, FLAG_V)
456460 context.set_touched(REG_A)
457461 context.set_unmeaningful(REG_A)
458 context.invalidate_range(dest)
459 elif opcode in ('inc', 'dec'):
460 self.assert_type(TYPE_BYTE, dest)
461 context.assert_meaningful(dest)
462 context.set_written(dest, FLAG_Z, FLAG_N)
462 context.set_written(dest, FLAG_Z, FLAG_N, FLAG_C, FLAG_V)
463463 context.invalidate_range(dest)
464464 elif opcode == 'cmp':
465 self.assert_type(TYPE_BYTE, src, dest)
466465 context.assert_meaningful(src, dest)
466 if isinstance(src, IndexedRef):
467 context.assert_types_for_read_table(instr, src, dest, TYPE_BYTE)
468 else:
469 self.assert_type(TYPE_BYTE, src, dest)
467470 context.set_written(FLAG_Z, FLAG_N, FLAG_C)
468471 elif opcode == 'and':
469 self.assert_type(TYPE_BYTE, src, dest)
472 if isinstance(src, IndexedRef):
473 context.assert_types_for_read_table(instr, src, dest, TYPE_BYTE)
474 else:
475 self.assert_type(TYPE_BYTE, src, dest)
470476 context.assert_meaningful(src, dest)
471477 context.set_written(dest, FLAG_Z, FLAG_N)
472478 # If you AND the A register with a value V, the resulting value of A
473479 # cannot exceed the value of V; i.e. the maximum value of A becomes
474480 # the maximum value of V.
475 context.set_top_of_range(dest, context.get_top_of_range(src))
481 if not isinstance(src, IndexedRef):
482 context.set_top_of_range(dest, context.get_top_of_range(src))
476483 elif opcode in ('or', 'xor'):
477 self.assert_type(TYPE_BYTE, src, dest)
484 if isinstance(src, IndexedRef):
485 context.assert_types_for_read_table(instr, src, dest, TYPE_BYTE)
486 else:
487 self.assert_type(TYPE_BYTE, src, dest)
478488 context.assert_meaningful(src, dest)
479489 context.set_written(dest, FLAG_Z, FLAG_N)
480490 context.invalidate_range(dest)
491 elif opcode in ('inc', 'dec'):
492 context.assert_meaningful(dest)
493 if isinstance(dest, IndexedRef):
494 context.assert_types_for_update_table(instr, dest, TYPE_BYTE)
495 context.set_written(dest.ref, FLAG_Z, FLAG_N)
496 #context.invalidate_range(dest)
497 else:
498 self.assert_type(TYPE_BYTE, dest)
499 context.set_written(dest, FLAG_Z, FLAG_N)
500 context.invalidate_range(dest)
481501 elif opcode in ('shl', 'shr'):
482 self.assert_type(TYPE_BYTE, dest)
483502 context.assert_meaningful(dest, FLAG_C)
484 context.set_written(dest, FLAG_Z, FLAG_N, FLAG_C)
485 context.invalidate_range(dest)
503 if isinstance(dest, IndexedRef):
504 context.assert_types_for_update_table(instr, dest, TYPE_BYTE)
505 context.set_written(dest.ref, FLAG_Z, FLAG_N, FLAG_C)
506 #context.invalidate_range(dest)
507 else:
508 self.assert_type(TYPE_BYTE, dest)
509 context.set_written(dest, FLAG_Z, FLAG_N, FLAG_C)
510 context.invalidate_range(dest)
486511 elif opcode == 'call':
487512 type = instr.location.type
488513 if isinstance(type, VectorType):
473473 | }
474474 ? UnmeaningfulReadError: x
475475
476 There are other operations you can do on tables.
476 There are other operations you can do on tables. (1/3)
477477
478478 | byte table[256] many
479479 |
480480 | routine main
481481 | inputs many
482482 | outputs many
483 | trashes a, x, c, n, z
483 | trashes a, x, c, n, z, v
484484 | {
485485 | ld x, 0
486486 | ld a, 0
488488 | add a, many + x
489489 | sub a, many + x
490490 | cmp a, many + x
491 | }
492 = ok
493
494 There are other operations you can do on tables. (2/3)
495
496 | byte table[256] many
497 |
498 | routine main
499 | inputs many
500 | outputs many
501 | trashes a, x, c, n, z
502 | {
503 | ld x, 0
504 | ld a, 0
491505 | and a, many + x
492506 | or a, many + x
493507 | xor a, many + x
508 | }
509 = ok
510
511
512 There are other operations you can do on tables. (3/3)
513
514 | byte table[256] many
515 |
516 | routine main
517 | inputs many
518 | outputs many
519 | trashes a, x, c, n, z
520 | {
521 | ld x, 0
522 | ld a, 0
523 | st off, c
494524 | shl many + x
495525 | shr many + x
496526 | inc many + x