CAR: added stack operations, call, ret, jmp and some other random stuff
This commit is contained in:
@ -5,7 +5,8 @@
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
//#define _DEBUG
|
||||
|
||||
@ -27,6 +28,22 @@ int processor_start(pstate_t* state);
|
||||
|
||||
void dump_regs(pstate_t* s);
|
||||
|
||||
void _push(uint32_t v, pstate_t* state);
|
||||
void _pop(uint32_t* a, pstate_t* state);
|
||||
|
||||
|
||||
// returns !error (true on no error, false on error) { true on safe address, false on invalid address }
|
||||
static inline bool check_addr(uint32_t addr, pstate_t* state)
|
||||
{
|
||||
if (addr < state->memory_size)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
fprintf(stderr, "[ERROR]: memory address out of range: address 0x%x with memory size 0x%x\n", addr, (uint32_t) state->memory_size);
|
||||
return false;
|
||||
}
|
||||
|
||||
#define FLAG_CARRY (1 << 0)
|
||||
#define FLAG_SIGN (1 << 1)
|
||||
#define FLAG_OVERFLOW (1 << 2)
|
||||
@ -116,21 +133,31 @@ typedef struct
|
||||
pstate_t* state)
|
||||
|
||||
static const op_return_t _OP_RETV_NORMAL = { .do_inc_pc = true, .exiting_error = false };
|
||||
static const op_return_t _OP_RETV_EXITING_ERROR = { .do_inc_pc = true, .exiting_error = true };
|
||||
static const op_return_t _OP_RETV_EXITING_ERROR = { .do_inc_pc = true, .exiting_error = true };
|
||||
static const op_return_t _OP_RETV_NO_INC_PC = { .do_inc_pc = false, .exiting_error = false };
|
||||
|
||||
#define OP_RETURN_NORMAL return _OP_RETV_NORMAL;
|
||||
#define OP_RETURN_NO_INC_PC return _OP_RETV_NO_INC_PC;
|
||||
#define OP_RETURN_EXITING_ERROR return _OP_RETV_EXITING_ERROR;
|
||||
|
||||
typedef op_return_t (*op)(raw_instruction_t*, pstate_t*);
|
||||
|
||||
static DEFINE_OP(nop)
|
||||
{
|
||||
OP_RETURN_NORMAL
|
||||
}
|
||||
DEFINE_OP(nop);
|
||||
|
||||
DEFINE_OP(call);
|
||||
DEFINE_OP(ret);
|
||||
|
||||
DEFINE_OP(jmp);
|
||||
|
||||
static const op misc_ops[] =
|
||||
{
|
||||
op_nop,
|
||||
|
||||
op_call,
|
||||
op_ret,
|
||||
|
||||
op_jmp,
|
||||
op_jb,
|
||||
};
|
||||
static const size_t NUM_MISC_OPCODES = sizeof(misc_ops) / sizeof(misc_ops[0]);
|
||||
|
||||
@ -152,6 +179,12 @@ DEFINE_OP(bnot);
|
||||
|
||||
DEFINE_OP(xchg);
|
||||
|
||||
DEFINE_OP(fp_add);
|
||||
DEFINE_OP(fp_sub);
|
||||
DEFINE_OP(fp_mul);
|
||||
DEFINE_OP(fp_div);
|
||||
DEFINE_OP(fp_mod);
|
||||
|
||||
static const op reg_ops[] =
|
||||
{
|
||||
op_add,
|
||||
@ -171,6 +204,12 @@ static const op reg_ops[] =
|
||||
op_bnot,
|
||||
|
||||
op_xchg,
|
||||
|
||||
op_fp_add,
|
||||
op_fp_sub,
|
||||
op_fp_mul,
|
||||
op_fp_div,
|
||||
op_fp_mod,
|
||||
};
|
||||
static const size_t NUM_REG_OPCODES = sizeof(reg_ops) / sizeof(reg_ops[0]);
|
||||
|
||||
@ -188,6 +227,13 @@ DEFINE_OP(ldh);
|
||||
DEFINE_OP(sti);
|
||||
DEFINE_OP(stj);
|
||||
|
||||
DEFINE_OP(push);
|
||||
DEFINE_OP(pushi); // push immediate
|
||||
DEFINE_OP(pop);
|
||||
|
||||
DEFINE_OP(sth);
|
||||
DEFINE_OP(stk);
|
||||
|
||||
static const op ls_ops[] =
|
||||
{
|
||||
op_ldr,
|
||||
@ -203,6 +249,15 @@ static const op ls_ops[] =
|
||||
|
||||
op_sti,
|
||||
op_stj,
|
||||
|
||||
op_push,
|
||||
op_pushi,
|
||||
op_pop,
|
||||
|
||||
op_sth, // store high 11 bits of immediate at address with base of pc
|
||||
op_stk, // store high 11 bits of immediate at address with base of sp
|
||||
|
||||
// 1 more
|
||||
};
|
||||
static const size_t NUM_LS_OPCODES = sizeof(ls_ops) / sizeof(ls_ops[0]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user