116 lines
2.7 KiB
Rust
116 lines
2.7 KiB
Rust
// © 2023 John Breaux
|
|
//! A [`Register`] represents [one of the MSP430 processor's registers](https://mspgcc.sourceforge.net/manual/x82.html)
|
|
use super::*;
|
|
use std::str::FromStr;
|
|
|
|
/// A [Register] epresents [one of the MSP430 processor's registers](https://mspgcc.sourceforge.net/manual/x82.html)
|
|
#[allow(non_camel_case_types)]
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
pub enum Register {
|
|
/// Program Counter
|
|
pc,
|
|
/// Stack Pointer
|
|
sp,
|
|
/// Status Register
|
|
sr,
|
|
/// Constant Generator
|
|
cg,
|
|
r4,
|
|
r5,
|
|
r6,
|
|
r7,
|
|
r8,
|
|
r9,
|
|
r10,
|
|
r11,
|
|
r12,
|
|
r13,
|
|
r14,
|
|
r15,
|
|
}
|
|
|
|
impl Parsable for Register {
|
|
fn parse<'text, T>(_: &Parser, stream: &mut T) -> Result<Self, Error>
|
|
where T: crate::TokenStream<'text> {
|
|
stream
|
|
.expect(Type::Register)
|
|
.map_err(|e: Error| e.context(stream.context()))?
|
|
.lexeme()
|
|
.parse()
|
|
.map_err(|e: Error| e.context(stream.context()))
|
|
}
|
|
}
|
|
|
|
impl From<Register> for u16 {
|
|
fn from(value: Register) -> Self { value as u16 }
|
|
}
|
|
|
|
impl TryFrom<u16> for Register {
|
|
type Error = Error;
|
|
fn try_from(value: u16) -> Result<Self, Self::Error> {
|
|
use Register::*;
|
|
Ok(match value {
|
|
0 => pc,
|
|
1 => sp,
|
|
2 => sr,
|
|
3 => cg,
|
|
4 => r4,
|
|
5 => r5,
|
|
6 => r6,
|
|
7 => r7,
|
|
8 => r8,
|
|
9 => r9,
|
|
10 => r10,
|
|
11 => r11,
|
|
12 => r12,
|
|
13 => r13,
|
|
14 => r14,
|
|
15 => r15,
|
|
_ => return Err(Error::RegisterTooHigh(value)),
|
|
})
|
|
}
|
|
}
|
|
|
|
impl FromStr for Register {
|
|
type Err = Error;
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
use Register::*;
|
|
match s {
|
|
"pc" => Ok(pc),
|
|
"sp" => Ok(sp),
|
|
"sr" => Ok(sr),
|
|
"cg" => Ok(cg),
|
|
_ => str::parse::<u16>(&s[1..]).map_err(|_| -> Self::Err { Error::NotARegister(s.into()) })?.try_into(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<Register> for &str {
|
|
fn from(value: Register) -> Self {
|
|
use Register::*;
|
|
match value {
|
|
pc => "pc",
|
|
sp => "sp",
|
|
sr => "sr",
|
|
cg => "cg",
|
|
r4 => "r4",
|
|
r5 => "r5",
|
|
r6 => "r6",
|
|
r7 => "r7",
|
|
r8 => "r8",
|
|
r9 => "r9",
|
|
r10 => "r10",
|
|
r11 => "r11",
|
|
r12 => "r12",
|
|
r13 => "r13",
|
|
r14 => "r14",
|
|
r15 => "r15",
|
|
}
|
|
}
|
|
}
|
|
|
|
impl std::fmt::Display for Register {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", <&str>::from(*self)) }
|
|
}
|