summaryrefslogtreecommitdiff
path: root/instruction.c
diff options
context:
space:
mode:
Diffstat (limited to 'instruction.c')
-rw-r--r--instruction.c50
1 files changed, 39 insertions, 11 deletions
diff --git a/instruction.c b/instruction.c
index 0ab99c8..6fd06dc 100644
--- a/instruction.c
+++ b/instruction.c
@@ -60,7 +60,7 @@ static int call(struct nios2 *cpu, uint32_t code)
J_TYPE(instr, code);
cpu->gp_regs[ra] = cpu->pc + 4;
- cpu->pc = (instr->imm26 * 4) | (cpu->pc & 0xF0000000);
+ cpu->pc = (cpu->pc & 0xF0000000) | (instr->imm26 * 4);
return PC_INC_BY_INSTR;
}
@@ -70,7 +70,7 @@ static int jmpi(struct nios2 *cpu, uint32_t code)
{
J_TYPE(instr, code);
- cpu->pc = (instr->imm26 * 4) | (cpu->pc & 0xF0000000);
+ cpu->pc = (cpu->pc & 0xF0000000) | (instr->imm26 * 4);
return PC_INC_BY_INSTR;
}
@@ -87,7 +87,7 @@ static int ldbu(struct nios2 *cpu, uint32_t code)
uint32_t addr = gp_regs[instr->a] + (int16_t) instr->imm16;
uint8_t byte;
- if (nios2_load_byte(cpu, addr, &byte))
+ if (nios2_load(cpu, addr, &byte, 1))
return INSTR_ERR;
gp_regs[instr->b] = (uint32_t) byte;
@@ -113,8 +113,9 @@ 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;
+ uint8_t data = gp_regs[instr->b] & 0xFF;
- if (nios2_store_byte(cpu, addr, gp_regs[instr->b] & 0xFF))
+ if (nios2_store(cpu, addr, &data, 1))
return INSTR_ERR;
return PC_INC_NORMAL;
@@ -138,7 +139,7 @@ static int ldb(struct nios2 *cpu, uint32_t code)
uint32_t addr = gp_regs[instr->a] + (int16_t) instr->imm16;
uint8_t byte;
- if (nios2_load_byte(cpu, addr, &byte))
+ if (nios2_load(cpu, addr, &byte, 1))
return INSTR_ERR;
gp_regs[instr->b] = (int32_t) byte;
@@ -146,10 +147,37 @@ static int ldb(struct nios2 *cpu, uint32_t code)
return PC_INC_NORMAL;
}
-/* */
-static int ldhu(struct nios2 *cpu __unused, uint32_t code __unused)
+/*
+ * if ((signed) rA >= (signed) @(IMM16))
+ * rB <- 1
+ * else
+ * rB <- 0
+ */
+static int cmpgei(struct nios2 *cpu, uint32_t code)
{
- /* TODO */
+ I_TYPE(instr, code);
+ uint32_t *gp_regs = cpu->gp_regs;
+
+ if ((int32_t) gp_regs[instr->a] >= (int32_t) ((int16_t) instr->imm16))
+ gp_regs[instr->b] = 1;
+ else
+ gp_regs[instr->b] = 0;
+
+ return PC_INC_NORMAL;
+}
+
+/* rB <- 0x0000 : Mem16[rA + @IMM16)] */
+static int ldhu(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;
+ uint16_t halfword;
+
+ if (nios2_load(cpu, addr, &halfword, 2))
+ return INSTR_ERR;
+
+ gp_regs[instr->b] = (int32_t) halfword;
return PC_INC_NORMAL;
}
@@ -199,7 +227,7 @@ static int ldh(struct nios2 *cpu __unused, uint32_t code __unused)
}
/*
- * if ((signed) rA < (signed) @(IMM16)
+ * if ((signed) rA < (signed) @(IMM16))
* rB <- 1
* else
* rB <- 0
@@ -268,7 +296,7 @@ static int ldw(struct nios2 *cpu, uint32_t 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]))
+ if (nios2_load(cpu, addr, &gp_regs[instr->b], 4))
return INSTR_ERR;
return PC_INC_NORMAL;
@@ -409,7 +437,7 @@ static struct instruction i_type_instructions[I_TYPE_COUNT] = {
[STB] = INSTRUCTION(stb),
[BR] = INSTRUCTION(br),
[LDB] = INSTRUCTION(ldb),
- [CMPGEI] = INSTRUCTION_UNIMPLEMENTED(cmpgei),
+ [CMPGEI] = INSTRUCTION(cmpgei),
[LDHU] = INSTRUCTION(ldhu),
[ANDI] = INSTRUCTION(andi),
[STH] = INSTRUCTION(sth),