rvemu

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit e4f8168882930df9b5947a9ac146cb176c4fad53
parent c2e829caab204946155130c494312cf543871f68
Author: Michail Konstantinos Dimopoulos <mk@mcdim.xyz>
Date:   Sun, 22 Mar 2026 01:07:16 +0200

Stores added

Diffstat:
Mmain.c | 179+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 170 insertions(+), 9 deletions(-)

diff --git a/main.c b/main.c @@ -2,6 +2,9 @@ #include <stdio.h> #include <stdlib.h> +#define MEMSIZE 2052 + + typedef struct { uint32_t x[32]; /* general purpose registers */ uint32_t pc; @@ -15,11 +18,19 @@ typedef struct { typedef struct { uint8_t opcode; - uint8_t rd, rs1, imm; + uint8_t rd, rs1; + uint16_t imm; uint8_t funct3; uint8_t funct7, inimm; } itype_t; +typedef struct { + uint8_t opcode; + uint8_t rs1, rs2; + uint16_t imm; + uint8_t funct3; +} stype_t; + void print_bin16(uint16_t x) { for (int i = 15; i >= 0; i--) { putchar((x >> i) & 1 ? '1' : '0'); @@ -61,7 +72,7 @@ void exec_itype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { /**print**/ printf("f7 rs2 rs1 f3 rd opcode\n"); - print_binless(i.imm, 11); + print_binless(i.imm, 12); printf(" "); print_binless(i.rs1, 5); printf(" "); @@ -264,7 +275,7 @@ void exec_ltype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { /**print**/ printf("imm rs1 f3 rd opcode\n"); - print_binless(i.imm, 11); + print_binless(i.imm, 12); printf(" "); print_binless(i.rs1, 5); printf(" "); @@ -274,19 +285,127 @@ void exec_ltype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { printf("\n"); /*********/ + int32_t addr = i.imm + cpu->x[i.rs1]; + + /* TODO: do I need to check before loading halves and words */ + int32_t x; switch(i.funct3) { case 0x0: - x = (int8_t)mem[i.imm+i.rs1]; + printf("Load byte\n"); + x = (uint32_t)(int32_t)(int8_t)mem[addr]; break; + case 0x1: + printf("Load half, little endian\n"); + uint16_t half = (uint16_t)mem[addr] | ((uint16_t)mem[addr+1] << 8); + x = (uint32_t)(int32_t)(int16_t)half; + break; + case 0x2: + printf("Load word, little endian"); + x = (uint32_t)(int32_t)( + ((uint16_t)mem[addr] | ((uint16_t)mem[addr+1] << 8)) + | + (((uint16_t)mem[addr+2] | ((uint16_t)mem[addr+3] << 8)) + << 16) + ); + break; + case 0x4: + printf("Load byte (U) zero-extends\n"); + x = (uint32_t)(uint32_t)(uint8_t)mem[addr]; + break; + + case 0x5: + printf("Load half, little endian\n"); + int16_t uhalf = (int16_t)mem[addr] | ((int16_t)mem[addr+1] << 8); + x = (uint32_t)(int32_t)uhalf; + break; + default: + fprintf(stderr, "Illegal funct3\n"); + return; } if (i.rd != 0) { cpu->x[i.rd] = x; } - printf("rd:%d\n", cpu->x[i.rd]); + printf("\nrd:%d\n", cpu->x[i.rd]); + printf("rd:%x\n", cpu->x[i.rd]); + +} + +/* +S-TYPE INSTRUCTION FORMAT +31 25 24 20 19 15 14 12 11 7 6 0 ++------------+--------+--------+--------+---------+--------+ +| imm[11:0] | rs2 | rs1 | funct3 |imm[4:0] | opcode | ++------------+--------+--------+--------+---------+--------+ +opcode 0x33 0100011 +*/ +void exec_stype(cpu_state_t *cpu, uint32_t inst, uint8_t *mem) { + printf("TYPE S\n"); + stype_t s; + + uint32_t imm_11_5 = (inst >> 25) & 127; + uint32_t imm_4_0 = (inst >> 7) & 31; + s.imm = (imm_4_0) | (imm_11_5 << 5); + + s.funct3 = (inst >> 12) & 7; + s.rs1 = (inst >> 15) & 31; + s.rs2 = (inst >> 20) & 31; + + printf("\nimm:%x\n", s.imm); + + /**print**/ + printf("imm rs2 rs1 f3 imm opcode\n"); + printf("[11:5] [4:0]\n"); + print_binless(imm_11_5, 7); + printf(" "); + print_binless(s.rs2, 5); + printf(" "); + print_binless(s.rs1, 5); + printf(" "); + print_binless(s.funct3, 3); + printf(" "); + print_binless(imm_4_0, 5); + printf("\n"); + /*********/ + + uint32_t addr = s.imm + cpu->x[s.rs1]; + switch(s.funct3) { + case 0x0: + printf("STORE BYTE\n"); + mem[addr] = cpu->x[s.rs2] & 255; + break; + case 0x1: + printf("STORE half, little endian\n"); + if (addr+1 > MEMSIZE-1) { + fprintf(stderr, "Illegal addr\n"); + return; + } + + if (addr % 2 == 0) { + mem[addr] = cpu->x[s.rs2]; + mem[addr+1] = cpu->x[s.rs2] >> 8; + } + break; + case 0x2: + printf("STORE word, little endian\n"); + if (addr+3 > MEMSIZE-1) { + fprintf(stderr, "Illegal addr\n"); + return; + } + if (addr % 4 == 0) { + mem[addr] = cpu->x[s.rs2]; + mem[addr+1] = cpu->x[s.rs2] >> 8; + mem[addr+2] = cpu->x[s.rs2] >> 16; + mem[addr+3] = cpu->x[s.rs2] >> 24; + } + break; + default: + fprintf(stderr, "Illegal funct3\n"); + return; + } } int main() { @@ -298,6 +417,7 @@ int main() { opcode_table[0x33] = exec_rtype; opcode_table[0x13] = exec_itype; opcode_table[0x03] = exec_ltype; + opcode_table[0x23] = exec_stype; /*opcode_table[0x13] = exec_rtype_imm; opcode_table[0x03] = exec_load; opcode_table[0x23] = exec_store; @@ -336,16 +456,44 @@ int main() { // imm rs1 f3 rd opcode // 000000000101 00010 111 00011 0010011 - //inst = 0x517193; /* ANDi 101 */ + inst = 0x517193; /* ANDi 101 */ // imm rs1 f3 rd opcode // 000000000001 00010 101 00011 0010011 - //inst = 0x115193; /* shift logical right i 1*/ + inst = 0x115193; /* shift logical right i 1*/ // imm rs1 f3 rd opcode // 011111111111 00000 000 00011 0000011 inst = 0x100183; /* LOAD Byte from address 0x3*/ + // imm rs1 f3 rd opcode + // 000000000000 00000 001 00011 0000011 + inst = 0x1183; /* LOAD half from address 0x0*/ + + // imm rs1 f3 rd opcode + // 000000000000 00000 010 00011 0000011 + inst = 0x2183; /* LOAD word from address 0x0*/ + + // imm rs1 rs2 f3 imm opcode + // [11:5] [4:0] + // 0000000 00000 00000 000 00000 0100011 + inst = 0x23; /* STORE rs2 contents to mem 0x0*/ + + // imm rs2 rs1 f3 imm opcode + // [11:5] [4:0] + // 0000000 00000 00000 000 00010 0100011 + inst = 0xA3; /* STORE rs2 contents to mem 0x0*/ + + // imm rs2 rs1 f3 imm opcode + // [11:5] [4:0] + // 0000000 00000 00000 010 00100 0100011 + inst = 0x2223; /* STORE rs2 contents to mem 0x04 (word)*/ + + // imm rs2 rs1 f3 imm opcode + // [11:5] [4:0] + // 0000000 00000 00000 010 00011 0100011 + inst = 0x21A3; /* STORE rs2 contents to mem 0x03, FAIL (word)*/ + print_bin32(inst); printf("\n"); @@ -357,12 +505,22 @@ int main() { exec_fn fn = opcode_table[opcode]; cpu_state_t cpu; + /* init cpu state */ + for (int i=0; i<32; i++) { + cpu.x[i] = 0; + } cpu.x[1] = 51; - cpu.x[2] = 14; - uint8_t mem[2056] = {0}; + cpu.x[2] = 00; + + uint8_t mem[MEMSIZE] = {0}; + /* set mem for test */ for (int i=0; i<2056; i++) { mem[i] = (uint8_t)i; } + for (int i=0; i<32; i++) { + printf("0x%x: 0x%x\n", i, mem[i]); + } + if (!fn) { //illegal(NULL, inst); @@ -371,6 +529,9 @@ int main() { } fn(&cpu,inst,mem); + for (int i=0; i<32; i++) { + printf("0x%x: 0x%x\n", i, mem[i]); + } return 0; }