diff options
Diffstat (limited to 'src/arm32/instruction/mod.rs')
-rw-r--r-- | src/arm32/instruction/mod.rs | 175 |
1 files changed, 162 insertions, 13 deletions
diff --git a/src/arm32/instruction/mod.rs b/src/arm32/instruction/mod.rs index 8e527d5..7cc3718 100644 --- a/src/arm32/instruction/mod.rs +++ b/src/arm32/instruction/mod.rs @@ -23,56 +23,205 @@ mod test; mod display; -mod encode_arm; use crate::arm32::{ Predicate, Flag, Register, Shifter, - Signed, - Unsigned, }; /// An Arm32 instruction. -#[derive(Clone, Debug, Eq, PartialEq)] +/// +/// An instruction must be encoded before it can be used by a processor. +/// This can be done using the [`InstructionCodec`](crate::arm32::InstructionCodec) type. +/// +/// Do note that these enumerations do not exactly match instructions used in assembly. +/// For example, the following two lines are completely identical (with respect to the final binary, disregarding optimisations): +/// +/// ```as +/// CPY r1, r0 +/// MOV r1, r0 +/// ``` +/// +/// Yet only `MOV` ([`Move`](Instruction::Move)) is provided as a variant. +/// Similarly, some combinations of operands yield the same results as multiple instructions. +/// See [`Shifter`] for more information. +/// +/// Also note that not all operands can be encoded in Arm instruction sets. +/// Even the largest immediates usually have a limit at (24) significant figures. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum Instruction { Add { predicate: Predicate, destination: Register, base: Register, source: Shifter, - s: Flag<'S'> }, + s: Flag<'S'>, + }, + + AddCarry { + predicate: Predicate, + destination: Register, + base: Register, + source: Shifter, + s: Flag<'S'>, + }, + + And { + predicate: Predicate, + destination: Register, + base: Register, + source: Shifter, + s: Flag<'S'>, + }, + + BitClear { + predicate: Predicate, + destination: Register, + base: Register, + source: Shifter, + s: Flag<'S'>, + }, Branch { predicate: Predicate, - immediate: Signed }, + immediate: i32, + }, BranchExchange { predicate: Predicate, - register: Register }, + register: Register, + }, BranchLink { predicate: Predicate, - immediate: Signed + immediate: i32, }, Breakpoint { - immediate: Unsigned }, + immediate: u32, + }, + + CountLeadingZeroes { + predicate: Predicate, + destination: Register, + source: Register, + }, + + Compare { + predicate: Predicate, + lhs: Register, + rhs: Shifter, + }, + + CompareNegated { + predicate: Predicate, + lhs: Register, + rhs: Shifter, + }, + + ExclusiveOr { + predicate: Predicate, + destination: Register, + base: Register, + source: Shifter, + s: Flag<'S'>, + }, + + InclusiveOr { + predicate: Predicate, + destination: Register, + base: Register, + source: Shifter, + s: Flag<'S'>, + }, Move { predicate: Predicate, destination: Register, source: Shifter, - s: Flag<'S'> }, + s: Flag<'S'>, + }, - MoveNegated { + MoveNot { predicate: Predicate, destination: Register, source: Shifter, - s: Flag<'S'> }, + s: Flag<'S'>, + }, + + Multiply { + predicate: Predicate, + destination: Register, + base: Register, + source: Register, + s: Flag<'S'>, + }, + + MultiplyAccumulate { + predicate: Predicate, + destination: Register, + base: Register, + source: Register, + shift: Register, + s: Flag<'S'>, + }, + + Reverse { + predicate: Predicate, + destination: Register, + source: Register, + }, + + ReverseSubtract { + predicate: Predicate, + destination: Register, + base: Register, + source: Shifter, + s: Flag<'S'>, + }, + + ReverseSubtractCarry { + predicate: Predicate, + destination: Register, + base: Register, + source: Shifter, + s: Flag<'S'>, + }, + + SaturatingAdd { + predicate: Predicate, + destination: Register, + base: Register, + source: Register, + }, + + SaturatingSubtract { + predicate: Predicate, + destination: Register, + base: Register, + source: Register, + }, SoftwareInterrupt { predicate: Predicate, - immediate: Unsigned }, + immediate: u32, + }, + + Subtract { + predicate: Predicate, + destination: Register, + base: Register, + source: Shifter, + s: Flag<'S'>, + }, + + SubtractCarry { + predicate: Predicate, + destination: Register, + base: Register, + source: Shifter, + s: Flag<'S'>, + }, } |