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/ir_emitter.cpp
|
||||
frontend/A32/ir_emitter.h
|
||||
frontend/A32/ITState.h
|
||||
frontend/A32/location_descriptor.cpp
|
||||
frontend/A32/location_descriptor.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/common_types.h"
|
||||
#include "frontend/A32/ITState.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
|
||||
|
@ -35,8 +36,7 @@ namespace Dynarmic::A32 {
|
|||
class PSR final {
|
||||
public:
|
||||
/// Valid processor modes that may be indicated.
|
||||
enum class Mode : u32
|
||||
{
|
||||
enum class Mode : u32 {
|
||||
User = 0b10000,
|
||||
FIQ = 0b10001,
|
||||
IRQ = 0b10010,
|
||||
|
@ -49,8 +49,7 @@ public:
|
|||
};
|
||||
|
||||
/// Instruction sets that may be signified through a PSR.
|
||||
enum class InstructionSet
|
||||
{
|
||||
enum class InstructionSet {
|
||||
ARM,
|
||||
Jazelle,
|
||||
Thumb,
|
||||
|
@ -114,10 +113,11 @@ public:
|
|||
value = (value & ~0xF0000) | (data & 0xF) << 16;
|
||||
}
|
||||
|
||||
u32 IT() const {
|
||||
return (value & 0x6000000) >> 25 | (value & 0xFC00) >> 8;
|
||||
ITState IT() const {
|
||||
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 & ~0x6000000) | (data & 0b00000011) << 25;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue