From a88d41bf0037ad08ded5af39a1b33cdc2c1988ac Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 25 Feb 2024 15:21:54 -0500 Subject: [PATCH 1/2] List the flags. --- InstructionSets/ARM/Status.hpp | 29 +++++++++++++++++++ .../Clock Signal.xcodeproj/project.pbxproj | 2 ++ 2 files changed, 31 insertions(+) create mode 100644 InstructionSets/ARM/Status.hpp diff --git a/InstructionSets/ARM/Status.hpp b/InstructionSets/ARM/Status.hpp new file mode 100644 index 000000000..37d9567d2 --- /dev/null +++ b/InstructionSets/ARM/Status.hpp @@ -0,0 +1,29 @@ +// +// Status.hpp +// Clock Signal +// +// Created by Thomas Harte on 25/02/2024. +// Copyright © 2024 Thomas Harte. All rights reserved. +// + +#pragma once + +#include "OperationMapper.hpp" + +namespace InstructionSet::ARM { + +namespace ConditionCode { + +static constexpr uint32_t Negative = 1 << 31; +static constexpr uint32_t Zero = 1 << 30; +static constexpr uint32_t Carry = 1 << 29; +static constexpr uint32_t Overflow = 1 << 28; +static constexpr uint32_t IRQDisable = 1 << 27; +static constexpr uint32_t FIQDisable = 1 << 26; +static constexpr uint32_t Mode = (1 << 1) | (1 << 0); + +static constexpr uint32_t Address = FIQDisable - Mode - 1; + +} + +} diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 5534d4fbe..b7ea5cdac 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -1335,6 +1335,7 @@ 4B1EDB431E39A0AC009D6819 /* chip.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = chip.png; sourceTree = ""; }; 4B2005402B804AA300420C5C /* OperationMapper.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = OperationMapper.hpp; sourceTree = ""; }; 4B2005422B804D6400420C5C /* ARMDecoderTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ARMDecoderTests.mm; sourceTree = ""; }; + 4B2005462B8BD7A500420C5C /* Status.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Status.hpp; sourceTree = ""; }; 4B2130E0273A7A0A008A77B4 /* Audio.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Audio.cpp; sourceTree = ""; }; 4B2130E1273A7A0A008A77B4 /* Audio.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Audio.hpp; sourceTree = ""; }; 4B228CD424D773B30077EF25 /* CSScanTarget.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = CSScanTarget.mm; sourceTree = ""; }; @@ -2759,6 +2760,7 @@ isa = PBXGroup; children = ( 4B2005402B804AA300420C5C /* OperationMapper.hpp */, + 4B2005462B8BD7A500420C5C /* Status.hpp */, ); path = ARM; sourceTree = ""; From 481b6d0e698854f7a57b42a9138c52762e9fc8ce Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 25 Feb 2024 22:01:51 -0500 Subject: [PATCH 2/2] Sketch out some status flags. --- InstructionSets/ARM/Status.hpp | 105 ++++++++++++++++++ .../Mac/Clock SignalTests/ARMDecoderTests.mm | 1 + 2 files changed, 106 insertions(+) diff --git a/InstructionSets/ARM/Status.hpp b/InstructionSets/ARM/Status.hpp index 37d9567d2..3cf3cba60 100644 --- a/InstructionSets/ARM/Status.hpp +++ b/InstructionSets/ARM/Status.hpp @@ -26,4 +26,109 @@ static constexpr uint32_t Address = FIQDisable - Mode - 1; } +enum class Mode { + User = 0b00, + FIQ = 0b01, + IRQ = 0b10, + Supervisor = 0b11, +}; + +struct Status { + public: + /// Sets the N and Z flags according to the value of @c result. + void set_nz(uint32_t value) { + zero_result_ = negative_flag_ = value; + } + + /// Sets C if @c value is non-zero; resets it otherwise. + void set_c(uint32_t value) { + carry_flag_ = value; + } + + /// Sets V if the highest bit of @c value is set; resets it otherwise. + void set_v(uint32_t value) { + overflow_flag_ = value; + } + + /// @returns The program counter address only, optionally with a post-increment. + template + uint32_t pc() { + const uint32_t result = pc_; + if constexpr (increment) { + pc_ = (pc_ + 4) & ConditionCode::Address; + } + return result; + } + + void begin_irq() { interrupt_flags_ |= ConditionCode::IRQDisable; } + void begin_fiq() { interrupt_flags_ |= ConditionCode::FIQDisable; } + + /// @returns The full PC + status bits. + uint32_t get() const { + return + uint32_t(mode_) | + pc_ | + (negative_flag_ & ConditionCode::Negative) | + (zero_result_ ? 0 : ConditionCode::Zero) | + (carry_flag_ ? ConditionCode::Carry : 0) | + ((overflow_flag_ >> 3) & ConditionCode::Overflow) | + interrupt_flags_; + } + + bool test(Condition condition) { + const auto ne = [&]() -> bool { + return zero_result_; + }; + const auto cs = [&]() -> bool { + return carry_flag_; + }; + const auto mi = [&]() -> bool { + return negative_flag_ & ConditionCode::Negative; + }; + const auto vs = [&]() -> bool { + return overflow_flag_ & ConditionCode::Negative; + }; + const auto hi = [&]() -> bool { + return carry_flag_ && zero_result_; + }; + const auto lt = [&]() -> bool { + return (negative_flag_ ^ overflow_flag_) & ConditionCode::Negative; + }; + const auto le = [&]() -> bool { + return !zero_result_ || lt(); + }; + + switch(condition) { + case Condition::EQ: return !ne(); + case Condition::NE: return ne(); + case Condition::CS: return cs(); + case Condition::CC: return !cs(); + case Condition::MI: return mi(); + case Condition::PL: return !mi(); + case Condition::VS: return vs(); + case Condition::VC: return !vs(); + + case Condition::HI: return hi(); + case Condition::LS: return !hi(); + case Condition::GE: return !lt(); + case Condition::LT: return lt(); + case Condition::GT: return !le(); + case Condition::LE: return le(); + + case Condition::AL: return true; + case Condition::NV: return false; + } + } + + private: + uint32_t pc_ = 0; + Mode mode_ = Mode::Supervisor; + + uint32_t zero_result_ = 0; + uint32_t negative_flag_ = 0; + uint32_t interrupt_flags_ = 0; + uint32_t carry_flag_ = 0; + uint32_t overflow_flag_ = 0; +}; + } diff --git a/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm b/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm index 3cfeffbce..5e5533b2b 100644 --- a/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm +++ b/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm @@ -9,6 +9,7 @@ #import #include "../../../InstructionSets/ARM/OperationMapper.hpp" +#include "../../../InstructionSets/ARM/Status.hpp" using namespace InstructionSet::ARM;