@@ -12,7 +12,6 @@ when the latter is modified, but can also be run manually. | |||
from __future__ import print_function | |||
from itertools import product | |||
import re | |||
import time | |||
@@ -46,6 +45,18 @@ def _atoi(value): | |||
except ValueError: | |||
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): | |||
""" | |||
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] | |||
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): | |||
""" | |||
Return a modified byte list to accomodate for prefixes and immediates. | |||
@@ -258,21 +286,16 @@ class Instruction(object): | |||
index = types.index("immediate") | |||
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") | |||
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: | |||
msg = "Unsupported return byte: {0}" | |||
@@ -338,6 +361,7 @@ class Instruction(object): | |||
cond = self._build_case_type_check(ctype) | |||
lines.append(TAB + "if ({0}) {{".format(cond)) | |||
self._step_state = {} | |||
subcases = [(perm, sub["return"]) for sub in case["cases"] | |||
for perm in self._iter_permutations(ctype, sub["cond"])] | |||
for cond, ret in subcases: | |||
@@ -7,7 +7,7 @@ | |||
`make` should trigger a rebuild when it is modified; if not, use: | |||
`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 */ | |||
@@ -93,18 +93,8 @@ bit: | |||
cases: | |||
- cond: [bit, a] | |||
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] | |||
cases: | |||
- cond: [bit, _] | |||
@@ -119,22 +109,8 @@ call: | |||
return: [0xCD, u16] | |||
- type: [condition, immediate] | |||
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: | |||
args: no | |||
@@ -147,14 +123,8 @@ cp: | |||
cases: | |||
- cond: [a] | |||
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] | |||
return: [0xBC] | |||
- cond: [l|il] | |||
@@ -199,14 +169,8 @@ dec: | |||
cases: | |||
- cond: [a] | |||
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] | |||
return: [0x25] | |||
- cond: [l|il] | |||
@@ -283,18 +247,8 @@ in: | |||
return: [0xDB, u8] | |||
- cond: [a, reg.c] | |||
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] | |||
cases: | |||
- cond: [reg.c] | |||
@@ -307,14 +261,8 @@ inc: | |||
cases: | |||
- cond: [a] | |||
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] | |||
return: [0x24] | |||
- cond: [l|il] | |||
@@ -357,22 +305,8 @@ jp: | |||
return: [0xC3, u16] | |||
- type: [condition, immediate] | |||
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] | |||
cases: | |||
- cond: [_] | |||
@@ -397,70 +331,40 @@ ld: | |||
cases: | |||
- cond: [a, a] | |||
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] | |||
return: [0x7C] | |||
- cond: [a, l|il] | |||
return: [0x7D] | |||
- cond: [b, a] | |||
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] | |||
return: [0x44] | |||
- cond: [b, l|il] | |||
return: [0x45] | |||
- cond: [c, a] | |||
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] | |||
return: [0x4C] | |||
- cond: [c, l|il] | |||
return: [0x4D] | |||
- cond: [d, a] | |||
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] | |||
return: [0x54] | |||
- cond: [d, l|il] | |||
return: [0x55] | |||
- cond: [e, a] | |||
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] | |||
return: [0x5C] | |||
- cond: [e, l|il] | |||
@@ -507,14 +411,8 @@ ld: | |||
cases: | |||
- cond: [a, 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] | |||
return: [0x26, u8] | |||
- cond: [l|il, u8] | |||
@@ -531,18 +429,8 @@ ld: | |||
cases: | |||
- cond: [a, _] | |||
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] | |||
cases: | |||
- cond: [a, reg.bc] | |||
@@ -563,18 +451,8 @@ ld: | |||
cases: | |||
- cond: [_, a] | |||
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] | |||
cases: | |||
- cond: [_, u8] | |||