fix assembler
This commit is contained in:
parent
19f68cc6ac
commit
2ad1dfce92
@ -158,6 +158,7 @@ auto Assembler::assemble_file()
|
||||
if (line->labels) {
|
||||
define_labels(*line->labels);
|
||||
}
|
||||
assemble_line(*line);
|
||||
|
||||
lines.push_back(std::move(line));
|
||||
}
|
||||
@ -181,7 +182,7 @@ void Assembler::define_labels(const std::vector<Label>& labels)
|
||||
{
|
||||
for (const auto& label : labels) {
|
||||
if (label.is_local) {
|
||||
m_sublabels[label_ident(label)] = m_builder.ip();
|
||||
m_syms[label_ident(label)] = m_builder.ip();
|
||||
} else {
|
||||
m_superlabel = label.ident;
|
||||
m_syms[std::string(label.ident)] = m_builder.ip();
|
||||
@ -325,7 +326,7 @@ void Assembler::assemble_line(const Line& line)
|
||||
auto op1 = eval_operand(*line.args[0]);
|
||||
auto op2 = eval_operand(*line.args[1]);
|
||||
|
||||
if (not op1 or op2)
|
||||
if (not op1 or not op2)
|
||||
return;
|
||||
|
||||
if (not op1->is_reg())
|
||||
@ -345,7 +346,7 @@ void Assembler::assemble_line(const Line& line)
|
||||
auto dst = eval_operand(*line.args[0]);
|
||||
auto src = eval_operand(*line.args[1]);
|
||||
|
||||
if (not dst or src)
|
||||
if (not dst or not src)
|
||||
return;
|
||||
|
||||
auto dst_ty = dst->ty;
|
||||
@ -641,7 +642,7 @@ auto Assembler::eval_operand_mem(const Expr& expr)
|
||||
}
|
||||
case Expr::Ty::Reg:
|
||||
return std::make_unique<EO>(
|
||||
expr.loc, EOT::MemWordReg, expr.as_reg());
|
||||
expr.loc, EOT::MemWordReg, EO::RegImmPair { expr.as_reg(), 0 });
|
||||
case Expr::Ty::Str:
|
||||
case Expr::Ty::Mem:
|
||||
case Expr::Ty::MemByte:
|
||||
@ -716,14 +717,12 @@ auto Assembler::eval_operand_to_imm(const Expr& expr)
|
||||
case Expr::Ty::Ident: {
|
||||
auto ident = std::string(expr.as_ident());
|
||||
if (!m_syms.contains(ident)) {
|
||||
if (m_second_pass) {
|
||||
error(expr.loc,
|
||||
std::format(
|
||||
"symbol \"{}\" not defined", expr.as_ident()));
|
||||
return nullptr;
|
||||
} else {
|
||||
if (not m_second_pass)
|
||||
return std::make_unique<EO>(loc, EOT::Imm, uint16_t { 0 });
|
||||
}
|
||||
|
||||
error(expr.loc,
|
||||
std::format("symbol \"{}\" not defined", expr.as_ident()));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto value = m_syms[ident];
|
||||
@ -731,18 +730,16 @@ auto Assembler::eval_operand_to_imm(const Expr& expr)
|
||||
}
|
||||
case Expr::Ty::SubLabel: {
|
||||
auto ident = sublabel_ident(expr.as_ident());
|
||||
if (!m_sublabels.contains(ident)) {
|
||||
if (m_second_pass) {
|
||||
error(expr.loc,
|
||||
std::format(
|
||||
"symbol \"{}\" not defined", expr.as_ident()));
|
||||
return nullptr;
|
||||
} else {
|
||||
if (!m_syms.contains(ident)) {
|
||||
if (not m_second_pass)
|
||||
return std::make_unique<EO>(loc, EOT::Imm, uint16_t { 0 });
|
||||
}
|
||||
|
||||
error(expr.loc,
|
||||
std::format("symbol \"{}\" not defined", expr.as_ident()));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto value = m_sublabels[ident];
|
||||
auto value = m_syms[ident];
|
||||
return std::make_unique<EO>(loc, EOT::Imm, value);
|
||||
}
|
||||
case Expr::Ty::Reg:
|
||||
|
||||
@ -242,7 +242,6 @@ namespace asmer {
|
||||
Builder m_builder;
|
||||
std::unordered_map<std::string, uint16_t> m_syms {};
|
||||
std::string m_superlabel {};
|
||||
std::unordered_map<std::string, uint16_t> m_sublabels {};
|
||||
bool m_second_pass = false;
|
||||
bool m_failed = false;
|
||||
};
|
||||
|
||||
@ -68,20 +68,30 @@ private:
|
||||
|
||||
}
|
||||
|
||||
#define LOG_F \
|
||||
{ \
|
||||
std::println("assembling {} at {}", __func__, this->m_ip); \
|
||||
}
|
||||
|
||||
#define LOG
|
||||
|
||||
void Builder::nop()
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::Nop);
|
||||
i.build(*this);
|
||||
}
|
||||
|
||||
void Builder::hlt()
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::Hlt);
|
||||
i.build(*this);
|
||||
}
|
||||
|
||||
void Builder::jmp_reg(Reg op1)
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::Jmp);
|
||||
i.op1_reg(op1);
|
||||
i.build(*this);
|
||||
@ -89,6 +99,7 @@ void Builder::jmp_reg(Reg op1)
|
||||
|
||||
void Builder::jmp_imm(uint16_t op1)
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::Jmp);
|
||||
i.imm(op1);
|
||||
i.build(*this);
|
||||
@ -96,6 +107,7 @@ void Builder::jmp_imm(uint16_t op1)
|
||||
|
||||
void Builder::jnz_reg(Reg op1, Reg op2)
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::Jnz);
|
||||
i.op1_reg(op1);
|
||||
i.op2_reg(op2);
|
||||
@ -104,6 +116,7 @@ void Builder::jnz_reg(Reg op1, Reg op2)
|
||||
|
||||
void Builder::jnz_imm(Reg op1, uint16_t op2)
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::Jnz);
|
||||
i.op1_reg(op1);
|
||||
i.imm(op2);
|
||||
@ -112,6 +125,7 @@ void Builder::jnz_imm(Reg op1, uint16_t op2)
|
||||
|
||||
void Builder::mov_reg(Reg dst, Reg src)
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::Mov);
|
||||
i.reg(dst, 12, 0b1111);
|
||||
i.reg(src, 7, 0b1111);
|
||||
@ -120,6 +134,7 @@ void Builder::mov_reg(Reg dst, Reg src)
|
||||
|
||||
void Builder::mov_imm(Reg dst, uint16_t imm)
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::Mov);
|
||||
i.reg(dst, 12, 0b1111);
|
||||
i.imm(imm);
|
||||
@ -128,6 +143,7 @@ void Builder::mov_imm(Reg dst, uint16_t imm)
|
||||
|
||||
void Builder::load_word_reg(Reg dst, Reg addr, uint16_t offset)
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::LoadWord);
|
||||
i.dst_reg(dst);
|
||||
i.op1_reg(addr);
|
||||
@ -137,6 +153,7 @@ void Builder::load_word_reg(Reg dst, Reg addr, uint16_t offset)
|
||||
|
||||
void Builder::load_word_imm(Reg dst, uint16_t addr)
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::LoadWord);
|
||||
i.dst_reg(dst);
|
||||
i.imm(addr);
|
||||
@ -145,6 +162,7 @@ void Builder::load_word_imm(Reg dst, uint16_t addr)
|
||||
|
||||
void Builder::store_word_reg(Reg dst, uint16_t offset, Reg op2)
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::StoreWord);
|
||||
i.dst_reg(dst);
|
||||
i.imm_without_flag(offset);
|
||||
@ -154,6 +172,7 @@ void Builder::store_word_reg(Reg dst, uint16_t offset, Reg op2)
|
||||
|
||||
void Builder::store_word_imm(uint16_t dst, Reg op2)
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::StoreWord);
|
||||
i.imm(dst);
|
||||
i.op2_reg(op2);
|
||||
@ -162,6 +181,7 @@ void Builder::store_word_imm(uint16_t dst, Reg op2)
|
||||
|
||||
void Builder::load_byte_reg(Reg dst, Reg addr, uint16_t offset)
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::LoadByte);
|
||||
i.dst_reg(dst);
|
||||
i.op1_reg(addr);
|
||||
@ -171,6 +191,7 @@ void Builder::load_byte_reg(Reg dst, Reg addr, uint16_t offset)
|
||||
|
||||
void Builder::load_byte_imm(Reg dst, uint16_t addr)
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::LoadByte);
|
||||
i.dst_reg(dst);
|
||||
i.imm(addr);
|
||||
@ -179,6 +200,7 @@ void Builder::load_byte_imm(Reg dst, uint16_t addr)
|
||||
|
||||
void Builder::store_byte_reg(Reg dst, uint16_t offset, Reg op2)
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::StoreByte);
|
||||
i.dst_reg(dst);
|
||||
i.imm_without_flag(offset);
|
||||
@ -188,6 +210,7 @@ void Builder::store_byte_reg(Reg dst, uint16_t offset, Reg op2)
|
||||
|
||||
void Builder::store_byte_imm(uint16_t dst, Reg op2)
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::StoreByte);
|
||||
i.imm(dst);
|
||||
i.op2_reg(op2);
|
||||
@ -196,6 +219,7 @@ void Builder::store_byte_imm(uint16_t dst, Reg op2)
|
||||
|
||||
void Builder::cmp_reg(Reg op1, Reg op2)
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::Cmp);
|
||||
i.op1_reg(op1);
|
||||
i.op2_reg(op2);
|
||||
@ -204,6 +228,7 @@ void Builder::cmp_reg(Reg op1, Reg op2)
|
||||
|
||||
void Builder::cmp_imm(Reg op1, uint16_t op2)
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::Cmp);
|
||||
i.op1_reg(op1);
|
||||
i.imm(op2);
|
||||
@ -212,101 +237,121 @@ void Builder::cmp_imm(Reg op1, uint16_t op2)
|
||||
|
||||
void Builder::or_reg(Reg dst, Reg op1, Reg op2)
|
||||
{
|
||||
LOG;
|
||||
binary_reg(dst, op1, op2, Op::Or);
|
||||
}
|
||||
|
||||
void Builder::and_reg(Reg dst, Reg op1, Reg op2)
|
||||
{
|
||||
LOG;
|
||||
binary_reg(dst, op1, op2, Op::And);
|
||||
}
|
||||
|
||||
void Builder::xor_reg(Reg dst, Reg op1, Reg op2)
|
||||
{
|
||||
LOG;
|
||||
binary_reg(dst, op1, op2, Op::Xor);
|
||||
}
|
||||
|
||||
void Builder::shl_reg(Reg dst, Reg op1, Reg op2)
|
||||
{
|
||||
LOG;
|
||||
binary_reg(dst, op1, op2, Op::Shl);
|
||||
}
|
||||
|
||||
void Builder::rshl_reg(Reg dst, Reg op1, Reg op2)
|
||||
{
|
||||
LOG;
|
||||
binary_reg(dst, op1, op2, Op::RShl);
|
||||
}
|
||||
|
||||
void Builder::shr_reg(Reg dst, Reg op1, Reg op2)
|
||||
{
|
||||
LOG;
|
||||
binary_reg(dst, op1, op2, Op::Shr);
|
||||
}
|
||||
|
||||
void Builder::rshr_reg(Reg dst, Reg op1, Reg op2)
|
||||
{
|
||||
LOG;
|
||||
binary_reg(dst, op1, op2, Op::RShr);
|
||||
}
|
||||
|
||||
void Builder::add_reg(Reg dst, Reg op1, Reg op2)
|
||||
{
|
||||
LOG;
|
||||
binary_reg(dst, op1, op2, Op::Add);
|
||||
}
|
||||
|
||||
void Builder::sub_reg(Reg dst, Reg op1, Reg op2)
|
||||
{
|
||||
LOG;
|
||||
binary_reg(dst, op1, op2, Op::Sub);
|
||||
}
|
||||
|
||||
void Builder::rsub_reg(Reg dst, Reg op1, Reg op2)
|
||||
{
|
||||
LOG;
|
||||
binary_reg(dst, op1, op2, Op::RSub);
|
||||
}
|
||||
|
||||
void Builder::or_imm(Reg dst, Reg op1, uint16_t op2)
|
||||
{
|
||||
LOG;
|
||||
binary_imm(dst, op1, op2, Op::Xor);
|
||||
}
|
||||
|
||||
void Builder::and_imm(Reg dst, Reg op1, uint16_t op2)
|
||||
{
|
||||
LOG;
|
||||
binary_imm(dst, op1, op2, Op::And);
|
||||
}
|
||||
|
||||
void Builder::xor_imm(Reg dst, Reg op1, uint16_t op2)
|
||||
{
|
||||
LOG;
|
||||
binary_imm(dst, op1, op2, Op::Xor);
|
||||
}
|
||||
|
||||
void Builder::shl_imm(Reg dst, Reg op1, uint16_t op2)
|
||||
{
|
||||
LOG;
|
||||
binary_imm(dst, op1, op2, Op::Shl);
|
||||
}
|
||||
|
||||
void Builder::rshl_imm(Reg dst, Reg op1, uint16_t op2)
|
||||
{
|
||||
LOG;
|
||||
binary_imm(dst, op1, op2, Op::RShl);
|
||||
}
|
||||
|
||||
void Builder::shr_imm(Reg dst, Reg op1, uint16_t op2)
|
||||
{
|
||||
LOG;
|
||||
binary_imm(dst, op1, op2, Op::Shr);
|
||||
}
|
||||
|
||||
void Builder::rshr_imm(Reg dst, Reg op1, uint16_t op2)
|
||||
{
|
||||
LOG;
|
||||
binary_imm(dst, op1, op2, Op::RShr);
|
||||
}
|
||||
|
||||
void Builder::add_imm(Reg dst, Reg op1, uint16_t op2)
|
||||
{
|
||||
LOG;
|
||||
binary_imm(dst, op1, op2, Op::Add);
|
||||
}
|
||||
|
||||
void Builder::sub_imm(Reg dst, Reg op1, uint16_t op2)
|
||||
{
|
||||
LOG;
|
||||
binary_imm(dst, op1, op2, Op::Sub);
|
||||
}
|
||||
|
||||
void Builder::rsub_imm(Reg dst, Reg op1, uint16_t op2)
|
||||
{
|
||||
LOG;
|
||||
binary_imm(dst, op1, op2, Op::RSub);
|
||||
}
|
||||
|
||||
@ -330,12 +375,14 @@ void Builder::binary_imm(Reg dst, Reg op1, uint16_t op2, Op op)
|
||||
|
||||
void Builder::reti()
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::RetI);
|
||||
i.build(*this);
|
||||
}
|
||||
|
||||
void Builder::lvcd_reg(Reg op1)
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::LVCD);
|
||||
i.op1_reg(op1);
|
||||
i.build(*this);
|
||||
@ -343,6 +390,7 @@ void Builder::lvcd_reg(Reg op1)
|
||||
|
||||
void Builder::lvcd_imm(uint16_t op1)
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::LVCD);
|
||||
i.imm(op1);
|
||||
i.build(*this);
|
||||
@ -350,6 +398,7 @@ void Builder::lvcd_imm(uint16_t op1)
|
||||
|
||||
void Builder::lkbd_reg(Reg op1)
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::LKBD);
|
||||
i.op1_reg(op1);
|
||||
i.build(*this);
|
||||
@ -357,6 +406,7 @@ void Builder::lkbd_reg(Reg op1)
|
||||
|
||||
void Builder::lkbd_imm(uint16_t op1)
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::LKBD);
|
||||
i.imm(op1);
|
||||
i.build(*this);
|
||||
@ -364,6 +414,7 @@ void Builder::lkbd_imm(uint16_t op1)
|
||||
|
||||
void Builder::dskr(Reg dst, Reg op1)
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::DSKR);
|
||||
i.dst_reg(dst);
|
||||
i.op1_reg(op1);
|
||||
@ -372,6 +423,7 @@ void Builder::dskr(Reg dst, Reg op1)
|
||||
|
||||
void Builder::dskw(Reg dst, Reg op1)
|
||||
{
|
||||
LOG;
|
||||
auto i = InsBuilder(Op::DSKW);
|
||||
i.dst_reg(dst);
|
||||
i.op1_reg(op1);
|
||||
|
||||
20
src/main.cpp
20
src/main.cpp
@ -24,6 +24,15 @@ int main(int argc, char** argv)
|
||||
|
||||
make_program(disk.data());
|
||||
|
||||
std::println("memory disk");
|
||||
for (size_t i = 0; i < 64; i += 4) {
|
||||
std::println("{:02x} {:02x} {:02x} {:02x}",
|
||||
disk.data()[i],
|
||||
disk.data()[i + 1],
|
||||
disk.data()[i + 2],
|
||||
disk.data()[i + 3]);
|
||||
}
|
||||
|
||||
auto vm = VM(*device, disk);
|
||||
vm.run();
|
||||
} else {
|
||||
@ -38,18 +47,13 @@ int main(int argc, char** argv)
|
||||
auto memory_block = std::vector<uint8_t>(BlockDevice::block_size);
|
||||
memory_disk.read(memory_block.data(), 0);
|
||||
|
||||
std::println("file memory");
|
||||
std::println("file disk");
|
||||
for (size_t i = 0; i < 64; i += 4) {
|
||||
std::println(
|
||||
"{:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x} {:02x}",
|
||||
std::println("{:02x} {:02x} {:02x} {:02x}",
|
||||
file_block[i],
|
||||
file_block[i + 1],
|
||||
file_block[i + 2],
|
||||
file_block[i + 3],
|
||||
memory_block[i],
|
||||
memory_block[i + 1],
|
||||
memory_block[i + 2],
|
||||
memory_block[i + 3]);
|
||||
file_block[i + 3]);
|
||||
}
|
||||
|
||||
auto vm = VM(*device, disk);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user