Skip to content

Instantly share code, notes, and snippets.

@gregorygaines
Last active December 29, 2022 02:45
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gregorygaines/2dbbb84ac85b262cc86d7d0b061225e3 to your computer and use it in GitHub Desktop.
Save gregorygaines/2dbbb84ac85b262cc86d7d0b061225e3 to your computer and use it in GitHub Desktop.
type Instruction func(opcode uint32, arm *ARM7TDMI)
func DecodeARMInstruction(opcode uint32) Instruction {
switch {
case IsBranchAndBranchExchange(opcode):
return BranchAndBranchExchange;
case IsBlockDataTransfer(opcode):
return BlockDataTransfer;
case IsBranchAndBranchWithLink(opcode):
return BranchAndBranchWithLink;
case IsSoftwareInterrupt(opcode):
return SoftwareInterrupt
case IsUndefined(opcode):
return Undefined
case IsSingleDataTransfer(opcode):
return SingleDataTransfer
case IsSingleDataSwap(opcode):
return SingleDataSwap
case IsMultiply(opcode):
return Multiply
case IsHalfwordDataTransferRegister(opcode):
return HalfwordDataTransferRegister
case IsHalfwordDataTransferImmediate(opcode):
return HalfwordDataTransferImmediate
case IsPSRTransferMRS(opcode):
return PSRTransferMRS
case IsPSRTransferMSR(opcode):
return PSRTransferMSR
case IsDataProcessing(opcode):
return DataProcessing
}
return UnimplementedARMInstruction
}
func IsBranchAndBranchExchange(opcode uint32) bool {
const branchAndExchangeFormat = 0b0000_0001_0010_1111_1111_1111_0001_0000
const formatMask = 0b0000_1111_1111_1111_1111_1111_1111_0000
var extractedFormat = opcode & formatMask
return extractedFormat == branchAndExchangeFormat
}
func IsBlockDataTransfer(opcode uint32) bool {
const blockDataTransferFormat = 0b0000_1000_0000_0000_0000_0000_0000_0000
const formatMask = 0b0000_1110_0000_0000_0000_0000_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == blockDataTransferFormat
}
func IsBranchAndBranchWithLink(opcode uint32) bool {
const branchFormat = 0b0000_1010_0000_0000_0000_0000_0000_0000
const branchWithLinkFormat = 0b0000_1011_0000_0000_0000_0000_0000_0000
const formatMask = 0b0000_1111_0000_0000_0000_0000_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == branchFormat || extractedFormat == branchWithLinkFormat
}
func IsSoftwareInterrupt(opcode uint32) bool {
const softwareInterruptFormat = 0b0000_1111_0000_0000_0000_0000_0000_0000
const formatMask = 0b0000_1111_0000_0000_0000_0000_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == softwareInterruptFormat
}
func IsUndefined(opcode uint32) bool {
const undefinedFormat = 0b0000_0110_0000_0000_0000_0000_0001_0000
const formatMask = 0b0000_1110_0000_0000_0000_0000_0001_0000
var extractedFormat = opcode & formatMask
return extractedFormat == undefinedFormat
}
func IsSingleDataTransfer(opcode uint32) bool {
const singleDataTransferFormat = 0b0000_0100_0000_0000_0000_0000_0000_0000
const formatMask = 0b0000_1100_0000_0000_0000_0000_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == singleDataTransferFormat
}
func IsSingleDataSwap(opcode uint32) bool {
const singleDataSwapFormat = 0b0000_0001_0000_0000_0000_0000_1001_0000
const formatMask = 0b0000_1111_1000_0000_0000_1111_1111_0000
var extractedFormat = opcode & formatMask
return extractedFormat == singleDataSwapFormat
}
func IsMultiply(opcode uint32) bool {
const multiplyFormat = 0b0000_0000_0000_0000_0000_0000_1001_0000
const multiplyLongFormat = 0b0000_0000_1000_0000_0000_0000_1001_0000
const formatMask = 0b0000_1111_1000_0000_0000_0000_1111_0000
var extractedFormat = opcode & formatMask
return extractedFormat == multiplyFormat || extractedFormat == multiplyLongFormat
}
func IsHalfwordDataTransferRegister(opcode uint32) bool {
const halfwordDataTransferRegisterFormat = 0b0000_0000_0000_0000_0000_0000_1001_0000
const formatMask = 0b0000_1110_0100_0000_0000_1111_1001_0000
var extractedFormat = opcode & formatMask
return extractedFormat == halfwordDataTransferRegisterFormat
}
func IsHalfwordDataTransferImmediate(opcode uint32) bool {
const halfwordDataTransferImmediateFormat = 0b0000_0000_0100_0000_0000_0000_1001_0000
const formatMask = 0b0000_1110_0100_0000_0000_0000_1001_0000
var extractedFormat = opcode & formatMask
return extractedFormat == halfwordDataTransferImmediateFormat
}
func IsPSRTransferMRS(opcode uint32) bool {
const mrsFormat = 0b0000_0001_0000_1111_0000_0000_0000_0000
const formatMask = 0b0000_1111_1011_1111_0000_0000_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == mrsFormat
}
func IsPSRTransferMSR(opcode uint32) bool {
const msrFormat = 0b0000_0001_0010_0000_1111_0000_0000_0000
const formatMask = 0b0000_1101_1011_0000_1111_0000_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == msrFormat
}
func IsDataProcessing(opcode uint32) bool {
const dataProcessingFormat = 0b0000_0000_0000_0000_0000_0000_0000_0000
const formatMask = 0b0000_1100_0000_0000_0000_0000_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == dataProcessingFormat
}
type Instruction func(opcode uint16, arm *ARM7TDMI)
func DecodeTHUMBInstruction(opcode uint16) Instruction {
switch {
case IsTHUMBSoftwareInterrupt(opcode):
return THUMBSoftwareInterrupt
case IsUnconditionalBranch(opcode):
return UnconditionalBranch
case IsConditionalBranch(opcode):
return ConditionalBranch
case IsMultipleLoadStore(opcode):
return MultipleLoadstore
case IsLongBranchWithLink(opcode):
return LongBranchWithLink
case IsAddOffsetToStackPointer(opcode):
return AddOffsetToStackPointer
case IsPushPopRegisters(opcode):
return PushPopRegisters
case IsLoadStoreHalfword(opcode):
return LoadStoreHalfword
case IsSPRelativeLoadStore(opcode):
return SPRelatvieLoadStore
case IsLoadAddress(opcode):
return LoadAddress
case IsLoadStoreWithImmediateOffset(opcode):
return LoadStoreWithImmediateOffset
case IsLoadStoreWithRegisterOffset(opcode):
return LoadStoreWithRegisterOffset
case IsLoadStoreSignExtendedByteHalfword(opcode):
return LoadStoreSignExtendedByteHalfword
case IsPCRelativeLoad(opcode):
return PCRelativeLoad
case IsHiRegisterOperationsBranchExchange(opcode):
return HiRegisterOperationsBranchExchange
case IsALUOperations(opcode):
return ALUOperations
case IsMoveCompareAddSubtractImmediate(opcode):
return MoveCompareAddSubtractImmediate
case IsAddSubtract(opcode):
return AddSubtract
case IsMoveShiftedRegister(opcode):
return MoveShiftedRegister
}
return UnimplementedTHUMBInstruction
}
func IsTHUMBSoftwareInterrupt(opcode uint16) bool {
const softwareInterruptFormat = 0b1101_1111_0000_0000
const formatMask = 0b1111_1111_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == softwareInterruptFormat
}
func IsUnconditionalBranch(opcode uint16) bool {
const unconditionalBranchFormat = 0b1110_0000_0000_0000
const formatMask = 0b1111_1000_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == unconditionalBranchFormat
}
func IsConditionalBranch(opcode uint16) bool {
const conditionalBranchFormat = 0b1101_0000_0000_0000
const formatMask = 0b1111_0000_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == conditionalBranchFormat
}
func IsMultipleLoadStore(opcode uint16) bool {
const multipleLoadStoreFormat = 0b1100_0000_0000_0000
const formatMask = 0b1111_0000_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == multipleLoadStoreFormat
}
func IsLongBranchWithLink(opcode uint16) bool {
const longBranchWithLinkFormat = 0b1111_0000_0000_0000
const formatMask = 0b1111_0000_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == longBranchWithLinkFormat
}
func IsAddOffsetToStackPointer(opcode uint16) bool {
const addOffsetToStackPointerFormat = 0b1011_0000_0000_0000
const formatMask = 0b1111_1111_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == addOffsetToStackPointerFormat
}
func IsPushPopRegisters(opcode uint16) bool {
const pushPopRegistersFormat = 0b1011_0100_0000_0000
const formatMask = 0b1111_0110_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == pushPopRegistersFormat
}
func IsLoadStoreHalfword(opcode uint16) bool {
const loadStoreHalfwordFormat = 0b1000_0000_0000_0000
const formatMask = 0b1111_0000_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == loadStoreHalfwordFormat
}
func IsSPRelativeLoadStore(opcode uint16) bool {
const spRelativeLoadStoreFormat = 0b1001_0000_0000_0000
const formatMask = 0b1111_0000_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == spRelativeLoadStoreFormat
}
func IsLoadAddress(opcode uint16) bool {
const loadAddressFormat = 0b1010_0000_0000_0000
const formatMask = 0b1111_0000_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == loadAddressFormat
}
func IsLoadStoreWithImmediateOffset(opcode uint16) bool {
const loadStoreImmediateOffsetFormat = 0b0110_0000_0000_0000
const formatMask = 0b1110_0000_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == loadStoreImmediateOffsetFormat
}
func IsLoadStoreWithRegisterOffset(opcode uint16) bool {
const loadStoreRegisterOffsetFormat = 0b0101_0000_0000_0000
const formatMask = 0b1111_0010_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == loadStoreRegisterOffsetFormat
}
func IsLoadStoreSignExtendedByteHalfword(opcode uint16) bool {
const loadStoreSignExtendedByteHalfwordFormat = 0b0101_0010_0000_0000
const formatMask = 0b1111_0010_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == loadStoreSignExtendedByteHalfwordFormat
}
func IsPCRelativeLoad(opcode uint16) bool {
const pcRelativeLoadFormat = 0b0100_1000_0000_0000
const formatMask = 0b1111_1000_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == pcRelativeLoadFormat
}
func IsHiRegisterOperationsBranchExchange(opcode uint16) bool {
const hiRegisterOperationsBranchExchangeFormat = 0b0100_0100_0000_0000
const formatMask = 0b1111_1100_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == hiRegisterOperationsBranchExchangeFormat
}
func IsALUOperations(opcode uint16) bool {
const aluOperationsFormat = 0b0100_0000_0000_0000
const formatMask = 0b1111_1100_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == aluOperationsFormat
}
func IsMoveCompareAddSubtractImmediate(opcode uint16) bool {
const moveCompareAddSubtractImmediateFormat = 0b0010_0000_0000_0000
const formatMask = 0b1110_0000_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == moveCompareAddSubtractImmediateFormat
}
func IsAddSubtract(opcode uint16) bool {
const addSubtractFormat = 0b0001_1000_0000_0000
const formatMask = 0b1111_1000_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == addSubtractFormat
}
func IsMoveShiftedRegister(opcode uint16) bool {
const moveShiftedRegistersFormat = 0b0000_0000_0000_0000
const formatMask = 0b1110_0000_0000_0000
var extractedFormat = opcode & formatMask
return extractedFormat == moveShiftedRegistersFormat
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment