rprlib/
node.rs

1use serde::{Deserialize, Serialize};
2
3
4#[derive(Debug, Clone)]
5#[derive(Serialize, Deserialize)]
6pub enum Node {
7    Label(Label),
8    Inst(Instruction),
9    PseudoInst(PseudoInst),
10    PseudoOps(Pseudo),
11}
12
13
14#[derive(Debug, Clone)]
15#[derive(Serialize, Deserialize)]
16pub struct Pseudo(pub String, pub Vec<Expr>);
17
18
19#[derive(Debug, Clone)]
20#[derive(Serialize, Deserialize)]
21pub enum Expr {
22    Str(String),
23    Num(String),
24    Sym(String),
25}
26
27
28#[derive(Debug, Clone)]
29#[derive(Serialize, Deserialize)]
30pub struct PseudoInst(pub Instruction);
31
32
33#[derive(Debug, Clone)]
34#[derive(Serialize, Deserialize)]
35pub struct Instruction(pub String, pub Vec<InstExpr>);
36
37
38#[derive(Debug, Clone)]
39#[derive(Serialize, Deserialize)]
40pub enum InstExpr {
41    Reg(Register),
42    RealTimeOffset(Offset),
43}
44
45
46#[derive(Debug, Clone)]
47#[derive(Serialize, Deserialize)]
48pub enum Offset {
49    Rf(Rf, Option<Register>),
50    Imm(Symbol, Option<Register>),
51}
52
53
54#[derive(Debug, Clone)]
55#[derive(Serialize, Deserialize)]
56pub struct Rf(pub RfKeyword, pub Symbol);
57
58
59#[derive(Debug, Clone)]
60#[derive(Serialize, Deserialize)]
61pub enum RfKeyword {
62    Hi,
63    Lo,
64    PcrelHi,
65    PcrelLo,
66    TprelHiE,
67    TprelLoE,
68    GotPcrelHi,
69    TlsIePcrelHiS,
70    TlsGdPcrelHis,
71}
72
73
74#[derive(Debug, Clone)]
75#[derive(Serialize, Deserialize)]
76pub struct Symbol(pub String, pub u64);
77
78
79#[derive(Debug, Clone)]
80#[derive(Serialize, Deserialize)]
81pub struct Register(u8);
82
83
84#[derive(Debug, Clone)]
85#[derive(Serialize, Deserialize)]
86pub struct Label(pub Symbol);
87
88
89macro_rules! transform_rf_keyword {
90    ($i: expr, $s: expr, $r: expr) => {
91        if $i == $s {
92            return Some($r);
93        }
94    };
95}
96
97impl From<&str> for RfKeyword {
98    fn from(i: &str) -> Self {
99        RfKeyword::from_sym(i).expect("invalid riscv assembler relocation functions")
100    }
101}
102
103impl RfKeyword {
104    #[inline]
105    fn from_sym(i: &str) -> Option<Self> {
106        transform_rf_keyword!(i, "hi", RfKeyword::Hi);
107        transform_rf_keyword!(i, "lo", RfKeyword::Lo);
108        transform_rf_keyword!(i, "pcrel_hi", RfKeyword::PcrelHi);
109        transform_rf_keyword!(i, "pcrel_lo", RfKeyword::PcrelLo);
110        transform_rf_keyword!(i, "tprel_hi_e", RfKeyword::TprelHiE);
111        transform_rf_keyword!(i, "tprel_lo_e", RfKeyword::TprelLoE);
112        transform_rf_keyword!(i, "got_pcrel_hi", RfKeyword::GotPcrelHi);
113        transform_rf_keyword!(i, "tls_ie_pcrel_hi_s", RfKeyword::TlsIePcrelHiS);
114        transform_rf_keyword!(i, "tls_gd_pcrel_hi_s", RfKeyword::TlsGdPcrelHis);
115        None
116    }
117}
118
119impl Register {
120    #[inline]
121    pub fn new(i: u8) -> Self {
122        assert!(i < 32);
123        Register(i)
124    }
125
126    #[inline]
127    pub fn from_sym(i: &str) -> Option<Self> {
128        let record = [
129            vec!["x0", "zero"],
130            vec!["x1", "ra"],
131            vec!["x2", "sp"],
132            vec!["x3", "gp"],
133            vec!["x4", "tp"],
134            vec!["x5", "t0"],
135            vec!["x6", "t1"],
136            vec!["x7", "t2"],
137            vec!["x8", "s0", "fp"],
138            vec!["x9", "s1"],
139            vec!["x10", "a0"],
140            vec!["x11", "a1"],
141            vec!["x12", "a2"],
142            vec!["x13", "a3"],
143            vec!["x14", "a4"],
144            vec!["x15", "a5"],
145            vec!["x16", "a6"],
146            vec!["x17", "a7"],
147            vec!["x18", "s2"],
148            vec!["x19", "s3"],
149            vec!["x20", "s4"],
150            vec!["x21", "s5"],
151            vec!["x22", "s6"],
152            vec!["x23", "s7"],
153            vec!["x24", "s8"],
154            vec!["x25", "s9"],
155            vec!["x26", "s10"],
156            vec!["x27", "s11"],
157            vec!["x28", "t3"],
158            vec!["x29", "t4"],
159            vec!["x30", "t5"],
160            vec!["x31", "t6"],
161        ];
162        for (line, item) in record.iter().enumerate() {
163            for reg in item.iter() {
164                if i == *reg {
165                    return Some(Register::new(line as u8));
166                }
167            }
168        }
169        None
170    }
171}
172
173impl From<&str> for Register {
174    fn from(i: &str) -> Self {
175        Register::from_sym(i).expect("invalid riscv register symbol")
176    }
177}