Skip to content

Instantly share code, notes, and snippets.

@xorgy
Created February 26, 2018 13:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xorgy/6c3aff4dda169728c9711d5ce4a1b130 to your computer and use it in GitHub Desktop.
Save xorgy/6c3aff4dda169728c9711d5ce4a1b130 to your computer and use it in GitHub Desktop.
// R-type ops
static const uint32_t OpRMask = 0b11111110000000000111000001111111;
enum OpR : uint32_t {
// RV32I
OR = 0b110000000110011,
ADD = 0b000000000110011,
};
// I-type ops
static const uint32_t OpIMask = 0b111000001111111;
static const uint32_t IImmMask = 0xFFF00000;
enum OpI : uint32_t {
// RV32I
ADDI = 0b000000000010011,
JALR = 0b000000001100111,
ORI = 0b110000000010011,
// RV64I
LD = 0b011000000000011,
};
// Special I-type ops for shift instructions with
// seven function bits at the top of the immediate.
enum OpIS : uint32_t {
SLLI = 0b00000000000000000001000000010011,
SRLI = 0b00000000000000000101000000010011,
SRAI = 0b01000000000000000101000000010011,
};
// U-type ops
static const uint32_t OpUMask = 0b1111111;
static const uint32_t UImmMask = 0xFFFFF000;
enum OpU : uint32_t {
// RV32I
AUIPC = 0b0010111,
LUI = 0b0110111,
};
// S-type ops
static const uint32_t OpSMask = 0b111000001111111;
static const uint32_t SUpperImmMask = 0b1111111 << 25;
static const uint32_t SLowerImmMask = 0b11111 << 7;
enum OpS : uint32_t {
// RV64I
SD = 0b011000000100011,
};
enum OpC : uint16_t {
C_NOP = 0b1,
};
static uint32_t assemble(OpI op, Register rd, Register rs,
int32_t imm) {
return op | rd.code() << 7 | rs.code() << 15 | imm << 20;
}
static uint32_t assemble(OpIS op, Register rd, Register rs,
uint32_t imm) {
return op | rd.code() << 7 | rs.code() << 15 | imm << 20;
}
static uint32_t assemble(OpR op, Register rd, Register rs1,
Register rs2) {
return op | rd.code() << 7 | rs1.code() << 15 | rs2.code() << 20;
}
static uint32_t assemble(OpS op, Register rs1, Register rs2,
int32_t imm) {
uint32_t cimm = imm << 20;
return op | cimm & SUpperImmMask | rs2.code() << 20 | rs1.code() << 15 |
(cimm >> 13) & SLowerImmMask;
}
static uint32_t assemble(OpU op, Register rd, int32_t imm) {
return op | rd.code() << 7 | imm << 12;
}
static uint16_t assemble(OpC op) {
// Incomplete, filled in for C_NOP
return op;
}
template <typename... T>
static void emit(T... a) {
auto instruction = assemble(a...);
*reinterpret_cast<decltype(instruction)*>(pc_) = instruction;
pc_ += sizeof(instruction);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment