1pub mod Linux;
2
3
4use crate::Endian;
5
6
7#[derive (Clone, Copy, Debug, Eq, PartialEq)]
8enum MipsInstructionOpcode
9{
10 REG = 0b000000,
11 ADDI = 0b001000,
12 ADDIU = 0b001001,
13 SLTI = 0b001010,
14 SLTIU = 0b001011,
15 ANDI = 0b001100,
16 ORI = 0b001101,
17 XORI = 0b001110,
18 LUI = 0b001111,
19 LB = 0b100000,
20 LH = 0b100001,
21 LW = 0b100011,
22 LHU = 0b100101,
23 SH = 0b101001,
24 SW = 0b101011,
25 SB = 0b101000,
26 BEQ = 0b000100,
27 BNE = 0b000101,
28}
29
30
31#[derive (Clone, Copy, Debug, Eq, PartialEq)]
32enum MipsInstructionFunctionCode
33{
34 SYSCALL = 0b001100,
35 SYNC = 0x001111,
36 MFHI = 0b010000,
37 MTHI = 0b010001,
38 MFLO = 0b010010,
39 MTLO = 0b010011,
40 MULT = 0b011000,
41 MULTU = 0b011001,
42 DIV = 0b011010,
43 DIVU = 0b011011,
44 ADD = 0b100000,
45 ADDU = 0b100001,
46 SUB = 0b100010,
47 SUBU = 0b100011,
48 AND = 0b100100,
49 OR = 0b100101,
50 XOR = 0b100110,
51 NOR = 0b100111,
52 SLT = 0b101010,
53 SLTU = 0b101011,
54}
55
56
57#[derive (Clone, Copy, Debug, Eq, PartialEq)]
68pub enum MipsRegister
69{
70 ZERO = 0,
71 UNKNOWN1 = 1,
72 V0 = 2,
73 V1 = 3,
74 A0 = 4,
75 A1 = 5,
76 A2 = 6,
77 A3 = 7,
78 T0 = 8,
79 T1 = 9,
80 T2 = 10,
81 T3 = 11,
82 T4 = 12,
83 T5 = 13,
84 T6 = 14,
85 T7 = 15,
86 S0 = 16,
87 S1 = 17,
88 S2 = 18,
89 S3 = 19,
90 S4 = 20,
91 S5 = 21,
92 S6 = 22,
93 S7 = 23,
94 T8 = 24,
95 T9 = 25,
96 UNKNOWN26 = 26,
97 UNKNOWN27 = 27,
98 GP = 28,
99 SP = 29,
100 FP = 30,
101 RA = 31,
102}
103
104impl TryFrom<usize> for MipsRegister
105{
106 type Error = ();
107
108 fn try_from (value: usize) -> Result<Self, Self::Error>
109 {
110 match value
111 {
112 x if x == Self::ZERO as usize => Ok(Self::ZERO),
113 x if x == Self::UNKNOWN1 as usize => Ok(Self::UNKNOWN1),
114 x if x == Self::V0 as usize => Ok(Self::V0),
115 x if x == Self::V1 as usize => Ok(Self::V1),
116 x if x == Self::A0 as usize => Ok(Self::A0),
117 x if x == Self::A1 as usize => Ok(Self::A1),
118 x if x == Self::A2 as usize => Ok(Self::A2),
119 x if x == Self::A3 as usize => Ok(Self::A3),
120 x if x == Self::T0 as usize => Ok(Self::T0),
121 x if x == Self::T1 as usize => Ok(Self::T1),
122 x if x == Self::T2 as usize => Ok(Self::T2),
123 x if x == Self::T3 as usize => Ok(Self::T3),
124 x if x == Self::T4 as usize => Ok(Self::T4),
125 x if x == Self::T5 as usize => Ok(Self::T5),
126 x if x == Self::T6 as usize => Ok(Self::T6),
127 x if x == Self::T7 as usize => Ok(Self::T7),
128 x if x == Self::S0 as usize => Ok(Self::S0),
129 x if x == Self::S1 as usize => Ok(Self::S1),
130 x if x == Self::S2 as usize => Ok(Self::S2),
131 x if x == Self::S3 as usize => Ok(Self::S3),
132 x if x == Self::S4 as usize => Ok(Self::S4),
133 x if x == Self::S5 as usize => Ok(Self::S5),
134 x if x == Self::S6 as usize => Ok(Self::S6),
135 x if x == Self::S7 as usize => Ok(Self::S7),
136 x if x == Self::T8 as usize => Ok(Self::T8),
137 x if x == Self::T9 as usize => Ok(Self::T9),
138 x if x == Self::UNKNOWN26 as usize => Ok(Self::UNKNOWN26),
139 x if x == Self::UNKNOWN27 as usize => Ok(Self::UNKNOWN27),
140 x if x == Self::GP as usize => Ok(Self::GP),
141 x if x == Self::SP as usize => Ok(Self::SP),
142 x if x == Self::FP as usize => Ok(Self::FP),
143 x if x == Self::RA as usize => Ok(Self::RA),
144 _ => Err(()),
145 }
146 }
147}
148
149
150#[derive (Clone, Copy, Debug, Eq, PartialEq)]
151struct RTypeInstruction
152{
153 opcode: MipsInstructionOpcode,
154 rs: MipsRegister,
155 rt: MipsRegister,
156 rd: MipsRegister,
157 shamt: usize,
158 funct: MipsInstructionFunctionCode,
159}
160
161impl RTypeInstruction
162{
163 pub fn New (opcode: MipsInstructionOpcode, rs: MipsRegister, rt: MipsRegister, rd: MipsRegister, shamt: usize, funct: MipsInstructionFunctionCode) -> Self
164 {
165 Self
166 {
167 opcode,
168 rs,
169 rt,
170 rd,
171 shamt,
172 funct,
173 }
174 }
175
176 pub fn ToByteArray (&self, endian: Endian) -> Vec<u8>
177 {
178 let op = (self.opcode as usize)&0b111111;
179 let rs = (self.rs as usize)&0b11111;
180 let rt = (self.rt as usize)&0b11111;
181 let rd = (self.rd as usize)&0b11111;
182 let shamt = self.shamt&0b11111;
183 let funct = (self.funct as usize)&0b111111;
184
185 let code: u32 = ((op<<26) | (rs<<21) | (rt<<16) | (rd<<11) | (shamt<<6) | funct) as u32;
186
187 if endian == Endian::BIG
188 {
189 code.to_be_bytes ().to_vec ()
190 }
191 else
192 {
193 code.to_le_bytes ().to_vec ()
194 }
195 }
196
197 pub fn ToAssemblySource (&self) -> String
198 {
199 unimplemented! ();
200 }
201}
202
203
204#[derive (Clone, Copy, Debug, Eq, PartialEq)]
205struct ITypeInstruction
206{
207 opcode: MipsInstructionOpcode,
208 rs: MipsRegister,
209 rt: MipsRegister,
210 addrImm: u16,
211}
212
213impl ITypeInstruction
214{
215 pub fn New (opcode: MipsInstructionOpcode, rs: MipsRegister, rt: MipsRegister, addrImm: u16) -> Self
216 {
217 Self
218 {
219 opcode,
220 rs,
221 rt,
222 addrImm,
223 }
224 }
225
226 pub fn ToByteArray (&self, endian: Endian) -> Vec<u8>
227 {
228 let op = (self.opcode as usize)&0b111111;
229 let rs = (self.rs as usize)&0b11111;
230 let rt = (self.rt as usize)&0b11111;
231
232 let code: u32 = ((op<<26) | (rs<<21) | (rt<<16) | self.addrImm as usize) as u32;
233
234 if endian == Endian::BIG
235 {
236 code.to_be_bytes ().to_vec ()
237 }
238 else
239 {
240 code.to_le_bytes ().to_vec ()
241 }
242 }
243
244 pub fn ToAssemblySource (&self) -> String
245 {
246 unimplemented! ();
247 }
248}
249
250
251#[derive (Clone, Copy, Debug, Eq, PartialEq)]
252struct JTypeInstruction
253{
254 opcode: MipsInstructionOpcode,
255 targetAddress: usize,
256}
257
258impl JTypeInstruction
259{
260 pub fn New (opcode: MipsInstructionOpcode, targetAddress: usize) -> Self
261 {
262 Self
263 {
264 opcode,
265 targetAddress,
266 }
267 }
268
269 pub fn ToByteArray (&self, endian: Endian) -> Vec<u8>
271 {
272 let op = (self.opcode as usize)&0b111111;
273 let targetAddress = self.targetAddress&0b1111_1111_1111_1111_1111_1111_11;
274
275 let code: u32 = ((op<<26) | targetAddress) as u32;
276
277 if endian == Endian::BIG
278 {
279 code.to_be_bytes ().to_vec ()
280 }
281 else
282 {
283 code.to_le_bytes ().to_vec ()
284 }
285 }
286
287 pub fn ToAssemblySource (&self) -> String
288 {
289 unimplemented! ();
290 }
291}
292
293
294#[derive (Clone, Copy, Debug, Eq, PartialEq)]
295enum MipsInstruction
296{
297 RType(RTypeInstruction),
298 IType(ITypeInstruction),
299 JType(JTypeInstruction),
300}
301
302impl MipsInstruction
303{
304 pub fn ToByteArray (&self, endian: Endian) -> Vec<u8>
305 {
306 match self
307 {
308 Self::RType(instruction) => instruction.ToByteArray (endian),
309 Self::IType(instruction) => instruction.ToByteArray (endian),
310 Self::JType(instruction) => instruction.ToByteArray (endian),
311 }
312 }
313
314 pub fn ToAssemblySource (&self) -> String
315 {
316 match self
317 {
318 Self::RType(instruction) => instruction.ToAssemblySource (),
319 Self::IType(instruction) => instruction.ToAssemblySource (),
320 Self::JType(instruction) => instruction.ToAssemblySource (),
321 }
322 }
323}