use crate::isa::Long;
use std::error::Error;
use std::fmt::{self, Display, Formatter};
use std::hint::select_unpredictable;
#[repr(transparent)]
#[derive(Copy, Debug)]
#[derive_const(
Clone,
Eq,
Ord,
PartialEq,
PartialOrd,
)]
pub struct Exception(u8);
impl Exception {
pub const ACCESS_FAULT: Self = Self::from_u8(2);
pub const ADDRESS_ERROR: Self = Self::from_u8(3);
pub const ILLEGAL_INSTRUCTION: Self = Self::from_u8(4);
pub const INTEGER_DIVIDE_BY_ZERO: Self = Self::from_u8(5);
#[inline(always)]
#[must_use]
pub const fn from_u8(value: u8) -> Self {
Self(value)
}
#[inline]
#[must_use]
pub const fn from_addr(addr: Long) -> Option<Self> {
let value = addr.as_u32() >> 2;
let exception = Self::from_u8(value.truncate::<u8>());
select_unpredictable(
addr.as_usize() < 0x400,
Some(exception),
None,
)
}
#[inline]
#[must_use]
pub const fn trap(index: u8) -> Self {
const TRAP_BASE: u8 = 32;
assert!(
index <= 15,
"cannot construct trap exception with index greater than `15`",
);
Self::from_u8(TRAP_BASE + index)
}
#[inline]
#[must_use]
pub const fn addr(self) -> Long {
Long::from(u32::from(self.as_u8()) << 2)
}
#[inline(always)]
#[must_use]
pub const fn as_u8(self) -> u8 {
self.0
}
#[inline]
#[must_use]
pub const fn as_str(self) -> &'static str {
match self.0 {
000 => "reset initial stack pointer",
001 => "reset initial programme counter",
002 => "access fault",
003 => "address error",
004 => "illegal instruction",
005 => "integer divide by zero",
006 => "`chk` or `chk2` instruction",
007 => "`ftrapcc` or `trapcc` or `trapv` instruction",
008 => "privilege violation",
009 => "trace",
010 => "line `1010` emulator",
011 => "line `1111` emulator",
012 => "unknown exception `12`",
013 => "coprocessor protocol violation",
014 => "format error",
015 => "uninitialised interrupt",
016 => "unknown exception `16`",
017 => "unknown exception `17`",
018 => "unknown exception `18`",
019 => "unknown exception `19`",
020 => "unknown exception `20`",
021 => "unknown exception `21`",
022 => "unknown exception `22`",
023 => "unknown exception `23`",
024 => "spurious interrupt",
025 => "level `1` interrupt autovector",
026 => "level `2` interrupt autovector",
027 => "level `3` interrupt autovector",
028 => "level `4` interrupt autovector",
029 => "level `5` interrupt autovector",
030 => "level `6` interrupt autovector",
031 => "level `7` interrupt autovector",
032 => "`trap #0` instruction",
033 => "`trap #1` instruction",
034 => "`trap #2` instruction",
035 => "`trap #3` instruction",
036 => "`trap #4` instruction",
037 => "`trap #5` instruction",
038 => "`trap #6` instruction",
039 => "`trap #7` instruction",
040 => "`trap #8` instruction",
041 => "`trap #9` instruction",
042 => "`trap #10` instruction",
043 => "`trap #11` instruction",
044 => "`trap #12` instruction",
045 => "`trap #13` instruction",
046 => "`trap #14` instruction",
047 => "`trap #15` instruction",
048 => "fp branch or set on unordered condition",
049 => "fp inexact result",
050 => "fp divide by zero",
051 => "fp underflow",
052 => "fp operand error",
053 => "fp overflow",
054 => "fp signaling nan",
055 => "fp unimplemented data type",
056 => "mmu configuration error",
057 => "mmu illeagl operation error",
058 => "mmu access level violation error",
059 => "unknown exception `59`",
060 => "unknown exception `60`",
061 => "unknown exception `61`",
062 => "unknown exception `62`",
063 => "unknown exception `63`",
064 => "user defined vector `1`",
065 => "user defined vector `2`",
066 => "user defined vector `3`",
067 => "user defined vector `4`",
068 => "user defined vector `5`",
069 => "user defined vector `6`",
070 => "user defined vector `7`",
071 => "user defined vector `8`",
072 => "user defined vector `9`",
073 => "user defined vector `10`",
074 => "user defined vector `11`",
075 => "user defined vector `12`",
076 => "user defined vector `13`",
077 => "user defined vector `14`",
078 => "user defined vector `15`",
079 => "user defined vector `16`",
080 => "user defined vector `17`",
081 => "user defined vector `18`",
082 => "user defined vector `19`",
083 => "user defined vector `20`",
084 => "user defined vector `21`",
085 => "user defined vector `22`",
086 => "user defined vector `23`",
087 => "user defined vector `24`",
088 => "user defined vector `25`",
089 => "user defined vector `26`",
090 => "user defined vector `27`",
091 => "user defined vector `28`",
092 => "user defined vector `29`",
093 => "user defined vector `30`",
094 => "user defined vector `31`",
095 => "user defined vector `32`",
096 => "user defined vector `33`",
097 => "user defined vector `34`",
098 => "user defined vector `35`",
099 => "user defined vector `36`",
100 => "user defined vector `37`",
101 => "user defined vector `38`",
102 => "user defined vector `39`",
103 => "user defined vector `40`",
104 => "user defined vector `41`",
105 => "user defined vector `42`",
106 => "user defined vector `43`",
107 => "user defined vector `44`",
108 => "user defined vector `45`",
109 => "user defined vector `46`",
110 => "user defined vector `47`",
111 => "user defined vector `48`",
112 => "user defined vector `49`",
113 => "user defined vector `50`",
114 => "user defined vector `51`",
115 => "user defined vector `52`",
116 => "user defined vector `53`",
117 => "user defined vector `54`",
118 => "user defined vector `55`",
119 => "user defined vector `56`",
120 => "user defined vector `57`",
121 => "user defined vector `58`",
122 => "user defined vector `59`",
123 => "user defined vector `60`",
124 => "user defined vector `61`",
125 => "user defined vector `62`",
126 => "user defined vector `63`",
127 => "user defined vector `64`",
128 => "user defined vector `65`",
129 => "user defined vector `66`",
130 => "user defined vector `67`",
131 => "user defined vector `68`",
132 => "user defined vector `69`",
133 => "user defined vector `70`",
134 => "user defined vector `71`",
135 => "user defined vector `72`",
136 => "user defined vector `73`",
137 => "user defined vector `74`",
138 => "user defined vector `75`",
139 => "user defined vector `76`",
140 => "user defined vector `77`",
141 => "user defined vector `78`",
142 => "user defined vector `79`",
143 => "user defined vector `80`",
144 => "user defined vector `81`",
145 => "user defined vector `82`",
146 => "user defined vector `83`",
147 => "user defined vector `84`",
148 => "user defined vector `85`",
149 => "user defined vector `86`",
150 => "user defined vector `87`",
151 => "user defined vector `88`",
152 => "user defined vector `89`",
153 => "user defined vector `90`",
154 => "user defined vector `91`",
155 => "user defined vector `92`",
156 => "user defined vector `93`",
157 => "user defined vector `94`",
158 => "user defined vector `95`",
159 => "user defined vector `96`",
160 => "user defined vector `97`",
161 => "user defined vector `98`",
162 => "user defined vector `99`",
163 => "user defined vector `100`",
164 => "user defined vector `101`",
165 => "user defined vector `102`",
166 => "user defined vector `103`",
167 => "user defined vector `104`",
168 => "user defined vector `105`",
169 => "user defined vector `106`",
170 => "user defined vector `107`",
171 => "user defined vector `108`",
172 => "user defined vector `109`",
173 => "user defined vector `110`",
174 => "user defined vector `111`",
175 => "user defined vector `112`",
176 => "user defined vector `113`",
177 => "user defined vector `114`",
178 => "user defined vector `115`",
179 => "user defined vector `116`",
180 => "user defined vector `117`",
181 => "user defined vector `118`",
182 => "user defined vector `119`",
183 => "user defined vector `120`",
184 => "user defined vector `121`",
185 => "user defined vector `122`",
186 => "user defined vector `123`",
187 => "user defined vector `124`",
188 => "user defined vector `125`",
189 => "user defined vector `126`",
190 => "user defined vector `127`",
191 => "user defined vector `128`",
192 => "user defined vector `129`",
193 => "user defined vector `130`",
194 => "user defined vector `131`",
195 => "user defined vector `132`",
196 => "user defined vector `133`",
197 => "user defined vector `134`",
198 => "user defined vector `135`",
199 => "user defined vector `136`",
200 => "user defined vector `137`",
201 => "user defined vector `138`",
202 => "user defined vector `139`",
203 => "user defined vector `140`",
204 => "user defined vector `141`",
205 => "user defined vector `142`",
206 => "user defined vector `143`",
207 => "user defined vector `144`",
208 => "user defined vector `145`",
209 => "user defined vector `146`",
210 => "user defined vector `147`",
211 => "user defined vector `148`",
212 => "user defined vector `149`",
213 => "user defined vector `150`",
214 => "user defined vector `151`",
215 => "user defined vector `152`",
216 => "user defined vector `153`",
217 => "user defined vector `154`",
218 => "user defined vector `155`",
219 => "user defined vector `156`",
220 => "user defined vector `157`",
221 => "user defined vector `158`",
222 => "user defined vector `159`",
223 => "user defined vector `160`",
224 => "user defined vector `161`",
225 => "user defined vector `162`",
226 => "user defined vector `163`",
227 => "user defined vector `164`",
228 => "user defined vector `165`",
229 => "user defined vector `166`",
230 => "user defined vector `167`",
231 => "user defined vector `168`",
232 => "user defined vector `169`",
233 => "user defined vector `170`",
234 => "user defined vector `171`",
235 => "user defined vector `172`",
236 => "user defined vector `173`",
237 => "user defined vector `174`",
238 => "user defined vector `175`",
239 => "user defined vector `176`",
240 => "user defined vector `177`",
241 => "user defined vector `178`",
242 => "user defined vector `179`",
243 => "user defined vector `180`",
244 => "user defined vector `181`",
245 => "user defined vector `182`",
246 => "user defined vector `183`",
247 => "user defined vector `184`",
248 => "user defined vector `185`",
249 => "user defined vector `186`",
250 => "user defined vector `187`",
251 => "user defined vector `188`",
252 => "user defined vector `189`",
253 => "user defined vector `190`",
254 => "user defined vector `191`",
255 => "user defined vector `192`",
}
}
}
impl Display for Exception {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
impl Error for Exception {}