1use crate::{types::TypeSize, utils::half_float::HFloat};
2
3pub type Reg = u8; pub type ConstPos = u16;
5pub type GlobalPos = u8;
6pub type Offset = i16;
7pub type StateOffset = intx::U24;
9#[derive(Debug, Clone, Copy, PartialEq)]
11pub enum Instruction {
12 Move(Reg, Reg),
14 MoveConst(Reg, ConstPos),
16 MoveImmF(Reg, HFloat),
18 MoveRange(Reg, Reg, TypeSize),
20 Call(Reg, u8, TypeSize),
23 CallCls(Reg, u8, TypeSize),
25 CallExtFun(Reg, u8, TypeSize),
31 Closure(Reg, Reg),
33 Close(Reg),
35 GetUpValue(Reg, Reg, TypeSize),
37 SetUpValue(Reg, Reg, TypeSize),
38
39 GetGlobal(Reg, GlobalPos, TypeSize),
41 SetGlobal(GlobalPos, Reg, TypeSize),
42 GetState(Reg, TypeSize),
44 SetState(Reg, TypeSize),
45 PushStatePos(StateOffset),
46 PopStatePos(StateOffset),
47
48 Return0,
50 Return(Reg, TypeSize),
52 Delay(Reg, Reg, Reg),
54 Mem(Reg, Reg),
55
56 Jmp(Offset),
58 JmpIfNeg(Reg, Offset),
60
61 AddF(Reg, Reg, Reg),
64 SubF(Reg, Reg, Reg),
65 MulF(Reg, Reg, Reg),
66 DivF(Reg, Reg, Reg),
67 ModF(Reg, Reg, Reg),
68 NegF(Reg, Reg),
69 AbsF(Reg, Reg),
70 SqrtF(Reg, Reg),
71 SinF(Reg, Reg),
72 CosF(Reg, Reg),
73 PowF(Reg, Reg, Reg),
74 LogF(Reg, Reg),
75
76 AddI(Reg, Reg, Reg),
78 SubI(Reg, Reg, Reg),
79 MulI(Reg, Reg, Reg),
80 DivI(Reg, Reg, Reg),
81 ModI(Reg, Reg, Reg),
82 NegI(Reg, Reg),
83 AbsI(Reg, Reg),
84
85 PowI(Reg, Reg, Reg),
86 LogI(Reg, Reg, Reg),
87 Not(Reg, Reg),
89 Eq(Reg, Reg, Reg),
90 Ne(Reg, Reg, Reg),
91 Gt(Reg, Reg, Reg),
92 Ge(Reg, Reg, Reg),
93 Lt(Reg, Reg, Reg),
94 Le(Reg, Reg, Reg),
95 And(Reg, Reg, Reg),
96 Or(Reg, Reg, Reg),
97
98 CastFtoI(Reg, Reg),
99 CastItoF(Reg, Reg),
100 CastItoB(Reg, Reg),
101 AllocArray(Reg, Reg, TypeSize),
104 GetArrayElem(Reg, Reg, Reg),
106 SetArrayElem(Reg, Reg, Reg),
109
110 Dummy,
112}
113
114impl std::fmt::Display for Instruction {
115 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
116 match self {
117 Instruction::Return0 => write!(f, "ret0"),
118 Instruction::Jmp(dst) => write!(f, "{:<10} {}", "jmp", dst),
119 Instruction::GetState(dst, size) => write!(f, "{:<10} {} {}", "getstate", dst, size),
120 Instruction::SetState(src, size) => write!(f, "{:<10} {} {}", "setstate", src, size),
121 Instruction::PushStatePos(v) => write!(f, "{:<10} {}", "pushsttpos", v),
122 Instruction::PopStatePos(v) => write!(f, "{:<10} {}", "popsttpos", v),
123 Instruction::Move(dst, src) => write!(f, "{:<10} {} {}", "mov", dst, src),
124 Instruction::MoveConst(dst, num) => write!(f, "{:<10} {} {}", "movc", dst, num),
125 Instruction::MoveImmF(dst, v) => write!(f, "{:<10} {} {}", "movimmF", dst, v),
126 Instruction::MoveRange(dst, src, n) => {
127 write!(
128 f,
129 "{:<10} {}-{} {}-{}",
130 "mov",
131 dst,
132 dst + n - 1,
133 src,
134 src + n - 1
135 )
136 }
137 Instruction::Closure(dst, src) => {
138 write!(f, "{:<10} {} {}", "closure", dst, src)
139 }
140 Instruction::Close(src) => {
141 write!(f, "{:<10} {}", "close", src)
142 }
143 Instruction::Delay(dst, src, time) => {
144 write!(f, "{:<10} {} {} {}", "delay", dst, src, time)
145 }
146 Instruction::Mem(dst, src) => {
147 write!(f, "{:<10} {} {}", "mem", dst, src)
148 }
149 Instruction::Return(iret, nret) => write!(f, "{:<10} {} {}", "ret", iret, nret),
150 Instruction::GetUpValue(dst, srcup, size) => {
151 write!(f, "{:<10} {} {} {}", "getupv", dst, srcup, size)
152 }
153 Instruction::SetUpValue(dstup, src, size) => {
154 write!(f, "{:<10} {} {} {}", "setupv", dstup, src, size)
155 }
156 Instruction::GetGlobal(dst, src, size) => {
157 write!(f, "{:<10} {} {} {}", "getglobal", dst, src, size)
158 }
159 Instruction::SetGlobal(dst, src, size) => {
160 write!(f, "{:<10} {} {} {}", "setglobal", dst, src, size)
161 }
162 Instruction::JmpIfNeg(dst, cond) => write!(f, "{:<10} {} {}", "jmpifneg", dst, cond),
163 Instruction::AbsF(dst, src) => write!(f, "{:<10} {} {}", "absf", dst, src),
164 Instruction::NegF(dst, src) => write!(f, "{:<10} {} {}", "negf", dst, src),
165 Instruction::SinF(dst, src) => write!(f, "{:<10} {} {}", "sin", dst, src),
166 Instruction::CosF(dst, src) => write!(f, "{:<10} {} {}", "cos", dst, src),
167 Instruction::SqrtF(dst, src) => write!(f, "{:<10} {} {}", "sqrt", dst, src),
168 Instruction::LogF(dst, src) => write!(f, "{:<10} {} {} ", "logf", dst, src),
169 Instruction::AbsI(dst, src) => write!(f, "{:<10} {} {}", "abs", dst, src),
170 Instruction::NegI(dst, src) => write!(f, "{:<10} {} {}", "neg", dst, src),
171 Instruction::Not(dst, src) => write!(f, "{:<10} {} {}", "not", dst, src),
172 Instruction::CastFtoI(dst, src) => write!(f, "{:<10} {} {}", "f2i", dst, src),
173 Instruction::CastItoF(dst, src) => write!(f, "{:<10} {} {}", "i2f", dst, src),
174 Instruction::CastItoB(dst, src) => write!(f, "{:<10} {} {}", "i2b", dst, src),
175 Instruction::Call(func, nargs, nret_req) => {
176 write!(f, "{:<10} {} {} {}", "call", func, nargs, nret_req)
177 }
178 Instruction::CallCls(func, nargs, nret_req) => {
179 write!(f, "{:<10} {} {} {}", "callcls", func, nargs, nret_req)
180 }
181 Instruction::CallExtFun(func, nargs, nret_req) => {
182 write!(f, "{:<10} {} {} {}", "callext", func, nargs, nret_req)
183 }
184 Instruction::LogI(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "logi", dst, lhs, rhs),
185 Instruction::PowI(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "powi", dst, lhs, rhs),
186 Instruction::AddF(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "addf", dst, lhs, rhs),
187 Instruction::SubF(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "subf", dst, lhs, rhs),
188 Instruction::MulF(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "mulf", dst, lhs, rhs),
189 Instruction::DivF(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "divf", dst, lhs, rhs),
190 Instruction::ModF(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "modf", dst, lhs, rhs),
191 Instruction::PowF(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "powf", dst, lhs, rhs),
192 Instruction::AddI(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "add", dst, lhs, rhs),
193 Instruction::SubI(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "sub", dst, lhs, rhs),
194 Instruction::MulI(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "mul", dst, lhs, rhs),
195 Instruction::DivI(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "div", dst, lhs, rhs),
196 Instruction::ModI(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "mod", dst, lhs, rhs),
197 Instruction::Eq(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "eq", dst, lhs, rhs),
198 Instruction::Ne(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "ne", dst, lhs, rhs),
199 Instruction::Gt(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "gt", dst, lhs, rhs),
200 Instruction::Ge(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "ge", dst, lhs, rhs),
201 Instruction::Lt(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "le", dst, lhs, rhs),
202 Instruction::Le(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "lt", dst, lhs, rhs),
203 Instruction::And(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "and", dst, lhs, rhs),
204 Instruction::Or(dst, lhs, rhs) => write!(f, "{:<10} {} {} {}", "or", dst, lhs, rhs),
205 Instruction::AllocArray(dst, size, typesize) => {
206 write!(f, "{:<10} {} {} {}", "array", dst, size, typesize)
207 }
208 Instruction::GetArrayElem(dst, arr, idx) => {
209 write!(f, "{:<10} {} {} {}", "getarray", dst, arr, idx)
210 }
211 Instruction::SetArrayElem(arr, idx, val) => {
212 write!(f, "{:<10} {} {} {}", "setarray", arr, idx, val)
213 }
214 Instruction::Dummy => write!(f, "dummy"),
215 }
216 }
217}
218
219#[cfg(test)]
220#[test]
221fn ensure_bytecode_size() {
222 let size = std::mem::size_of::<Instruction>();
223 assert_eq!(4, size);
224}