disassemble: initial disassembler

This commit is contained in:
Zack Buhman 2023-09-03 05:30:36 +00:00
parent ddf46ce8fd
commit 5cd19c51ce
7 changed files with 142 additions and 51 deletions

2
.gitignore vendored
View File

@ -1,6 +1,8 @@
main main
scu-dsp-asm scu-dsp-asm
scu-dsp-asm.* scu-dsp-asm.*
scu-dsp-dis
scu-dsp-dis.*
.~* .~*
*.o *.o
*.gch *.gch

View File

@ -3,28 +3,37 @@ CXXFLAGS = -Og -g -Wall -Wextra -Werror -Wfatal-errors -Wno-c99-designator -std=
LDFLAGS = LDFLAGS =
TARGET ?= TARGET ?=
CXX = $(TARGET)clang++ CXX = $(TARGET)g++
SRC = main.cpp ASM_SRC = main.cpp
SRC += lexer.cpp ASM_SRC += lexer.cpp
SRC += ast_printer.cpp ASM_SRC += ast_printer.cpp
SRC += ast_resolver.cpp ASM_SRC += ast_resolver.cpp
SRC += ast_emitter.cpp ASM_SRC += ast_emitter.cpp
SRC += parser.cpp ASM_SRC += parser.cpp
SRC += stmt_string.cpp ASM_SRC += stmt_string.cpp
OBJ = $(patsubst %.cpp,%.o,$(SRC)) ASM_OBJ = $(patsubst %.cpp,%.o,$(ASM_SRC))
DEP = $(patsubst %.cpp,%.d,$(SRC)) ASM_DEP = $(patsubst %.cpp,%.d,$(ASM_SRC))
ASM_MAIN ?= scu-dsp-asm
MAIN ?= scu-dsp-asm DIS_SRC = disassemble.cpp
DIS_SRC += ast_printer.cpp
DIS_SRC += stmt_string.cpp
DIS_OBJ = $(patsubst %.cpp,%.o,$(DIS_SRC))
DIS_DEP = $(patsubst %.cpp,%.d,$(DIS_SRC))
DIS_MAIN ?= scu-dsp-dis
all: $(MAIN) all: $(ASM_MAIN) $(DIS_MAIN)
-include $(DEP) -include $(sort $(ASM_DEP) $(DIS_DEP))
%.o: %.cpp %.o: %.cpp
$(CXX) $(CXXFLAGS) -MMD -MF $(basename $<).d -c $< -o $@ $(CXX) $(CXXFLAGS) -MMD -MF $(basename $<).d -c $< -o $@
$(MAIN): $(OBJ) $(SRC_MAIN): $(SRC_OBJ)
$(CXX) $(STATIC) $(LDFLAGS) $^ -o $@
$(DIS_MAIN): $(DIS_OBJ)
$(CXX) $(STATIC) $(LDFLAGS) $^ -o $@ $(CXX) $(STATIC) $(LDFLAGS) $^ -o $@
clean: clean:

View File

@ -7,6 +7,7 @@
#include "stmt_base.hpp" #include "stmt_base.hpp"
#include "stmt_ins.hpp" #include "stmt_ins.hpp"
#include "ins.hpp"
namespace dsp { namespace dsp {
@ -32,7 +33,7 @@ using op_t = std::variant<andl_t,
mov_imm_d1_t, mov_imm_d1_t,
mov_ram_d1_t>; mov_ram_d1_t>;
struct control_word_t : stmt_accept_t<control_word_t> struct control_word_t : stmt_accept_t<control_word_t>, ins_t<control_word_t>
{ {
control_word_t(std::vector<op_t> ops) control_word_t(std::vector<op_t> ops)
: ops(ops) : ops(ops)
@ -42,30 +43,27 @@ struct control_word_t : stmt_accept_t<control_word_t>
std::vector<op_t> build_ops(uint32_t code) std::vector<op_t> build_ops(uint32_t code)
{ {
std::vector<op_t> ops; std::vector<op_t> ops;
if (andl_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<andl_t>, code}); if (andl_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<andl_t>, code});
else if (orl_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<orl_t>, code}); if (orl_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<orl_t>, code});
else if (xorl_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<xorl_t>, code}); if (xorl_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<xorl_t>, code});
else if (add_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<add_t>, code}); if (add_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<add_t>, code});
else if (sub_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<sub_t>, code}); if (sub_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<sub_t>, code});
else if (ad2_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<ad2_t>, code}); if (ad2_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<ad2_t>, code});
else if (sr_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<sr_t>, code}); if (sr_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<sr_t>, code});
else if (rr_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<rr_t>, code}); if (rr_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<rr_t>, code});
else if (sl_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<sl_t>, code}); if (sl_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<sl_t>, code});
else if (rl_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<rl_t>, code}); if (rl_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<rl_t>, code});
else if (rl8_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<rl8_t>, code}); if (rl8_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<rl8_t>, code});
else if (mov_ram_x_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_ram_x_t>, code}); if (mov_ram_x_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_ram_x_t>, code});
else if (mov_mul_p_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_mul_p_t>, code}); if (mov_mul_p_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_mul_p_t>, code});
else if (mov_ram_p_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_ram_p_t>, code}); if (mov_ram_p_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_ram_p_t>, code});
else if (mov_ram_y_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_ram_y_t>, code}); if (mov_ram_y_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_ram_y_t>, code});
else if (clr_a_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<clr_a_t>, code}); if (clr_a_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<clr_a_t>, code});
else if (mov_alu_a_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_alu_a_t>, code}); if (mov_alu_a_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_alu_a_t>, code});
else if (mov_ram_a_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_ram_a_t>, code}); if (mov_ram_a_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_ram_a_t>, code});
else if (mov_imm_d1_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_imm_d1_t>, code}); if (mov_imm_d1_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_imm_d1_t>, code});
else if (mov_ram_d1_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_ram_d1_t>, code}); if (mov_ram_d1_t::pred(code)) ops.emplace_back(op_t{std::in_place_type<mov_ram_d1_t>, code});
else {
std::cerr << "invalid control word code: " << (code) << std::endl;
throw std::runtime_error("invalid control word code");
}
return ops; return ops;
} }
@ -74,9 +72,9 @@ struct control_word_t : stmt_accept_t<control_word_t>
const std::vector<op_t> ops; const std::vector<op_t> ops;
uint32_t mask() const { return 0b11 << 30; } static constexpr uint32_t mask() { return 0b11 << 30; }
uint32_t code() const { return 0b00 << 30; } static constexpr uint32_t code() { return 0b00 << 30; }
uint32_t bits() const { return 0; } static constexpr uint32_t bits() { return 0; }
}; };
} }

