From 5c6f1c288b68066609c4d73a8b484b450d09d095 Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Mon, 18 May 2015 04:12:54 -0400 Subject: [PATCH] Implement AND; cleanup for unconditional subcases. --- scripts/update_asm_instructions.py | 25 ++++++++++------ src/assembler/instructions.inc.c | 58 +++++++++++++++++++++++++++++++++----- src/assembler/instructions.yml | 30 ++++++++++++++++++-- 3 files changed, 94 insertions(+), 19 deletions(-) diff --git a/scripts/update_asm_instructions.py b/scripts/update_asm_instructions.py index 2897d5f..161514f 100755 --- a/scripts/update_asm_instructions.py +++ b/scripts/update_asm_instructions.py @@ -179,7 +179,7 @@ class Instruction(object): """ conds = [self._SUBCASE_LOOKUP_TABLE[types[i]](self, i, cond) for i, cond in enumerate(conds) if cond != "_"] - return " && ".join(conds) if conds else "1" + return " && ".join(conds) def _iter_permutations(self, types, conds): """ @@ -281,22 +281,29 @@ class Instruction(object): """ Return code to handle an instruction case. """ + ctype = case["type"] for pseudo in self.PSEUDO_TYPES: - if pseudo in case["type"]: + if pseudo in ctype: return self._handle_pseudo_case(pseudo, case) lines = [] - cond = self._build_case_type_check(case["type"]) + cond = self._build_case_type_check(ctype) lines.append(TAB + "if ({0}) {{".format(cond)) - for subcase in case["cases"]: - for perm in self._iter_permutations(case["type"], subcase["cond"]): - cond = self._build_subcase_check(case["type"], perm) - ret = self._adapt_return(case["type"], perm, subcase["return"]) - lines.append(TAB * 2 + "if ({0})".format(cond)) + subcases = [(perm, sub["return"]) for sub in case["cases"] + for perm in self._iter_permutations(ctype, sub["cond"])] + for cond, ret in subcases: + check = self._build_subcase_check(ctype, cond) + ret = self._adapt_return(ctype, cond, ret) + if check: + lines.append(TAB * 2 + "if ({0})".format(check)) lines.append(self._handle_return(ret, 3)) + else: + lines.append(self._handle_return(ret, 2)) + break # Unconditional subcase + else: + lines.append(TAB * 2 + "INST_ERROR(ARG_VALUE)") - lines.append(TAB * 2 + "INST_ERROR(ARG_VALUE)") lines.append(TAB + "}") return lines diff --git a/src/assembler/instructions.inc.c b/src/assembler/instructions.inc.c index d33f4b5..564a469 100644 --- a/src/assembler/instructions.inc.c +++ b/src/assembler/instructions.inc.c @@ -7,7 +7,7 @@ `make` should trigger a rebuild when it is modified; if not, use: `python scripts/update_asm_instructions.py`. - @AUTOGEN_DATE Mon May 18 05:31:58 2015 UTC + @AUTOGEN_DATE Mon May 18 08:11:32 2015 UTC */ /* @AUTOGEN_INST_BLOCK_START */ @@ -146,6 +146,53 @@ INST_FUNC(add) INST_ERROR(ARG_TYPE) } +INST_FUNC(and) +{ + INST_TAKES_ARGS( + AT_IMMEDIATE|AT_INDEXED|AT_INDIRECT|AT_REGISTER, + AT_NONE, + AT_NONE + ) + if (INST_NARGS == 1 && INST_TYPE(0) == AT_REGISTER) { + if (INST_REG(0) == REG_A) + INST_RETURN(1, 0xA7) + if (INST_REG(0) == REG_B) + INST_RETURN(1, 0xA0) + if (INST_REG(0) == REG_C) + INST_RETURN(1, 0xA1) + if (INST_REG(0) == REG_D) + INST_RETURN(1, 0xA2) + if (INST_REG(0) == REG_E) + INST_RETURN(1, 0xA3) + if (INST_REG(0) == REG_H) + INST_RETURN(1, 0xA4) + if (INST_REG(0) == REG_IXH) + INST_RETURN(2, INST_IX_PREFIX, 0xA4) + if (INST_REG(0) == REG_IYH) + INST_RETURN(2, INST_IY_PREFIX, 0xA4) + if (INST_REG(0) == REG_L) + INST_RETURN(1, 0xA5) + if (INST_REG(0) == REG_IXL) + INST_RETURN(2, INST_IX_PREFIX, 0xA5) + if (INST_REG(0) == REG_IYL) + INST_RETURN(2, INST_IY_PREFIX, 0xA5) + INST_ERROR(ARG_VALUE) + } + if (INST_NARGS == 1 && INST_TYPE(0) == AT_IMMEDIATE) { + if (INST_IMM(0).mask & IMM_U8) + INST_RETURN(2, 0xE6, INST_IMM(0).uval) + INST_ERROR(ARG_VALUE) + } + if (INST_NARGS == 1 && INST_TYPE(0) == AT_INDIRECT && + (INST_INDIRECT(0).type == AT_REGISTER && INST_INDIRECT(0).addr.reg == REG_HL)) { + INST_RETURN(1, 0xA6) + } + if (INST_NARGS == 1 && INST_TYPE(0) == AT_INDEXED) { + INST_RETURN(3, INST_INDEX_PREFIX(0), 0xA6, INST_INDEX(0).offset) + } + INST_ERROR(ARG_TYPE) +} + INST_FUNC(ccf) { INST_TAKES_NO_ARGS @@ -258,14 +305,10 @@ INST_FUNC(inc) } if (INST_NARGS == 1 && INST_TYPE(0) == AT_INDIRECT && (INST_INDIRECT(0).type == AT_REGISTER && INST_INDIRECT(0).addr.reg == REG_HL)) { - if (1) - INST_RETURN(1, 0x34) - INST_ERROR(ARG_VALUE) + INST_RETURN(1, 0x34) } if (INST_NARGS == 1 && INST_TYPE(0) == AT_INDEXED) { - if (1) - INST_RETURN(3, INST_INDEX_PREFIX(0), 0x34, INST_INDEX(0).offset) - INST_ERROR(ARG_VALUE) + INST_RETURN(3, INST_INDEX_PREFIX(0), 0x34, INST_INDEX(0).offset) } INST_ERROR(ARG_TYPE) } @@ -797,6 +840,7 @@ static ASMInstParser lookup_parser(uint32_t key) /* @AUTOGEN_LOOKUP_BLOCK_START */ HANDLE(adc) HANDLE(add) + HANDLE(and) HANDLE(ccf) HANDLE(cpd) HANDLE(cpdr) diff --git a/src/assembler/instructions.yml b/src/assembler/instructions.yml index 104a64a..3f247b8 100644 --- a/src/assembler/instructions.yml +++ b/src/assembler/instructions.yml @@ -82,9 +82,33 @@ add: - cond: [a, _] return: [0x86] -# and: -# args: yes -# return: TODO +and: + args: yes + cases: + - type: [register] + cases: + - cond: [a] + return: [0xA7] + - cond: [b] + return: [0xA0] + - cond: [c] + return: [0xA1] + - cond: [d] + return: [0xA2] + - cond: [e] + return: [0xA3] + - cond: [h|ih] + return: [0xA4] + - cond: [l|il] + return: [0xA5] + - type: [immediate] + cases: + - cond: [u8] + return: [0xE6, u8] + - type: [indirect_hl_or_indexed] + cases: + - cond: [_] + return: [0xA6] # bit: # args: yes