A32: Add ITState
This commit is contained in:
parent
6e2cd35e4f
commit
74633301c1
3 changed files with 80 additions and 7 deletions
|
@ -91,6 +91,7 @@ add_library(dynarmic
|
||||||
frontend/A32/FPSCR.h
|
frontend/A32/FPSCR.h
|
||||||
frontend/A32/ir_emitter.cpp
|
frontend/A32/ir_emitter.cpp
|
||||||
frontend/A32/ir_emitter.h
|
frontend/A32/ir_emitter.h
|
||||||
|
frontend/A32/ITState.h
|
||||||
frontend/A32/location_descriptor.cpp
|
frontend/A32/location_descriptor.cpp
|
||||||
frontend/A32/location_descriptor.h
|
frontend/A32/location_descriptor.h
|
||||||
frontend/A32/PSR.h
|
frontend/A32/PSR.h
|
||||||
|
|
72
src/frontend/A32/ITState.h
Normal file
72
src/frontend/A32/ITState.h
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
/* This file is part of the dynarmic project.
|
||||||
|
* Copyright (c) 2019 MerryMage
|
||||||
|
* This software may be used and distributed according to the terms of the GNU
|
||||||
|
* General Public License version 2 or any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/common_types.h"
|
||||||
|
#include "common/bit_util.h"
|
||||||
|
#include "frontend/ir/cond.h"
|
||||||
|
|
||||||
|
namespace Dynarmic::A32 {
|
||||||
|
|
||||||
|
class ITState final {
|
||||||
|
public:
|
||||||
|
ITState() = default;
|
||||||
|
explicit ITState(u8 data) : value(data) {}
|
||||||
|
|
||||||
|
ITState& operator=(u8 data) {
|
||||||
|
value = data;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
IR::Cond Cond() const {
|
||||||
|
return static_cast<IR::Cond>(Common::Bits<4, 7>(value));
|
||||||
|
}
|
||||||
|
void Cond(IR::Cond cond) {
|
||||||
|
value = Common::ModifyBits<4, 7>(value, static_cast<u8>(cond));
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 Mask() const {
|
||||||
|
return Common::Bits<0, 3>(value);
|
||||||
|
}
|
||||||
|
void Mask(u8 mask) {
|
||||||
|
value = Common::ModifyBits<0, 3>(value, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsInITBlock() const {
|
||||||
|
return Mask() != 0b0000;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsLastInITBlock() const {
|
||||||
|
return Mask() == 0b1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
ITState Advance() const {
|
||||||
|
ITState result{*this};
|
||||||
|
result.Mask(result.Mask() << 1);
|
||||||
|
if (result.Mask() == 0) {
|
||||||
|
return ITState{0};
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 Value() const {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
u8 value;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool operator==(ITState lhs, ITState rhs) {
|
||||||
|
return lhs.Value() == rhs.Value();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator!=(ITState lhs, ITState rhs) {
|
||||||
|
return !operator==(lhs, rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Dynarmic::A32
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include "common/bit_util.h"
|
#include "common/bit_util.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "frontend/A32/ITState.h"
|
||||||
|
|
||||||
namespace Dynarmic::A32 {
|
namespace Dynarmic::A32 {
|
||||||
|
|
||||||
|
@ -35,8 +36,7 @@ namespace Dynarmic::A32 {
|
||||||
class PSR final {
|
class PSR final {
|
||||||
public:
|
public:
|
||||||
/// Valid processor modes that may be indicated.
|
/// Valid processor modes that may be indicated.
|
||||||
enum class Mode : u32
|
enum class Mode : u32 {
|
||||||
{
|
|
||||||
User = 0b10000,
|
User = 0b10000,
|
||||||
FIQ = 0b10001,
|
FIQ = 0b10001,
|
||||||
IRQ = 0b10010,
|
IRQ = 0b10010,
|
||||||
|
@ -49,8 +49,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Instruction sets that may be signified through a PSR.
|
/// Instruction sets that may be signified through a PSR.
|
||||||
enum class InstructionSet
|
enum class InstructionSet {
|
||||||
{
|
|
||||||
ARM,
|
ARM,
|
||||||
Jazelle,
|
Jazelle,
|
||||||
Thumb,
|
Thumb,
|
||||||
|
@ -114,10 +113,11 @@ public:
|
||||||
value = (value & ~0xF0000) | (data & 0xF) << 16;
|
value = (value & ~0xF0000) | (data & 0xF) << 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 IT() const {
|
ITState IT() const {
|
||||||
return (value & 0x6000000) >> 25 | (value & 0xFC00) >> 8;
|
return ITState{static_cast<u8>((value & 0x6000000) >> 25 | (value & 0xFC00) >> 8)};
|
||||||
}
|
}
|
||||||
void IT(u32 data) {
|
void IT(ITState it_state) {
|
||||||
|
const u32 data = it_state.Value();
|
||||||
value = (value & ~0x000FC00) | (data & 0b11111100) << 8;
|
value = (value & ~0x000FC00) | (data & 0b11111100) << 8;
|
||||||
value = (value & ~0x6000000) | (data & 0b00000011) << 25;
|
value = (value & ~0x6000000) | (data & 0b00000011) << 25;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue