Extend rvcpp ISA sim to cover RVC. Passes RV32IC compliance.
This commit is contained in:
		
							parent
							
								
									670099e461
								
							
						
					
					
						commit
						8e7e8f4008
					
				| 
						 | 
					@ -7,10 +7,14 @@
 | 
				
			||||||
#include <tuple>
 | 
					#include <tuple>
 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "rv_opcodes.h"
 | 
				
			||||||
#include "rv_types.h"
 | 
					#include "rv_types.h"
 | 
				
			||||||
#include "mem.h"
 | 
					#include "mem.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Minimal RISC-V interpreter, supporting RV32IM only
 | 
					// Minimal RISC-V interpreter, supporting:
 | 
				
			||||||
 | 
					// - RV32I
 | 
				
			||||||
 | 
					// - M
 | 
				
			||||||
 | 
					// - C (also called Zca)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Use unsigned arithmetic everywhere, with explicit sign extension as required.
 | 
					// Use unsigned arithmetic everywhere, with explicit sign extension as required.
 | 
				
			||||||
static inline ux_t sext(ux_t bits, int sign_bit) {
 | 
					static inline ux_t sext(ux_t bits, int sign_bit) {
 | 
				
			||||||
| 
						 | 
					@ -20,6 +24,12 @@ static inline ux_t sext(ux_t bits, int sign_bit) {
 | 
				
			||||||
		return (bits & (1u << sign_bit + 1) - 1) - ((bits & 1u << sign_bit) << 1);
 | 
							return (bits & (1u << sign_bit + 1) - 1) - ((bits & 1u << sign_bit) << 1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Inclusive msb:lsb style, like Verilog (and like the ISA manual)
 | 
				
			||||||
 | 
					#define BITS_UPTO(msb) (~((-1u << (msb)) << 1))
 | 
				
			||||||
 | 
					#define BITRANGE(msb, lsb) (BITS_UPTO((msb) - (lsb)) << (lsb))
 | 
				
			||||||
 | 
					#define GETBITS(x, msb, lsb) (((x) & BITRANGE(msb, lsb)) >> (lsb))
 | 
				
			||||||
 | 
					#define GETBIT(x, bit) (((x) >> (bit)) & 1u)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline ux_t imm_i(uint32_t instr) {
 | 
					static inline ux_t imm_i(uint32_t instr) {
 | 
				
			||||||
	return (instr >> 20) - (instr >> 19 & 0x1000);
 | 
						return (instr >> 20) - (instr >> 19 & 0x1000);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -48,6 +58,45 @@ static inline ux_t imm_j(uint32_t instr) {
 | 
				
			||||||
	 	- (instr >> 11 & 0x100000);
 | 
						 	- (instr >> 11 & 0x100000);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline ux_t imm_ci(uint32_t instr) {
 | 
				
			||||||
 | 
						return GETBITS(instr, 6, 2) - (GETBIT(instr, 12) << 5);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline ux_t imm_cj(uint32_t instr) {
 | 
				
			||||||
 | 
						return -(GETBIT(instr, 12) << 11)
 | 
				
			||||||
 | 
							+ (GETBIT(instr, 11) << 4)
 | 
				
			||||||
 | 
							+ (GETBITS(instr, 10, 9) << 8)
 | 
				
			||||||
 | 
							+ (GETBIT(instr, 8) << 10)
 | 
				
			||||||
 | 
							+ (GETBIT(instr, 7) << 6)
 | 
				
			||||||
 | 
							+ (GETBIT(instr, 6) << 7)
 | 
				
			||||||
 | 
							+ (GETBITS(instr, 5, 3) << 1)
 | 
				
			||||||
 | 
							+ (GETBIT(instr, 2) << 5);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline ux_t imm_cb(uint32_t instr) {
 | 
				
			||||||
 | 
						return -(GETBIT(instr, 12) << 8)
 | 
				
			||||||
 | 
							+ (GETBITS(instr, 11, 10) << 3)
 | 
				
			||||||
 | 
							+ (GETBITS(instr, 6, 5) << 6)
 | 
				
			||||||
 | 
							+ (GETBITS(instr, 4, 3) << 1)
 | 
				
			||||||
 | 
							+ (GETBIT(instr, 2) << 5);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint c_rs1_s(uint32_t instr) {
 | 
				
			||||||
 | 
						return GETBITS(instr, 9, 7) + 8;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint c_rs2_s(uint32_t instr) {
 | 
				
			||||||
 | 
						return GETBITS(instr, 4, 2) + 8;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint c_rs1_l(uint32_t instr) {
 | 
				
			||||||
 | 
						return GETBITS(instr, 11, 7);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline uint c_rs2_l(uint32_t instr) {
 | 
				
			||||||
 | 
						return GETBITS(instr, 6, 2);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct RVCSR {
 | 
					struct RVCSR {
 | 
				
			||||||
	enum {
 | 
						enum {
 | 
				
			||||||
		WRITE = 0,
 | 
							WRITE = 0,
 | 
				
			||||||
| 
						 | 
					@ -96,7 +145,7 @@ struct RVCore {
 | 
				
			||||||
	ux_t pc;
 | 
						ux_t pc;
 | 
				
			||||||
	RVCSR csr;
 | 
						RVCSR csr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	RVCore(ux_t reset_vector=0xc0) {
 | 
						RVCore(ux_t reset_vector=0x40) {
 | 
				
			||||||
		std::fill(std::begin(regs), std::end(regs), 0);
 | 
							std::fill(std::begin(regs), std::end(regs), 0);
 | 
				
			||||||
		pc = reset_vector;
 | 
							pc = reset_vector;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -115,8 +164,8 @@ struct RVCore {
 | 
				
			||||||
		OPC_SYSTEM   = 0b11'100
 | 
							OPC_SYSTEM   = 0b11'100
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void step(MemBase32 &mem) {
 | 
						void step(MemBase32 &mem, bool trace=false) {
 | 
				
			||||||
		uint32_t instr = mem.r32(pc);
 | 
							uint32_t instr = mem.r16(pc) | (mem.r16(pc + 2) << 16);
 | 
				
			||||||
		std::optional<ux_t> rd_wdata;
 | 
							std::optional<ux_t> rd_wdata;
 | 
				
			||||||
		std::optional<ux_t> pc_wdata;
 | 
							std::optional<ux_t> pc_wdata;
 | 
				
			||||||
		uint regnum_rs1 = instr >> 15 & 0x1f;
 | 
							uint regnum_rs1 = instr >> 15 & 0x1f;
 | 
				
			||||||
| 
						 | 
					@ -130,6 +179,8 @@ struct RVCore {
 | 
				
			||||||
		uint funct3 = instr >> 12 & 0x7;
 | 
							uint funct3 = instr >> 12 & 0x7;
 | 
				
			||||||
		uint funct7 = instr >> 25 & 0x7f;
 | 
							uint funct7 = instr >> 25 & 0x7f;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ((instr & 0x3) == 0x3) {
 | 
				
			||||||
 | 
								// 32-bit instruction
 | 
				
			||||||
			switch (opc) {
 | 
								switch (opc) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			case OPC_OP: {
 | 
								case OPC_OP: {
 | 
				
			||||||
| 
						 | 
					@ -176,7 +227,6 @@ struct RVCore {
 | 
				
			||||||
							rd_wdata = mul_result >> XLEN;
 | 
												rd_wdata = mul_result >> XLEN;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					else {
 | 
										else {
 | 
				
			||||||
					asm volatile("" : : : "memory");
 | 
					 | 
				
			||||||
						if (funct3 == 0b100) {
 | 
											if (funct3 == 0b100) {
 | 
				
			||||||
							if (rs2 == 0)
 | 
												if (rs2 == 0)
 | 
				
			||||||
								rd_wdata = -1;
 | 
													rd_wdata = -1;
 | 
				
			||||||
| 
						 | 
					@ -336,28 +386,167 @@ struct RVCore {
 | 
				
			||||||
				instr_invalid = true;
 | 
									instr_invalid = true;
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								regnum_rd = 0;
 | 
				
			||||||
 | 
								// 16-bit instructions
 | 
				
			||||||
 | 
								// RVC Quadrant 00:
 | 
				
			||||||
 | 
								if (RVOPC_MATCH(instr, C_ADDI4SPN)) {
 | 
				
			||||||
 | 
									regnum_rd = c_rs2_s(instr);
 | 
				
			||||||
 | 
									rd_wdata = regs[2]
 | 
				
			||||||
 | 
										+ (GETBITS(instr, 12, 11) << 4)
 | 
				
			||||||
 | 
										+ (GETBITS(instr, 10, 7) << 6)
 | 
				
			||||||
 | 
										+ (GETBIT(instr, 6) << 2)
 | 
				
			||||||
 | 
										+ (GETBIT(instr, 5) << 3);
 | 
				
			||||||
 | 
								} else if (RVOPC_MATCH(instr, C_LW)) {
 | 
				
			||||||
 | 
									regnum_rd = c_rs2_s(instr);
 | 
				
			||||||
 | 
									uint32_t addr = regs[c_rs1_s(instr)]
 | 
				
			||||||
 | 
										+ (GETBIT(instr, 6) << 2)
 | 
				
			||||||
 | 
										+ (GETBITS(instr, 12, 10) << 3)
 | 
				
			||||||
 | 
										+ (GETBIT(instr, 5) << 6);
 | 
				
			||||||
 | 
									rd_wdata = mem.r32(addr);
 | 
				
			||||||
 | 
								} else if (RVOPC_MATCH(instr, C_SW)) {
 | 
				
			||||||
 | 
									uint32_t addr = regs[c_rs1_s(instr)]
 | 
				
			||||||
 | 
										+ (GETBIT(instr, 6) << 2)
 | 
				
			||||||
 | 
										+ (GETBITS(instr, 12, 10) << 3)
 | 
				
			||||||
 | 
										+ (GETBIT(instr, 5) << 6);
 | 
				
			||||||
 | 
									mem.w32(addr, regs[c_rs2_s(instr)]);
 | 
				
			||||||
 | 
								// RVC Quadrant 01:
 | 
				
			||||||
 | 
								} else if (RVOPC_MATCH(instr, C_ADDI)) {
 | 
				
			||||||
 | 
									regnum_rd = c_rs1_l(instr);
 | 
				
			||||||
 | 
									rd_wdata = regs[c_rs1_l(instr)] + imm_ci(instr);
 | 
				
			||||||
 | 
								} else if (RVOPC_MATCH(instr, C_JAL)) {
 | 
				
			||||||
 | 
									pc_wdata = pc + imm_cj(instr);
 | 
				
			||||||
 | 
									regnum_rd = 1;
 | 
				
			||||||
 | 
									rd_wdata = pc + 2;
 | 
				
			||||||
 | 
								} else if (RVOPC_MATCH(instr, C_LI)) {
 | 
				
			||||||
 | 
									regnum_rd = c_rs1_l(instr);
 | 
				
			||||||
 | 
									rd_wdata = imm_ci(instr);
 | 
				
			||||||
 | 
								} else if (RVOPC_MATCH(instr, C_LUI)) {
 | 
				
			||||||
 | 
									regnum_rd = c_rs1_l(instr);
 | 
				
			||||||
 | 
									// ADDI16SPN if rd is sp
 | 
				
			||||||
 | 
									if (regnum_rd == 2) {
 | 
				
			||||||
 | 
										rd_wdata = regs[2]
 | 
				
			||||||
 | 
											- (GETBIT(instr, 12) << 9)
 | 
				
			||||||
 | 
											+ (GETBIT(instr, 6) << 4)
 | 
				
			||||||
 | 
											+ (GETBIT(instr, 5) << 6)
 | 
				
			||||||
 | 
											+ (GETBITS(instr, 4, 3) << 7)
 | 
				
			||||||
 | 
											+ (GETBIT(instr, 2) << 5);
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										rd_wdata = -(GETBIT(instr, 12) << 17)
 | 
				
			||||||
 | 
										+ (GETBITS(instr, 6, 2) << 12);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else if (RVOPC_MATCH(instr, C_SRLI)) {
 | 
				
			||||||
 | 
									regnum_rd = c_rs1_s(instr);
 | 
				
			||||||
 | 
									rd_wdata = regs[regnum_rd] >> GETBITS(instr, 6, 2);
 | 
				
			||||||
 | 
								} else if (RVOPC_MATCH(instr, C_SRAI)) {
 | 
				
			||||||
 | 
									regnum_rd = c_rs1_s(instr);
 | 
				
			||||||
 | 
									rd_wdata = (sx_t)regs[regnum_rd] >> GETBITS(instr, 6, 2);
 | 
				
			||||||
 | 
								} else if (RVOPC_MATCH(instr, C_ANDI)) {
 | 
				
			||||||
 | 
									regnum_rd = c_rs1_s(instr);
 | 
				
			||||||
 | 
									rd_wdata = regs[regnum_rd] & imm_ci(instr);
 | 
				
			||||||
 | 
								} else if (RVOPC_MATCH(instr, C_SUB)) {
 | 
				
			||||||
 | 
									regnum_rd = c_rs1_s(instr);
 | 
				
			||||||
 | 
									rd_wdata = regs[c_rs1_s(instr)] - regs[c_rs2_s(instr)];
 | 
				
			||||||
 | 
								} else if (RVOPC_MATCH(instr, C_XOR)) {
 | 
				
			||||||
 | 
									regnum_rd = c_rs1_s(instr);
 | 
				
			||||||
 | 
									rd_wdata = regs[c_rs1_s(instr)] ^ regs[c_rs2_s(instr)];
 | 
				
			||||||
 | 
								} else if (RVOPC_MATCH(instr, C_OR)) {
 | 
				
			||||||
 | 
									regnum_rd = c_rs1_s(instr);
 | 
				
			||||||
 | 
									rd_wdata = regs[c_rs1_s(instr)] | regs[c_rs2_s(instr)];
 | 
				
			||||||
 | 
								} else if (RVOPC_MATCH(instr, C_AND)) {
 | 
				
			||||||
 | 
									regnum_rd = c_rs1_s(instr);
 | 
				
			||||||
 | 
									rd_wdata = regs[c_rs1_s(instr)] & regs[c_rs2_s(instr)];
 | 
				
			||||||
 | 
								} else if (RVOPC_MATCH(instr, C_J)) {
 | 
				
			||||||
 | 
									pc_wdata = pc + imm_cj(instr);
 | 
				
			||||||
 | 
								} else if (RVOPC_MATCH(instr, C_BEQZ)) {
 | 
				
			||||||
 | 
									if (regs[c_rs1_s(instr)] == 0) {
 | 
				
			||||||
 | 
										pc_wdata = pc + imm_cb(instr);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else if (RVOPC_MATCH(instr, C_BNEZ)) {
 | 
				
			||||||
 | 
									if (regs[c_rs1_s(instr)] != 0) {
 | 
				
			||||||
 | 
										pc_wdata = pc + imm_cb(instr);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								// RVC Quadrant 10:
 | 
				
			||||||
 | 
								} else if (RVOPC_MATCH(instr, C_SLLI)) {
 | 
				
			||||||
 | 
									regnum_rd = c_rs1_s(instr);
 | 
				
			||||||
 | 
									rd_wdata = regs[regnum_rd] << GETBITS(instr, 6, 2);
 | 
				
			||||||
 | 
								} else if (RVOPC_MATCH(instr, C_MV)) {
 | 
				
			||||||
 | 
									if (c_rs2_l(instr) == 0) {
 | 
				
			||||||
 | 
										// c.jr
 | 
				
			||||||
 | 
										pc_wdata = regs[c_rs1_l(instr)] & -2u;;
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										regnum_rd = c_rs1_l(instr);
 | 
				
			||||||
 | 
										rd_wdata = regs[c_rs2_l(instr)];
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else if (RVOPC_MATCH(instr, C_ADD)) {
 | 
				
			||||||
 | 
									if (c_rs2_l(instr) == 0) {
 | 
				
			||||||
 | 
										// c.jalr
 | 
				
			||||||
 | 
										pc_wdata = regs[c_rs1_l(instr)] & -2u;
 | 
				
			||||||
 | 
										regnum_rd = 1;
 | 
				
			||||||
 | 
										rd_wdata = pc + 2;
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										regnum_rd = c_rs1_l(instr);
 | 
				
			||||||
 | 
										rd_wdata = regs[c_rs1_l(instr)] + regs[c_rs2_l(instr)];
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else if (RVOPC_MATCH(instr, C_LWSP)) {
 | 
				
			||||||
 | 
									regnum_rd = c_rs1_l(instr);
 | 
				
			||||||
 | 
									ux_t addr = regs[2]
 | 
				
			||||||
 | 
										+ (GETBIT(instr, 12) << 5)
 | 
				
			||||||
 | 
										+ (GETBITS(instr, 6, 4) << 2)
 | 
				
			||||||
 | 
										+ (GETBITS(instr, 3, 2) << 6);
 | 
				
			||||||
 | 
									rd_wdata = mem.r32(addr);
 | 
				
			||||||
 | 
								} else if (RVOPC_MATCH(instr, C_SWSP)) {
 | 
				
			||||||
 | 
									ux_t addr = regs[2]
 | 
				
			||||||
 | 
										+ (GETBITS(instr, 12, 9) << 2)
 | 
				
			||||||
 | 
										+ (GETBITS(instr, 8, 7) << 6);
 | 
				
			||||||
 | 
									mem.w32(addr, regs[c_rs2_l(instr)]);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									instr_invalid = true;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		if (instr_invalid)
 | 
							if (instr_invalid)
 | 
				
			||||||
			printf("Invalid instr %08x at %08x\n", instr, pc);
 | 
								printf("Invalid instr %08x at %08x\n", instr, pc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (trace) {
 | 
				
			||||||
 | 
								printf("%08x: ", pc);
 | 
				
			||||||
 | 
								if ((instr & 0x3) == 0x3) {
 | 
				
			||||||
 | 
									printf("%08x : ", instr);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									printf("    %04x : ", instr & 0xffffu);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (regnum_rd != 0) {
 | 
				
			||||||
 | 
									printf("%-3s <- %08x ", friendly_reg_names[regnum_rd], *rd_wdata);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									printf("                ");
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (pc_wdata) {
 | 
				
			||||||
 | 
									printf(": pc <- %08x\n", *pc_wdata);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									printf(":\n");
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (pc_wdata)
 | 
							if (pc_wdata)
 | 
				
			||||||
			pc = *pc_wdata;
 | 
								pc = *pc_wdata;
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			pc = pc + 4;
 | 
								pc = pc + ((instr & 0x3) == 0x3 ? 4 : 2);
 | 
				
			||||||
		if (rd_wdata && regnum_rd != 0)
 | 
							if (rd_wdata && regnum_rd != 0)
 | 
				
			||||||
			regs[regnum_rd] = *rd_wdata;
 | 
								regs[regnum_rd] = *rd_wdata;
 | 
				
			||||||
		csr.step();
 | 
							csr.step();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char *help_str =
 | 
					const char *help_str =
 | 
				
			||||||
"Usage: tb binfile [--dump start end] [--cycles n]\n"
 | 
					"Usage: tb [--bin x.bin] [--dump start end] [--vcd x.vcd] [--cycles n]\n"
 | 
				
			||||||
"    binfile          : Binary to load into start of memory\n"
 | 
					"    --bin x.bin      : Flat binary file loaded to address 0x0 in RAM\n"
 | 
				
			||||||
 | 
					"    --vcd x.vcd      : Dummy option for compatibility with CXXRTL tb\n"
 | 
				
			||||||
"    --dump start end : Print out memory contents between start and end (exclusive)\n"
 | 
					"    --dump start end : Print out memory contents between start and end (exclusive)\n"
 | 
				
			||||||
"                       after execution finishes. Can be passed multiple times.\n"
 | 
					"                       after execution finishes. Can be passed multiple times.\n"
 | 
				
			||||||
"    --cycles n       : Maximum number of cycles to run before exiting.\n"
 | 
					"    --cycles n       : Maximum number of cycles to run before exiting.\n"
 | 
				
			||||||
"    --memsize n      : Memory size in units of 1024 bytes, default is 16 MB\n"
 | 
					"    --memsize n      : Memory size in units of 1024 bytes, default is 16 MB\n"
 | 
				
			||||||
 | 
					"    --trace          : Print out execution tracing info\n"
 | 
				
			||||||
;
 | 
					;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void exit_help(std::string errtext = "") {
 | 
					void exit_help(std::string errtext = "") {
 | 
				
			||||||
| 
						 | 
					@ -372,10 +561,26 @@ int main(int argc, char **argv) {
 | 
				
			||||||
	std::vector<std::tuple<uint32_t, uint32_t>> dump_ranges;
 | 
						std::vector<std::tuple<uint32_t, uint32_t>> dump_ranges;
 | 
				
			||||||
	int64_t max_cycles = 100000;
 | 
						int64_t max_cycles = 100000;
 | 
				
			||||||
	uint32_t ramsize = 16 * (1 << 20);
 | 
						uint32_t ramsize = 16 * (1 << 20);
 | 
				
			||||||
 | 
						bool load_bin = false;
 | 
				
			||||||
 | 
						std::string bin_path;
 | 
				
			||||||
 | 
						bool trace_execution = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (int i = 2; i < argc; ++i) {
 | 
						for (int i = 1; i < argc; ++i) {
 | 
				
			||||||
		std::string s(argv[i]);
 | 
							std::string s(argv[i]);
 | 
				
			||||||
		if (s == "--dump") {
 | 
							if (s == "--bin") {
 | 
				
			||||||
 | 
								if (argc - i < 2)
 | 
				
			||||||
 | 
									exit_help("Option --bin requires an argument\n");
 | 
				
			||||||
 | 
								load_bin = true;
 | 
				
			||||||
 | 
								bin_path = argv[i + 1];
 | 
				
			||||||
 | 
								i += 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if (s == "--vcd") {
 | 
				
			||||||
 | 
								if (argc - i < 2)
 | 
				
			||||||
 | 
									exit_help("Option --vcd requires an argument\n");
 | 
				
			||||||
 | 
								// (We ignore this argument, it's supported for
 | 
				
			||||||
 | 
								i += 1;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else if (s == "--dump") {
 | 
				
			||||||
			if (argc - i < 3)
 | 
								if (argc - i < 3)
 | 
				
			||||||
				exit_help("Option --dump requires 2 arguments\n");
 | 
									exit_help("Option --dump requires 2 arguments\n");
 | 
				
			||||||
			dump_ranges.push_back(std::make_tuple(
 | 
								dump_ranges.push_back(std::make_tuple(
 | 
				
			||||||
| 
						 | 
					@ -396,6 +601,9 @@ int main(int argc, char **argv) {
 | 
				
			||||||
			ramsize = 1024 * std::stol(argv[i + 1], 0, 0);
 | 
								ramsize = 1024 * std::stol(argv[i + 1], 0, 0);
 | 
				
			||||||
			i += 1;
 | 
								i += 1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							else if (s == "--trace") {
 | 
				
			||||||
 | 
								trace_execution = true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		else {
 | 
							else {
 | 
				
			||||||
			std::cerr << "Unrecognised argument " << s << "\n";
 | 
								std::cerr << "Unrecognised argument " << s << "\n";
 | 
				
			||||||
			exit_help("");
 | 
								exit_help("");
 | 
				
			||||||
| 
						 | 
					@ -408,7 +616,8 @@ int main(int argc, char **argv) {
 | 
				
			||||||
	mem.add(0, ramsize, &ram);
 | 
						mem.add(0, ramsize, &ram);
 | 
				
			||||||
	mem.add(0x80000000u, 12, &io);
 | 
						mem.add(0x80000000u, 12, &io);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::ifstream fd(argv[1], std::ios::binary | std::ios::ate);
 | 
						if (load_bin) {
 | 
				
			||||||
 | 
							std::ifstream fd(bin_path, std::ios::binary | std::ios::ate);
 | 
				
			||||||
		std::streamsize bin_size = fd.tellg();
 | 
							std::streamsize bin_size = fd.tellg();
 | 
				
			||||||
		if (bin_size > ramsize) {
 | 
							if (bin_size > ramsize) {
 | 
				
			||||||
			std::cerr << "Binary file (" << bin_size << " bytes) is larger than memory (" << ramsize << " bytes)\n";
 | 
								std::cerr << "Binary file (" << bin_size << " bytes) is larger than memory (" << ramsize << " bytes)\n";
 | 
				
			||||||
| 
						 | 
					@ -416,13 +625,14 @@ int main(int argc, char **argv) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		fd.seekg(0, std::ios::beg);
 | 
							fd.seekg(0, std::ios::beg);
 | 
				
			||||||
		fd.read((char*)ram.mem, bin_size);
 | 
							fd.read((char*)ram.mem, bin_size);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	RVCore core;
 | 
						RVCore core;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int64_t cyc;
 | 
						int64_t cyc;
 | 
				
			||||||
	try {
 | 
						try {
 | 
				
			||||||
		for (cyc = 0; cyc < max_cycles; ++cyc)
 | 
							for (cyc = 0; cyc < max_cycles; ++cyc)
 | 
				
			||||||
			core.step(mem);
 | 
								core.step(mem, trace_execution);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	catch (TBExitException e) {
 | 
						catch (TBExitException e) {
 | 
				
			||||||
		printf("CPU requested halt. Exit code %d\n", e.exitcode);
 | 
							printf("CPU requested halt. Exit code %d\n", e.exitcode);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,346 @@
 | 
				
			||||||
 | 
					#ifndef _RV_OPCODES_H
 | 
				
			||||||
 | 
					#define _RV_OPCODES_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Base ISA (some of these are Z now)
 | 
				
			||||||
 | 
					#define RVOPC_BEQ_BITS         0b00000000000000000000000001100011
 | 
				
			||||||
 | 
					#define RVOPC_BEQ_MASK         0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_BNE_BITS         0b00000000000000000001000001100011
 | 
				
			||||||
 | 
					#define RVOPC_BNE_MASK         0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_BLT_BITS         0b00000000000000000100000001100011
 | 
				
			||||||
 | 
					#define RVOPC_BLT_MASK         0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_BGE_BITS         0b00000000000000000101000001100011
 | 
				
			||||||
 | 
					#define RVOPC_BGE_MASK         0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_BLTU_BITS        0b00000000000000000110000001100011
 | 
				
			||||||
 | 
					#define RVOPC_BLTU_MASK        0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_BGEU_BITS        0b00000000000000000111000001100011
 | 
				
			||||||
 | 
					#define RVOPC_BGEU_MASK        0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_JALR_BITS        0b00000000000000000000000001100111
 | 
				
			||||||
 | 
					#define RVOPC_JALR_MASK        0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_JAL_BITS         0b00000000000000000000000001101111
 | 
				
			||||||
 | 
					#define RVOPC_JAL_MASK         0b00000000000000000000000001111111
 | 
				
			||||||
 | 
					#define RVOPC_LUI_BITS         0b00000000000000000000000000110111
 | 
				
			||||||
 | 
					#define RVOPC_LUI_MASK         0b00000000000000000000000001111111
 | 
				
			||||||
 | 
					#define RVOPC_AUIPC_BITS       0b00000000000000000000000000010111
 | 
				
			||||||
 | 
					#define RVOPC_AUIPC_MASK       0b00000000000000000000000001111111
 | 
				
			||||||
 | 
					#define RVOPC_ADDI_BITS        0b00000000000000000000000000010011
 | 
				
			||||||
 | 
					#define RVOPC_ADDI_MASK        0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_SLLI_BITS        0b00000000000000000001000000010011
 | 
				
			||||||
 | 
					#define RVOPC_SLLI_MASK        0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_SLTI_BITS        0b00000000000000000010000000010011
 | 
				
			||||||
 | 
					#define RVOPC_SLTI_MASK        0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_SLTIU_BITS       0b00000000000000000011000000010011
 | 
				
			||||||
 | 
					#define RVOPC_SLTIU_MASK       0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_XORI_BITS        0b00000000000000000100000000010011
 | 
				
			||||||
 | 
					#define RVOPC_XORI_MASK        0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_SRLI_BITS        0b00000000000000000101000000010011
 | 
				
			||||||
 | 
					#define RVOPC_SRLI_MASK        0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_SRAI_BITS        0b01000000000000000101000000010011
 | 
				
			||||||
 | 
					#define RVOPC_SRAI_MASK        0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_ORI_BITS         0b00000000000000000110000000010011
 | 
				
			||||||
 | 
					#define RVOPC_ORI_MASK         0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_ANDI_BITS        0b00000000000000000111000000010011
 | 
				
			||||||
 | 
					#define RVOPC_ANDI_MASK        0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_ADD_BITS         0b00000000000000000000000000110011
 | 
				
			||||||
 | 
					#define RVOPC_ADD_MASK         0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_SUB_BITS         0b01000000000000000000000000110011
 | 
				
			||||||
 | 
					#define RVOPC_SUB_MASK         0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_SLL_BITS         0b00000000000000000001000000110011
 | 
				
			||||||
 | 
					#define RVOPC_SLL_MASK         0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_SLT_BITS         0b00000000000000000010000000110011
 | 
				
			||||||
 | 
					#define RVOPC_SLT_MASK         0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_SLTU_BITS        0b00000000000000000011000000110011
 | 
				
			||||||
 | 
					#define RVOPC_SLTU_MASK        0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_XOR_BITS         0b00000000000000000100000000110011
 | 
				
			||||||
 | 
					#define RVOPC_XOR_MASK         0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_SRL_BITS         0b00000000000000000101000000110011
 | 
				
			||||||
 | 
					#define RVOPC_SRL_MASK         0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_SRA_BITS         0b01000000000000000101000000110011
 | 
				
			||||||
 | 
					#define RVOPC_SRA_MASK         0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_OR_BITS          0b00000000000000000110000000110011
 | 
				
			||||||
 | 
					#define RVOPC_OR_MASK          0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_AND_BITS         0b00000000000000000111000000110011
 | 
				
			||||||
 | 
					#define RVOPC_AND_MASK         0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_LB_BITS          0b00000000000000000000000000000011
 | 
				
			||||||
 | 
					#define RVOPC_LB_MASK          0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_LH_BITS          0b00000000000000000001000000000011
 | 
				
			||||||
 | 
					#define RVOPC_LH_MASK          0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_LW_BITS          0b00000000000000000010000000000011
 | 
				
			||||||
 | 
					#define RVOPC_LW_MASK          0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_LBU_BITS         0b00000000000000000100000000000011
 | 
				
			||||||
 | 
					#define RVOPC_LBU_MASK         0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_LHU_BITS         0b00000000000000000101000000000011
 | 
				
			||||||
 | 
					#define RVOPC_LHU_MASK         0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_SB_BITS          0b00000000000000000000000000100011
 | 
				
			||||||
 | 
					#define RVOPC_SB_MASK          0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_SH_BITS          0b00000000000000000001000000100011
 | 
				
			||||||
 | 
					#define RVOPC_SH_MASK          0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_SW_BITS          0b00000000000000000010000000100011
 | 
				
			||||||
 | 
					#define RVOPC_SW_MASK          0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_FENCE_BITS       0b00000000000000000000000000001111
 | 
				
			||||||
 | 
					#define RVOPC_FENCE_MASK       0b00000000000011111111111111111111
 | 
				
			||||||
 | 
					#define RVOPC_FENCE_I_BITS     0b00000000000000000001000000001111
 | 
				
			||||||
 | 
					#define RVOPC_FENCE_I_MASK     0b11111111111111111111111111111111
 | 
				
			||||||
 | 
					#define RVOPC_ECALL_BITS       0b00000000000000000000000001110011
 | 
				
			||||||
 | 
					#define RVOPC_ECALL_MASK       0b11111111111111111111111111111111
 | 
				
			||||||
 | 
					#define RVOPC_EBREAK_BITS      0b00000000000100000000000001110011
 | 
				
			||||||
 | 
					#define RVOPC_EBREAK_MASK      0b11111111111111111111111111111111
 | 
				
			||||||
 | 
					#define RVOPC_CSRRW_BITS       0b00000000000000000001000001110011
 | 
				
			||||||
 | 
					#define RVOPC_CSRRW_MASK       0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_CSRRS_BITS       0b00000000000000000010000001110011
 | 
				
			||||||
 | 
					#define RVOPC_CSRRS_MASK       0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_CSRRC_BITS       0b00000000000000000011000001110011
 | 
				
			||||||
 | 
					#define RVOPC_CSRRC_MASK       0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_CSRRWI_BITS      0b00000000000000000101000001110011
 | 
				
			||||||
 | 
					#define RVOPC_CSRRWI_MASK      0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_CSRRSI_BITS      0b00000000000000000110000001110011
 | 
				
			||||||
 | 
					#define RVOPC_CSRRSI_MASK      0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_CSRRCI_BITS      0b00000000000000000111000001110011
 | 
				
			||||||
 | 
					#define RVOPC_CSRRCI_MASK      0b00000000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_MRET_BITS        0b00110000001000000000000001110011
 | 
				
			||||||
 | 
					#define RVOPC_MRET_MASK        0b11111111111111111111111111111111
 | 
				
			||||||
 | 
					#define RVOPC_SYSTEM_BITS      0b00000000000000000000000001110011
 | 
				
			||||||
 | 
					#define RVOPC_SYSTEM_MASK      0b00000000000000000000000001111111
 | 
				
			||||||
 | 
					#define RVOPC_WFI_BITS         0b00010000010100000000000001110011
 | 
				
			||||||
 | 
					#define RVOPC_WFI_MASK         0b11111111111111111111111111111111
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// M extension
 | 
				
			||||||
 | 
					#define RVOPC_MUL_BITS         0b00000010000000000000000000110011
 | 
				
			||||||
 | 
					#define RVOPC_MUL_MASK         0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_MULH_BITS        0b00000010000000000001000000110011
 | 
				
			||||||
 | 
					#define RVOPC_MULH_MASK        0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_MULHSU_BITS      0b00000010000000000010000000110011
 | 
				
			||||||
 | 
					#define RVOPC_MULHSU_MASK      0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_MULHU_BITS       0b00000010000000000011000000110011
 | 
				
			||||||
 | 
					#define RVOPC_MULHU_MASK       0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_DIV_BITS         0b00000010000000000100000000110011
 | 
				
			||||||
 | 
					#define RVOPC_DIV_MASK         0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_DIVU_BITS        0b00000010000000000101000000110011
 | 
				
			||||||
 | 
					#define RVOPC_DIVU_MASK        0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_REM_BITS         0b00000010000000000110000000110011
 | 
				
			||||||
 | 
					#define RVOPC_REM_MASK         0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_REMU_BITS        0b00000010000000000111000000110011
 | 
				
			||||||
 | 
					#define RVOPC_REMU_MASK        0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A extension
 | 
				
			||||||
 | 
					#define RVOPC_LR_W_BITS        0b00010000000000000010000000101111
 | 
				
			||||||
 | 
					#define RVOPC_LR_W_MASK        0b11111001111100000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_SC_W_BITS        0b00011000000000000010000000101111
 | 
				
			||||||
 | 
					#define RVOPC_SC_W_MASK        0b11111000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_AMOSWAP_W_BITS   0b00001000000000000010000000101111
 | 
				
			||||||
 | 
					#define RVOPC_AMOSWAP_W_MASK   0b11111000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_AMOADD_W_BITS    0b00000000000000000010000000101111
 | 
				
			||||||
 | 
					#define RVOPC_AMOADD_W_MASK    0b11111000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_AMOXOR_W_BITS    0b00100000000000000010000000101111
 | 
				
			||||||
 | 
					#define RVOPC_AMOXOR_W_MASK    0b11111000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_AMOAND_W_BITS    0b01100000000000000010000000101111
 | 
				
			||||||
 | 
					#define RVOPC_AMOAND_W_MASK    0b11111000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_AMOOR_W_BITS     0b01000000000000000010000000101111
 | 
				
			||||||
 | 
					#define RVOPC_AMOOR_W_MASK     0b11111000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_AMOMIN_W_BITS    0b10000000000000000010000000101111
 | 
				
			||||||
 | 
					#define RVOPC_AMOMIN_W_MASK    0b11111000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_AMOMAX_W_BITS    0b10100000000000000010000000101111
 | 
				
			||||||
 | 
					#define RVOPC_AMOMAX_W_MASK    0b11111000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_AMOMINU_W_BITS   0b11000000000000000010000000101111
 | 
				
			||||||
 | 
					#define RVOPC_AMOMINU_W_MASK   0b11111000000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_AMOMAXU_W_BITS   0b11100000000000000010000000101111
 | 
				
			||||||
 | 
					#define RVOPC_AMOMAXU_W_MASK   0b11111000000000000111000001111111
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Zba (address generation)
 | 
				
			||||||
 | 
					#define RVOPC_SH1ADD_BITS      0b00100000000000000010000000110011
 | 
				
			||||||
 | 
					#define RVOPC_SH1ADD_MASK      0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_SH2ADD_BITS      0b00100000000000000100000000110011
 | 
				
			||||||
 | 
					#define RVOPC_SH2ADD_MASK      0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_SH3ADD_BITS      0b00100000000000000110000000110011
 | 
				
			||||||
 | 
					#define RVOPC_SH3ADD_MASK      0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Zbb (basic bit manipulation)
 | 
				
			||||||
 | 
					#define RVOPC_ANDN_BITS        0b01000000000000000111000000110011
 | 
				
			||||||
 | 
					#define RVOPC_ANDN_MASK        0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_CLZ_BITS         0b01100000000000000001000000010011
 | 
				
			||||||
 | 
					#define RVOPC_CLZ_MASK         0b11111111111100000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_CPOP_BITS        0b01100000001000000001000000010011
 | 
				
			||||||
 | 
					#define RVOPC_CPOP_MASK        0b11111111111100000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_CTZ_BITS         0b01100000000100000001000000010011
 | 
				
			||||||
 | 
					#define RVOPC_CTZ_MASK         0b11111111111100000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_MAX_BITS         0b00001010000000000110000000110011
 | 
				
			||||||
 | 
					#define RVOPC_MAX_MASK         0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_MAXU_BITS        0b00001010000000000111000000110011
 | 
				
			||||||
 | 
					#define RVOPC_MAXU_MASK        0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_MIN_BITS         0b00001010000000000100000000110011
 | 
				
			||||||
 | 
					#define RVOPC_MIN_MASK         0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_MINU_BITS        0b00001010000000000101000000110011
 | 
				
			||||||
 | 
					#define RVOPC_MINU_MASK        0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_ORC_B_BITS       0b00101000011100000101000000010011
 | 
				
			||||||
 | 
					#define RVOPC_ORC_B_MASK       0b11111111111100000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_ORN_BITS         0b01000000000000000110000000110011
 | 
				
			||||||
 | 
					#define RVOPC_ORN_MASK         0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_REV8_BITS        0b01101001100000000101000000010011
 | 
				
			||||||
 | 
					#define RVOPC_REV8_MASK        0b11111111111100000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_ROL_BITS         0b01100000000000000001000000110011
 | 
				
			||||||
 | 
					#define RVOPC_ROL_MASK         0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_ROR_BITS         0b01100000000000000101000000110011
 | 
				
			||||||
 | 
					#define RVOPC_ROR_MASK         0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_RORI_BITS        0b01100000000000000101000000010011
 | 
				
			||||||
 | 
					#define RVOPC_RORI_MASK        0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_SEXT_B_BITS      0b01100000010000000001000000010011
 | 
				
			||||||
 | 
					#define RVOPC_SEXT_B_MASK      0b11111111111100000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_SEXT_H_BITS      0b01100000010100000001000000010011
 | 
				
			||||||
 | 
					#define RVOPC_SEXT_H_MASK      0b11111111111100000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_XNOR_BITS        0b01000000000000000100000000110011
 | 
				
			||||||
 | 
					#define RVOPC_XNOR_MASK        0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_ZEXT_H_BITS      0b00001000000000000100000000110011
 | 
				
			||||||
 | 
					#define RVOPC_ZEXT_H_MASK      0b11111111111100000111000001111111
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Zbc (carry-less multiply)
 | 
				
			||||||
 | 
					#define RVOPC_CLMUL_BITS       0b00001010000000000001000000110011
 | 
				
			||||||
 | 
					#define RVOPC_CLMUL_MASK       0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_CLMULH_BITS      0b00001010000000000011000000110011
 | 
				
			||||||
 | 
					#define RVOPC_CLMULH_MASK      0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_CLMULR_BITS      0b00001010000000000010000000110011
 | 
				
			||||||
 | 
					#define RVOPC_CLMULR_MASK      0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Zbs (single-bit manipulation)
 | 
				
			||||||
 | 
					#define RVOPC_BCLR_BITS        0b01001000000000000001000000110011
 | 
				
			||||||
 | 
					#define RVOPC_BCLR_MASK        0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_BCLRI_BITS       0b01001000000000000001000000010011
 | 
				
			||||||
 | 
					#define RVOPC_BCLRI_MASK       0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_BEXT_BITS        0b01001000000000000101000000110011
 | 
				
			||||||
 | 
					#define RVOPC_BEXT_MASK        0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_BEXTI_BITS       0b01001000000000000101000000010011
 | 
				
			||||||
 | 
					#define RVOPC_BEXTI_MASK       0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_BINV_BITS        0b01101000000000000001000000110011
 | 
				
			||||||
 | 
					#define RVOPC_BINV_MASK        0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_BINVI_BITS       0b01101000000000000001000000010011
 | 
				
			||||||
 | 
					#define RVOPC_BINVI_MASK       0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_BSET_BITS        0b00101000000000000001000000110011
 | 
				
			||||||
 | 
					#define RVOPC_BSET_MASK        0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_BSETI_BITS       0b00101000000000000001000000010011
 | 
				
			||||||
 | 
					#define RVOPC_BSETI_MASK       0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Zbkb (basic bit manipulation for crypto) (minus those in Zbb)
 | 
				
			||||||
 | 
					#define RVOPC_PACK_BITS        0b00001000000000000100000000110011
 | 
				
			||||||
 | 
					#define RVOPC_PACK_MASK        0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_PACKH_BITS       0b00001000000000000111000000110011
 | 
				
			||||||
 | 
					#define RVOPC_PACKH_MASK       0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_BREV8_BITS       0b01101000011100000101000000010011
 | 
				
			||||||
 | 
					#define RVOPC_BREV8_MASK       0b11111111111100000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_UNZIP_BITS       0b00001000111100000101000000010011
 | 
				
			||||||
 | 
					#define RVOPC_UNZIP_MASK       0b11111111111100000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_ZIP_BITS         0b00001000111100000001000000010011
 | 
				
			||||||
 | 
					#define RVOPC_ZIP_MASK         0b11111111111100000111000001111111
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Zbkc is a subset of Zbc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Zbkx (crossbar permutation)
 | 
				
			||||||
 | 
					#define RVOPC_XPERM_B_BITS     0b00101000000000000100000000110011
 | 
				
			||||||
 | 
					#define RVOPC_XPERM_B_MASK     0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_XPERM_N_BITS     0b00101000000000000010000000110011
 | 
				
			||||||
 | 
					#define RVOPC_XPERM_N_MASK     0b11111110000000000111000001111111
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Hazard3 custom instructions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Xh3b (Hazard3 custom bitmanip): currently just a multi-bit version of bext/bexti from Zbs
 | 
				
			||||||
 | 
					#define RVOPC_H3_BEXTM_BITS    0b00000000000000000000000000001011 // custom-0 funct3=0
 | 
				
			||||||
 | 
					#define RVOPC_H3_BEXTM_MASK    0b11100010000000000111000001111111
 | 
				
			||||||
 | 
					#define RVOPC_H3_BEXTMI_BITS   0b00000000000000000100000000001011 // custom-0 funct3=4
 | 
				
			||||||
 | 
					#define RVOPC_H3_BEXTMI_MASK   0b11100010000000000111000001111111
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// C Extension
 | 
				
			||||||
 | 
					#define RVOPC_C_ADDI4SPN_BITS  0b0000000000000000 // *** illegal if imm 0
 | 
				
			||||||
 | 
					#define RVOPC_C_ADDI4SPN_MASK  0b1110000000000011
 | 
				
			||||||
 | 
					#define RVOPC_C_LW_BITS        0b0100000000000000
 | 
				
			||||||
 | 
					#define RVOPC_C_LW_MASK        0b1110000000000011
 | 
				
			||||||
 | 
					#define RVOPC_C_SW_BITS        0b1100000000000000
 | 
				
			||||||
 | 
					#define RVOPC_C_SW_MASK        0b1110000000000011
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define RVOPC_C_ADDI_BITS      0b0000000000000001
 | 
				
			||||||
 | 
					#define RVOPC_C_ADDI_MASK      0b1110000000000011
 | 
				
			||||||
 | 
					#define RVOPC_C_JAL_BITS       0b0010000000000001
 | 
				
			||||||
 | 
					#define RVOPC_C_JAL_MASK       0b1110000000000011
 | 
				
			||||||
 | 
					#define RVOPC_C_J_BITS         0b1010000000000001
 | 
				
			||||||
 | 
					#define RVOPC_C_J_MASK         0b1110000000000011
 | 
				
			||||||
 | 
					#define RVOPC_C_LI_BITS        0b0100000000000001
 | 
				
			||||||
 | 
					#define RVOPC_C_LI_MASK        0b1110000000000011
 | 
				
			||||||
 | 
					// addi16sp when rd=2:
 | 
				
			||||||
 | 
					#define RVOPC_C_LUI_BITS       0b0110000000000001 // *** reserved if imm 0 (for both LUI and ADDI16SP)
 | 
				
			||||||
 | 
					#define RVOPC_C_LUI_MASK       0b1110000000000011
 | 
				
			||||||
 | 
					#define RVOPC_C_SRLI_BITS      0b1000000000000001 // On RV32 imm[5] (instr[12]) must be 0, else reserved NSE.
 | 
				
			||||||
 | 
					#define RVOPC_C_SRLI_MASK      0b1111110000000011
 | 
				
			||||||
 | 
					#define RVOPC_C_SRAI_BITS      0b1000010000000001 // On RV32 imm[5] (instr[12]) must be 0, else reserved NSE.
 | 
				
			||||||
 | 
					#define RVOPC_C_SRAI_MASK      0b1111110000000011
 | 
				
			||||||
 | 
					#define RVOPC_C_ANDI_BITS      0b1000100000000001
 | 
				
			||||||
 | 
					#define RVOPC_C_ANDI_MASK      0b1110110000000011
 | 
				
			||||||
 | 
					#define RVOPC_C_SUB_BITS       0b1000110000000001
 | 
				
			||||||
 | 
					#define RVOPC_C_SUB_MASK       0b1111110001100011
 | 
				
			||||||
 | 
					#define RVOPC_C_XOR_BITS       0b1000110000100001
 | 
				
			||||||
 | 
					#define RVOPC_C_XOR_MASK       0b1111110001100011
 | 
				
			||||||
 | 
					#define RVOPC_C_OR_BITS        0b1000110001000001
 | 
				
			||||||
 | 
					#define RVOPC_C_OR_MASK        0b1111110001100011
 | 
				
			||||||
 | 
					#define RVOPC_C_AND_BITS       0b1000110001100001
 | 
				
			||||||
 | 
					#define RVOPC_C_AND_MASK       0b1111110001100011
 | 
				
			||||||
 | 
					#define RVOPC_C_BEQZ_BITS      0b1100000000000001
 | 
				
			||||||
 | 
					#define RVOPC_C_BEQZ_MASK      0b1110000000000011
 | 
				
			||||||
 | 
					#define RVOPC_C_BNEZ_BITS      0b1110000000000001
 | 
				
			||||||
 | 
					#define RVOPC_C_BNEZ_MASK      0b1110000000000011
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define RVOPC_C_SLLI_BITS      0b0000000000000010 // On RV32 imm[5] (instr[12]) must be 0, else reserved NSE.
 | 
				
			||||||
 | 
					#define RVOPC_C_SLLI_MASK      0b1111000000000011
 | 
				
			||||||
 | 
					// jr if !rs2:
 | 
				
			||||||
 | 
					#define RVOPC_C_MV_BITS        0b1000000000000010 // *** reserved if JR and !rs1 (instr[11:7])
 | 
				
			||||||
 | 
					#define RVOPC_C_MV_MASK        0b1111000000000011
 | 
				
			||||||
 | 
					// jalr if !rs2:
 | 
				
			||||||
 | 
					#define RVOPC_C_ADD_BITS       0b1001000000000010 // *** EBREAK if !instr[11:2]
 | 
				
			||||||
 | 
					#define RVOPC_C_ADD_MASK       0b1111000000000011
 | 
				
			||||||
 | 
					#define RVOPC_C_LWSP_BITS      0b0100000000000010
 | 
				
			||||||
 | 
					#define RVOPC_C_LWSP_MASK      0b1110000000000011
 | 
				
			||||||
 | 
					#define RVOPC_C_SWSP_BITS      0b1100000000000010
 | 
				
			||||||
 | 
					#define RVOPC_C_SWSP_MASK      0b1110000000000011
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Zcb simple additional compressed instructions
 | 
				
			||||||
 | 
					#define RVOPC_C_LBU_BITS       0b1000000000000000
 | 
				
			||||||
 | 
					#define RVOPC_C_LBU_MASK       0b1111110000000011
 | 
				
			||||||
 | 
					#define RVOPC_C_LHU_BITS       0b1000010000000000
 | 
				
			||||||
 | 
					#define RVOPC_C_LHU_MASK       0b1111110001000011
 | 
				
			||||||
 | 
					#define RVOPC_C_LH_BITS        0b1000010001000000
 | 
				
			||||||
 | 
					#define RVOPC_C_LH_MASK        0b1111110001000011
 | 
				
			||||||
 | 
					#define RVOPC_C_SB_BITS        0b1000100000000000
 | 
				
			||||||
 | 
					#define RVOPC_C_SB_MASK        0b1111110000000011
 | 
				
			||||||
 | 
					#define RVOPC_C_SH_BITS        0b1000110000000000
 | 
				
			||||||
 | 
					#define RVOPC_C_SH_MASK        0b1111110001000011
 | 
				
			||||||
 | 
					#define RVOPC_C_ZEXT_B_BITS    0b1001110001100001
 | 
				
			||||||
 | 
					#define RVOPC_C_ZEXT_B_MASK    0b1111110001111111
 | 
				
			||||||
 | 
					#define RVOPC_C_SEXT_B_BITS    0b1001110001100101
 | 
				
			||||||
 | 
					#define RVOPC_C_SEXT_B_MASK    0b1111110001111111
 | 
				
			||||||
 | 
					#define RVOPC_C_ZEXT_H_BITS    0b1001110001101001
 | 
				
			||||||
 | 
					#define RVOPC_C_ZEXT_H_MASK    0b1111110001111111
 | 
				
			||||||
 | 
					#define RVOPC_C_SEXT_H_BITS    0b1001110001101101
 | 
				
			||||||
 | 
					#define RVOPC_C_SEXT_H_MASK    0b1111110001111111
 | 
				
			||||||
 | 
					#define RVOPC_C_NOT_BITS       0b1001110001110101
 | 
				
			||||||
 | 
					#define RVOPC_C_NOT_MASK       0b1111110001111111
 | 
				
			||||||
 | 
					#define RVOPC_C_MUL_BITS       0b1001110001000001
 | 
				
			||||||
 | 
					#define RVOPC_C_MUL_MASK       0b1111110001100011
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Zcmp push/pop instructions
 | 
				
			||||||
 | 
					#define RVOPC_CM_PUSH_BITS     0b1011100000000010
 | 
				
			||||||
 | 
					#define RVOPC_CM_PUSH_MASK     0b1111111100000011
 | 
				
			||||||
 | 
					#define RVOPC_CM_POP_BITS      0b1011101000000010
 | 
				
			||||||
 | 
					#define RVOPC_CM_POP_MASK      0b1111111100000011
 | 
				
			||||||
 | 
					#define RVOPC_CM_POPRETZ_BITS  0b1011110000000010
 | 
				
			||||||
 | 
					#define RVOPC_CM_POPRETZ_MASK  0b1111111100000011
 | 
				
			||||||
 | 
					#define RVOPC_CM_POPRET_BITS   0b1011111000000010
 | 
				
			||||||
 | 
					#define RVOPC_CM_POPRET_MASK   0b1111111100000011
 | 
				
			||||||
 | 
					#define RVOPC_CM_MVSA01_BITS   0b1010110000100010
 | 
				
			||||||
 | 
					#define RVOPC_CM_MVSA01_MASK   0b1111110001100011
 | 
				
			||||||
 | 
					#define RVOPC_CM_MVA01S_BITS   0b1010110001100010
 | 
				
			||||||
 | 
					#define RVOPC_CM_MVA01S_MASK   0b1111110001100011
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define _RVOPC_MATCH(x, instr_mask, instr_bits) ((x & instr_mask) == instr_bits)
 | 
				
			||||||
 | 
					#define RVOPC_MATCH(x, instr) _RVOPC_MATCH(x, RVOPC_ ## instr ## _MASK, RVOPC_ ## instr ## _BITS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const char *friendly_reg_names[32] = {
 | 
				
			||||||
 | 
						"x0", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2",
 | 
				
			||||||
 | 
						"a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9",
 | 
				
			||||||
 | 
						"s10", "s11", "t3", "t4", "t5", "t6"
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
		Loading…
	
		Reference in New Issue