113 lines
3.0 KiB
C++
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
|