Debugging instructions (system mostly)
This commit is contained in:
		@@ -6,5 +6,8 @@ Juraj's Blog, mostly:
 | 
			
		||||
- https://jborza.com/post/2021-04-04-riscv-supervisor-mode/
 | 
			
		||||
- https://jborza.com/emulation/2021/04/22/ecalls-and-syscalls.html
 | 
			
		||||
 | 
			
		||||
RISC-V SBI Specifications:
 | 
			
		||||
- https://github.com/riscv-non-isa/riscv-sbi-doc/releases
 | 
			
		||||
 | 
			
		||||
Buildroot fork for nommu linux:
 | 
			
		||||
- https://github.com/regymm/buildroot
 | 
			
		||||
 
 | 
			
		||||
@@ -60,4 +60,7 @@
 | 
			
		||||
#define FUNC3_OR 0x7
 | 
			
		||||
#define FUNC3_AND 0x8
 | 
			
		||||
 | 
			
		||||
#define IMM_ECALL 0x0
 | 
			
		||||
#define IMM_EBREAK 0x1
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -35,6 +35,8 @@ typedef struct INSTRUCTION
 | 
			
		||||
	uint8_t rs2;
 | 
			
		||||
} instruction_t;
 | 
			
		||||
 | 
			
		||||
static void cpu_print_instruction(instruction_t* instruction);
 | 
			
		||||
 | 
			
		||||
void cpu_init()
 | 
			
		||||
{
 | 
			
		||||
	cpu0 = malloc(sizeof(rv32_cpu_t));
 | 
			
		||||
@@ -99,6 +101,9 @@ static void cpu_decode(raw_instruction_t raw_instruction, instruction_t* output)
 | 
			
		||||
			// Bits of rd are immediate bits 4:0
 | 
			
		||||
			output->immediate |= raw_instruction.rd;
 | 
			
		||||
			break;
 | 
			
		||||
		case OPCODE_NOP:
 | 
			
		||||
			// TODO : Decode NOP instructions
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			fprintf(stderr, "Error: Unknown instruction opcode 0x%x, could not decode\n", raw_instruction.opcode);
 | 
			
		||||
			exit(EXIT_FAILURE);
 | 
			
		||||
@@ -300,12 +305,12 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction)
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_SLLI:
 | 
			
		||||
					// Sign-extend immediate in rs2 from 5 bits to 32 bits
 | 
			
		||||
					immediate = (cpu->regs.x[instruction->rs2] & 0x1F) | (cpu->regs.x[instruction->rs2] & 0x10 ? 0xFFFFFFE0 : 0);
 | 
			
		||||
					immediate = (instruction->rs2 & 0x1F) | (instruction->rs2 & 0x10 ? 0xFFFFFFE0 : 0);
 | 
			
		||||
					cpu->regs.x[instruction->rd] = cpu->regs.x[instruction->rs1] << immediate;
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_SRLI_SRAI:
 | 
			
		||||
					// Sign-extend immediate in rs2 from 5 bits to 32 bits
 | 
			
		||||
					immediate = (cpu->regs.x[instruction->rs2] & 0x1F) | (cpu->regs.x[instruction->rs2] & 0x10 ? 0xFFFFFFE0 : 0);
 | 
			
		||||
					immediate = (instruction->rs2 & 0x1F) | (instruction->rs2 & 0x10 ? 0xFFFFFFE0 : 0);
 | 
			
		||||
					// Analyse func7 to know which is it
 | 
			
		||||
					switch(instruction->func7)
 | 
			
		||||
					{
 | 
			
		||||
@@ -314,10 +319,7 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction)
 | 
			
		||||
							break;
 | 
			
		||||
						case FUNC7_SRAI:
 | 
			
		||||
							// Arithmetic slide
 | 
			
		||||
							uint32_t sign_bit = cpu->regs.x[instruction->rs1] & 0x80000000;
 | 
			
		||||
							cpu->regs.x[instruction->rd] = cpu->regs.x[instruction->rs1] >> immediate;
 | 
			
		||||
							if(sign_bit)
 | 
			
		||||
								cpu->regs.x[instruction->rd] |= ~(0xFFFFFFFF >> immediate);
 | 
			
		||||
							cpu->regs.x[instruction->rd] = ((int32_t) cpu->regs.x[instruction->rs1]) >> immediate;
 | 
			
		||||
							break;
 | 
			
		||||
						default:
 | 
			
		||||
							fprintf(stderr, "FATAL: Unknown func7 0x%x for arithlog immediate SRLI/SRAI instruction, could not execute\n", instruction->func7);
 | 
			
		||||
