summaryrefslogtreecommitdiff
path: root/instruction.c
diff options
context:
space:
mode:
authorTobias Klauser <tklauser@distanz.ch>2010-11-19 14:06:15 +0100
committerTobias Klauser <tklauser@distanz.ch>2010-11-19 14:06:15 +0100
commitabb6c10f3a5be99396c303e60d286606ddc72e17 (patch)
tree0b3316ca032be864cdb10cfca15c12f57bdda9c0 /instruction.c
parentee8bd1d0bd8f243cba595623050815afe411b7b0 (diff)
Implement memory load/store operations
Diffstat (limited to 'instruction.c')
-rw-r--r--instruction.c59
1 files changed, 53 insertions, 6 deletions
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),