vc5/src/builder.hpp
2026-01-29 23:19:00 +01:00

113 lines
3.0 KiB
C++

#pragma once
#include "vm.hpp"
#include <cstdint>
#include <print>
#define BINARY_INSTRUCTIONS \
X(or, Or) \
X(and, And) \
X(xor, Xor) \
X(shl, Shl) \
X(rshl, RShl) \
X(shr, Shr) \
X(rshr, RShr) \
X(add, Add) \
X(sub, Sub) \
X(rsub, RSub) \
X(mul, Mul) \
X(imul, IMul)
namespace vc5::tools {
using namespace vc5;
class Builder {
public:
Builder(uint8_t* data)
: m_data(data)
{
}
void nop();
void hlt();
void jmp_reg(Reg op1);
void jmp_imm(uint16_t op1);
void jnz_reg(Reg op1, Reg op2);
void jnz_imm(Reg op1, uint16_t op2);
void mov_reg(Reg dst, Reg src);
void mov_imm(Reg dst, uint16_t imm);
void ldw_reg(Reg dst, Reg addr, uint16_t offset);
void ldw_imm(Reg dst, uint16_t addr);
void stw_reg(Reg dst, uint16_t offset, Reg op2);
void stw_imm(uint16_t dst, Reg op2);
void ldb_reg(Reg dst, Reg addr, uint16_t offset);
void ldb_imm(Reg dst, uint16_t addr);
void stb_reg(Reg dst, uint16_t offset, Reg op2);
void stb_imm(uint16_t dst, Reg op2);
void cmp_reg(Reg op1, Reg op2);
void cmp_imm(Reg op1, uint16_t op2);
#define X(NAME, OP) \
void NAME##_reg(Reg dst, Reg op1, Reg op2); \
void NAME##_imm(Reg dst, Reg op1, uint16_t op2);
BINARY_INSTRUCTIONS
#undef X
void call_reg(Reg op1);
void call_imm(uint16_t op1);
void ret();
void reti();
void lvcd_reg(Reg op1);
void lvcd_imm(uint16_t op1);
void lkbd_reg(Reg op1);
void lkbd_imm(uint16_t op1);
void dskr(Reg dst, Reg op1);
void dskw(Reg dst, Reg op1);
uint16_t ip() const
{
return m_ip & 0xffff;
}
void set_ip(uint16_t ip)
{
m_ip = ip;
}
void push(uint16_t v)
{
m_data[m_ip] = v >> 8;
m_data[m_ip + 1] = v & 0xff;
m_ip += 2;
}
void push_byte(uint8_t v)
{
m_data[m_ip] = v;
m_ip += 1;
}
void align_word()
{
if (m_ip & 1) {
m_ip += 1;
}
}
private:
void binary_reg(Reg dst, Reg op1, Reg op2, Op op);
void binary_imm(Reg dst, Reg op1, uint16_t op2, Op op);
uint8_t* m_data;
size_t m_ip = 0;
};
}
#ifndef DEFINE_BINARY_INSTRUCTIONS
#undef BINARY_INSTRUCTIONS
#endif