Files

99 lines
3.5 KiB
C#
Raw Permalink Normal View History

2025-02-17 16:36:25 -05:00
using Nezu.Core.Enums;
using System.Diagnostics;
using static Nezu.Core.Helpers.Math;
namespace Nezu.Core.ARM11
{
public partial class ARM11Core
{
2025-02-21 19:50:43 -05:00
private void DecodeAndExecuteARM(uint instruction)
2025-02-17 16:36:25 -05:00
{
var conditionCode = (ConditionCode)(instruction >> 28);
if (!IsConditionSet(conditionCode))
return;
// See ARMv6 manual, Figure A3-1
// Special unconditional instructions, see Figure A3-6
if (conditionCode is ConditionCode.UD)
2025-02-18 22:42:34 -05:00
DecodeUnconditional(instruction);
2025-02-17 16:36:25 -05:00
uint group = (instruction >> 25) & 0b111;
2025-02-21 22:26:09 -05:00
uint opcode;
2025-02-17 16:36:25 -05:00
switch (group)
{
case 0b000:
2025-02-19 16:07:54 -05:00
if ((instruction & 0x90) == 0x90)
{
2025-02-21 22:26:09 -05:00
if (IsBitSet(instruction, 24) || ((instruction >> 5) & 0b11) != 0)
2025-02-19 16:07:54 -05:00
DecodeExtraLoadStore(instruction);
else
DecodeMultInstruction(instruction);
}
2025-02-17 16:36:25 -05:00
else
2025-02-19 16:07:54 -05:00
{
opcode = (instruction >> 21) & 0b1111;
if (!IsBitSet(instruction, 20) && (opcode >> 2) == 0b10)
DecodeMiscInstruction(instruction);
else
DecodeDataProcessing(instruction);
}
2025-02-17 16:36:25 -05:00
break;
case 0b001:
opcode = (instruction >> 21) & 0b1111;
2025-02-18 22:42:34 -05:00
if (!IsBitSet(instruction, 20) && (opcode >> 2) == 0b10)
2025-02-17 16:36:25 -05:00
{
// Assert not undefined instruction
Debug.Assert((opcode & 1) != 0);
2025-02-18 22:42:34 -05:00
DecodeMoveSR(instruction);
2025-02-17 16:36:25 -05:00
}
else
2025-02-18 22:42:34 -05:00
DecodeDataProcessing(instruction);
2025-02-17 16:36:25 -05:00
break;
2025-02-18 22:42:34 -05:00
case 0b010: DecodeLoadStoreOffset(instruction, false); break;
2025-02-17 16:36:25 -05:00
case 0b011:
if (IsBitSet(instruction, 4))
{
#if DEBUG
// Assert not architecturally undefined instruction
bool higherUnset = ((~instruction >> 20) & 0b11111) != 0;
bool lowerUnset = ((~instruction >> 4) & 0b1111) != 0;
Debug.Assert(higherUnset || lowerUnset);
#endif
2025-02-18 22:42:34 -05:00
DecodeMediaInstruction(instruction);
2025-02-17 16:36:25 -05:00
}
else
{
2025-02-18 22:42:34 -05:00
DecodeLoadStoreOffset(instruction, true);
2025-02-17 16:36:25 -05:00
}
break;
2025-02-19 16:07:54 -05:00
// Load/Store multiple: See A3-12
case 0b100:
2025-02-21 19:52:21 -05:00
if (IsBitSet(instruction, 20)) ARM_LDM(instruction);
else ARM_STM(instruction);
2025-02-19 16:07:54 -05:00
break;
2025-02-17 16:36:25 -05:00
2025-03-03 22:45:52 -05:00
// Handles both B and BL
case 0b101: ARM_B_L(instruction); break;
2025-02-17 16:36:25 -05:00
2025-02-18 22:42:34 -05:00
case 0b110: DecodeCoprocessorTransfer(instruction); break;
2025-02-17 16:36:25 -05:00
case 0b111:
if (IsBitSet(instruction, 24))
2025-02-18 22:42:34 -05:00
{
// call SWI impl directly. there is no more decoding to be done; SWI is a single instruction.
}
2025-02-17 16:36:25 -05:00
else
2025-02-18 22:42:34 -05:00
DecodeCoprocessorInstruction(instruction);
2025-02-17 16:36:25 -05:00
break;
default:
throw new NotImplementedException($"Unrecognized instruction: 0x{instruction:X8}");
}
}
}
}