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