git @ Cat's Eye Technologies SixtyPical / 8b30a23
Analyze `copy`, but... we now need more sophisticated context. :/ Chris Pressey 6 years ago
5 changed file(s) with 110 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
333333 copy <src-memory-location>, <dest-memory-location>
334334
335335 Reads from src and writes to dest. Differs from `st` in that is able to
336 copy more general types of data (for example, vectors,) and it sets the
337 `z` and `n` flags and trashes the `a` register.
336 copy more general types of data (for example, vectors,) and it trashes the
337 `z` and `n` flags and the `a` register.
338338
339339 * It is illegal if dest is read-only.
340340 * It is illegal if dest does not occur in the WRITES lists of the current
342342 * It is illegal if src is not of same type as dest.
343343 * It is illegal if src is uninitialized.
344344
345 After execution, dest is considered initialized, as are `z` and `n`, while
346 `a` is considered uninitialized.
345 After execution, dest is considered initialized, and `z` and `n`, and
346 `a` are considered uninitialized.
347347
348348 Grammar
349349 -------
11
22 from sixtypical.ast import Program, Routine, Block, Instr
33 from sixtypical.model import (
4 TYPE_BYTE, TYPE_BYTE_TABLE,
5 ConstantRef, LocationRef, FLAG_Z, FLAG_N, FLAG_V, FLAG_C
4 TYPE_BYTE, TYPE_BYTE_TABLE, TYPE_ROUTINE, TYPE_VECTOR,
5 ConstantRef, LocationRef,
6 REG_A, FLAG_Z, FLAG_N, FLAG_V, FLAG_C
67 )
78
89
213214 analyze_block(instr.block, context, routines)
214215
215216 # NB I *think* that's enough... but it might not be?
217 elif opcode == 'copy':
218 if src.type == dest.type:
219 pass
220 elif src.type == TYPE_ROUTINE and dest.type == TYPE_VECTOR:
221 pass
222 else:
223 raise TypeMismatchError((src, dest))
224 context.assert_initialized(src)
225 context.assert_writeable(dest)
226 context.set_initialized(dest)
227 context.set_uninitialized(REG_A, FLAG_Z, FLAG_N)
216228 else:
217229 raise NotImplementedError(opcode)
153153 eval_block(instr.block, context, routines)
154154 while context.get(src) == 0:
155155 eval_block(instr.block, context, routines)
156 elif opcode == 'copy':
157 context.set(dest, context.get(src))
158 # these are trashed; so could be anything really
159 context.set(REG_A, 0)
160 context.set(FLAG_Z, 0)
161 context.set(FLAG_N, 0)
156162 else:
157163 raise NotImplementedError
964964 | } until z
965965 | }
966966 ? UninitializedAccessError: y
967
968 ### copy ###
969
970 Can't `copy` from a memory location that isn't initialized.
971
972 | byte lives
973 | routine main
974 | inputs x
975 | outputs lives
976 | trashes a, z, n
977 | {
978 | copy x, lives
979 | }
980 = ok
981
982 | byte lives
983 | routine main
984 | outputs lives
985 | trashes x, a, z, n
986 | {
987 | copy x, lives
988 | }
989 ? UninitializedAccessError: x
990
991 Can't `st` to a memory location that doesn't appear in (outputs ∪ trashes).
992
993 | byte lives
994 | routine main
995 | trashes lives, a, z, n
996 | {
997 | copy 0, lives
998 | }
999 = ok
1000
1001 | byte lives
1002 | routine main
1003 | outputs lives
1004 | trashes a, z, n
1005 | {
1006 | copy 0, lives
1007 | }
1008 = ok
1009
1010 | byte lives
1011 | routine main
1012 | inputs lives
1013 | trashes a, z, n
1014 | {
1015 | copy 0, lives
1016 | }
1017 ? IllegalWriteError: lives
1018
1019 a, z, and n are trashed, and must be declared as such
1020
1021 | byte lives
1022 | routine main
1023 | outputs lives
1024 | {
1025 | copy 0, lives
1026 | }
1027 ? IllegalWriteError: a
1028
1029 a, z, and n are trashed, and must not be declared as outputs.
1030
1031 | byte lives
1032 | routine main
1033 | outputs lives, a, z, n
1034 | {
1035 | copy 0, lives
1036 | }
1037 ? UninitializedOutputError: a
384384 = x: 10
385385 = y: 25
386386 = z: 1
387
388 Copy instruction. Note that the state of a, z, and n are not defined
389 after copy executes.
390
391 | routine main {
392 | ld x, 5
393 | copy x, y
394 | }
395 = a: 0
396 = c: 0
397 = n: 0
398 = v: 0
399 = x: 5
400 = y: 5
401 = z: 0