#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[repr(u8)]
#[allow(clippy::upper_case_acronyms)]
pub enum Register {
R0 = 0x00, R1 = 0x01, R2 = 0x02, R3 = 0x03, R4 = 0x04, R5 = 0x05, R6 = 0x06, R7 = 0x07,
R8 = 0x08, R9 = 0x09, R10 = 0x0A, R11 = 0x0B, R12 = 0x0C, R13 = 0x0D, R14 = 0x0E, R15 = 0x0F,
R16 = 0x10, R17 = 0x11, R18 = 0x12, R19 = 0x13, R20 = 0x14, R21 = 0x15, R22 = 0x16, R23 = 0x17,
R24 = 0x18, R25 = 0x19, R26 = 0x1A, R27 = 0x1B, R28 = 0x1C, RFP = 0x1D, RLR = 0x1E, RZR = 0x1F,
}
pub const RSP: Register = Register::RZR;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[repr(u8)]
#[allow(clippy::upper_case_acronyms)]
pub enum Condition {
EQ = 0x0, NE = 0x1,
CS = 0x2, CC = 0x3,
MI = 0x4, PL = 0x5,
VS = 0x6, VC = 0x7,
HI = 0x8, LS = 0x9,
GE = 0xA, LT = 0xB,
GT = 0xC, LE = 0xD,
}
use Condition::*;
pub const ALL_CONDITIONS: [Condition; 14] = [EQ, NE, CS, CC, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE];
impl Condition {
pub fn invert(self) -> Self {
ALL_CONDITIONS[(self as usize) ^ 1]
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[repr(u8)]
#[allow(clippy::upper_case_acronyms)]
pub enum MemOp {
STR = 0,
LDR = 1,
LDRS64 = 2,
LDRS32 = 3,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[repr(u8)]
#[allow(clippy::upper_case_acronyms)]
pub enum ShiftOp {
LSL = 0,
LSR = 1,
ASR = 2,
ROR = 3,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[repr(u8)]
#[allow(clippy::upper_case_acronyms)]
pub enum AddOp {
ADD = 0,
ADDS = 1,
SUB = 2,
SUBS = 3,
}
use AddOp::*;
pub const ALL_ADD_OPS: [AddOp; 4] = [ADD, ADDS, SUB, SUBS];
impl AddOp {
pub fn negate(self) -> Self {
ALL_ADD_OPS[(self as usize) ^ 2]
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[repr(u8)]
#[allow(clippy::upper_case_acronyms)]
pub enum LogicOp {
AND = 0,
ORR = 1,
EOR = 2,
ANDS = 3,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn condition() {
for (i, &cc) in ALL_CONDITIONS.iter().enumerate() {
assert_eq!(i, cc as usize);
}
}
#[test]
fn invert() {
use Condition::*;
assert_eq!(EQ.invert(), NE);
assert_eq!(NE.invert(), EQ);
assert_eq!(CS.invert(), CC);
assert_eq!(CC.invert(), CS);
assert_eq!(MI.invert(), PL);
assert_eq!(PL.invert(), MI);
assert_eq!(VS.invert(), VC);
assert_eq!(VC.invert(), VS);
assert_eq!(HI.invert(), LS);
assert_eq!(LS.invert(), HI);
assert_eq!(GE.invert(), LT);
assert_eq!(LT.invert(), GE);
assert_eq!(GT.invert(), LE);
assert_eq!(LE.invert(), GT);
}
#[test]
fn negate() {
use AddOp::*;
assert_eq!(ADD.negate(), SUB);
assert_eq!(ADDS.negate(), SUBS);
assert_eq!(SUB.negate(), ADD);
assert_eq!(SUBS.negate(), ADDS);
}
}