diff --git a/InstructionSets/ARM/Registers.hpp b/InstructionSets/ARM/Registers.hpp
index d893b8b36..02123203e 100644
--- a/InstructionSets/ARM/Registers.hpp
+++ b/InstructionSets/ARM/Registers.hpp
@@ -59,24 +59,14 @@ struct Registers {
 			overflow_flag_ = value;
 		}
 
-		/// @returns The program counter address only, optionally with a post-increment.
-		template <bool increment>
-		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 {
+		uint32_t status(uint32_t offset) const {
 			return
 				uint32_t(mode_) |
-				pc_ |
+				((active[15] + offset) & ConditionCode::Address) |
 				(negative_flag_ & ConditionCode::Negative) |
 				(zero_result_ ? 0 : ConditionCode::Zero) |
 				(carry_flag_ ? ConditionCode::Carry : 0) |
@@ -84,6 +74,10 @@ struct Registers {
 				interrupt_flags_;
 		}
 
+		uint32_t pc(uint32_t offset) const {
+			return (active[15] + offset) & ConditionCode::Address;
+		}
+
 		bool test(Condition condition) {
 			const auto ne = [&]() -> bool {
 				return zero_result_;
@@ -129,8 +123,9 @@ struct Registers {
 			}
 		}
 
+		uint32_t active[16];	// TODO: register swaps with mode.
+
 	private:
-		uint32_t pc_ = 0;
 		Mode mode_ = Mode::Supervisor;
 
 		uint32_t zero_result_ = 0;
diff --git a/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm b/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm
index 5b9d6c0bc..483130e21 100644
--- a/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm	
+++ b/OSBindings/Mac/Clock SignalTests/ARMDecoderTests.mm	
@@ -106,7 +106,7 @@ void shift(ShiftType type, uint32_t &source, uint32_t amount, uint32_t *carry) {
 
 struct Scheduler {
 	bool should_schedule(Condition condition) {
-		return status.test(condition);
+		return registers_.test(condition);
 	}
 
 	template <Flags f> void perform(DataProcessing fields) {
@@ -146,10 +146,23 @@ struct Scheduler {
 		// or Rm.
 
 		constexpr DataProcessingFlags flags(f);
-		auto &destination = registers_[fields.destination()];
-		const uint32_t operand1 = registers_[fields.operand1()];
+		const bool shift_by_register = !flags.operand2_is_immediate() && fields.shift_count_is_register();
+
+		auto &destination = registers_.active[fields.destination()];
+
+		// When R15 appears in either of the Rn or Rs positions it will give the value
+		// of the PC alone, with the PSR bits replaced by zeroes. ...
+		//
+		// If the shift amount is specified in the instruction, the PC will be 8 bytes ahead.
+		// If a register is used to specify the shift amount, the PC will be ... 12 bytes ahead
+		// when used as Rn or Rm.
+		const uint32_t operand1 =
+			(fields.operand1() == 15) ?
+				registers_.pc(shift_by_register ? 12 : 8) :
+				registers_.active[fields.operand1()];
+
 		uint32_t operand2;
-		uint32_t rotate_carry = status.c();
+		uint32_t rotate_carry = registers_.c();
 
 		// Populate carry from the shift only if it'll be used.
 		constexpr bool shift_sets_carry = is_logical(flags.operation()) && flags.set_condition_codes();
@@ -163,12 +176,30 @@ struct Scheduler {
 		} else {
 			uint32_t shift_amount;
 			if(fields.shift_count_is_register()) {
-				shift_amount = registers_[fields.shift_register()];
+				// When R15 appears in either of the Rn or Rs positions it will give the value
+				// of the PC alone, with the PSR bits replaced by zeroes. ...
+				//
+				// If a register is used to specify the shift amount, the
+				// PC will be 8 bytes ahead when used as Rs.
+				shift_amount =
+					fields.shift_register() == 15 ?
+						registers_.pc(8) :
+						registers_.active[fields.shift_register()];
 			} else {
 				shift_amount = fields.shift_amount();
 			}
 
-			operand2 = registers_[fields.operand2()];
+			// When R15 appears in the Rm position it will give the value of the PC together
+			// with the PSR flags to the barrel shifter. ...
+			//
+			// If the shift amount is specified in the instruction, the PC will be 8 bytes ahead.
+			// If a register is used to specify the shift amount, the PC will be ... 12 bytes ahead
+			// when used as Rn or Rm.
+			if(fields.operand2() == 15) {
+				operand2 = registers_.status(shift_by_register ? 12 : 8);
+			} else {
+				operand2 = registers_.active[fields.operand2()];
+			}
 			shift<shift_sets_carry>(fields.shift_type(), operand2, shift_amount, &rotate_carry);
 		}
 
@@ -193,12 +224,12 @@ struct Scheduler {
 				conditions = operand1 + operand2;
 
 				if constexpr (flags.operation() == DataProcessingOperation::ADC) {
-					conditions += status.c();
+					conditions += registers_.c();
 				}
 
 				if constexpr (flags.set_condition_codes()) {
-					status.set_c(Numeric::carried_out<true, 31>(operand1, operand2, conditions));
-					status.set_v(Numeric::overflow<true>(operand1, operand2, conditions));
+					registers_.set_c(Numeric::carried_out<true, 31>(operand1, operand2, conditions));
+					registers_.set_v(Numeric::overflow<true>(operand1, operand2, conditions));
 				}
 
 				if constexpr (!is_comparison(flags.operation())) {
@@ -212,12 +243,12 @@ struct Scheduler {
 				conditions = operand1 - operand2;
 
 				if constexpr (flags.operation() == DataProcessingOperation::SBC) {
-					conditions -= status.c();
+					conditions -= registers_.c();
 				}
 
 				if constexpr (flags.set_condition_codes()) {
-					status.set_c(Numeric::carried_out<false, 31>(operand1, operand2, conditions));
-					status.set_v(Numeric::overflow<false>(operand1, operand2, conditions));
+					registers_.set_c(Numeric::carried_out<false, 31>(operand1, operand2, conditions));
+					registers_.set_v(Numeric::overflow<false>(operand1, operand2, conditions));
 				}
 
 				if constexpr (!is_comparison(flags.operation())) {
@@ -230,12 +261,12 @@ struct Scheduler {
 				conditions = operand2 - operand1;
 
 				if constexpr (flags.operation() == DataProcessingOperation::RSC) {
-					conditions -= status.c();
+					conditions -= registers_.c();
 				}
 
 				if constexpr (flags.set_condition_codes()) {
-					status.set_c(Numeric::carried_out<false, 31>(operand2, operand1, conditions));
-					status.set_v(Numeric::overflow<false>(operand2, operand1, conditions));
+					registers_.set_c(Numeric::carried_out<false, 31>(operand2, operand1, conditions));
+					registers_.set_v(Numeric::overflow<false>(operand2, operand1, conditions));
 				}
 
 				destination = conditions;
@@ -244,12 +275,12 @@ struct Scheduler {
 
 		// Set N and Z in a unified way.
 		if constexpr (flags.set_condition_codes()) {
-			status.set_nz(conditions);
+			registers_.set_nz(conditions);
 		}
 
 		// Set C from the barrel shifter if applicable.
 		if constexpr (shift_sets_carry) {
-			status.set_c(rotate_carry);
+			registers_.set_c(rotate_carry);
 		}
 
 		// TODO: If register 15 was in use as a destination, write back and clean up.
@@ -270,9 +301,7 @@ struct Scheduler {
 	void unknown(uint32_t) {}
 
 private:
-	Registers status;
-
-	uint32_t registers_[16];	// TODO: register swaps with mode.
+	Registers registers_;
 };
 
 }