| @@ -12,7 +12,6 @@ when the latter is modified, but can also be run manually. | |||||
| from __future__ import print_function | from __future__ import print_function | ||||
| from itertools import product | |||||
| import re | import re | ||||
| import time | import time | ||||
| @@ -46,6 +45,18 @@ def _atoi(value): | |||||
| except ValueError: | except ValueError: | ||||
| return int(value, 16) | return int(value, 16) | ||||
| def _is_call(call, func): | |||||
| """ | |||||
| Return whether the first argument is a function call of the second. | |||||
| """ | |||||
| return call.startswith(func + "(") and call.endswith(")") | |||||
| def _call_args(call, func): | |||||
| """ | |||||
| Given a call and a function name, return the function call arguments. | |||||
| """ | |||||
| return call[len(func) + 1:-1].strip() | |||||
| class Instruction(object): | class Instruction(object): | ||||
| """ | """ | ||||
| Represent a single ASM instruction mnemonic. | Represent a single ASM instruction mnemonic. | ||||
| @@ -222,6 +233,23 @@ class Instruction(object): | |||||
| choices = [cond * num if len(cond) == 1 else cond for cond in splits] | choices = [cond * num if len(cond) == 1 else cond for cond in splits] | ||||
| return zip(*choices) | return zip(*choices) | ||||
| def _step(self, argdata): | |||||
| """ | |||||
| Evaluate a step function call into a single byte. | |||||
| """ | |||||
| args = _call_args(argdata, "step") | |||||
| if " " in args: | |||||
| base, stride = map(_atoi, args.split(" ")) | |||||
| else: | |||||
| base, stride = _atoi(args), 1 | |||||
| if base not in self._step_state: | |||||
| self._step_state[base] = 0 | |||||
| byte = base + self._step_state[base] * stride | |||||
| self._step_state[base] += 1 | |||||
| return byte | |||||
| def _adapt_return(self, types, conds, ret): | def _adapt_return(self, types, conds, ret): | ||||
| """ | """ | ||||
| Return a modified byte list to accomodate for prefixes and immediates. | Return a modified byte list to accomodate for prefixes and immediates. | ||||
| @@ -258,21 +286,16 @@ class Instruction(object): | |||||
| index = types.index("immediate") | index = types.index("immediate") | ||||
| ret[i] = "INST_IMM({0}).sval - 2".format(index) | ret[i] = "INST_IMM({0}).sval - 2".format(index) | ||||
| elif byte.startswith("bit(") and byte.endswith(")"): | |||||
| elif _is_call(byte, "bit"): | |||||
| index = types.index("immediate") | index = types.index("immediate") | ||||
| base = byte[4:-1] | |||||
| ret[i] = "{0} + 8 * INST_IMM({1}).uval".format(base, index) | |||||
| elif byte.startswith("step(") and byte.endswith(")"): | |||||
| arg = byte[5:-1] | |||||
| if " " in arg: | |||||
| base, stride = map(_atoi, arg.split(" ")) | |||||
| else: | |||||
| base, stride = _atoi(arg), 1 | |||||
| if base not in self._step_state: | |||||
| self._step_state[base] = 0 | |||||
| ret[i] = base + self._step_state[base] * stride | |||||
| self._step_state[base] += 1 | |||||
| base = _call_args(byte, "bit") | |||||
| if _is_call(base, "step"): | |||||
| base = self._step(base) | |||||
| ret[i] = "0x{0:02X} + 8 * INST_IMM({1}).uval".format( | |||||
| _atoi(base), index) | |||||
| elif _is_call(byte, "step"): | |||||
| ret[i] = self._step(byte) | |||||
| else: | else: | ||||
| msg = "Unsupported return byte: {0}" | msg = "Unsupported return byte: {0}" | ||||
| @@ -338,6 +361,7 @@ class Instruction(object): | |||||
| cond = self._build_case_type_check(ctype) | cond = self._build_case_type_check(ctype) | ||||
| lines.append(TAB + "if ({0}) {{".format(cond)) | lines.append(TAB + "if ({0}) {{".format(cond)) | ||||
| self._step_state = {} | |||||
| subcases = [(perm, sub["return"]) for sub in case["cases"] | subcases = [(perm, sub["return"]) for sub in case["cases"] | ||||
| for perm in self._iter_permutations(ctype, sub["cond"])] | for perm in self._iter_permutations(ctype, sub["cond"])] | ||||
| for cond, ret in subcases: | for cond, ret in subcases: | ||||
| @@ -7,7 +7,7 @@ | |||||
| `make` should trigger a rebuild when it is modified; if not, use: | `make` should trigger a rebuild when it is modified; if not, use: | ||||
| `python scripts/update_asm_instructions.py`. | `python scripts/update_asm_instructions.py`. | ||||
| @AUTOGEN_DATE Thu May 21 21:05:17 2015 UTC | |||||
| @AUTOGEN_DATE Thu May 21 22:35:58 2015 UTC | |||||
| */ | */ | ||||
| /* @AUTOGEN_INST_BLOCK_START */ | /* @AUTOGEN_INST_BLOCK_START */ | ||||
| @@ -93,18 +93,8 @@ bit: | |||||
| cases: | cases: | ||||
| - cond: [bit, a] | - cond: [bit, a] | ||||
| return: [0xCB, bit(0x47)] | return: [0xCB, bit(0x47)] | ||||
| - cond: [bit, b] | |||||
| return: [0xCB, bit(0x40)] | |||||
| - cond: [bit, c] | |||||
| return: [0xCB, bit(0x41)] | |||||
| - cond: [bit, d] | |||||
| return: [0xCB, bit(0x42)] | |||||
| - cond: [bit, e] | |||||
| return: [0xCB, bit(0x43)] | |||||
| - cond: [bit, h] | |||||
| return: [0xCB, bit(0x44)] | |||||
| - cond: [bit, l] | |||||
| return: [0xCB, bit(0x45)] | |||||
| - cond: [bit, b|c|d|e|h|l] | |||||
| return: [0xCB, bit(step(0x40))] | |||||
| - type: [immediate, indirect_hl_or_indexed] | - type: [immediate, indirect_hl_or_indexed] | ||||
| cases: | cases: | ||||
| - cond: [bit, _] | - cond: [bit, _] | ||||
| @@ -119,22 +109,8 @@ call: | |||||
| return: [0xCD, u16] | return: [0xCD, u16] | ||||
| - type: [condition, immediate] | - type: [condition, immediate] | ||||
| cases: | cases: | ||||
| - cond: [nz, u16] | |||||
| return: [0xC4, u16] | |||||
| - cond: [z, u16] | |||||
| return: [0xCC, u16] | |||||
| - cond: [nc, u16] | |||||
| return: [0xD4, u16] | |||||
| - cond: [c, u16] | |||||
| return: [0xDC, u16] | |||||
| - cond: [po, u16] | |||||
| return: [0xE4, u16] | |||||
| - cond: [pe, u16] | |||||
| return: [0xEC, u16] | |||||
| - cond: [p, u16] | |||||
| return: [0xF4, u16] | |||||
| - cond: [m, u16] | |||||
| return: [0xFC, u16] | |||||
| - cond: [nz|z|nc|c|po|pe|p|m, u16] | |||||
| return: [step(0xC4 0x08), u16] | |||||
| ccf: | ccf: | ||||
| args: no | args: no | ||||
| @@ -147,14 +123,8 @@ cp: | |||||
| cases: | cases: | ||||
| - cond: [a] | - cond: [a] | ||||
| return: [0xBF] | return: [0xBF] | ||||
| - cond: [b] | |||||
| return: [0xB8] | |||||
| - cond: [c] | |||||
| return: [0xB9] | |||||
| - cond: [d] | |||||
| return: [0xBA] | |||||
| - cond: [e] | |||||
| return: [0xBB] | |||||
| - cond: [b|c|d|e] | |||||
| return: [step(0xB8)] | |||||
| - cond: [h|ih] | - cond: [h|ih] | ||||
| return: [0xBC] | return: [0xBC] | ||||
| - cond: [l|il] | - cond: [l|il] | ||||
| @@ -199,14 +169,8 @@ dec: | |||||
| cases: | cases: | ||||
| - cond: [a] | - cond: [a] | ||||
| return: [0x3D] | return: [0x3D] | ||||
| - cond: [b] | |||||
| return: [0x05] | |||||
| - cond: [c] | |||||
| return: [0x0D] | |||||
| - cond: [d] | |||||
| return: [0x15] | |||||
| - cond: [e] | |||||
| return: [0x1D] | |||||
| - cond: [b|c|d|e] | |||||
| return: [step(0x05 0x08)] | |||||
| - cond: [h|ih] | - cond: [h|ih] | ||||
| return: [0x25] | return: [0x25] | ||||
| - cond: [l|il] | - cond: [l|il] | ||||
| @@ -283,18 +247,8 @@ in: | |||||
| return: [0xDB, u8] | return: [0xDB, u8] | ||||
| - cond: [a, reg.c] | - cond: [a, reg.c] | ||||
| return: [0xED, 0x78] | return: [0xED, 0x78] | ||||
| - cond: [b, reg.c] | |||||
| return: [0xED, 0x40] | |||||
| - cond: [c, reg.c] | |||||
| return: [0xED, 0x48] | |||||
| - cond: [d, reg.c] | |||||
| return: [0xED, 0x50] | |||||
| - cond: [e, reg.c] | |||||
| return: [0xED, 0x58] | |||||
| - cond: [h, reg.c] | |||||
| return: [0xED, 0x60] | |||||
| - cond: [l, reg.c] | |||||
| return: [0xED, 0x68] | |||||
| - cond: [b|c|d|e|h|l, reg.c] | |||||
| return: [0xED, step(0x40 0x08)] | |||||
| - type: [port] | - type: [port] | ||||
| cases: | cases: | ||||
| - cond: [reg.c] | - cond: [reg.c] | ||||
| @@ -307,14 +261,8 @@ inc: | |||||
| cases: | cases: | ||||
| - cond: [a] | - cond: [a] | ||||
| return: [0x3C] | return: [0x3C] | ||||
| - cond: [b] | |||||
| return: [0x04] | |||||
| - cond: [c] | |||||
| return: [0x0C] | |||||
| - cond: [d] | |||||
| return: [0x14] | |||||
| - cond: [e] | |||||
| return: [0x1C] | |||||
| - cond: [b|c|d|e] | |||||
| return: [step(0x04 0x08)] | |||||
| - cond: [h|ih] | - cond: [h|ih] | ||||
| return: [0x24] | return: [0x24] | ||||
| - cond: [l|il] | - cond: [l|il] | ||||
| @@ -357,22 +305,8 @@ jp: | |||||
| return: [0xC3, u16] | return: [0xC3, u16] | ||||
| - type: [condition, immediate] | - type: [condition, immediate] | ||||
| cases: | cases: | ||||
| - cond: [nz, u16] | |||||
| return: [0xC2, u16] | |||||
| - cond: [z, u16] | |||||
| return: [0xCA, u16] | |||||
| - cond: [nc, u16] | |||||
| return: [0xD2, u16] | |||||
| - cond: [c, u16] | |||||
| return: [0xDA, u16] | |||||
| - cond: [po, u16] | |||||
| return: [0xE2, u16] | |||||
| - cond: [pe, u16] | |||||
| return: [0xEA, u16] | |||||
| - cond: [p, u16] | |||||
| return: [0xF2, u16] | |||||
| - cond: [m, u16] | |||||
| return: [0xFA, u16] | |||||
| - cond: [nz|z|nc|c|po|pe|p|m, u16] | |||||
| return: [step(0xC2 0x08), u16] | |||||
| - type: [indirect_hl_or_indexed] | - type: [indirect_hl_or_indexed] | ||||
| cases: | cases: | ||||
| - cond: [_] | - cond: [_] | ||||
| @@ -397,70 +331,40 @@ ld: | |||||
| cases: | cases: | ||||
| - cond: [a, a] | - cond: [a, a] | ||||
| return: [0x7F] | return: [0x7F] | ||||
| - cond: [a, b] | |||||
| return: [0x78] | |||||
| - cond: [a, c] | |||||
| return: [0x79] | |||||
| - cond: [a, d] | |||||
| return: [0x7A] | |||||
| - cond: [a, e] | |||||
| return: [0x7B] | |||||
| - cond: [a, b|c|d|e] | |||||
| return: [step(0x78)] | |||||
| - cond: [a, h|ih] | - cond: [a, h|ih] | ||||
| return: [0x7C] | return: [0x7C] | ||||
| - cond: [a, l|il] | - cond: [a, l|il] | ||||
| return: [0x7D] | return: [0x7D] | ||||
| - cond: [b, a] | - cond: [b, a] | ||||
| return: [0x47] | return: [0x47] | ||||
| - cond: [b, b] | |||||
| return: [0x40] | |||||
| - cond: [b, c] | |||||
| return: [0x41] | |||||
| - cond: [b, d] | |||||
| return: [0x42] | |||||
| - cond: [b, e] | |||||
| return: [0x43] | |||||
| - cond: [b, b|c|d|e] | |||||
| return: [step(0x40)] | |||||
| - cond: [b, h|ih] | - cond: [b, h|ih] | ||||
| return: [0x44] | return: [0x44] | ||||
| - cond: [b, l|il] | - cond: [b, l|il] | ||||
| return: [0x45] | return: [0x45] | ||||
| - cond: [c, a] | - cond: [c, a] | ||||
| return: [0x4F] | return: [0x4F] | ||||
| - cond: [c, b] | |||||
| return: [0x48] | |||||
| - cond: [c, c] | |||||
| return: [0x49] | |||||
| - cond: [c, d] | |||||
| return: [0x4A] | |||||
| - cond: [c, e] | |||||
| return: [0x4B] | |||||
| - cond: [c, b|c|d|e] | |||||
| return: [step(0x48)] | |||||
| - cond: [c, h|ih] | - cond: [c, h|ih] | ||||
| return: [0x4C] | return: [0x4C] | ||||
| - cond: [c, l|il] | - cond: [c, l|il] | ||||
| return: [0x4D] | return: [0x4D] | ||||
| - cond: [d, a] | - cond: [d, a] | ||||
| return: [0x57] | return: [0x57] | ||||
| - cond: [d, b] | |||||
| return: [0x50] | |||||
| - cond: [d, c] | |||||
| return: [0x51] | |||||
| - cond: [d, d] | |||||
| return: [0x52] | |||||
| - cond: [d, e] | |||||
| return: [0x53] | |||||
| - cond: [d, b|c|d|e] | |||||
| return: [step(0x50)] | |||||
| - cond: [d, h|ih] | - cond: [d, h|ih] | ||||
| return: [0x54] | return: [0x54] | ||||
| - cond: [d, l|il] | - cond: [d, l|il] | ||||
| return: [0x55] | return: [0x55] | ||||
| - cond: [e, a] | - cond: [e, a] | ||||
| return: [0x5F] | return: [0x5F] | ||||
| - cond: [e, b] | |||||
| return: [0x58] | |||||
| - cond: [e, c] | |||||
| return: [0x59] | |||||
| - cond: [e, d] | |||||
| return: [0x5A] | |||||
| - cond: [e, e] | |||||
| return: [0x5B] | |||||
| - cond: [e, b|c|d|e] | |||||
| return: [step(0x58)] | |||||
| - cond: [e, h|ih] | - cond: [e, h|ih] | ||||
| return: [0x5C] | return: [0x5C] | ||||
| - cond: [e, l|il] | - cond: [e, l|il] | ||||
| @@ -507,14 +411,8 @@ ld: | |||||
| cases: | cases: | ||||
| - cond: [a, u8] | - cond: [a, u8] | ||||
| return: [0x3E, u8] | return: [0x3E, u8] | ||||
| - cond: [b, u8] | |||||
| return: [0x06, u8] | |||||
| - cond: [c, u8] | |||||
| return: [0x0E, u8] | |||||
| - cond: [d, u8] | |||||
| return: [0x16, u8] | |||||
| - cond: [e, u8] | |||||
| return: [0x1E, u8] | |||||
| - cond: [b|c|d|e, u8] | |||||
| return: [step(0x06 0x08), u8] | |||||
| - cond: [h|ih, u8] | - cond: [h|ih, u8] | ||||
| return: [0x26, u8] | return: [0x26, u8] | ||||
| - cond: [l|il, u8] | - cond: [l|il, u8] | ||||
| @@ -531,18 +429,8 @@ ld: | |||||
| cases: | cases: | ||||
| - cond: [a, _] | - cond: [a, _] | ||||
| return: [0x7E] | return: [0x7E] | ||||
| - cond: [b, _] | |||||
| return: [0x46] | |||||
| - cond: [c, _] | |||||
| return: [0x4E] | |||||
| - cond: [d, _] | |||||
| return: [0x56] | |||||
| - cond: [e, _] | |||||
| return: [0x5E] | |||||
| - cond: [h, _] | |||||
| return: [0x66] | |||||
| - cond: [l, _] | |||||
| return: [0x6E] | |||||
| - cond: [b|c|d|e|h|l, _] | |||||
| return: [step(0x46 0x08)] | |||||
| - type: [register, indirect] | - type: [register, indirect] | ||||
| cases: | cases: | ||||
| - cond: [a, reg.bc] | - cond: [a, reg.bc] | ||||
| @@ -563,18 +451,8 @@ ld: | |||||
| cases: | cases: | ||||
| - cond: [_, a] | - cond: [_, a] | ||||
| return: [0x77] | return: [0x77] | ||||
| - cond: [_, b] | |||||
| return: [0x70] | |||||
| - cond: [_, c] | |||||
| return: [0x71] | |||||
| - cond: [_, d] | |||||
| return: [0x72] | |||||
| - cond: [_, e] | |||||
| return: [0x73] | |||||
| - cond: [_, h] | |||||
| return: [0x74] | |||||
| - cond: [_, l] | |||||
| return: [0x75] | |||||
| - cond: [_, b|c|d|e|h|l] | |||||
| return: [step(0x70)] | |||||
| - type: [indirect_hl_or_indexed, immediate] | - type: [indirect_hl_or_indexed, immediate] | ||||
| cases: | cases: | ||||
| - cond: [_, u8] | - cond: [_, u8] | ||||