mipsasm 2.0.1

A MIPS assembler targeting the N64
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
use crate::ast;

type I = ast::ITypeOp;
type J = ast::JTypeOp;
type R = ast::RTypeOp;

#[rustfmt::skip]
pub fn assemble(insts: Vec<ast::Instruction>) -> Vec<u32> {
    let mut bytes = vec![];
    for inst in insts {
        let i = match inst {
            ast::Instruction::Immediate { op, rs, rt, imm } => match op {
                I::Addi => 0b001000 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Addiu => 0b001001 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Andi => 0b001100 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::B => 0b000100 << 26 | imm.as_u32(),
                I::Bal => 0b000001 << 26 | 0b10001 << 16 | imm.as_u32(),
                I::Bc0f => 0b010000 << 26 | 0b01000 << 21 | imm.as_u32(),
                I::Bc0fl => 0b010000 << 26 | 0b01000 << 21 | 0b00010 << 16 | imm.as_u32(),
                I::Bc0t => 0b010000 << 26 | 0b01000 << 21 | 0b00001 << 16 | imm.as_u32(),
                I::Bc0tl => 0b010000 << 26 | 0b01000 << 21 | 0b00011 << 16 | imm.as_u32(),
                I::Bc1f => 0b010001 << 26 | 0b01000 << 21 | imm.as_u32(),
                I::Bc1fl => 0b010001 << 26 | 0b01000 << 21 | 0b00010 << 16 | imm.as_u32(),
                I::Bc1t => 0b010001 << 26 | 0b01000 << 21 | 0b00001 << 16 | imm.as_u32(),
                I::Bc1tl => 0b010001 << 26 | 0b01000 << 21 | 0b00011 << 16 | imm.as_u32(),
                I::Beq => 0b000100 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Beql => 0b010100 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Beqz => 0b000100 << 26 | rs.as_num() << 21 | imm.as_u32(),
                I::Beqzl => 0b010100 << 26 | rs.as_num() << 21 | imm.as_u32(),
                I::Bge => {
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b000001 << 11 | 0b101010);
                    0b000100 << 26 | 0b000001 << 21 | (imm.as_u32() - 1)
                }
                I::Bgel => {
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b000001 << 11 | 0b101010);
                    0b010100 << 26 | 0b000001 << 21 | (imm.as_u32() - 1)
                }
                I::Bgeu => {
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b000001 << 11 | 0b101011);
                    0b000100 << 26 | 0b000001 << 21 | (imm.as_u32() - 1)
                }
                I::Bgeul => {
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b000001 << 11 | 0b101011);
                    0b010100 << 26 | 0b000001 << 21 | (imm.as_u32() - 1)
                }
                I::Bgez => 0b000001 << 26 | rs.as_num() << 21 | 0b00001 << 16 | imm.as_u32(),
                I::Bgezal => 0b000001 << 26 | rs.as_num() << 21 | 0b10001 << 16 | imm.as_u32(),
                I::Bgezall => 0b000001 << 26 | rs.as_num() << 21 | 0b10011 << 16 | imm.as_u32(),
                I::Bgezl => 0b000001 << 26 | rs.as_num() << 21 | 0b00011 << 16 | imm.as_u32(),
                I::Bgt => {
                    bytes.push(rt.as_num() << 21 | rs.as_num() << 16 | 0b000001 << 11 | 0b101010);
                    0b000101 << 26 | 0b000001 << 21 | (imm.as_u32() - 1)
                }
                I::Bgtl => {
                    bytes.push(rt.as_num() << 21 | rs.as_num() << 16 | 0b000001 << 11 | 0b101010);
                    0b010101 << 26 | 0b000001 << 21 | (imm.as_u32() - 1)
                }
                I::Bgtu => {
                    bytes.push(rt.as_num() << 21 | rs.as_num() << 16 | 0b000001 << 11 | 0b101011);
                    0b000101 << 26 | 0b000001 << 21 | (imm.as_u32() - 1)
                }
                I::Bgtul => {
                    bytes.push(rt.as_num() << 21 | rs.as_num() << 16 | 0b000001 << 11 | 0b101011);
                    0b010101 << 26 | 0b000001 << 21 | (imm.as_u32() - 1)
                }
                I::Bgtz => 0b000111 << 26 | rs.as_num() << 21 | imm.as_u32(),
                I::Bgtzl => 0b010111 << 26 | rs.as_num() << 21 | imm.as_u32(),
                I::Ble => {
                    bytes.push(rt.as_num() << 21 | rs.as_num() << 16 | 0b000001 << 11 | 0b101010);
                    0b000100 << 26 | 0b000001 << 21 | (imm.as_u32() - 1)
                }
                I::Blel => {
                    bytes.push(rt.as_num() << 21 | rs.as_num() << 16 | 0b000001 << 11 | 0b101010);
                    0b010100 << 26 | 0b000001 << 21 | (imm.as_u32() - 1)
                }
                I::Bleu => {
                    bytes.push(rt.as_num() << 21 | rs.as_num() << 16 | 0b000001 << 11 | 0b101011);
                    0b000100 << 26 | 0b000001 << 21 | (imm.as_u32() - 1)
                }
                I::Bleul => {
                    bytes.push(rt.as_num() << 21 | rs.as_num() << 16 | 0b000001 << 11 | 0b101011);
                    0b010100 << 26 | 0b000001 << 21 | (imm.as_u32() - 1)
                }
                I::Blez => 0b000110 << 26 | rs.as_num() << 21| imm.as_u32(),
                I::Blezl => 0b010110 << 26 | rs.as_num() << 21| imm.as_u32(),
                I::Blt => {
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b000001 << 11 | 0b101010);
                    0b000101 << 26 | 0b000001 << 21 | (imm.as_u32() - 1)
                }
                I::Bltl => {
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b000001 << 11 | 0b101010);
                    0b010101 << 26 | 0b000001 << 21 | (imm.as_u32() - 1)
                }
                I::Bltu => {
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b000001 << 11 | 0b101011);
                    0b000101 << 26 | 0b000001 << 21 | (imm.as_u32() - 1)
                }
                I::Bltul => {
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b000001 << 11 | 0b101011);
                    0b010101 << 26 | 0b000001 << 21 | (imm.as_u32() - 1)
                }
                I::Bltz => 0b000001 << 26 | rs.as_num() << 21 | imm.as_u32(),
                I::Bltzal => 0b000001 << 26 | rs.as_num() << 21 | 0b10000 << 16 | imm.as_u32(),
                I::Bltzall => 0b000001 << 26 | rs.as_num() << 21 | 0b10010 << 16 | imm.as_u32(),
                I::Bltzl => 0b000001 << 26 | rs.as_num() << 21 | 0b00010 << 16 | imm.as_u32(),
                I::Bne => 0b000101 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Bnel => 0b010101 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Bnez => 0b000101 << 26 | rs.as_num() << 21| imm.as_u32(),
                I::Bnezl => 0b010101 << 26 | rs.as_num() << 21| imm.as_u32(),
                I::Cache => 0b101111 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Daddi => 0b011000 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Daddiu => 0b011001 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Dli => {
                    bytes.push(0b001111 << 26 | rt.as_num() << 16 | (imm.as_u64() >> 48) as u32);
                    bytes.push(0b001101 << 26 | rt.as_num() << 21 | rt.as_num() << 16 | ((imm.as_u64() >> 32) & 0xFFFF) as u32);
                    bytes.push(rt.as_num() << 16 | rt.as_num() << 11 | 16 << 6 | 0b111000);
                    bytes.push(0b001101 << 26 | rt.as_num() << 21 | rt.as_num() << 16 | ((imm.as_u64() >> 16) & 0xFFFF) as u32);
                    bytes.push(rt.as_num() << 16 | rt.as_num() << 11 | 16 << 6 | 0b111000);
                    0b001101 << 26 | rt.as_num() << 21 | rt.as_num() << 16 | (imm.as_u64() & 0xFFFF) as u32

                }
                I::Dsubi => 0b011000 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | -(imm.as_u32() as i64) as u32 & 0xFFFF,
                I::Dsubiu => 0b011001 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | -(imm.as_u32() as i64) as u32 & 0xFFFF,
                I::Lb => 0b100000 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Lbu => 0b100100 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Ld => 0b110111 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Ldc1 => 0b110101 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Ldl => 0b011010 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Ldr => 0b011011 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Lh => 0b100001 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Lhu => 0b100101 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Li => {
                    bytes.push(0b001111 << 26 | rt.as_num() << 16 | imm.as_u32() >> 16);
                    0b001101 << 26 | rt.as_num() << 21 | rt.as_num() << 16 | imm.as_u32() & 0xFFFF
                }
                I::Ll => 0b110000 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Lld => 0b110100 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Lli => 0b001101 << 26 | rt.as_num() << 16 | imm.as_u32(),
                I::Lui => 0b001111 << 26 | rt.as_num() << 16 | imm.as_u32(),
                I::Lw => 0b100011 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Lwc1 => 0b110001 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Lwl => 0b100010 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Lwr => 0b100110 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Lwu => 0b100111 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Ori => 0b001101 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Sb => 0b101000 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Sc => 0b111000 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Scd => 0b111100 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Sd => 0b111111 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Sdc1 => 0b111101 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Sdl => 0b101100 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Sdr => 0b101101 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Sh => 0b101001 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Slti => 0b001010 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Sltiu => 0b001011 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Subi => 0b001000 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | (-(imm.as_u32() as i32) as u32) & 0xFFFF,
                I::Subiu => 0b001001 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | (-(imm.as_u32() as i32) as u32) & 0xFFFF,
                I::Sw => 0b101011 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Swc1 => 0b111001 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Swl => 0b101010 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Swr => 0b101110 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
                I::Teqi => 0b000001 << 26 | rs.as_num() << 21 | 0b01100 << 16 | imm.as_u32(),
                I::Tgei => 0b000001 << 26 | rs.as_num() << 21 | 0b01000 << 16 | imm.as_u32(),
                I::Tgeiu => 0b000001 << 26 | rs.as_num() << 21 | 0b01001 << 16 | imm.as_u32(),
                I::Tlti => 0b000001 << 26 | rs.as_num() << 21 | 0b01010 << 16 | imm.as_u32(),
                I::Tltiu => 0b000001 << 26 | rs.as_num() << 21 | 0b01011 << 16 | imm.as_u32(),
                I::Tnei => 0b000001 << 26 | rs.as_num() << 21 | 0b01110 << 16 | imm.as_u32(),
                I::Xori => 0b001110 << 26 | rs.as_num() << 21 | rt.as_num() << 16 | imm.as_u32(),
            }
            ast::Instruction::Jump { op, target } => match op {
                J::J => 0b000010 << 26 | (target.as_u32() & 0x3FFFFFF) >> 2,
                J::Jal => 0b000011 << 26 | (target.as_u32() & 0x3FFFFFF) >> 2,
            }
            ast::Instruction::Register { op, rs, rt, rd, sa } => match op {
                R::Abs => {
                    bytes.push(rs.as_num() << 16 | 0b000001 << 11 | 31 << 6 | 0b000011);
                    bytes.push(rs.as_num() << 21 | 0b000001 << 16 | rd.as_num() << 11 | 0b100110);
                    rd.as_num() << 21 | 0b000001 << 16 | rd.as_num() << 11 | 0b100011
                }
                R::AbsS => 0b010001 << 26 | 0b10000 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b000101,
                R::AbsD => 0b010001 << 26 | 0b10001 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b000101,
                R::Add => rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b100000,
                R::Addu => rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b100001,
                R::AddS => 0b010001 << 26 | 0b10000 << 21 | rt.as_num() << 16 | rs.as_num() << 11 | rd.as_num() << 6,
                R::AddD => 0b010001 << 26 | 0b10001 << 21 | rt.as_num() << 16 | rs.as_num() << 11 | rd.as_num() << 6,
                R::And => rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b100100,
                R::Break => sa << 6 | 0b001101,
                R::Clear => rd.as_num() << 11 | 0b100001,
                R::Cs => 0b010001 << 26 | 0b10000 << 21 | rt.as_num() << 16 | rs.as_num() << 11 | 0b0000011 << 4 | sa as u32,
                R::Cd => 0b010001 << 26 | 0b10001 << 21 | rt.as_num() << 16 | rs.as_num() << 11 | 0b0000011 << 4 | sa as u32,
                R::CeilLS => 0b010001 << 26 | 0b10000 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b001010,
                R::CeilLD => 0b010001 << 26 | 0b10001 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b001010,
                R::CeilWS => 0b010001 << 26 | 0b10000 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b001110,
                R::CeilWD => 0b010001 << 26 | 0b10001 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b001110,
                R::Cfc0 => 0b010000 << 26 | 0b00010 << 21 | rt.as_num() << 16 | rd.as_num() << 11,
                R::Cfc1 => 0b010001 << 26 | 0b00010 << 21 | rt.as_num() << 16 | rd.as_num() << 11,
                R::Ctc0 => 0b010000 << 26 | 0b00110 << 21 | rt.as_num() << 16 | rd.as_num() << 11,
                R::Ctc1 => 0b010001 << 26 | 0b00110 << 21 | rt.as_num() << 16 | rd.as_num() << 11,
                R::CvtDS => 0b010001 << 26 | 0b10000 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b100001,
                R::CvtDW => 0b010001 << 26 | 0b10100 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b100001,
                R::CvtDL => 0b010001 << 26 | 0b10101 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b100001,
                R::CvtLS => 0b010001 << 26 | 0b10000 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b100101,
                R::CvtLD => 0b010001 << 26 | 0b10001 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b100101,
                R::CvtSD => 0b010001 << 26 | 0b10001 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b100000,
                R::CvtSW => 0b010001 << 26 | 0b10100 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b100000,
                R::CvtSL => 0b010001 << 26 | 0b10101 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b100000,
                R::CvtWS => 0b010001 << 26 | 0b10000 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b100100,
                R::CvtWD => 0b010001 << 26 | 0b10001 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b100100,
                R::Dabs => {
                    bytes.push(rs.as_num() << 16 | 0b000001 << 11 | 31 << 6 | 0b111011);
                    bytes.push(rs.as_num() << 21 | 0b000001 << 16 | rd.as_num() << 11 | 0b100110);
                    rd.as_num() << 21 | 0b000001 << 16 | rd.as_num() << 11 | 0b101110
                }
                R::Dadd => rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b101100,
                R::Daddu => rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b101101,
                R::Ddiv => {
                    if rt.as_num() == 0 {
                        rd.as_num() << 21 | rs.as_num() << 16 | 0b011110
                    } else {
                        bytes.push(rt.as_num() << 21 | 7 << 6 | 0b110100);
                        bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b011110);
                        bytes.push(0b011001 << 26 | 0b000001 << 16 | 0xFFFF);
                        bytes.push(0b000101 << 26 | rt.as_num() << 21 | 0b000001 << 16 | 4);
                        bytes.push(0b011001 << 26 | 0b000001 << 16 | 1);
                        bytes.push(0b000001 << 16 | 0b000001 << 11 | 31 << 6 | 0b111100);
                        bytes.push(rs.as_num() << 21 | 0b000001 << 16 | 6 << 6 | 0b110100);
                        rd.as_num() << 11 | 0b010010

                    }
                },
                R::Ddivu => {
                    if rt.as_num() == 0 {
                        rd.as_num() << 21 | rs.as_num() << 16 | 0b011111
                    } else {
                        bytes.push(rt.as_num() << 21 | 7 << 6 | 0b110100);
                        bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b011111);
                        rd.as_num() << 11 | 0b010010
                    }
                },
                R::Div => if rt.as_num() == 0 {
                    rd.as_num() << 21 | rs.as_num() << 16 | 0b011010
                } else {
                    bytes.push(rt.as_num() << 21 | 7 << 6 | 0b110100);
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b011010);
                    bytes.push(0b001111 << 26 | 0b000001 << 16 | 0xFFFF);
                    bytes.push(0b001101 << 26 | 0b000001 << 21 | 0b000001 << 16 | 0xFFFF);
                    bytes.push(0b000101 << 26 | rt.as_num() << 21 | 0b000001 << 16 | 3);
                    bytes.push(0b001111 << 26 | 0b000001 << 16 | 0x8000);
                    bytes.push(rs.as_num() << 21 | 0b000001 << 16 | 6 << 6 | 0b110100);
                    rd.as_num() << 11 | 0b010010
                }
                R::Divu => if rt.as_num() == 0 {
                    rd.as_num() << 21 | rs.as_num() << 16 | 0b011011
                } else {
                    bytes.push(rt.as_num() << 21 | 7 << 6 | 0b110100);
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b011011);
                    rd.as_num() << 11 | 0b010010
                }
                R::DivS => 0b010001 << 26 | 0b10000 << 21 | rt.as_num() << 16 | rs.as_num() << 11 | rd.as_num() << 6 | 0b000011,
                R::DivD => 0b010001 << 26 | 0b10001 << 21 | rt.as_num() << 16 | rs.as_num() << 11 | rd.as_num() << 6 | 0b000011,
                R::Dmfc0 => 0b010000 << 26 | 0b00001 << 21 | rt.as_num() << 16 | rd.as_num() << 11,
                R::Dmfc1 => 0b010001 << 26 | 0b00001 << 21 | rt.as_num() << 16 | rd.as_num() << 11,
                R::Dmove => rs.as_num() << 21 | rd.as_num() << 11 | 0b101101,
                R::Dmtc0 => 0b010000 << 26 | 0b00101 << 21 | rt.as_num() << 16 | rd.as_num() << 11,
                R::Dmtc1 => 0b010001 << 26 | 0b00101 << 21 | rt.as_num() << 16 | rd.as_num() << 11,
                R::Dmul => {
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b011100);
                    rd.as_num() << 11 | 0b010010
                }
                R::Dmulo => {
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b011100);
                    bytes.push(rd.as_num() << 11 | 0b010010);
                    bytes.push(rd.as_num() << 16 | rd.as_num() << 11 | 31 << 6 | 0b111111);
                    bytes.push(0b000001 << 11 | 0b010000);
                    bytes.push(rd.as_num() << 21 | 0b000001 << 16 | 6 << 6 | 0b110110);
                    rd.as_num() << 11 | 0b010010
                }
                R::Dmulou => {
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b011101);
                    bytes.push(0b000001 << 11 | 0b010000);
                    bytes.push(rd.as_num() << 11 | 0b010010);
                    0b000001 << 21 | 6 << 6 | 0b110110
                }
                R::Dmult => rs.as_num() << 21 | rt.as_num() << 16 | 0b011100,
                R::Dmulu => {
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b011101);
                    rd.as_num() << 11 | 0b010010
                }
                R::Dmultu => rs.as_num() << 21 | rt.as_num() << 16 | 0b011101,
                R::Dneg => rs.as_num() << 16 | rd.as_num() << 11 | 0b101110,
                R::Dnegu => rs.as_num() << 16 | rd.as_num() << 11 | 0b101111,
                R::Drem => {
                    bytes.push(rt.as_num() << 21 | 7 << 6 | 0b110100);
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b011110);
                    bytes.push(0b011001 << 26 | 0b000001 << 16 | 0xFFFF);
                    bytes.push(0b000101 << 26 | rt.as_num() << 21 | 0b000001 << 16 | 4);
                    bytes.push(0b011001 << 26 | 0b000001 << 16 | 1);
                    bytes.push(0b000001 << 16 | 0b000001 << 11 | 31 << 6 | 0b111100);
                    bytes.push(rs.as_num() << 21 | 0b000001 << 16 | 6 << 6 | 0b110100);
                    rd.as_num() << 11 | 0b010000
                }
                R::Dremu => {
                    bytes.push(rt.as_num() << 21 | 7 << 6 | 0b110100);
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b011111);
                    rd.as_num() << 11 | 0b010000
                }
                R::Drol => {
                    bytes.push(rt.as_num() << 16 | 0b000001 << 11 | 0b101111);
                    bytes.push(0b000001 << 21 | rs.as_num() << 16 | 0b000001 << 11 | 0b010110);
                    bytes.push(rt.as_num() << 21 | rs.as_num() << 16 | rd.as_num() << 11 | 0b010100);
                    rd.as_num() << 21 | 0b000001 << 16 | rd.as_num() << 11 | 0b100101
                }
                R::Dror => {
                    bytes.push(rt.as_num() << 16 | 0b000001 << 11 | 0b101111);
                    bytes.push(0b000001 << 21 | rs.as_num() << 16 | 0b000001 << 11 | 0b010100);
                    bytes.push(rt.as_num() << 21 | rs.as_num() << 16 | rd.as_num() << 11 | 0b010110);
                    rd.as_num() << 21 | 0b000001 << 16 | rd.as_num() << 11 | 0b100101
                }
                R::Dsll => rt.as_num() << 16 | rd.as_num() << 11 | (sa as u32) << 6 | 0b111000,
                R::Dsll32 => rt.as_num() << 16 | rd.as_num() << 11 | (sa as u32) << 6 | 0b111100,
                R::Dsllv => rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b010100,
                R::Dsra => rt.as_num() << 16 | rd.as_num() << 11 | (sa as u32) << 6 | 0b111011,
                R::Dsra32 => rt.as_num() << 16 | rd.as_num() << 11 | (sa as u32) << 6 | 0b111111,
                R::Dsrav => rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b010111,
                R::Dsrl => rt.as_num() << 16 | rd.as_num() << 11 | (sa as u32) << 6 | 0b111010,
                R::Dsrl32 => rt.as_num() << 16 | rd.as_num() << 11 | (sa as u32) << 6 | 0b111110,
                R::Dsrlv => rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b010110,
                R::Dsub => rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b101110,
                R::Dsubu => rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b101111,
                R::Eret => 0b010000 << 26 | 0b00001 << 25 | 0b011000,
                R::FloorLS => 0b010001 << 26 | 0b10000 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b001011,
                R::FloorLD => 0b010001 << 26 | 0b10001 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b001011,
                R::FloorWS => 0b010001 << 26 | 0b10000 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b001111,
                R::FloorWD => 0b010001 << 26 | 0b10001 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b001111,
                R::Jalr => rs.as_num() << 21 | rd.as_num() << 11 | 0b001001,
                R::Jr => rs.as_num() << 21 | 0b001000,
                R::Mfc0 => 0b010000 << 26 | rt.as_num() << 16 | rd.as_num() << 11,
                R::Mfc1 => 0b010001 << 26 | rt.as_num() << 16 | rd.as_num() << 11,
                R::Mfhi => rd.as_num() << 11 | 0b010000,
                R::Mflo => rd.as_num() << 11 | 0b010010,
                R::Move => rs.as_num() << 16 | rd.as_num() << 11 | 0b100001,
                R::MovS => 0b010001 << 26 | 0b10000 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b000110,
                R::MovD => 0b010001 << 26 | 0b10001 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b000110,
                R::Mtc0 => 0b010000 << 26 | 0b00100 << 21 | rt.as_num() << 16 | rd.as_num() << 11,
                R::Mtc1 => 0b010001 << 26 | 0b00100 << 21 | rt.as_num() << 16 | rd.as_num() << 11,
                R::Mthi => rs.as_num() << 21 | 0b010001,
                R::Mtlo => rs.as_num() << 21 | 0b010011,
                R::Mul => {
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b011000);
                    rd.as_num() << 11 | 0b010010
                }
                R::Mulu => {
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b011001);
                    rd.as_num() << 11 | 0b010010
                }
                R::MulS => 0b010001 << 26 | 0b10000 << 21 | rt.as_num() << 16 | rs.as_num() << 11 | rd.as_num() << 6 | 0b000010,
                R::MulD => 0b010001 << 26 | 0b10001 << 21 | rt.as_num() << 16 | rs.as_num() << 11 | rd.as_num() << 6 | 0b000010,
                R::Mulo => {
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b011000);
                    bytes.push(rd.as_num() << 11 | 0b010010);
                    bytes.push(rd.as_num() << 16 | rd.as_num() << 11 | 31 << 6 | 0b000011);
                    bytes.push(0b000001 << 11 | 0b010000);
                    bytes.push(rd.as_num() << 21 | 0b000001 << 16 | 6 << 6 | 0b110110);
                    rd.as_num() << 11 | 0b010010
                }
                R::Mulou => {
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b011001);
                    bytes.push(0b000001 << 11 | 0b010000);
                    bytes.push(rd.as_num() << 11 | 0b010010);
                    0b000001 << 21 | 6 << 6 | 0b110110
                }
                R::Mult => rs.as_num() << 21 | rt.as_num() << 16 | 0b011000,
                R::Multu => rs.as_num() << 21 | rt.as_num() << 16 | 0b011001,
                R::Neg => rs.as_num() << 16 | rd.as_num() << 11 | 0b100010,
                R::Negu => rs.as_num() << 16 | rd.as_num() << 11 | 0b100011,
                R::NegS => 0b010001 << 26 | 0b10000 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b000111,
                R::NegD => 0b010001 << 26 | 0b10001 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b000111,
                R::Nop => 0,
                R::Nor => rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b100111,
                R::Not => rs.as_num() << 21 | rd.as_num() << 11 | 0b100111,
                R::Or => rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b100101,
                R::Rem => {
                    bytes.push(rt.as_num() << 21 | 7 << 6 | 0b110100);
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b011010);
                    bytes.push(0b001111 << 26 | 0b000001 << 16 | 0xFFFF);
                    bytes.push(0b001101 << 26 | 0b000001 << 21 | 0b000001 << 16 | 0xFFFF);
                    bytes.push(0b000101 << 26 | rt.as_num() << 21 | 0b000001 << 16 | 3);
                    bytes.push(0b001111 << 26 | 0b000001 << 16 | 0x8000);
                    bytes.push(rs.as_num() << 21 | 0b000001 << 16 | 6 << 6 | 0b110100);
                    rd.as_num() << 11 | 0b010000
                }
                R::Remu => {
                    bytes.push(rt.as_num() << 21 | 7 << 6 | 0b110100);
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | 0b011011);
                    rd.as_num() << 11 | 0b010000
                }
                R::RoundLS => 0b010001 << 26 | 0b10000 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b001000,
                R::RoundLD => 0b010001 << 26 | 0b10001 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b001000,
                R::RoundWS => 0b010001 << 26 | 0b10000 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b001100,
                R::RoundWD => 0b010001 << 26 | 0b10001 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b001100,
                R::Seq => {
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b100110);
                    0b001011 << 26 | rd.as_num() << 21 | rd.as_num() << 16 | 1
                }
                R::Sge => {
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b101010);
                    0b001110 << 26 | rd.as_num() << 21 | rd.as_num() << 16 | 1
                }
                R::Sgeu => {
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b101011);
                    0b001110 << 26 | rd.as_num() << 21 | rd.as_num() << 16 | 1
                }
                R::Sgt => rt.as_num() << 21 | rs.as_num() << 16 | rd.as_num() << 11 | 0b101010,
                R::Sgtu => rt.as_num() << 21 | rs.as_num() << 16 | rd.as_num() << 11 | 0b101011,
                R::Sle => {
                    bytes.push(rt.as_num() << 21 | rs.as_num() << 16 | rd.as_num() << 11 | 0b101010);
                    0b001110 << 26 | rd.as_num() << 21 | rd.as_num() << 16 | 1
                }
                R::Sleu => {
                    bytes.push(rt.as_num() << 21 | rs.as_num() << 16 | rd.as_num() << 11 | 0b101011);
                    0b001110 << 26 | rd.as_num() << 21 | rd.as_num() << 16 | 1
                }
                R::Sll => rt.as_num() << 16 | rd.as_num() << 11 | (sa as u32) << 6,
                R::Sllv => rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b000100,
                R::Slt => rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b101010,
                R::Sltu => rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b101011,
                R::Sne => {
                    bytes.push(rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b100110);
                    rd.as_num() << 16 | rd.as_num() << 11 | 0b101011
                }
                R::SqrtS => 0b010001 << 26 | 0b10000 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b000100,
                R::SqrtD => 0b010001 << 26 | 0b10001 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b000100,
                R::Sra => rt.as_num() << 16 | rd.as_num() << 11 | (sa as u32) << 6 | 0b000011,
                R::Srav => rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b000111,
                R::Srl => rt.as_num() << 16 | rd.as_num() << 11 | (sa as u32) << 6 | 0b000010,
                R::Srlv => rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b000110,
                R::Sub => rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b100010,
                R::Subu => rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b100011,
                R::SubS => 0b010001 << 26 | 0b10000 << 21 | rt.as_num() << 16 | rs.as_num() << 11 | rd.as_num() << 6 | 0b000001,
                R::SubD => 0b010001 << 26 | 0b10001 << 21 | rt.as_num() << 16 | rs.as_num() << 11 | rd.as_num() << 6 | 0b000001,
                R::Sync => 0b001111,
                R::Syscall => sa << 6 | 0b001100,
                R::Teq => rs.as_num() << 21 | rt.as_num() << 16 | 0b110100,
                R::Tge => rs.as_num() << 21 | rt.as_num() << 16 | 0b110000,
                R::Tgeu => rs.as_num() << 21 | rt.as_num() << 16 | 0b110001,
                R::Tlbp => 0b010000 << 26 | 0b00001 << 25 | 0b001000,
                R::Tlbr => 0b010000 << 26 | 0b00001 << 25 | 0b000001,
                R::Tlbwi => 0b010000 << 26 | 0b00001 << 25 | 0b000010,
                R::Tlbwr => 0b010000 << 26 | 0b00001 << 25 | 0b000110,
                R::Tlt => rs.as_num() << 21 | rt.as_num() << 16 | 0b110010,
                R::Tltu => rs.as_num() << 21 | rt.as_num() << 16 | 0b110011,
                R::Tne => rs.as_num() << 21 | rt.as_num() << 16 | 0b110110,
                R::TruncLS => 0b010001 << 26 | 0b10000 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b001001,
                R::TruncLD => 0b010001 << 26 | 0b10001 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b001001,
                R::TruncWS => 0b010001 << 26 | 0b10000 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b001101,
                R::TruncWD => 0b010001 << 26 | 0b10001 << 21 | rs.as_num() << 11 | rd.as_num() << 6 | 0b001101,
                R::Xor => rs.as_num() << 21 | rt.as_num() << 16 | rd.as_num() << 11 | 0b100110,
            }
        };
        bytes.push(i);
    }
    bytes
}