164 lines
3.6 KiB
C++
164 lines
3.6 KiB
C++
#pragma once
|
|
|
|
#include <cstdint>
|
|
#include "elna/source/optimizer.hpp"
|
|
|
|
namespace elna::riscv
|
|
{
|
|
enum class address_t
|
|
{
|
|
text,
|
|
high20,
|
|
lower12i
|
|
};
|
|
|
|
struct reference
|
|
{
|
|
std::string name;
|
|
std::size_t offset;
|
|
address_t target;
|
|
};
|
|
|
|
enum class x_register : std::uint8_t
|
|
{
|
|
zero = 0,
|
|
ra = 1,
|
|
sp = 2,
|
|
gp = 3,
|
|
tp = 4,
|
|
t0 = 5,
|
|
t1 = 6,
|
|
t2 = 7,
|
|
s0 = 8,
|
|
s1 = 9,
|
|
a0 = 10,
|
|
a1 = 11,
|
|
a2 = 12,
|
|
a3 = 13,
|
|
a4 = 14,
|
|
a5 = 15,
|
|
a6 = 16,
|
|
a7 = 17,
|
|
s2 = 18,
|
|
s3 = 19,
|
|
s4 = 20,
|
|
s5 = 21,
|
|
s6 = 22,
|
|
s7 = 23,
|
|
s8 = 24,
|
|
s9 = 25,
|
|
s10 = 26,
|
|
s11 = 27,
|
|
t3 = 28,
|
|
t4 = 29,
|
|
t5 = 30,
|
|
t6 = 31,
|
|
};
|
|
|
|
enum class funct3_t : std::uint8_t
|
|
{
|
|
addi = 0b000,
|
|
slti = 0b001,
|
|
sltiu = 0b011,
|
|
andi = 0b111,
|
|
ori = 0b110,
|
|
xori = 0b100,
|
|
slli = 0b000,
|
|
srli = 0b101,
|
|
srai = 0b101,
|
|
add = 0b000,
|
|
slt = 0b010,
|
|
sltu = 0b011,
|
|
_and = 0b111,
|
|
_or = 0b110,
|
|
_xor = 0b100,
|
|
sll = 0b001,
|
|
srl = 0b101,
|
|
sub = 0b000,
|
|
sra = 0b101,
|
|
beq = 0b000,
|
|
bne = 0b001,
|
|
blt = 0b100,
|
|
bltu = 0b110,
|
|
bge = 0b101,
|
|
bgeu = 0b111,
|
|
fence = 0b000,
|
|
fenceI = 0b001,
|
|
csrrw = 0b001,
|
|
csrrs = 0b010,
|
|
csrrc = 0b011,
|
|
csrrwi = 0b101,
|
|
csrrsi = 0b110,
|
|
csrrci = 0b111,
|
|
priv = 0b000,
|
|
sb = 0b000,
|
|
sh = 0b001,
|
|
sw = 0b010,
|
|
lb = 0b000,
|
|
lh = 0b001,
|
|
lw = 0b010,
|
|
lbu = 0b100,
|
|
lhu = 0b101,
|
|
jalr = 0b000,
|
|
mul = 0b000,
|
|
mulh = 0b001,
|
|
mulhsu = 0b010,
|
|
mulhu = 0b011,
|
|
div = 0b100,
|
|
divu = 0b101,
|
|
rem = 0b110,
|
|
remu = 0b111
|
|
};
|
|
|
|
enum class funct12_t : std::uint8_t
|
|
{
|
|
ecall = 0b000000000000,
|
|
ebreak = 0b000000000001,
|
|
};
|
|
|
|
enum class funct7_t : std::uint8_t
|
|
{
|
|
none = 0,
|
|
sub = 0b0100000,
|
|
muldiv = 0b0000001
|
|
};
|
|
|
|
enum class base_opcode : std::uint8_t
|
|
{
|
|
opImm = 0b0010011,
|
|
lui = 0b0110111,
|
|
auipc = 0b0010111,
|
|
op = 0b0110011,
|
|
jal = 0b1101111,
|
|
jalr = 0b1100111,
|
|
branch = 0b1100011,
|
|
load = 0b0000011,
|
|
store = 0b0100011,
|
|
miscMem = 0b0001111,
|
|
system = 0b1110011,
|
|
};
|
|
|
|
struct instruction
|
|
{
|
|
instruction() = default; // NOP = addi x0, x0, 0.
|
|
instruction(base_opcode opcode);
|
|
|
|
instruction& i(x_register rd, funct3_t funct3, x_register rs1, std::uint32_t immediate);
|
|
instruction& s(std::uint32_t imm, funct3_t funct3, x_register rs1, x_register rs2);
|
|
instruction& b(std::uint32_t imm, funct3_t funct3, x_register rs1, x_register rs2);
|
|
instruction& r(x_register rd, funct3_t funct3, x_register rs1, x_register rs2,
|
|
funct7_t funct7 = funct7_t::none);
|
|
instruction& u(x_register rd, std::uint32_t imm);
|
|
instruction& j(x_register rd, std::uint32_t imm);
|
|
|
|
const std::byte *cbegin() const;
|
|
const std::byte *cend() const;
|
|
|
|
private:
|
|
std::uint32_t representation{ 0 };
|
|
};
|
|
|
|
std::vector<reference> generate(source::intermediate_code_generator generator,
|
|
std::shared_ptr<source::symbol_table> table, std::shared_ptr<source::writer<std::byte>> writer);
|
|
}
|