70 lines
2.0 KiB
C
70 lines
2.0 KiB
C
#include <assert.h>
|
|
|
|
#include "execute.h"
|
|
#include "operations.h"
|
|
#include "state_helpers.h"
|
|
#include "decode_execute.h"
|
|
#include "exception.h"
|
|
|
|
uint16_t fetch(struct architectural_state * state, struct memory_map * map)
|
|
{
|
|
uint32_t address = zero_extend32(sign_extend32(state->pc[0]));
|
|
assert((address & 0b1) == 0);
|
|
return read_memory16(map, address);
|
|
}
|
|
|
|
void step(struct architectural_state * state, struct memory_map * map)
|
|
{
|
|
/*
|
|
* 3 Fetch the instruction bytes from the address in memory, as
|
|
* indicated by the current program counter, 2 bytes need to be
|
|
* fetched for each instruction.
|
|
*/
|
|
uint16_t instruction_code = fetch(state, map);
|
|
|
|
/*
|
|
* 4 Calculate the default values of PC’ and PR’. PC’ is set to the
|
|
* value of PC”, PR’ is set to the value of PR”.
|
|
*/
|
|
state->pc[1] = state->pc[2];
|
|
state->pr[1] = state->pr[2];
|
|
|
|
/*
|
|
* 5 Calculate the default values of PC” and PR” assuming continued
|
|
* sequential execution without procedure call or mode switch: PC”
|
|
* is PC’+2, while PR” is unchanged.
|
|
*/
|
|
state->pc[2] = state->pc[1] + 2;
|
|
state->pr[2] = state->pr[2]; // unchanged
|
|
|
|
/*
|
|
* 6 Decode and execute the instruction. This includes checks for
|
|
* synchronous events, such as exceptions and panics, and
|
|
* initiation of handling if required. Synchronous events are not
|
|
* accepted between a delayed branch and a delay slot. They are
|
|
* detected either before the delayed branch or after the delay
|
|
* slot.
|
|
*/
|
|
enum decode_status status = decode_and_execute_instruction(state, map, instruction_code);
|
|
switch (status) {
|
|
case DECODE__DEFINED:
|
|
break;
|
|
case DECODE__UNDEFINED: // undefined instruction
|
|
if (state->is_delay_slot)
|
|
ILLSLOT(state);
|
|
else
|
|
RESINST(state);
|
|
break;
|
|
default:
|
|
assert(false);
|
|
break;
|
|
}
|
|
|
|
/*
|
|
* 7 Set the current program counter (PC) to the value of the next
|
|
* program counter (PC’) and PR to the value of PR’.
|
|
*/
|
|
state->pc[0] = state->pc[1];
|
|
state->pr[0] = state->pr[1];
|
|
}
|