89
disassemble.cpp Normal file
View File

@ -0,0 +1,89 @@
#include <cstdint>
#include <string_view>
#include <fstream>
#include "stmt.hpp"
#include "stmt_ins.hpp"
#include "control_word.hpp"
#include "ast_printer.hpp"
static uint32_t uint32_be(std::string_view v)
{
return static_cast<uint8_t>(v[0]) << 24
| static_cast<uint8_t>(v[1]) << 16
| static_cast<uint8_t>(v[2]) << 8
| static_cast<uint8_t>(v[3]) << 0;
}
static dsp::stmt_t * decompile(uint32_t code)
{
using namespace dsp::op;
using namespace dsp::load;
using namespace dsp::dma;
using namespace dsp::jump;
using namespace dsp::loop;
using namespace dsp::end;
using namespace dsp::nop;
if (control_word_t::pred(code)) return new control_word_t(code);
else if (mvi_t::pred(code)) return new mvi_t(code);
else if (mvi_cond_t::pred(code)) return new mvi_cond_t(code);
else if (d0_dst_imm_t::pred(code)) return new d0_dst_imm_t(code);
else if (src_d0_imm_t::pred(code)) return new src_d0_imm_t(code);
else if (d0_dst_ram_t::pred(code)) return new d0_dst_ram_t(code);
else if (src_d0_ram_t::pred(code)) return new src_d0_ram_t(code);
else if (jmp_t::pred(code)) return new jmp_t(code);
else if (jmp_cond_t::pred(code)) return new jmp_cond_t(code);
else if (btm_t::pred(code)) return new btm_t(code);
else if (lps_t::pred(code)) return new lps_t(code);
else if (end_t::pred(code)) return new end_t(code);
else if (endi_t::pred(code)) return new endi_t(code);
else
throw std::runtime_error("undefined code");
}
static void run(std::string source)
{
std::string_view buf(source);
dsp::ast::printer_t printer(std::cout);
for (decltype(buf)::size_type i = 0; i < (buf.length() / 4); i++) {
uint32_t code = uint32_be(buf.substr(i * 4, 4));
dsp::stmt_t * stmt = decompile(code);
stmt->accept(&printer);
std::cout << std::endl;
}
}
static int run_file(char const * const input_filename)
{
std::ifstream is {input_filename, std::ios::binary | std::ios::ate};
if (!is.is_open()) {
std::cerr << "failed to open " << input_filename << std::endl;
return -1;
}
const std::streampos size = is.tellg();
std::string buf(size, '\0');
is.seekg(0);
if (!is.read(&buf[0], size)) {
std::cerr << "read failed" << std::endl;
return -1;
}
run(buf);
return 0;
}
int main(const int argc, char const * const argv[])
{
const std::string c_source("-s");
switch (argc) {
case 2: return run_file(argv[1]);
default:
std::cerr << "Usage: " << argv[0] << " input-filename" << std::endl;
return -1;
}
}

View File

@ -9,14 +9,10 @@ namespace dsp {
template <typename T> template <typename T>
struct ins_t struct ins_t
{ {
/*
virtual uint32_t bits() const;
uint32_t render() const uint32_t render() const
{ {
return T::code() | bits(); return T::code() | T::bits();
} }
*/
static bool pred(uint32_t ins) static bool pred(uint32_t ins)
{ {

View File

@ -1,8 +1,6 @@
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <string> #include <string>
#include <optional>
#include <bitset>
#include <sstream> #include <sstream>
#include <array> #include <array>
#include <iomanip> #include <iomanip>
@ -72,7 +70,6 @@ static void run(std::ostream& os, std::string source, bool hex_output, bool verb
while (auto stmt_o = pass2.statement()) { while (auto stmt_o = pass2.statement()) {
uint32_t output = (*stmt_o)->accept(&emitter); uint32_t output = (*stmt_o)->accept(&emitter);
if (output != 0xffff'ffff) { if (output != 0xffff'ffff) {
//std::cout << std::bitset<32>(output) << std::endl;
if (hex_output) write_hex(os, output); if (hex_output) write_hex(os, output);
else write_raw(os, output); else write_raw(os, output);
} }

View File

@ -37,7 +37,7 @@ struct mov_ram_d1_t;
struct control_word_t; struct control_word_t;
} }
namespace load{ namespace load {
struct mvi_t; struct mvi_t;
struct mvi_cond_t; struct mvi_cond_t;
} }