Browse Source

More work on update_asm_instructions.py

master
Ben Kurtovic 9 years ago
parent
commit
0548e5d18c
1 changed files with 79 additions and 5 deletions
  1. +79
    -5
      scripts/update_asm_instructions.py

+ 79
- 5
scripts/update_asm_instructions.py View File

@@ -36,18 +36,92 @@ re_lookup = re.compile(
r"(/\* @AUTOGEN_LOOKUP_BLOCK_START \*/\n*)(.*?)"
r"(\n*/\* @AUTOGEN_LOOKUP_BLOCK_END \*/)", re.S)

def build_inst(name, data):
class Instruction(object):
"""
Convert data for an individual instruction into a C parse function.
Represent a single ASM instruction mnemonic.
"""
# TODO
return "INST_FUNC({0})\n{{\n}}".format(name)
ARG_TYPES = {
"register": "AT_REGISTER",
"immediate": "AT_IMMEDIATE",
"indirect": "AT_INDIRECT",
"indexed": "AT_INDEXED|AT_INDIRECT",
"condition": "AT_CONDITION",
"port": "AT_PORT"
}

def __init__(self, name, data):
self._name = name
self._data = data

def _get_arg_parse_mask(self, num):
"""
Return the appropriate mask to parse_args() for the num-th argument.
"""
types = set()
optional = False
for case in self._data["cases"]:
if num < len(case["type"]):
types.add(self.ARG_TYPES[case["type"][num]])
else:
optional = True

if not types:
return "AT_NONE"
if optional:
types.add("AT_OPTIONAL")
return "|".join(types)

def _handle_return(self, arg, indent=1):
"""
Return code to handle an instruction return statement.
"""
tabs = TAB * indent
if arg == "error":
return tabs + "INST_ERROR(ARG_SYNTAX)"
else:
data = ", ".join("0x%02X" % byte for byte in arg)
return tabs + "INST_RETURN({0}, {1})".format(len(arg), data)

def _handle_case(self, case):
"""
TODO
"""
return [TAB + "// " + str(case)]

def render(self):
"""
Convert data for an individual instruction into a C parse function.
"""
lines = []

if self._data["args"]:
lines.append("{tab}INST_TAKES_ARGS(\n{tab2}{0}, \n{tab2}{1}, "
"\n{tab2}{2}\n{tab})".format(
self._get_arg_parse_mask(0), self._get_arg_parse_mask(1),
self._get_arg_parse_mask(2), tab=TAB, tab2=TAB * 2))
else:
lines.append(TAB + "INST_TAKES_NO_ARGS")

if "return" in self._data:
lines.append(self._handle_return(self._data["return"]))
elif "cases" in self._data:
for case in self._data["cases"]:
lines.extend(self._handle_case(case))
lines.append(TAB + "INST_ERROR(ARG_TYPE)")
else:
msg = "Missing return or case block for {0} instruction"
raise RuntimeError(msg.format(self._name))

contents = "\n".join(lines)
return "INST_FUNC({0})\n{{\n{1}\n}}".format(self._name, contents)


def build_inst_block(data):
"""
Return the instruction parser block, given instruction data.
"""
return "\n\n".join(build_inst(k, v) for k, v in sorted(data.items()))
return "\n\n".join(
Instruction(k, v).render() for k, v in sorted(data.items()))

def build_lookup_block(data):
"""


Loading…
Cancel
Save