initialise a memory structure or smth
Signed-off-by: Amneesh Singh <natto@weirdnatto.in>
This commit is contained in:
@@ -1,21 +1,3 @@
|
||||
enum class ArmInstructionFormat {
|
||||
DataProcessingAndFsrTransfer,
|
||||
Multiply,
|
||||
MultiplyLong,
|
||||
SingleDataSwap,
|
||||
BranchAndExchange,
|
||||
HalfwordDataTransferRegisterOffset,
|
||||
HalfwordDataTransferImmediateOffset,
|
||||
SingleDataTransfer,
|
||||
Undefined,
|
||||
BlockDataTransfer,
|
||||
Branch,
|
||||
CoprocessorDataTransfer,
|
||||
CoprocessorDataOperation,
|
||||
CoprocessorRegisterTransfer,
|
||||
SoftwareInterrupt
|
||||
};
|
||||
|
||||
enum class Condition {
|
||||
EQ = 0b0000,
|
||||
NE = 0b0001,
|
||||
@@ -53,7 +35,7 @@ enum class OpCode {
|
||||
MVN = 0b1111
|
||||
};
|
||||
|
||||
enum class Shift {
|
||||
enum class ShiftType {
|
||||
LSL = 0b00,
|
||||
LSR = 0b01,
|
||||
ASR = 0b10,
|
||||
|
||||
@@ -3,6 +3,19 @@
|
||||
#include <algorithm>
|
||||
#include <cstdio>
|
||||
|
||||
Cpu::Cpu(Bus bus)
|
||||
: gpr(0)
|
||||
, cpsr(0)
|
||||
, spsr(0)
|
||||
, bus(bus)
|
||||
, gpr_banked({ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 } })
|
||||
, spsr_banked({ 0, 0, 0, 0, 0 }) {
|
||||
cpsr.set_mode(Mode::System);
|
||||
cpsr.set_irq_disabled(true);
|
||||
cpsr.set_fiq_disabled(true);
|
||||
cpsr.set_state(State::Arm);
|
||||
}
|
||||
|
||||
/* change modes */
|
||||
void
|
||||
Cpu::chg_mode(Mode from, Mode to) {
|
||||
@@ -92,13 +105,13 @@ Cpu::chg_mode(Mode from, Mode to) {
|
||||
|
||||
// set register
|
||||
inline uint32_t&
|
||||
Cpu::operator[](size_t idx) {
|
||||
Cpu::operator[](uint8_t idx) {
|
||||
// avoid unneeded complexity like index checks
|
||||
return gpr[idx];
|
||||
}
|
||||
|
||||
// get register
|
||||
inline const uint32_t&
|
||||
Cpu::operator[](size_t idx) const {
|
||||
Cpu::operator[](uint8_t idx) const {
|
||||
return gpr[idx];
|
||||
}
|
||||
|
||||
104
src/cpu/cpu.hh
104
src/cpu/cpu.hh
@@ -7,71 +7,57 @@
|
||||
|
||||
using std::size_t;
|
||||
|
||||
static constexpr size_t GPR_VISIBLE_COUNT = 16;
|
||||
|
||||
static constexpr size_t GPR_FIQ_BANKED_FIRST = 8;
|
||||
static constexpr size_t GPR_FIQ_BANKED_COUNT = 7;
|
||||
|
||||
static constexpr size_t GPR_SVC_BANKED_FIRST = 13;
|
||||
static constexpr size_t GPR_SVC_BANKED_COUNT = 2;
|
||||
|
||||
static constexpr size_t GPR_ABT_BANKED_FIRST = 13;
|
||||
static constexpr size_t GPR_ABT_BANKED_COUNT = 2;
|
||||
|
||||
static constexpr size_t GPR_IRQ_BANKED_FIRST = 13;
|
||||
static constexpr size_t GPR_IRQ_BANKED_COUNT = 2;
|
||||
|
||||
static constexpr size_t GPR_UND_BANKED_FIRST = 13;
|
||||
static constexpr size_t GPR_UND_BANKED_COUNT = 2;
|
||||
|
||||
static constexpr size_t GPR_SYS_USR_BANKED_FIRST = 8;
|
||||
static constexpr size_t GPR_SYS_USR_BANKED_COUNT = 7;
|
||||
|
||||
struct _GprBanked {
|
||||
uint32_t fiq[GPR_FIQ_BANKED_COUNT];
|
||||
uint32_t svc[GPR_SVC_BANKED_COUNT];
|
||||
uint32_t abt[GPR_ABT_BANKED_COUNT];
|
||||
uint32_t irq[GPR_IRQ_BANKED_COUNT];
|
||||
uint32_t und[GPR_UND_BANKED_COUNT];
|
||||
|
||||
/* visible registers before the mode switch */
|
||||
uint32_t old[GPR_SYS_USR_BANKED_COUNT];
|
||||
};
|
||||
typedef struct _GprBanked GprBanked;
|
||||
|
||||
struct _SpsrBanked {
|
||||
Psr fiq;
|
||||
Psr svc;
|
||||
Psr abt;
|
||||
Psr irq;
|
||||
Psr und;
|
||||
};
|
||||
typedef struct _SpsrBanked SpsrBanked;
|
||||
|
||||
class Cpu {
|
||||
public:
|
||||
Cpu(Bus bus);
|
||||
|
||||
private:
|
||||
static constexpr size_t GPR_FIQ_BANKED_FIRST = 8;
|
||||
static constexpr size_t GPR_FIQ_BANKED_COUNT = 7;
|
||||
|
||||
static constexpr size_t GPR_SVC_BANKED_FIRST = 13;
|
||||
static constexpr size_t GPR_SVC_BANKED_COUNT = 2;
|
||||
|
||||
static constexpr size_t GPR_ABT_BANKED_FIRST = 13;
|
||||
static constexpr size_t GPR_ABT_BANKED_COUNT = 2;
|
||||
|
||||
static constexpr size_t GPR_IRQ_BANKED_FIRST = 13;
|
||||
static constexpr size_t GPR_IRQ_BANKED_COUNT = 2;
|
||||
|
||||
static constexpr size_t GPR_UND_BANKED_FIRST = 13;
|
||||
static constexpr size_t GPR_UND_BANKED_COUNT = 2;
|
||||
|
||||
static constexpr size_t GPR_SYS_USR_BANKED_FIRST = 8;
|
||||
static constexpr size_t GPR_SYS_USR_BANKED_COUNT = 7;
|
||||
|
||||
static constexpr size_t GPR_VISIBLE_COUNT = 16;
|
||||
|
||||
uint32_t gpr[GPR_VISIBLE_COUNT]; // general purpose registers
|
||||
GprBanked gpr_banked; // banked general purpose registers
|
||||
SpsrBanked spsr_banked; // banked saved program status registers
|
||||
Psr cpsr; // current program status register
|
||||
Psr spsr; // status program status register
|
||||
Bus bus;
|
||||
|
||||
struct {
|
||||
uint32_t fiq[GPR_FIQ_BANKED_COUNT];
|
||||
uint32_t svc[GPR_SVC_BANKED_COUNT];
|
||||
uint32_t abt[GPR_ABT_BANKED_COUNT];
|
||||
uint32_t irq[GPR_IRQ_BANKED_COUNT];
|
||||
uint32_t und[GPR_UND_BANKED_COUNT];
|
||||
|
||||
// visible registers before the mode switch
|
||||
uint32_t old[GPR_SYS_USR_BANKED_COUNT];
|
||||
} gpr_banked; // banked general purpose registers
|
||||
|
||||
struct {
|
||||
Psr fiq;
|
||||
Psr svc;
|
||||
Psr abt;
|
||||
Psr irq;
|
||||
Psr und;
|
||||
} spsr_banked; // banked saved program status registers
|
||||
|
||||
void chg_mode(Mode from, Mode to);
|
||||
|
||||
uint32_t& operator[](size_t idx);
|
||||
const uint32_t& operator[](size_t idx) const;
|
||||
|
||||
public:
|
||||
Cpu(Bus bus)
|
||||
: gpr(0)
|
||||
, gpr_banked({ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 } })
|
||||
, spsr_banked({ 0, 0, 0, 0, 0 })
|
||||
, cpsr(0)
|
||||
, spsr(0)
|
||||
, bus(bus) {
|
||||
cpsr.set_mode(Mode::System);
|
||||
cpsr.set_irq_disabled(true);
|
||||
cpsr.set_fiq_disabled(true);
|
||||
cpsr.set_state(State::Arm);
|
||||
}
|
||||
uint32_t& operator[](uint8_t idx);
|
||||
const uint32_t& operator[](uint8_t idx) const;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
lib_sources += files(
|
||||
'cpu.cc'
|
||||
'cpu.cc',
|
||||
'psr.cc'
|
||||
)
|
||||
|
||||
subdir('arm')
|
||||
49
src/cpu/psr.cc
Normal file
49
src/cpu/psr.cc
Normal file
@@ -0,0 +1,49 @@
|
||||
#include "psr.hh"
|
||||
#include "util/bits.hh"
|
||||
|
||||
Psr::Psr(uint32_t raw) {
|
||||
psr = raw & PSR_CLEAR_RESERVED;
|
||||
}
|
||||
|
||||
Mode
|
||||
Psr::mode() const {
|
||||
return static_cast<Mode>(psr & ~PSR_CLEAR_MODE);
|
||||
}
|
||||
|
||||
void
|
||||
Psr::set_mode(Mode mode) {
|
||||
psr &= PSR_CLEAR_MODE;
|
||||
psr |= static_cast<uint32_t>(mode);
|
||||
}
|
||||
|
||||
bool
|
||||
Psr::state() const {
|
||||
return get_nth_bit(psr, 5);
|
||||
}
|
||||
|
||||
void
|
||||
Psr::set_state(State state) {
|
||||
chg_nth_bit(psr, 5, static_cast<bool>(state));
|
||||
}
|
||||
|
||||
#define GET_SET_NTH_BIT_FUNCTIONS(name, n) \
|
||||
bool Psr::name() const { \
|
||||
return get_nth_bit(psr, n); \
|
||||
} \
|
||||
void Psr::set_##name(bool val) { \
|
||||
chg_nth_bit(psr, n, val); \
|
||||
}
|
||||
|
||||
GET_SET_NTH_BIT_FUNCTIONS(fiq_disabled, 6)
|
||||
|
||||
GET_SET_NTH_BIT_FUNCTIONS(irq_disabled, 7)
|
||||
|
||||
GET_SET_NTH_BIT_FUNCTIONS(v, 28);
|
||||
|
||||
GET_SET_NTH_BIT_FUNCTIONS(c, 29);
|
||||
|
||||
GET_SET_NTH_BIT_FUNCTIONS(z, 30);
|
||||
|
||||
GET_SET_NTH_BIT_FUNCTIONS(n, 31);
|
||||
|
||||
#undef GET_SET_NTH_BIT_FUNCTIONS
|
||||
@@ -1,55 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include "bits.hh"
|
||||
#include "util/bits.hh"
|
||||
#include "utility.hh"
|
||||
#include <cstdint>
|
||||
|
||||
static constexpr uint32_t PSR_CLEAR_RESERVED = 0xf00000ff;
|
||||
static constexpr uint32_t PSR_CLEAR_MODE = 0x0b00000;
|
||||
|
||||
class Psr {
|
||||
uint32_t psr;
|
||||
|
||||
public:
|
||||
// clear the reserved bits i.e, [8:27]
|
||||
Psr(uint32_t raw) { psr = raw & PSR_CLEAR_RESERVED; }
|
||||
Psr(uint32_t raw);
|
||||
|
||||
// Mode : [4:0]
|
||||
Mode mode() const { return static_cast<Mode>(psr & ~PSR_CLEAR_MODE); }
|
||||
void set_mode(Mode mode) {
|
||||
psr &= PSR_CLEAR_MODE;
|
||||
psr |= static_cast<uint32_t>(mode);
|
||||
}
|
||||
Mode mode() const;
|
||||
void set_mode(Mode mode);
|
||||
|
||||
// State : [5]
|
||||
bool state() const { return get_nth_bit(psr, 5); }
|
||||
void set_state(State state) {
|
||||
chg_nth_bit(psr, 5, static_cast<bool>(state));
|
||||
}
|
||||
bool state() const;
|
||||
void set_state(State state);
|
||||
|
||||
#define GET_SET_NTH_BIT_FUNCTIONS(name, n) \
|
||||
bool name() const { return get_nth_bit(psr, n); } \
|
||||
void set_##name(bool val) { chg_nth_bit(psr, n, val); }
|
||||
#define GET_SET_NTH_BIT_FUNCTIONS(name) \
|
||||
bool name() const; \
|
||||
void set_##name(bool val);
|
||||
|
||||
// FIQ disable : [6]
|
||||
GET_SET_NTH_BIT_FUNCTIONS(fiq_disabled, 6)
|
||||
GET_SET_NTH_BIT_FUNCTIONS(fiq_disabled)
|
||||
|
||||
// IRQ disable : [7]
|
||||
GET_SET_NTH_BIT_FUNCTIONS(irq_disabled, 7)
|
||||
GET_SET_NTH_BIT_FUNCTIONS(irq_disabled)
|
||||
|
||||
// Reserved bits : [27:8]
|
||||
|
||||
// Overflow flag : [28]
|
||||
GET_SET_NTH_BIT_FUNCTIONS(v, 28);
|
||||
GET_SET_NTH_BIT_FUNCTIONS(v)
|
||||
|
||||
// Carry flag : [29]
|
||||
GET_SET_NTH_BIT_FUNCTIONS(c, 29);
|
||||
GET_SET_NTH_BIT_FUNCTIONS(c)
|
||||
|
||||
// Zero flag : [30]
|
||||
GET_SET_NTH_BIT_FUNCTIONS(z, 30);
|
||||
GET_SET_NTH_BIT_FUNCTIONS(z)
|
||||
|
||||
// Negative flag : [30]
|
||||
GET_SET_NTH_BIT_FUNCTIONS(n, 31);
|
||||
GET_SET_NTH_BIT_FUNCTIONS(n)
|
||||
|
||||
#undef GET_SET_NTH_BIT_FUNCTIONS
|
||||
|
||||
private:
|
||||
static constexpr uint32_t PSR_CLEAR_RESERVED = 0xf00000ff;
|
||||
static constexpr uint32_t PSR_CLEAR_MODE = 0x0b00000;
|
||||
|
||||
uint32_t psr;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user