@@ -392,10 +394,7 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction)
 | 
			
		||||
						case FUNC7_SRA:
 | 
			
		||||
							// Slide Right Arithmetical
 | 
			
		||||
							uint32_t sra_value = cpu->regs.x[instruction->rs2] & 0x1F;
 | 
			
		||||
							uint32_t sign_bit = cpu->regs.x[instruction->rs1] & 0x80000000;
 | 
			
		||||
							cpu->regs.x[instruction->rd] = cpu->regs.x[instruction->rs1] >> sra_value;
 | 
			
		||||
							if(sign_bit)
 | 
			
		||||
								cpu->regs.x[instruction->rd] |= ~(0xFFFFFFFF >> sra_value);
 | 
			
		||||
							cpu->regs.x[instruction->rd] = ((int32_t) cpu->regs.x[instruction->rs1]) >> sra_value;
 | 
			
		||||
							break;
 | 
			
		||||
						default:
 | 
			
		||||
							fprintf(stderr, "FATAL: Unknown func7 0x%x for arithlog SRL/SRA instruction, could not execute\n", instruction->func7);
 | 
			
		||||
@@ -413,11 +412,24 @@ static void cpu_execute(rv32_cpu_t* cpu, instruction_t* instruction)
 | 
			
		||||
		case OPCODE_NOP:
 | 
			
		||||
		{
 | 
			
		||||
			// TODO : Implement PAUSE, FENCE, FENCE.TSO
 | 
			
		||||
			fprintf(stderr, "Warning: Unsupported NOP instruction\n");
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		case OPCODE_SYSTEM:
 | 
			
		||||
		{
 | 
			
		||||
			// TODO : Implement ECALL, EBREAK
 | 
			
		||||
			switch(instruction->immediate)
 | 
			
		||||
			{
 | 
			
		||||
				case IMM_ECALL:
 | 
			
		||||
					fprintf(stderr, "ECALL: a7(sbi ext id) = %d, a6(sbi funct id) = %d\n", cpu->regs.a7, cpu->regs.a6);
 | 
			
		||||
					break;
 | 
			
		||||
				case IMM_EBREAK:
 | 
			
		||||
					fprintf(stderr, "EBREAK\n");
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					fprintf(stderr, "FATAL: Unknown SYSTEM instruction while executing (IMM=0x%x)\n", instruction->immediate);
 | 
			
		||||
					exit(EXIT_FAILURE);
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		default:
 | 
			
		||||
@@ -444,9 +456,296 @@ void cpu_loop(rv32_cpu_t* cpu)
 | 
			
		||||
		instruction_t instruction;
 | 
			
		||||
		cpu_decode(raw_instruction, &instruction);
 | 
			
		||||
 | 
			
		||||
		cpu_print_instruction(&instruction);
 | 
			
		||||
 | 
			
		||||
		// Execute
 | 
			
		||||
		cpu_execute(cpu, &instruction);
 | 
			
		||||
 | 
			
		||||
		cpu->pc += 4;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void cpu_print_instruction(instruction_t* instruction)
 | 
			
		||||
{
 | 
			
		||||
	switch(instruction->opcode)
 | 
			
		||||
	{
 | 
			
		||||
		case OPCODE_LUI:
 | 
			
		||||
		{
 | 
			
		||||
			// Load Upper Immediate (load immediate(31:12 bits) in rd)
 | 
			
		||||
			printf("lui x%u, 0x%x\n", instruction->rd, instruction->immediate);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		case OPCODE_AUIPC:
 | 
			
		||||
		{
 | 
			
		||||
			// Add Upper Immediate to PC
 | 
			
		||||
			printf("auipc x%u, 0x%x\n", instruction->rd, instruction->immediate);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		case OPCODE_JAL:
 | 
			
		||||
		{
 | 
			
		||||
			// Jump And Link
 | 
			
		||||
			// Sign extend immediate from 21 bits to 32 bits
 | 
			
		||||
			uint32_t immediate = (instruction->immediate & 0x1FFFFF) | (instruction->immediate & 0x100000 ? 0xFFE00000 : 0);
 | 
			
		||||
			printf("jal x%u, 0x%x\n", instruction->rd, immediate);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		case OPCODE_JALR:
 | 
			
		||||
		{
 | 
			
		||||
			// Jump And Link Register
 | 
			
		||||
			// Sign extend immediate from 12 bits to 32 bits
 | 
			
		||||
			uint32_t immediate = (instruction->immediate & 0xFFF) | (instruction->immediate & 0x800 ? 0xFFFFF000 : 0);
 | 
			
		||||
			printf("jalr x%u, x%u, 0x%x\n", instruction->rd, instruction->rs1, immediate);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		case OPCODE_BRANCH:
 | 
			
		||||
		{
 | 
			
		||||
			// Branches ; to know which one, we must analyse func3
 | 
			
		||||
			// Sign extend immediate from 13 bits to 32 bits
 | 
			
		||||
			uint32_t immediate = (instruction->immediate & 0xFFF) | (instruction->immediate & 0x1000 ? 0xFFFFE000 : 0);
 | 
			
		||||
			immediate -= 4;
 | 
			
		||||
 | 
			
		||||
			switch(instruction->func3)
 | 
			
		||||
			{
 | 
			
		||||
				case FUNC3_BEQ:
 | 
			
		||||
					// Branch EQual
 | 
			
		||||
					printf("beq x%u, x%u, 0x%x\n", instruction->rs1, instruction->rs2, immediate);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_BNE:
 | 
			
		||||
					// Branch Not Equal
 | 
			
		||||
					printf("bne x%u, x%u, 0x%x\n", instruction->rs1, instruction->rs2, immediate);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_BLT:
 | 
			
		||||
					// Branch Less Than
 | 
			
		||||
					printf("blt x%u, x%u, %d\n", instruction->rs1, instruction->rs2, (int32_t) immediate);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_BLTU:
 | 
			
		||||
					// Branch Less Than Unsigned
 | 
			
		||||
					printf("bltu x%u, x%u, 0x%x\n", instruction->rs1, instruction->rs2, immediate);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_BGE:
 | 
			
		||||
					// Branch Greater Equal
 | 
			
		||||
					printf("bge x%u, x%u, %d\n", instruction->rs1, instruction->rs2, (int32_t) immediate);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_BGEU:
 | 
			
		||||
					// Branch Greater Equal Unsigned
 | 
			
		||||
					printf("bgeu x%u, x%u, 0x%x\n", instruction->rs1, instruction->rs2, immediate);
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					fprintf(stderr, "Warning: Unknown func3 0x%x for branch instruction\n", instruction->func3);
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		case OPCODE_LOAD:
 | 
			
		||||
		{
 | 
			
		||||
			// Loads ; to know which one, we must analyse func3
 | 
			
		||||
			// Sign extend immediate from 12 bits to 32 bits
 | 
			
		||||
			uint32_t immediate = (instruction->immediate & 0xFFF) | (instruction->immediate & 0x800 ? 0xFFFFF000 : 0);
 | 
			
		||||
 | 
			
		||||
			switch(instruction->func3)
 | 
			
		||||
			{
 | 
			
		||||
				case FUNC3_LB:
 | 
			
		||||
					printf("lb x%u, x%u, 0x%x\n", instruction->rd, instruction->rs1, immediate);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_LH:
 | 
			
		||||
					// Load Halfword (16-bits)
 | 
			
		||||
					printf("lh x%u, x%u, 0x%x\n", instruction->rd, instruction->rs1, immediate);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_LW:
 | 
			
		||||
					// Load Word (32-bits)
 | 
			
		||||
					printf("lw x%u, x%u, 0x%x\n", instruction->rd, instruction->rs1, immediate);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_LBU:
 | 
			
		||||
					// Load Byte Unsigned (8-bits)
 | 
			
		||||
					printf("lbu x%u, x%u, 0x%x\n", instruction->rd, instruction->rs1, immediate);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_LHU:
 | 
			
		||||
					// Load Halfword Unsigned (16-bits)
 | 
			
		||||
					printf("lhu x%u, x%u, 0x%x\n", instruction->rd, instruction->rs1, immediate);
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					fprintf(stderr, "Warning: Unknown func3 0x%x for load instruction\n", instruction->func3);
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		case OPCODE_STORE:
 | 
			
		||||
		{
 | 
			
		||||
			// Store ; to know which one, we must analyse func3
 | 
			
		||||
			// Sign extend immediate from 12 bits to 32 bits
 | 
			
		||||
			uint32_t immediate = (instruction->immediate & 0xFFF) | (instruction->immediate & 0x800 ? 0xFFFFF000 : 0);
 | 
			
		||||
 | 
			
		||||
			switch(instruction->func3)
 | 
			
		||||
			{
 | 
			
		||||
				case FUNC3_SB:
 | 
			
		||||
					// Store Byte (8-bits)
 | 
			
		||||
					printf("sb x%u, x%u, 0x%x\n", instruction->rs1, instruction->rs2, immediate);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_SH:
 | 
			
		||||
					// Store Halfword (16-bits)
 | 
			
		||||
					printf("sh x%u, x%u, 0x%x\n", instruction->rs1, instruction->rs2, immediate);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_SW:
 | 
			
		||||
					// Store Word (32-bits)
 | 
			
		||||
					printf("sw x%u, x%u, 0x%x\n", instruction->rs1, instruction->rs2, immediate);
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					fprintf(stderr, "Warning: Unknown func3 0x%x for store instruction\n", instruction->func3);
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		case OPCODE_ARITHLOG_IMM:
 | 
			
		||||
		{
 | 
			
		||||
			// Arithmetic and logic instructions on immediate values
 | 
			
		||||
			// To find out which operation, we must analyse func3
 | 
			
		||||
			// Sign extend immediate from 12 bits to 32 bits
 | 
			
		||||
			uint32_t immediate = (instruction->immediate & 0xFFF) | (instruction->immediate & 0x800 ? 0xFFFFF000 : 0);
 | 
			
		||||
 | 
			
		||||
			switch(instruction->func3)
 | 
			
		||||
			{
 | 
			
		||||
				case FUNC3_ADDI:
 | 
			
		||||
					// ADD Immediate
 | 
			
		||||
					printf("addi x%u, x%u, 0x%x\n", instruction->rd, instruction->rs1, immediate);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_SLTI:
 | 
			
		||||
					// Set Less Than Immediate
 | 
			
		||||
					printf("slti x%u, x%u, 0x%x\n", instruction->rd, instruction->rs1, immediate);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_SLTIU:
 | 
			
		||||
					printf("sltiu x%u, x%u, 0x%x\n", instruction->rd, instruction->rs1, immediate);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_XORI:
 | 
			
		||||
					// XOR Immediate
 | 
			
		||||
					printf("xori x%u, x%u, 0x%x\n", instruction->rd, instruction->rs1, immediate);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_ORI:
 | 
			
		||||
					// OR Immediate
 | 
			
		||||
					printf("ori x%u, x%u, 0x%x\n", instruction->rd, instruction->rs1, immediate);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_ANDI:
 | 
			
		||||
					// AND Immediate
 | 
			
		||||
					printf("andi x%u, x%u, 0x%x\n", instruction->rd, instruction->rs1, immediate);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_SLLI:
 | 
			
		||||
					// Sign-extend immediate in rs2 from 5 bits to 32 bits
 | 
			
		||||
					immediate = (instruction->rs2 & 0x1F) | (instruction->rs2 & 0x10 ? 0xFFFFFFE0 : 0);
 | 
			
		||||
					printf("slli x%u, x%u, %u\n", instruction->rd, instruction->rs1, immediate);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_SRLI_SRAI:
 | 
			
		||||
					// Sign-extend immediate in rs2 from 5 bits to 32 bits
 | 
			
		||||
					immediate = (instruction->rs2 & 0x1F) | (instruction->rs2 & 0x10 ? 0xFFFFFFE0 : 0);
 | 
			
		||||
					// Analyse func7 to know which is it
 | 
			
		||||
					switch(instruction->func7)
 | 
			
		||||
					{
 | 
			
		||||
						case FUNC7_SRLI:
 | 
			
		||||
							printf("srli x%u, x%u, %u\n", instruction->rd, instruction->rs1, immediate);
 | 
			
		||||
							break;
 | 
			
		||||
						case FUNC7_SRAI:
 | 
			
		||||
							// Arithmetic slide
 | 
			
		||||
							printf("srai x%u, x%u, %u\n", instruction->rd, instruction->rs1, immediate);
 | 
			
		||||
							break;
 | 
			
		||||
						default:
 | 
			
		||||
							fprintf(stderr, "Warning: Unknown func7 0x%x for arithlog immediate SRLI/SRAI instruction\n", instruction->func7);
 | 
			
		||||
							break;
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					fprintf(stderr, "Warning: Unknown func3 0x%x for arithlog immediate instruction, could not execute\n", instruction->func3);
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		case OPCODE_ARITHLOG:
 | 
			
		||||
		{
 | 
			
		||||
			// Arithmetic and logic instructions
 | 
			
		||||
			// To find out which operation, we must analyse func3 and func7
 | 
			
		||||
			switch(instruction->func3)
 | 
			
		||||
			{
 | 
			
		||||
				case FUNC3_ADD_SUB:
 | 
			
		||||
					switch(instruction->func7)
 | 
			
		||||
					{
 | 
			
		||||
						case FUNC7_ADD:
 | 
			
		||||
							printf("add x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
 | 
			
		||||
							break;
 | 
			
		||||
						case FUNC7_SUB:
 | 
			
		||||
							printf("sub x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
 | 
			
		||||
							break;
 | 
			
		||||
						default:
 | 
			
		||||
							fprintf(stderr, "Warning: Unknown func7 0x%x for arithlog ADD/SUB instruction, could not execute\n", instruction->func7);
 | 
			
		||||
							break;
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_SLL:
 | 
			
		||||
					// Slide Left Logical
 | 
			
		||||
					printf("sll x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_SLT:
 | 
			
		||||
					// Set Less Than
 | 
			
		||||
					printf("slt x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_SLTIU:
 | 
			
		||||
					// Set Less Than Unsigned
 | 
			
		||||
					printf("sltu x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_XOR:
 | 
			
		||||
					printf("xor x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_OR:
 | 
			
		||||
					printf("or x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_AND:
 | 
			
		||||
					printf("and x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
 | 
			
		||||
					break;
 | 
			
		||||
				case FUNC3_SRL_SRA:
 | 
			
		||||
					switch(instruction->func7)
 | 
			
		||||
					{
 | 
			
		||||
						case FUNC7_SRL:
 | 
			
		||||
							// Slide Right Logical
 | 
			
		||||
							printf("srl x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
 | 
			
		||||
							break;
 | 
			
		||||
						case FUNC7_SRA:
 | 
			
		||||
							// Slide Right Arithmetical
 | 
			
		||||
							printf("sra x%u, x%u, x%u\n", instruction->rd, instruction->rs1, instruction->rs2);
 | 
			
		||||
							break;
 | 
			
		||||
						default:
 | 
			
		||||
							fprintf(stderr, "Warning: Unknown func7 0x%x for arithlog SRL/SRA instruction\n", instruction->func7);
 | 
			
		||||
							exit(EXIT_FAILURE);
 | 
			
		||||
							break;
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					fprintf(stderr, "Warning: Unknown func3 0x%x for arithlog instruction\n", instruction->func3);
 | 
			
		||||
					exit(EXIT_FAILURE);
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		case OPCODE_NOP:
 | 
			
		||||
		{
 | 
			
		||||
			// TODO : Implement PAUSE, FENCE, FENCE.TSO
 | 
			
		||||
			fprintf(stderr, "Warning: Unsupported NOP instruction\n");
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		case OPCODE_SYSTEM:
 | 
			
		||||
		{
 | 
			
		||||
			switch(instruction->immediate)
 | 
			
		||||
			{
 | 
			
		||||
				case IMM_ECALL:
 | 
			
		||||
					printf("ecall\n");
 | 
			
		||||
					break;
 | 
			
		||||
				case IMM_EBREAK:
 | 
			
		||||
					printf("ebreak\n");
 | 
			
		||||
					break;
 | 
			
		||||
				default:
 | 
			
		||||
					fprintf(stderr, "Warning: Unknown SYSTEM instruction (IMM=0x%x)\n", instruction->immediate);
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		default:
 | 
			
		||||
			fprintf(stderr, "Warning: Unknown instruction opcode 0x%x while printing\n", instruction->opcode);
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user