summaryrefslogtreecommitdiff
path: root/src/arm32/instruction/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/arm32/instruction/mod.rs')
-rw-r--r--src/arm32/instruction/mod.rs175
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'>,
+ },
}