1use core::{
3 fmt::{self, Display, Debug},
4 slice,
5};
6use crate::{
7 core::*,
8 stream::*,
9 module::*,
10};
11use super::*;
12#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
14pub struct IdResultType(pub(crate) u32);
15impl Display for IdResultType {
16
17 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18 write!(f, "%{}", self.0)
19 }
20}
21impl Word for IdResultType {
22
23 #[inline]
24 fn from_word(word: u32) -> Self {
25 Self(word)
26 }
27}
28#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
30pub struct IdResult(pub(crate) u32);
31impl Display for IdResult {
32
33 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34 write!(f, "%{}", self.0)
35 }
36}
37impl Word for IdResult {
38
39 #[inline]
40 fn from_word(word: u32) -> Self {
41 Self(word)
42 }
43}
44#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
47pub struct IdMemorySemantics(pub(crate) u32);
48impl Display for IdMemorySemantics {
49
50 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51 write!(f, "%{}", self.0)
52 }
53}
54impl Word for IdMemorySemantics {
55
56 #[inline]
57 fn from_word(word: u32) -> Self {
58 Self(word)
59 }
60}
61#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
63pub struct IdScope(pub(crate) u32);
64impl Display for IdScope {
65
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 write!(f, "%{}", self.0)
68 }
69}
70impl Word for IdScope {
71
72 #[inline]
73 fn from_word(word: u32) -> Self {
74 Self(word)
75 }
76}
77#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
79pub struct IdRef(pub(crate) u32);
80impl Display for IdRef {
81
82 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83 write!(f, "%{}", self.0)
84 }
85}
86impl Word for IdRef {
87
88 #[inline]
89 fn from_word(word: u32) -> Self {
90 Self(word)
91 }
92}
93impl From<IdResultType> for IdRef {
94
95 #[inline]
96 fn from(value: IdResultType) -> Self {
97 Self(value.0)
98 }
99}
100impl From<IdResult> for IdRef {
101
102 #[inline]
103 fn from(value: IdResult) -> Self {
104 Self(value.0)
105 }
106}
107pub type LiteralInteger = u32;
109pub type LiteralString<'a> = CompilerStr<'a>;
111pub type LiteralFloat = f32;
113impl Word for LiteralFloat {
114
115 #[inline]
116 fn from_word(word: u32) -> Self {
117 Self::from_bits(word)
118 }
119}
120pub type LiteralContextDependentNumber = Literal;
123impl<'a> LiteralContextDependentNumber {
124
125 pub fn parse_one(
126 module: &Module<'a>,
127 stream: &mut InstructionStream<'a>,
128 ctx: &mut ParseContext,
129 ) -> ParseResult<Self> {
130 let Some(result_type) = ctx.result_type else {
131 return Err(ParseError::ExpectedContextResultType)
132 };
133 let mut ty_stream = module
134 .get_result(result_type.into())
135 .ok_or(ParseError::InvalidIdResult(result_type.into()))?;
136 match ty_stream.code() {
137 Code::TYPE_INT => {
138 ty_stream.advance(1)?;
139 let width = ty_stream.read()?;
140 let signedness = ty_stream.read()?;
141 Ok(if signedness == 1 {
142 match width {
143 8 => Literal::I8(u8::cast_signed(
144 stream.read()? as u8
145 )),
146 16 => Literal::I16(u16::cast_signed(
147 stream.read()? as u16,
148 )),
149 32 => Literal::I32(u32::cast_signed(
150 stream.read()?,
151 )),
152 64 => Literal::I64(u64::cast_signed(
153 stream.read()? as u64 |
154 ((stream.read()? as u64) << 32)
155 )),
156 x => return Err(ParseError
157 ::InvalidIntLiteralWidth(x)
158 )
159 }
160 } else {
161 match width {
162 8 => Literal::U8(stream.read()? as u8),
163 16 => Literal::U16(stream.read()? as u16),
164 32 => Literal::U32(stream.read()?),
165 64 => Literal::U64(
166 stream.read()? as u64 |
167 ((stream.read()? as u64) << 32)
168 ),
169 x => return Err(ParseError
170 ::InvalidIntLiteralWidth(x)
171 )
172 }
173 })
174 },
175 Code::TYPE_FLOAT => {
176 ty_stream.advance(1)?;
177 let width = ty_stream.read()?;
178 Ok(match width {
179 16 => Literal::F16(stream.read()? as u16),
180 32 => Literal::F32(f32::from_bits(stream.read()?)),
181 64 => Literal::F64(f64::from_bits(
182 stream.read()? as u64 |
183 ((stream.read()? as u64) << 32)
184 )),
185 x => return Err(ParseError
186 ::InvalidFloatLiteralWidth(x)
187 )
188 })
189 },
190 x => Err(ParseError::InvalidType {
191 expected: "float or int type",
192 found: x,
193 })
194 }
195 }
196}
197pub type LiteralExtInstInteger = u32;
200#[derive(Clone, Copy, Debug)]
203pub struct LiteralSpecConstantOpInteger<'a> {
204 pub code: Code,
205 pub operands: &'a [IdRef],
206}
207impl<'a> LiteralSpecConstantOpInteger<'a> {
208
209 pub fn parse_one(
210 stream: &mut InstructionStream<'a>,
211 ) -> ParseResult<Self>
212 {
213 Ok(Self {
214 code: Code::from_word(stream.read()?),
215 operands: IdRef::parse_eos(stream)?,
216 })
217 }
218}
219impl<'a> Display for LiteralSpecConstantOpInteger<'a> {
220
221 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
222 write!(f, "{}", self.code)?;
223 for operand in self.operands {
224 write!(f, " {operand}")?;
225 }
226 Ok(())
227 }
228}
229#[repr(C)]
230#[derive(Clone, Copy, Debug)]
231pub struct Pair<T, U>(T, U)
232 where
233 T: Word + Debug + Display,
234 U: Word + Debug + Display;
235impl<T, U> Display for Pair<T, U>
236 where
237 T: Word + Debug + Display,
238 U: Word + Debug + Display,
239{
240
241 #[inline]
242 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
243 write!(f, "{} {}", self.0, self.1)
244 }
245}
246impl<'a, T, U> Pair<T, U>
247 where
248 T: Word + Debug + Display,
249 U: Word + Debug + Display,
250{
251
252 #[inline]
253 pub fn parse_one(
254 stream: &mut InstructionStream<'a>,
255 ) -> ParseResult<Self> {
256 Ok(Self(T::from_word(stream.read()?), U::from_word(stream.read()?)))
257 }
258
259 #[inline]
260 pub fn parse_eos(
261 stream: &mut InstructionStream<'a>,
262 ) -> ParseResult<&'a [Self]> {
263 let words = stream.read_words(None)?;
264 if !words.len().is_multiple_of(2) {
265 return Err(ParseError::InvalidPairWordCount(words.len() as u32))
266 }
267 unsafe {
268 Ok(slice::from_raw_parts(
269 words.as_ptr().cast(),
270 words.len() / 2
271 ))
272 }
273 }
274}
275pub type PairLiteralIntegerIdRef = Pair<LiteralInteger, IdRef>;
276pub type PairIdRefLiteralInteger = Pair<IdRef, LiteralInteger>;
277pub type PairIdRefIdRef = Pair<IdRef, IdRef>;
278#[derive(Default, Clone, Copy)]
279pub struct InstInfo {
280 pub name: &'static str,
281 pub has_id_result_type: bool,
282 pub has_id_result: bool,
283}