163 lines
3.0 KiB
C
163 lines
3.0 KiB
C
/*
|
|
* Source file for load/store operations.
|
|
*
|
|
* CAR (Cool ARM Ripoff) copyright (c) 2026 David J Goeke. All rights reserved.
|
|
* Unauthorized (re)distribution is prohibited.
|
|
*/
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
|
|
#include "include/defs.h"
|
|
|
|
|
|
DEFINE_OP(ldr)
|
|
{
|
|
ls_instruction_t i = convert_raw2ls(ri);
|
|
|
|
uint8_t reg = i.reg;
|
|
|
|
uint32_t dest;
|
|
uint32_t addr = state->pc + i.imm;
|
|
|
|
//assert(addr < state->memory_size);
|
|
if (addr >= state->memory_size)
|
|
{
|
|
printf("addr >= state->memory_size!\n");
|
|
//OP_RETURN_EXITING_ERROR
|
|
}
|
|
|
|
printf("loading register %i with value from address 0x%04x, imm: 0x%04x\n", reg, addr, i.imm);
|
|
|
|
memcpy(&dest, state->memory + addr, sizeof(dest));
|
|
|
|
state->gprs[reg] = dest;
|
|
|
|
OP_RETURN_NORMAL
|
|
}
|
|
|
|
DEFINE_OP(lds)
|
|
{
|
|
ls_instruction_t i = convert_raw2ls(ri);
|
|
|
|
uint8_t reg = i.reg;
|
|
|
|
uint32_t dest;
|
|
uint32_t addr = state->sp + i.imm;
|
|
|
|
memcpy(&dest, state->memory + addr, sizeof(dest));
|
|
|
|
state->gprs[reg] = dest;
|
|
|
|
OP_RETURN_NORMAL
|
|
}
|
|
|
|
DEFINE_OP(ldb)
|
|
{
|
|
ls_instruction_t i = convert_raw2ls(ri);
|
|
|
|
uint8_t reg = i.reg;
|
|
|
|
uint32_t dest;
|
|
uint32_t base_value = state->gprs[get_reg_from_imm(i.imm)];
|
|
uint32_t addr = base_value + (uint32_t) get_imm_from_imm(i.imm);
|
|
|
|
memcpy(&dest, state->memory + addr, sizeof(dest));
|
|
|
|
state->gprs[reg] = dest;
|
|
|
|
OP_RETURN_NORMAL
|
|
}
|
|
|
|
DEFINE_OP(ldi)
|
|
{
|
|
ls_instruction_t i = convert_raw2ls(ri);
|
|
|
|
uint8_t reg = i.reg;
|
|
|
|
//uint32_t value = (i.imm) & 0b111111111111111111111; // should convert this to hex
|
|
uint32_t value = i.imm;
|
|
|
|
#ifdef _DEBUG
|
|
printf("In ldi, reg: 0b%05b, imm: 0x%x\n", reg, value);
|
|
#endif
|
|
|
|
state->gprs[reg] |= value;
|
|
|
|
OP_RETURN_NORMAL
|
|
}
|
|
|
|
DEFINE_OP(str)
|
|
{
|
|
ls_instruction_t i = convert_raw2ls(ri);
|
|
|
|
uint32_t value = state->gprs[i.reg];
|
|
uint32_t addr = state->pc + i.imm;
|
|
|
|
memcpy(state->memory + addr, &value, sizeof(value));
|
|
|
|
OP_RETURN_NORMAL
|
|
}
|
|
|
|
DEFINE_OP(sts)
|
|
{
|
|
ls_instruction_t i = convert_raw2ls(ri);
|
|
|
|
uint32_t value = state->gprs[i.reg];
|
|
uint32_t addr = state->sp + i.imm;
|
|
|
|
memcpy(state->memory + addr, &value, sizeof(value));
|
|
|
|
OP_RETURN_NORMAL
|
|
}
|
|
|
|
DEFINE_OP(stb)
|
|
{
|
|
ls_instruction_t i = convert_raw2ls(ri);
|
|
|
|
uint32_t value = state->gprs[i.reg];
|
|
uint32_t base_value = state->gprs[get_reg_from_imm(i.imm)];
|
|
uint32_t addr = base_value + (uint32_t) get_imm_from_imm(i.imm);
|
|
|
|
memcpy(state->memory + addr, &value, sizeof(value));
|
|
|
|
OP_RETURN_NORMAL
|
|
}
|
|
|
|
DEFINE_OP(ldh)
|
|
{
|
|
ls_instruction_t i = convert_raw2ls(ri);
|
|
|
|
uint8_t reg = i.reg;
|
|
|
|
uint32_t value = (i.imm) & 0b11111111111; // should convert this to hex
|
|
|
|
state->gprs[reg] = (state->gprs[reg] & 0x001FFFFF) | ((value & 0x7FF) << 21);
|
|
|
|
OP_RETURN_NORMAL
|
|
}
|
|
|
|
DEFINE_OP(sti)
|
|
{
|
|
ls_instruction_t i = convert_raw2ls(ri);
|
|
|
|
uint32_t addr = state->pc + state->gprs[i.reg];
|
|
uint32_t value = i.imm;
|
|
|
|
memcpy(state->memory + addr, &value, sizeof(value));
|
|
|
|
OP_RETURN_NORMAL
|
|
}
|
|
|
|
DEFINE_OP(stj)
|
|
{
|
|
ls_instruction_t i = convert_raw2ls(ri);
|
|
|
|
uint32_t addr = state->sp + state->gprs[i.reg];
|
|
uint32_t value = i.imm;
|
|
|
|
memcpy(state->memory + addr, &value, sizeof(value));
|
|
|
|
OP_RETURN_NORMAL
|
|
}
|