diff --git a/cpu.go b/cpu.go index 9d201c5..523285e 100644 --- a/cpu.go +++ b/cpu.go @@ -238,7 +238,36 @@ func (c *CPUState) Step() error { case 0b0100011: // SB/SH/SW - panic("todo") + + imm := ((opcode >> 7) & 0b11111) | (((opcode >> 25) & 0b1111111) << 5) + memAddr := c.Registers[opcode_rs1(opcode)] + imm + + // The SW, SH, and SB instructions store 32-bit, 16-bit, and 8-bit values from the low bits of register + // rs2 to memory. + funct3 := (opcode >> 12) & 0b111 + switch funct3 { + case 0b000: + // SB + err := c.w.WriteByte(memAddr, byte(c.Registers[opcode_rs2(opcode)])) + if err != nil { + return err + } + + case 0b001: + // SH + err := c.w.Write16(memAddr, uint16(c.Registers[opcode_rs2(opcode)])) + if err != nil { + return err + } + case 0b010: + // SW + err := c.w.Write32(memAddr, c.Registers[opcode_rs2(opcode)]) + if err != nil { + return err + } + default: + return ErrInvalidOpcode{} + } case 0b0010011: // ADDI/SLTI/SLTIU/XORI/ORI/ANDI/SLLI/SLRI/SRAI