diff options
-rw-r--r-- | disasm.cpp | 73 | ||||
-rw-r--r-- | test.bash | 31 |
2 files changed, 90 insertions, 14 deletions
@@ -590,10 +590,81 @@ static void disasm_move_movea( node.size = kInstructionSizeStepBytes + src.Size() + dst.Size(); } +static void disasm_move_from_sr( + DisasmNode& node, uint16_t instr, const DataBuffer &code, const Settings &s) +{ + const char suffix = 'w'; + const auto dst = AddrModeArg::Fetch( + node.offset + kInstructionSizeStepBytes, code, instr, suffix); + switch (dst.mode) { + case AddrMode::kInvalid: + return disasm_verbatim(node, instr, code, s); + case AddrMode::kDn: + break; + case AddrMode::kAn: + return disasm_verbatim(node, instr, code, s); + case AddrMode::kAnAddr: + case AddrMode::kAnAddrIncr: + case AddrMode::kAnAddrDecr: + case AddrMode::kD16AnAddr: + case AddrMode::kD8AnXiAddr: + case AddrMode::kWord: + case AddrMode::kLong: + break; + case AddrMode::kD16PCAddr: + case AddrMode::kD8PCXiAddr: + case AddrMode::kImmediate: + return disasm_verbatim(node, instr, code, s); + } + char dst_str[32]{}; + dst.SNPrint(dst_str, sizeof(dst_str)); + snprintf(node.mnemonic, kMnemonicBufferSize, "move%c", suffix); + snprintf(node.arguments, kArgsBufferSize, "%%sr,%s", dst_str); + node.size = kInstructionSizeStepBytes + dst.Size(); +} + +static void disasm_move_to( + DisasmNode& node, uint16_t instr, const DataBuffer &code, const Settings &s, const char* reg) +{ + const char suffix = 'w'; + const auto src = AddrModeArg::Fetch( + node.offset + kInstructionSizeStepBytes, code, instr, suffix); + switch (src.mode) { + case AddrMode::kInvalid: + return disasm_verbatim(node, instr, code, s); + case AddrMode::kDn: + break; + case AddrMode::kAn: + return disasm_verbatim(node, instr, code, s); + case AddrMode::kAnAddr: + case AddrMode::kAnAddrIncr: + case AddrMode::kAnAddrDecr: + case AddrMode::kD16AnAddr: + case AddrMode::kD8AnXiAddr: + case AddrMode::kWord: + case AddrMode::kLong: + case AddrMode::kD16PCAddr: + case AddrMode::kD8PCXiAddr: + case AddrMode::kImmediate: + break; + } + char src_str[32]{}; + src.SNPrint(src_str, sizeof(src_str)); + snprintf(node.mnemonic, kMnemonicBufferSize, "move%c", suffix); + snprintf(node.arguments, kArgsBufferSize, "%s,%%%s", src_str, reg); + node.size = kInstructionSizeStepBytes + src.Size(); +} + static void chunk_mf000_v4000( DisasmNode& node, uint16_t instr, const DataBuffer &code, const Settings &s) { - if (instr == 0x4e70) { + if ((instr & 0xffc0) == 0x40c0) { + return disasm_move_from_sr(node, instr, code, s); + } else if ((instr & 0xffc0) == 0x44c0) { + return disasm_move_to(node, instr, code, s, "ccr"); + } else if ((instr & 0xffc0) == 0x46c0) { + return disasm_move_to(node, instr, code, s, "sr"); + } else if (instr == 0x4e70) { node.size = kInstructionSizeStepBytes; snprintf(node.mnemonic, kMnemonicBufferSize, "reset"); return; @@ -18,7 +18,7 @@ CRST="\033[39m" rm -rf ${TEST_DIR} mkdir -p ${TEST_DIR} -run_test_simple() { +run_test_expect_short() { local test_name=$1 local test_name_sanitized=${test_name//[^a-zA-Z0-9_\-]/-} local data=$2 @@ -27,29 +27,29 @@ run_test_simple() { local file_as_o=${TEST_DIR}/${test_name_sanitized}.as.o local file_as_elf=${TEST_DIR}/${test_name_sanitized}.as.elf local file_as_bin=${TEST_DIR}/${test_name_sanitized}.as.bin - echo -ne "Test \"${test_name}\"... " + echo -ne "Test expect .short \"${test_name}\"... " echo -ne "${data}" >${file_orig_bin} ${DISASM} -o ${file_asm} ${file_orig_bin} ${AS} -m68000 -o ${file_as_o} ${file_asm} ${LD} -o ${file_as_elf} ${file_as_o} ${OBJCOPY} ${file_as_elf} -O binary ${file_as_bin} - if ! cmp ${file_orig_bin} ${file_as_bin} >/dev/null 2>&1; then + if ! grep ".short" ${file_asm} >/dev/null 2>&1; then + echo -e "${CRED}FAIL${CRST}: NOT .short emitted, but .short EXPECTED" + cat ${file_asm} + elif ! cmp ${file_orig_bin} ${file_as_bin} >/dev/null 2>&1; then echo -e "${CRED}FAIL${CRST}: output and input binaries do not match" cat ${file_asm} echo ${file_orig_bin} hexdump -Cv ${file_orig_bin} | head -n1 echo ${file_as_bin} hexdump -Cv ${file_as_bin} | head -n1 - elif grep ".short" ${file_asm} >/dev/null 2>&1; then - echo -e "${CRED}FAIL${CRST}: .short emitted" - cat ${file_asm} else echo -e "${CGREEN}OK${CRST}" #cat ${file_asm} fi } -run_test_expect_short() { +run_test_simple() { local test_name=$1 local test_name_sanitized=${test_name//[^a-zA-Z0-9_\-]/-} local data=$2 @@ -58,22 +58,22 @@ run_test_expect_short() { local file_as_o=${TEST_DIR}/${test_name_sanitized}.as.o local file_as_elf=${TEST_DIR}/${test_name_sanitized}.as.elf local file_as_bin=${TEST_DIR}/${test_name_sanitized}.as.bin - echo -ne "Test expect .short \"${test_name}\"... " + echo -ne "Test \"${test_name}\"... " echo -ne "${data}" >${file_orig_bin} ${DISASM} -o ${file_asm} ${file_orig_bin} ${AS} -m68000 -o ${file_as_o} ${file_asm} ${LD} -o ${file_as_elf} ${file_as_o} ${OBJCOPY} ${file_as_elf} -O binary ${file_as_bin} - if ! grep ".short" ${file_asm} >/dev/null 2>&1; then - echo -e "${CRED}FAIL${CRST}: NOT .short emitted, but .short EXPECTED" - cat ${file_asm} - elif ! cmp ${file_orig_bin} ${file_as_bin} >/dev/null 2>&1; then + if ! cmp ${file_orig_bin} ${file_as_bin} >/dev/null 2>&1; then echo -e "${CRED}FAIL${CRST}: output and input binaries do not match" cat ${file_asm} echo ${file_orig_bin} hexdump -Cv ${file_orig_bin} | head -n1 echo ${file_as_bin} hexdump -Cv ${file_as_bin} | head -n1 + elif grep ".short" ${file_asm} >/dev/null 2>&1; then + echo -e "${CRED}FAIL${CRST}: .short emitted" + cat ${file_asm} else echo -e "${CGREEN}OK${CRST}" #cat ${file_asm} @@ -93,6 +93,12 @@ run_test_iterative() { done } +# 40c0..40ff +# +run_test_simple "move from SR" "\x40\xc1" +run_test_simple "move to CCR" "\x44\xc2" +run_test_simple "move to SR" "\x46\xc3" + # 70xx / 72xx/ 74xx / 76xx / 78xx / 7axx / 7cxx / 7exx # run_test_simple "moveq #0 to D0" "\x70\x00" @@ -177,7 +183,6 @@ run_test_simple "moveml (xxx).L to all registers" "\x4c\xf9\xff\xff\x00\x00\x7f\ # run_test_expect_short "movem truncated" "\x48\x92" - # 5x38 / 5x78 / 5xb8 (xxx).W # run_test_simple "addqb #8,offset:w" "\x50\x38\x00\x73" |