From abb6c10f3a5be99396c303e60d286606ddc72e17 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Fri, 19 Nov 2010 14:06:15 +0100 Subject: Implement memory load/store operations --- instruction.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 6 deletions(-) (limited to 'instruction.c') diff --git a/instruction.c b/instruction.c index 133470d..0ab99c8 100644 --- a/instruction.c +++ b/instruction.c @@ -84,11 +84,16 @@ static int ldbu(struct nios2 *cpu, uint32_t code) { I_TYPE(instr, code); uint32_t *gp_regs = cpu->gp_regs; - int32_t addr = gp_regs[instr->a] + (int16_t) instr->imm16; + uint32_t addr = gp_regs[instr->a] + (int16_t) instr->imm16; + uint8_t byte; - gp_regs[instr->b] = memory_get_byte(cpu->mem, addr); + if (nios2_load_byte(cpu, addr, &byte)) + return INSTR_ERR; + + gp_regs[instr->b] = (uint32_t) byte; return PC_INC_NORMAL; + } /* rB <- rA + IMM16 */ @@ -102,12 +107,41 @@ static int addi(struct nios2 *cpu, uint32_t code) return PC_INC_NORMAL; } +/* Mem8[rA + @(IMM16)] <- rB(7..0) */ +static int stb(struct nios2 *cpu, uint32_t code) +{ + I_TYPE(instr, code); + uint32_t *gp_regs = cpu->gp_regs; + uint32_t addr = gp_regs[instr->a] + (int16_t) instr->imm16; + + if (nios2_store_byte(cpu, addr, gp_regs[instr->b] & 0xFF)) + return INSTR_ERR; + + return PC_INC_NORMAL; +} + /* PC <- PC + 4 + IMM16 */ static int br(struct nios2 *cpu, uint32_t code) { I_TYPE(instr, code); - cpu->pc += 4 + (instr->imm16 & 0xFFFC); + cpu->pc += 4 + (int16_t)(instr->imm16 & 0xFFFC); + + return PC_INC_NORMAL; +} + +/* rB <- @(Mem8[rA + @(IMM16)]) */ +static int ldb(struct nios2 *cpu, uint32_t code) +{ + I_TYPE(instr, code); + uint32_t *gp_regs = cpu->gp_regs; + uint32_t addr = gp_regs[instr->a] + (int16_t) instr->imm16; + uint8_t byte; + + if (nios2_load_byte(cpu, addr, &byte)) + return INSTR_ERR; + + gp_regs[instr->b] = (int32_t) byte; return PC_INC_NORMAL; } @@ -227,6 +261,19 @@ static int blt(struct nios2 *cpu, uint32_t code) return PC_INC_BY_INSTR; } +/* rB <- @(Mem32[rA + @(IMM16)]) */ +static int ldw(struct nios2 *cpu, uint32_t code) +{ + I_TYPE(instr, code); + uint32_t *gp_regs = cpu->gp_regs; + uint32_t addr = gp_regs[instr->a] + (int16_t) instr->imm16; + + if (nios2_load_word(cpu, addr, &gp_regs[instr->b])) + return INSTR_ERR; + + return PC_INC_NORMAL; +} + /* rB <- rA ^ IMM16 */ static int xori(struct nios2 *cpu, uint32_t code) { @@ -359,9 +406,9 @@ static struct instruction i_type_instructions[I_TYPE_COUNT] = { [JMPI] = INSTRUCTION(jmpi), [LDBU] = INSTRUCTION(ldbu), [ADDI] = INSTRUCTION(addi), - [STB] = INSTRUCTION_UNIMPLEMENTED(stb), + [STB] = INSTRUCTION(stb), [BR] = INSTRUCTION(br), - [LDB] = INSTRUCTION_UNIMPLEMENTED(ldb), + [LDB] = INSTRUCTION(ldb), [CMPGEI] = INSTRUCTION_UNIMPLEMENTED(cmpgei), [LDHU] = INSTRUCTION(ldhu), [ANDI] = INSTRUCTION(andi), @@ -373,7 +420,7 @@ static struct instruction i_type_instructions[I_TYPE_COUNT] = { [ORI] = INSTRUCTION(ori), [STW] = INSTRUCTION(stw), [BLT] = INSTRUCTION(blt), - [LDW] = INSTRUCTION_UNIMPLEMENTED(ldw), + [LDW] = INSTRUCTION(ldw), [CMPNEI] = INSTRUCTION_UNIMPLEMENTED(cmpnei), [FLUSHDA] = INSTRUCTION_NOP(flushda), [XORI] = INSTRUCTION(xori), -- cgit v1.2.3-54-g00ecf