@@ -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] | ||||