1use maplit::{btreeset, hashmap};
4use std::{
5 collections::{BTreeSet, HashMap},
6 sync::LazyLock,
7};
8
9#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
10pub enum DisabledOptions {
11 NoMul,
12 NoJmp,
14 NoXreg,
16 NoYreg,
18 Tiny1x,
20 NoLpm,
22 NoLpmX,
24 NoElpm,
26 NoElpmX,
28 NoSpm,
30 NoEspm,
32 NoMovw,
34 NoBreak,
36 NoEicall,
38 NoEijmp,
40 Avr8l,
42}
43
44#[derive(Clone, PartialEq, Eq, Debug)]
45pub struct Device {
46 pub flash_size: u32,
48 pub ram_start: u32,
49 pub ram_size: u32,
50 pub eeprom_size: u32,
51 pub disable_opts: BTreeSet<DisabledOptions>,
52}
53
54use DisabledOptions::*;
55
56use crate::instruction::operation::Operation;
57
58impl Device {
59 pub fn new(flash_size: u32) -> Self {
60 let flash_size = if flash_size == 0 { 4194304 } else { flash_size };
61 Self {
62 flash_size,
63 ram_start: 0x60,
64 ram_size: 8388608,
65 eeprom_size: 65536,
66 disable_opts: btreeset! {},
67 }
68 }
69
70 pub fn check_operation(&self, op: &Operation) -> bool {
71 match op {
72 Operation::Mul => self.allow(NoMul),
73 Operation::Jmp => self.allow(NoJmp),
74 Operation::Lpm => self.allow(NoLpm),
75 Operation::Elpm => self.allow(NoElpm),
76 Operation::Spm => self.allow(NoSpm),
77 Operation::Eicall => self.allow(NoEicall),
78 Operation::Eijmp => self.allow(NoEijmp),
79 Operation::Break => self.allow(NoBreak),
80 Operation::Movw => self.allow(NoMovw),
81 Operation::Adiw
83 | Operation::Sbiw
84 | Operation::Ijmp
85 | Operation::Icall
86 | Operation::Ldd
87 | Operation::Std
88 | Operation::Lds
89 | Operation::Sts
90 | Operation::Push
91 | Operation::Pop => {
92 if self.allow(Tiny1x) {
93 match op {
95 Operation::Adiw | Operation::Sbiw => self.allow(Avr8l),
96 _ => true,
97 }
98 } else {
99 false
100 }
101 }
102 _ => true,
103 }
104 }
105
106 pub fn is_avr8l(&self) -> bool {
107 self.disable_opts.contains(&Avr8l)
108 }
109
110 pub fn allow(&self, o: DisabledOptions) -> bool {
111 !self.disable_opts.contains(&o)
112 }
113}
114
115pub static DEVICES: LazyLock<HashMap<&'static str, Device>> = LazyLock::new(|| {
116 hashmap! {
117 "ATtiny10" => Device {flash_size: 512, ram_start: 0x00, ram_size: 0, eeprom_size: 0, disable_opts: btreeset!{NoMul, NoJmp, Tiny1x, NoXreg, NoYreg, NoLpmX, NoElpm, NoSpm, NoEspm, NoMovw, NoBreak, NoEicall, NoEijmp} },
123 "ATtiny11" => Device {flash_size: 512, ram_start: 0x00, ram_size: 0, eeprom_size: 0, disable_opts: btreeset!{NoMul, NoJmp, Tiny1x, NoXreg, NoYreg, NoLpmX, NoElpm, NoSpm, NoEspm, NoMovw, NoBreak, NoEicall, NoEijmp} },
124 "ATtiny12" => Device {flash_size: 512, ram_start: 0x00, ram_size: 0, eeprom_size: 64, disable_opts: btreeset!{NoMul, NoJmp, Tiny1x, NoXreg, NoYreg, NoLpmX, NoElpm, NoSpm, NoEspm, NoMovw, NoBreak, NoEicall, NoEijmp} },
125 "ATtiny13" => Device {flash_size: 512, ram_start: 0x60, ram_size: 64, eeprom_size: 64, disable_opts: btreeset!{NoMul, NoJmp, NoElpm, NoEspm, NoEicall, NoEijmp} },
126 "ATtiny13A" => Device {flash_size: 512, ram_start: 0x60, ram_size: 64, eeprom_size: 64, disable_opts: btreeset!{NoMul, NoJmp, NoElpm, NoEspm, NoEicall, NoEijmp} },
127 "ATtiny15" => Device {flash_size: 512, ram_start: 0x00, ram_size: 0, eeprom_size: 64, disable_opts: btreeset!{NoMul, NoJmp, Tiny1x, NoXreg, NoYreg, NoLpmX, NoElpm, NoSpm, NoEspm, NoMovw, NoBreak, NoEicall, NoEijmp} },
128 "ATtiny20" => Device {flash_size: 2048, ram_start: 0x40, ram_size: 128, eeprom_size: 0, disable_opts: btreeset!{Avr8l, NoJmp, NoMul, NoEijmp, NoEicall, NoMovw, NoLpm, NoElpm, NoSpm, NoEspm, NoBreak} },
129 "ATtiny22" => Device {flash_size: 1024, ram_start: 0x60, ram_size: 128, eeprom_size: 128, disable_opts: btreeset!{NoMul, NoJmp, NoLpmX, NoElpm, NoSpm, NoEspm, NoMovw, NoBreak, NoEicall, NoEijmp} },
130 "ATtiny24" => Device {flash_size: 1024, ram_start: 0x60, ram_size: 128, eeprom_size: 128, disable_opts: btreeset!{NoMul, NoJmp, NoElpm, NoEspm, NoEicall, NoEijmp} },
131 "ATtiny24A" => Device {flash_size: 1024, ram_start: 0x60, ram_size: 128, eeprom_size: 128, disable_opts: btreeset!{NoMul, NoJmp, NoElpm, NoEspm, NoEicall, NoEijmp} },
132 "ATtiny25" => Device {flash_size: 1024, ram_start: 0x60, ram_size: 128, eeprom_size: 128, disable_opts: btreeset!{NoMul, NoJmp, NoElpm, NoEspm, NoEicall, NoEijmp} },
133 "ATtiny26" => Device {flash_size: 1024, ram_start: 0x60, ram_size: 128, eeprom_size: 128, disable_opts: btreeset!{NoMul, NoJmp, NoElpm, NoSpm, NoEspm, NoMovw, NoBreak, NoEicall, NoEijmp} },
134 "ATtiny28" => Device {flash_size: 1024, ram_start: 0x00, ram_size: 0, eeprom_size: 0, disable_opts: btreeset!{NoMul, NoJmp, Tiny1x, NoXreg, NoYreg, NoLpmX, NoElpm, NoSpm, NoEspm, NoMovw, NoBreak, NoEicall, NoEijmp} },
135 "ATtiny44" => Device {flash_size: 2048, ram_start: 0x60, ram_size: 256, eeprom_size: 256, disable_opts: btreeset!{NoMul, NoJmp, NoElpm, NoEspm, NoEicall, NoEijmp} },
137 "ATtiny44A" => Device {flash_size: 2048, ram_start: 0x60, ram_size: 256, eeprom_size: 256, disable_opts: btreeset!{NoMul, NoJmp, NoElpm, NoEspm, NoEicall, NoEijmp} },
138 "ATtiny45" => Device {flash_size: 2048, ram_start: 0x60, ram_size: 256, eeprom_size: 256, disable_opts: btreeset!{NoMul, NoJmp, NoElpm, NoEspm, NoEicall, NoEijmp} },
139 "ATtiny48" => Device {flash_size: 2048, ram_start: 0x100, ram_size: 256, eeprom_size: 64, disable_opts: btreeset!{NoMul, NoJmp, NoElpm, NoEspm, NoEicall, NoEijmp} },
140 "ATtiny84" => Device {flash_size: 4096, ram_start: 0x60, ram_size: 512, eeprom_size: 512, disable_opts: btreeset!{NoMul, NoJmp, NoElpm, NoEspm, NoEicall, NoEijmp} },
141 "ATtiny85" => Device {flash_size: 4096, ram_start: 0x60, ram_size: 512, eeprom_size: 512, disable_opts: btreeset!{NoMul, NoJmp, NoElpm, NoEspm, NoEicall, NoEijmp} },
142 "ATtiny88" => Device {flash_size: 4096, ram_start: 0x100, ram_size: 512, eeprom_size: 64, disable_opts: btreeset!{NoMul, NoJmp, NoElpm, NoEspm, NoEicall, NoEijmp} },
143 "ATtiny2313" => Device {flash_size: 1024, ram_start: 0x60, ram_size: 128, eeprom_size: 128, disable_opts: btreeset!{NoMul, NoJmp, NoElpm, NoEspm, NoEicall, NoEijmp} },
149 "ATtiny2313A" => Device {flash_size: 1024, ram_start: 0x60, ram_size: 128, eeprom_size: 128, disable_opts: btreeset!{NoMul, NoJmp, NoElpm, NoEspm, NoEicall, NoEijmp} },
150 "ATtiny4313" => Device {flash_size: 2048, ram_start: 0x60, ram_size: 256, eeprom_size: 256, disable_opts: btreeset!{NoMul, NoJmp, NoElpm, NoEspm, NoEicall, NoEijmp} },
151 "AT90S1200" => Device {flash_size: 512, ram_start: 0x00, ram_size: 0, eeprom_size: 64, disable_opts: btreeset!{NoMul, NoJmp, Tiny1x, NoXreg, NoYreg, NoLpm, NoElpm, NoSpm, NoEspm, NoMovw, NoBreak, NoEicall, NoEijmp} }, "AT90S2313" => Device {flash_size: 1024, ram_start: 0x60, ram_size: 128, eeprom_size: 128, disable_opts: btreeset!{NoMul, NoJmp, NoLpmX, NoElpm, NoSpm, NoEspm, NoMovw, NoBreak, NoEicall, NoEijmp} },
154 "AT90S2323" => Device {flash_size: 1024, ram_start: 0x60, ram_size: 128, eeprom_size: 128, disable_opts: btreeset!{NoMul, NoJmp, NoLpmX, NoElpm, NoSpm, NoEspm, NoMovw, NoBreak, NoEicall, NoEijmp} },
155 "AT90S2333" => Device {flash_size: 1024, ram_start: 0x60, ram_size: 128, eeprom_size: 128, disable_opts: btreeset!{NoMul, NoJmp, NoLpmX, NoElpm, NoSpm, NoEspm, NoMovw, NoBreak, NoEicall, NoEijmp} },
156 "AT90S2343" => Device {flash_size: 1024, ram_start: 0x60, ram_size: 128, eeprom_size: 128, disable_opts: btreeset!{NoMul, NoJmp, NoLpmX, NoElpm, NoSpm, NoEspm, NoMovw, NoBreak, NoEicall, NoEijmp} },
157 "AT90S4414" => Device {flash_size: 2048, ram_start: 0x60, ram_size: 256, eeprom_size: 256, disable_opts: btreeset!{NoMul, NoJmp, NoLpmX, NoElpm, NoSpm, NoEspm, NoMovw, NoBreak, NoEicall, NoEijmp} },
158 "AT90S4433" => Device {flash_size: 2048, ram_start: 0x60, ram_size: 128, eeprom_size: 256, disable_opts: btreeset!{NoMul, NoJmp, NoLpmX, NoElpm, NoSpm, NoEspm, NoMovw, NoBreak, NoEicall, NoEijmp} },
159 "AT90S4434" => Device {flash_size: 2048, ram_start: 0x60, ram_size: 256, eeprom_size: 256, disable_opts: btreeset!{NoMul, NoJmp, NoLpmX, NoElpm, NoSpm, NoEspm, NoMovw, NoBreak, NoEicall, NoEijmp} },
160 "AT90S8515" => Device {flash_size: 4096, ram_start: 0x60, ram_size: 512, eeprom_size: 512, disable_opts: btreeset!{NoMul, NoJmp, NoLpmX, NoElpm, NoSpm, NoEspm, NoMovw, NoBreak, NoEicall, NoEijmp} }, "AT90C8534" => Device {flash_size: 4096, ram_start: 0x60, ram_size: 256, eeprom_size: 512, disable_opts: btreeset!{NoMul, NoJmp, NoLpmX, NoElpm, NoSpm, NoEspm, NoMovw, NoBreak, NoEicall, NoEijmp} },
162 "AT90S8535" => Device {flash_size: 4096, ram_start: 0x60, ram_size: 512, eeprom_size: 512, disable_opts: btreeset!{NoMul, NoJmp, NoLpmX, NoElpm, NoSpm, NoEspm, NoMovw, NoBreak, NoEicall, NoEijmp} },
163 "ATmega8" => Device {flash_size: 4096, ram_start: 0x60, ram_size: 1024, eeprom_size: 512, disable_opts: btreeset!{NoJmp, NoEicall, NoEijmp, NoElpm, NoEspm} },
168 "ATmega161" => Device {flash_size: 8192, ram_start: 0x60, ram_size: 1024, eeprom_size: 512, disable_opts: btreeset!{NoEicall, NoEijmp, NoElpm, NoEspm} },
169 "ATmega162" => Device {flash_size: 8192, ram_start: 0x100, ram_size: 1024, eeprom_size: 512, disable_opts: btreeset!{NoEicall, NoEijmp, NoElpm, NoEspm} },
170 "ATmega163" => Device {flash_size: 8192, ram_start: 0x60, ram_size: 1024, eeprom_size: 512, disable_opts: btreeset!{NoEicall, NoEijmp, NoElpm, NoEspm} },
171 "ATmega16" => Device {flash_size: 8192, ram_start: 0x60, ram_size: 1024, eeprom_size: 512, disable_opts: btreeset!{NoEicall, NoEijmp, NoElpm, NoEspm} },
172 "ATmega323" => Device {flash_size: 16384, ram_start: 0x60, ram_size: 2048, eeprom_size: 1024, disable_opts: btreeset!{NoEicall, NoEijmp, NoElpm, NoEspm} }, "ATmega328P" => Device {flash_size: 16384, ram_start: 0x100, ram_size: 2048, eeprom_size: 1024, disable_opts: btreeset!{NoEicall, NoEijmp, NoElpm, NoEspm} },
174 "ATmega32" => Device {flash_size: 16384, ram_start: 0x60, ram_size: 2048, eeprom_size: 1024, disable_opts: btreeset!{NoEicall, NoEijmp, NoElpm, NoEspm} },
175 "ATmega603" => Device {flash_size: 32768, ram_start: 0x60, ram_size: 4096, eeprom_size: 2048, disable_opts: btreeset!{NoEicall, NoEijmp, NoMul, NoMovw, NoLpmX, NoElpm, NoSpm, NoEspm, NoBreak} },
176 "ATmega103" => Device {flash_size: 65536, ram_start: 0x60, ram_size: 4096, eeprom_size: 4096, disable_opts: btreeset!{NoEicall, NoEijmp, NoMul, NoMovw, NoLpmX, NoElpmX, NoSpm, NoEspm, NoBreak} }, "ATmega104" => Device {flash_size: 65536, ram_start: 0x60, ram_size: 4096, eeprom_size: 4096, disable_opts: btreeset!{NoEicall, NoEijmp, NoEspm} }, "ATmega128" => Device {flash_size: 65536, ram_start: 0x100, ram_size: 4096, eeprom_size: 4096, disable_opts: btreeset!{NoEicall, NoEijmp, NoEspm} }, "ATmega48" => Device {flash_size: 2048, ram_start: 0x100, ram_size: 512, eeprom_size: 256, disable_opts: btreeset!{NoEicall, NoEijmp, NoElpm, NoEspm} },
180 "ATmega88" => Device {flash_size: 4096, ram_start: 0x100, ram_size: 1024, eeprom_size: 512, disable_opts: btreeset!{NoEicall, NoEijmp, NoElpm, NoEspm} },
181 "ATmega168" => Device {flash_size: 8192, ram_start: 0x100, ram_size: 1024, eeprom_size: 512, disable_opts: btreeset!{NoEicall, NoEijmp, NoElpm, NoEspm} },
182 "ATmega644" => Device {flash_size: 65536, ram_start: 0x100, ram_size: 4096, eeprom_size: 2048, disable_opts: btreeset!{NoEicall, NoEijmp, NoElpm, NoEspm} },
183 "ATmega8515" => Device {flash_size: 8192, ram_start: 0x60, ram_size: 512, eeprom_size: 512, disable_opts: btreeset!{NoEicall, NoEijmp, NoElpm, NoEspm} },
184 "ATmega1280" => Device {flash_size: 65536, ram_start: 0x200, ram_size: 8192, eeprom_size: 4096, disable_opts: btreeset!{NoEicall, NoEijmp, NoEspm} },
185 "ATmega2560" => Device {flash_size: 262144, ram_start: 0x200, ram_size: 8192, eeprom_size: 4096, disable_opts: btreeset!{NoEspm} },
186 "AT94K" => Device {flash_size: 8192, ram_start: 0x60, ram_size: 16384, eeprom_size: 0, disable_opts: btreeset!{NoEicall, NoEijmp, NoElpm, NoSpm, NoEspm, NoBreak} }, }
189});