#pragma once
#define USE_STL 0
#if USE_STL
#include <vector>
template <typename T>
using vector = std::vector<T>;
#else
#include "min_stl.hpp"
template <typename T>
using vector = min::vector<T>;
#endif
// < 64 op code
// 32 reg
// 6 + 5 + 5 -> 16 bits
// 8-bit codes? VLC - variable length codes, or fixed?
// 8-bit -> 16 ops, 4 regs
// some ops that don't take regs could be shared
// - 12 ops with 2 2-bit reg#
// - 7 ops with 1 2-bit reg#
// - 36 ops with no regs
// Add,Sub,Shl,Shr,Mul,Div,Mod,Or,Xor,And,MovRR,Cmp - 12 with a pair of regs
// Not,Ioctl,Jmp,Je,Jne,Push,Pop - 7 with a single reg (jumps are very short)
// Nop,Ret - 2 with no reg
// Others not able to be coded in 8-bits:
// Call,LongJmp
// MovIR,MovMR,MovCR,MovI0,MovM0,MovC0,MovIM,MovRM,Mov0M,MovMM,MovCM
//
enum OpCode
{
Nop,
Add,
// Adc,
Sub,
// Sbb,
// Inc
// Dec,
Shl,
Shr,
// Sal,
// Sar,
Mul,
Div,
Mod,
Not,
Or,
Xor,
And,
MovIR, // imm20 -> reg
MovRR, // reg -> reg
// 0R, // reg0 -> reg
MovMR, // mem[r] -> reg
MovCR, // const[r] -> reg
MovI0, // imm25 -> reg0
// R0, // reg -> reg0
// 00, // reg0 -> reg0
MovM0, // mem[addr] -> reg0
MovC0, // const[addr] -> reg0
MovIM, // imm20 -> mem[r]
MovRM, // reg -> mem[r]
Mov0M, // reg0 -> mem[addr]
MovMM, // mem[r] -> mem[r]
MovCM, // const[r] -> mem[r]
Cmp,
// fAdd,
// fSub,
// fMul,
// fDiv,
// fMod,
// fCmp,
// fLoad,
// fStore,
Ioctl,
Call,
Jmp,
Je,
Jne,
// Jc,
// Jb,
// Jo,
Push,
Pop,
// PushF,
// PopF,
// PushA,
// PopA,
Ret,
// In,
// Out,
// Nop,
// Reset,
// Cpuid
}; // 33
// over 32
enum SystemCalls
{
Syscall_exit,
Syscall_putc,
};
struct ProgramHeader
{
uint32_t m_headerSize;
uint32_t m_textOffset;
uint32_t m_textSize;
uint32_t m_textSize_x86;
uint32_t m_rodataOffset;
uint32_t m_rodataSize;
};
struct Program
{
ProgramHeader m_header;
vector<uint32_t> m_text;
vector<uint8_t> m_text_x86;
vector<uint32_t> m_rodata;
};