fix assembler

This commit is contained in:
sfja 2026-01-24 12:57:25 +01:00
parent 19f68cc6ac
commit 2ad1dfce92
4 changed files with 81 additions and 29 deletions

View File

@ -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:

View File

@ -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;
};

View File

@ -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);

View File

@ -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);