/* * 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 #include #include #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 } DEFINE_OP(push) { ls_instruction_t i = convert_raw2ls(ri); _push(state->gprs[i.reg], state); OP_RETURN_NORMAL } DEFINE_OP(pushi) { ls_instruction_t i = convert_raw2ls(ri); _push(i.imm, state); OP_RETURN_NORMAL } DEFINE_OP(pop) { ls_instruction_t i = convert_raw2ls(ri); uint32_t v; _pop(&v, state); state->gprs[i.reg] = v; OP_RETURN_NORMAL } DEFINE_OP(sth) { ls_instruction_t i = convert_raw2ls(ri); uint32_t addr = state->pc + state->gprs[i.reg]; uint32_t v = (i.imm >> 21) & 0x7ff; memcpy(state->memory + addr, &v, sizeof(v)); OP_RETURN_NORMAL } DEFINE_OP(stk) { ls_instruction_t i = convert_raw2ls(ri); uint32_t addr = state->sp + state->gprs[i.reg]; uint32_t v = (i.imm >> 21) & 0x7ff; memcpy(state->memory + addr, &v, sizeof(v)); OP_RETURN_NORMAL }