Files
CAR/load_store.c

163 lines
3.0 KiB
C
Raw Normal View History

2026-07-16 13:46:13 -05:00
/*
* 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
}