diff options
Diffstat (limited to 'src/arm32/register')
-rw-r--r-- | src/arm32/register/mod.rs | 111 |
1 files changed, 105 insertions, 6 deletions
diff --git a/src/arm32/register/mod.rs b/src/arm32/register/mod.rs index 2df521b..0013c46 100644 --- a/src/arm32/register/mod.rs +++ b/src/arm32/register/mod.rs @@ -19,7 +19,10 @@ // fero General Public License along with Pollex. // If not, see <https://www.gnu.org/licenses/>. +use crate::Error; + use core::fmt::Display; +use core::str::FromStr; /// An Arm register. /// @@ -38,15 +41,33 @@ pub enum Register { R6 = 0b0110, R7 = 0b0111, R8 = 0b1000, - Sb = 0b1001, // R9 - Sl = 0b1010, // R10 + R9 = 0b1001, // Sb + R10 = 0b1010, // Sl R11 = 0b1011, - Ip = 0b1100, // R12 + R12 = 0b1100, // Ip Sp = 0b1101, // R13 Lr = 0b1110, // R14 Pc = 0b1111, // R15 } +impl Register { + /// Checks if the register is a low register. + /// + /// That is, it is any of `r0`, `r1`, `r2`, `r3`, `r4`, `r5`, `r6`, or `r7` -- or any alias herof. + /// See also [`is_high`](Self::is_high). + #[inline(always)] + #[must_use] + pub const fn is_low(self) -> bool { (self as u8) <= 0x7 } + + /// Checks if the register is a high register. + /// + /// That is, it is any of `r8`, `r9`, `r10`, `r11`, `r12`, `sp`, `lr`, or `pc` -- or any alias herof. + /// See also [`is_low`](Self::is_low). + #[inline(always)] + #[must_use] + pub const fn is_high(self) -> bool { (self as u8) > 0x7 } +} + impl Display for Register { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { use Register::*; @@ -61,13 +82,91 @@ impl Display for Register { R6 => write!(f, "r6"), R7 => write!(f, "r7"), R8 => write!(f, "r8"), - Sb => write!(f, "sb"), - Sl => write!(f, "sl"), + R9 => write!(f, "r9"), + R10 => write!(f, "r10"), R11 => write!(f, "r11"), - Ip => write!(f, "ip"), + R12 => write!(f, "r12"), Sp => write!(f, "sp"), Lr => write!(f, "lr"), Pc => write!(f, "pc"), } } } + +impl FromStr for Register { + type Err = Error; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + use Register::*; + + match s.to_lowercase().as_str() { + | "r0" + | "a1" + => Ok(R0), + + | "r1" + | "a2" + => Ok(R1), + + | "r2" + | "a3" + => Ok(R2), + + | "r3" + | "a4" + => Ok(R3), + + | "r4" + | "v1" + => Ok(R4), + + | "r5" + | "v2" + => Ok(R5), + + | "r6" + | "v3" + => Ok(R6), + + | "r7" + | "v4" + => Ok(R7), + + | "r8" + | "v5" + => Ok(R8), + + | "r9" + | "sb" + | "v6" + => Ok(R9), + + | "r10" + | "sl" + | "v7" + => Ok(R10), + + | "r11" + | "v8" + => Ok(R11), + + | "ip" + | "r12" + => Ok(R12), + + | "r13" + | "sp" + => Ok(Sp), + + | "lr" + | "r14" + => Ok(Lr), + + | "pc" + | "r15" + => Ok(Pc), + + _ => Err(Error::UnknownRegister) + } + } +} |