1use crate::{interner::TypeNodeId, types::TypeSize, utils::half_float::HFloat};
2
3pub type Reg = u16; pub type ConstPos = u16;
5pub type GlobalPos = u8;
6pub type Offset = i16;
7pub type ShotrOffset = i8;
8pub type TypeTableIndex = u8;
9pub type StateOffset = intx::U24;
11#[derive(Debug, Clone, Copy, PartialEq)]
13pub enum Instruction {
14 Move(Reg, Reg),
16 MoveConst(Reg, ConstPos),
18 MoveImmF(Reg, HFloat),
20 MoveRange(Reg, Reg, TypeSize),
22 Call(Reg, u8, TypeSize),
25 CallCls(Reg, u8, TypeSize),
27 CallExtFun(Reg, u8, TypeSize),
33 Closure(Reg, Reg),
35 Close(Reg),
37
38 MakeHeapClosure(Reg, Reg, TypeSize),
42 CloseHeapClosure(Reg),
44 CloneHeap(Reg),
47 CallIndirect(Reg, u8, TypeSize),
49
50 BoxAlloc(Reg, Reg, TypeSize),
54 BoxLoad(Reg, Reg, TypeSize),
58 BoxClone(Reg),
61 BoxRelease(Reg),
64 BoxStore(Reg, Reg, TypeSize),
67 CloneUserSum(Reg, TypeSize, TypeTableIndex),
71 ReleaseUserSum(Reg, TypeSize, TypeTableIndex),
75
76 GetUpValue(Reg, Reg, TypeSize),
78 SetUpValue(Reg, Reg, TypeSize),
79
80 GetGlobal(Reg, GlobalPos, TypeSize),
82 SetGlobal(GlobalPos, Reg, TypeSize),
83 GetState(Reg, TypeSize),
85 SetState(Reg, TypeSize),
86 PushStatePos(StateOffset),
87 PopStatePos(StateOffset),
88
89 Return0,
91 Return(Reg, TypeSize),
93 Delay(Reg, Reg, Reg),
95 Mem(Reg, Reg),
96
97 Jmp(Offset),
99 JmpIfNeg(Reg, Offset),
101 JmpTable(Reg, u8),
106
107 AddF(Reg, Reg, Reg),
110 SubF(Reg, Reg, Reg),
111 MulF(Reg, Reg, Reg),
112 DivF(Reg, Reg, Reg),
113 ModF(Reg, Reg, Reg),
114 NegF(Reg, Reg),
115 AbsF(Reg, Reg),
116 SqrtF(Reg, Reg),
117 SinF(Reg, Reg),
118 CosF(Reg, Reg),
119 PowF(Reg, Reg, Reg),
120 LogF(Reg, Reg),
121
122 AddI(Reg, Reg, Reg),
124 SubI(Reg, Reg, Reg),
125 MulI(Reg, Reg, Reg),
126 DivI(Reg, Reg, Reg),
127 ModI(Reg, Reg, Reg),
128 NegI(Reg, Reg),
129 AbsI(Reg, Reg),
130
131 PowI(Reg, Reg, Reg),
132 LogI(Reg, Reg, Reg),
133 Not(Reg, Reg),
135 Eq(Reg, Reg, Reg),
136 Ne(Reg, Reg, Reg),
137 Gt(Reg, Reg, Reg),
138 Ge(Reg, Reg, Reg),
139 Lt(Reg, Reg, Reg),
140 Le(Reg, Reg, Reg),
141 And(Reg, Reg, Reg),
142 Or(Reg, Reg, Reg),
143
144 CastFtoI(Reg, Reg),
145 CastItoF(Reg, Reg),
146 CastItoB(Reg, Reg),
147 AllocArray(Reg, Reg, TypeSize),
150 GetArrayElem(Reg, Reg, Reg),
152 SetArrayElem(Reg, Reg, Reg),
155
156 Dummy,
158}
159
160impl std::fmt::Display for Instruction {
161 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
162 match self {
163 Instruction::Return0 => write!(f, "ret0"),
164 Instruction::Jmp(dst) => write!(f, "{:<10} {}", "jmp", dst),
165 Instruction::GetState(dst, size) => write!(f, "{:<10} {} {}", "getstate", dst, size),
166 Instruction::SetState(src, size) => write!(f, "{:<10} {} {}", "setstate", src, size),
167 Instruction::PushStatePos(v) => write!(f, "{:<10} {}", "pushsttpos", v),
168 Instruction::PopStatePos(v) => write!(f, "{:<10} {}", "popsttpos", v),
169 Instruction::Move(dst, src) => write!(f, "{:<10} {} {}", "mov", dst, src),
170 Instruction::MoveConst(dst, num) => write!(f, "{:<10} {} {}", "movc", dst, num),
171 Instruction::MoveImmF(dst, v) => write!(f, "{:<10} {} {}", "movimmF", dst, v),
172 Instruction::MoveRange(dst, src, n) => {
173 write!(
174 f,
175 "{:<10} {}-{} {}-{}",
176 "mov",
177 dst,
178 dst + n - 1,
179 src,
180 src + n - 1
181 )
182 }
183 Instruction::Closure(dst, src) => {
184 write!(f, "{:<10} {} {}", "closure", dst, src)
185 }
186 Instruction::Close(src) => {
187 write!(f, "{:<10} {}", "close", src)
188 }
189 Instruction::MakeHeapClosure(dst, fn_idx, size) => {
191 write!(f, "{:<10} {} {} {}", "mkheapcls", dst, fn_idx, size)
192 }
193 Instruction::CloseHeapClosure(addr) => {
194 write!(f, "{:<10} {}", "clsheapcls", addr)
195 }
196 Instruction::CloneHeap(addr) => {
197 write!(f, "{:<10} {}", "cloneheap", addr)
198 }
199 Instruction::CallIndirect(func, nargs, nret_req) => {
200 write!(f, "{:<10} {} {} {}", "callind", func, nargs, nret_req)
201 }
202 Instruction::BoxAlloc(dst, src, size) => {
203 write!(f, "{:<10} {} {} {}", "boxalloc", dst, src, size)
204 }
205 Instruction::BoxLoad(dst, src, size) => {
206 write!(f, "{:<10} {} {} {}", "boxload", dst, src, size)
207 }
208 Instruction::BoxClone(src) => {
209 write!(f, "{:<10} {}", "boxclone", src)
210 }
211 Instruction::BoxRelease(src) => {
212 write!(f, "{:<10} {}", "boxrelease", src)
213 }
214 Instruction::BoxStore(dst, src, size) => {
215 write!(f, "{:<10} {} {} {}", "boxstore", dst, src, size)
216 }
217 Instruction::CloneUserSum(src, size, type_idx) => {
218 write!(
219 f,
220 "{:<10} {} {} type_idx:{}",
221 "clone_usersum", src, size, type_idx
222 )
223 }
224 Instruction::ReleaseUserSum(src, size, type_idx) => {
225 write!(
226 f,
227 "{:<10} {} {} type_idx:{}",
228 "release_usersum", src, size, type_idx
229 )
230 }
231 Instruction::Delay(dst, src, time) => {
232 write!(f, "{:<10} {} {} {}", "delay", dst, src, time)
233 }
234 Instruction::Mem(dst, src) => {
235 write!(f, "{:<10} {} {}", "mem", dst, src)
236 }
237 Instruction::Return(iret, nret) => write!(f, "{:<10} {} {}", "ret", iret, nret),
238 Instruction::GetUpValue(dst, srcup, size) => {
239 write!(f, "{:<10} {} {} {}", "getupv", dst, srcup, size)
240 }
241 Instruction::SetUpValue(dstup, src, size) => {
242 write!(f, "{:<10} {} {} {}", "setupv", dstup, src, size)
243 }
244 Instruction::GetGlobal(dst, src, size) => {
245 write!(f, "{:<10} {} {} {}", "getglobal", dst, src, size)
246 }
247 Instruction::SetGlobal(dst, src, size) => {
248 write!(f, "{:<10} {} {} {}", "setglobal", dst, src, size)
249 }
250 Instruction::JmpIfNeg(dst, cond) => write!(f, "{:<10} {} {}", "jmpifneg", dst, cond),
251 Instruction::JmpTable(scrut, table_idx) => {
252 write!(f, "{:<10} {} {}", "jmptable", scrut, table_idx)
253 }
254 Instruction::AbsF(dst, src) => write!(f, "{:<10} {} {}", "absf", dst, src),
255 Instruction::NegF(dst, src) => write!(f, "{:<10} {} {}", "negf", dst, src),
256 Instruction::SinF(dst, src) => write!(f, "{:<10} {} {}", "sin", dst, src),
257 Instruction::CosF(dst, src) => write!(f, "{:<10} {} {}", "cos", dst, src),
258 Instruction::SqrtF(dst, src) => write!(f, "{:<10} {} {}", "sqrt", dst, src),
259 Instruction::LogF(dst, src) => write!(f, "{:<10} {} {} ", "logf", dst, src),
260 Instruction::AbsI(dst, src) => write!(f, "{:<10} {} {}", "abs", dst, src),
261 Instruction::NegI(dst, src) => write!(f, "{:<10} {} {}", "neg", dst, src),
262 Instruction::Not(dst, src) => write!(f, "{:<10} {} {}", "not", dst, src),
263 Instruction::CastFtoI(dst, src) => write!(f, "{:<10} {} {}", "f2i", dst, src),
264 Instruction::CastItoF(dst, src) => write!(f, "{:<10} {} {}", "i2f", dst, src),
265 Instruction::CastItoB(dst, src) => write!(f, "{:<10} {} {}", "i2b", dst, src),
266 Instruction::Call(func, nargs, nret_req) => {
267 write!(f, "{:<10} {} {} {}", "call", func, nargs, nret_req)
268 }
269 Instruction::CallCls(func, nargs, nret_req) => {
270 write!(f, "{:<10} {} {} {}", "callcls", func, nargs, nret_req)
271 }
272 Instruction::CallExtFun(func, nargs, nret_req) => {
273 write!(f, "{:<10} {} {} {}", "callext", func, nargs, nret_req)
274 }
275 Instruction::LogI(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "logi", dst, lhs, rhs),
276 Instruction::PowI(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "powi", dst, lhs, rhs),
277 Instruction::AddF(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "addf", dst, lhs, rhs),
278 Instruction::SubF(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "subf", dst, lhs, rhs),
279 Instruction::MulF(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "mulf", dst, lhs, rhs),
280 Instruction::DivF(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "divf", dst, lhs, rhs),
281 Instruction::ModF(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "modf", dst, lhs, rhs),
282 Instruction::PowF(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "powf", dst, lhs, rhs),
283 Instruction::AddI(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "add", dst, lhs, rhs),
284 Instruction::SubI(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "sub", dst, lhs, rhs),
285 Instruction::MulI(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "mul", dst, lhs, rhs),
286 Instruction::DivI(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "div", dst, lhs, rhs),
287 Instruction::ModI(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "mod", dst, lhs, rhs),
288 Instruction::Eq(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "eq", dst, lhs, rhs),
289 Instruction::Ne(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "ne", dst, lhs, rhs),
290 Instruction::Gt(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "gt", dst, lhs, rhs),
291 Instruction::Ge(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "ge", dst, lhs, rhs),
292 Instruction::Lt(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "le", dst, lhs, rhs),
293 Instruction::Le(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "lt", dst, lhs, rhs),
294 Instruction::And(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "and", dst, lhs, rhs),
295 Instruction::Or(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "or", dst, lhs, rhs),
296 Instruction::AllocArray(dst, size, typesize) => {
297 write!(f, "{:<10} {} {} {}", "array", dst, size, typesize)
298 }
299 Instruction::GetArrayElem(dst, arr, idx) => {
300 write!(f, "{:<10} {} {} {}", "getarray", dst, arr, idx)
301 }
302 Instruction::SetArrayElem(arr, idx, val) => {
303 write!(f, "{:<10} {} {} {}", "setarray", arr, idx, val)
304 }
305 Instruction::Dummy => write!(f, "dummy"),
306 }
307 }
308}
309
310#[cfg(test)]
311#[test]
312fn ensure_bytecode_size() {
313 let size = std::mem::size_of::<Instruction>();
314 assert_eq!(8, size);
315}