A32: Add ITState

This commit is contained in:
MerryMage 2019-05-05 23:45:32 +01:00
parent 6e2cd35e4f
commit 74633301c1
3 changed files with 80 additions and 7 deletions

View file

@ -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

View 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

View file

@ -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;
} }