1use {
2 super::{ExecutionResult, Vm, helpers::*},
3 crate::{errors::ExecutionError, instruction::Instruction, opcode::Opcode},
4};
5
6pub fn execute_jump(vm: &mut dyn Vm, inst: &Instruction) -> ExecutionResult<()> {
7 let off = get_offset(inst)?;
8 vm.set_pc(((vm.get_pc() as i64) + 1 + (off as i64)) as usize);
9 Ok(())
10}
11
12pub fn execute_jump_immediate(vm: &mut dyn Vm, inst: &Instruction) -> ExecutionResult<()> {
13 match inst.opcode {
14 Opcode::JeqImm => execute_jump_immediate_conditional(vm, inst, |a, b| a == b),
15 Opcode::JgtImm => execute_jump_immediate_conditional(vm, inst, |a, b| a > b),
16 Opcode::JgeImm => execute_jump_immediate_conditional(vm, inst, |a, b| a >= b),
17 Opcode::JltImm => execute_jump_immediate_conditional(vm, inst, |a, b| a < b),
18 Opcode::JleImm => execute_jump_immediate_conditional(vm, inst, |a, b| a <= b),
19 Opcode::JsetImm => execute_jump_immediate_conditional(vm, inst, |a, b| (a & b) != 0),
20 Opcode::JneImm => execute_jump_immediate_conditional(vm, inst, |a, b| a != b),
21 Opcode::JsgtImm => {
22 execute_jump_immediate_conditional(vm, inst, |a, b| (a as i64) > (b as i64))
23 }
24 Opcode::JsgeImm => {
25 execute_jump_immediate_conditional(vm, inst, |a, b| (a as i64) >= (b as i64))
26 }
27 Opcode::JsltImm => {
28 execute_jump_immediate_conditional(vm, inst, |a, b| (a as i64) < (b as i64))
29 }
30 Opcode::JsleImm => {
31 execute_jump_immediate_conditional(vm, inst, |a, b| (a as i64) <= (b as i64))
32 }
33 Opcode::Jeq32Imm => execute_jump_immediate_conditional_u32(vm, inst, |a, b| a == b),
34 Opcode::Jgt32Imm => execute_jump_immediate_conditional_u32(vm, inst, |a, b| a > b),
35 Opcode::Jge32Imm => execute_jump_immediate_conditional_u32(vm, inst, |a, b| a >= b),
36 Opcode::Jlt32Imm => execute_jump_immediate_conditional_u32(vm, inst, |a, b| a < b),
37 Opcode::Jle32Imm => execute_jump_immediate_conditional_u32(vm, inst, |a, b| a <= b),
38 Opcode::Jset32Imm => execute_jump_immediate_conditional_u32(vm, inst, |a, b| (a & b) != 0),
39 Opcode::Jne32Imm => execute_jump_immediate_conditional_u32(vm, inst, |a, b| a != b),
40 Opcode::Jsgt32Imm => execute_jump_immediate_conditional_i32(vm, inst, |a, b| a > b),
41 Opcode::Jsge32Imm => execute_jump_immediate_conditional_i32(vm, inst, |a, b| a >= b),
42 Opcode::Jslt32Imm => execute_jump_immediate_conditional_i32(vm, inst, |a, b| a < b),
43 Opcode::Jsle32Imm => execute_jump_immediate_conditional_i32(vm, inst, |a, b| a <= b),
44 _ => Err(ExecutionError::InvalidInstruction),
45 }
46}
47
48pub fn execute_jump_register(vm: &mut dyn Vm, inst: &Instruction) -> ExecutionResult<()> {
49 match inst.opcode {
50 Opcode::JeqReg => execute_jump_register_conditional(vm, inst, |a, b| a == b),
51 Opcode::JgtReg => execute_jump_register_conditional(vm, inst, |a, b| a > b),
52 Opcode::JgeReg => execute_jump_register_conditional(vm, inst, |a, b| a >= b),
53 Opcode::JltReg => execute_jump_register_conditional(vm, inst, |a, b| a < b),
54 Opcode::JleReg => execute_jump_register_conditional(vm, inst, |a, b| a <= b),
55 Opcode::JsetReg => execute_jump_register_conditional(vm, inst, |a, b| (a & b) != 0),
56 Opcode::JneReg => execute_jump_register_conditional(vm, inst, |a, b| a != b),
57 Opcode::JsgtReg => {
58 execute_jump_register_conditional(vm, inst, |a, b| (a as i64) > (b as i64))
59 }
60 Opcode::JsgeReg => {
61 execute_jump_register_conditional(vm, inst, |a, b| (a as i64) >= (b as i64))
62 }
63 Opcode::JsltReg => {
64 execute_jump_register_conditional(vm, inst, |a, b| (a as i64) < (b as i64))
65 }
66 Opcode::JsleReg => {
67 execute_jump_register_conditional(vm, inst, |a, b| (a as i64) <= (b as i64))
68 }
69 Opcode::Jeq32Reg => execute_jump_register_conditional_u32(vm, inst, |a, b| a == b),
70 Opcode::Jgt32Reg => execute_jump_register_conditional_u32(vm, inst, |a, b| a > b),
71 Opcode::Jge32Reg => execute_jump_register_conditional_u32(vm, inst, |a, b| a >= b),
72 Opcode::Jlt32Reg => execute_jump_register_conditional_u32(vm, inst, |a, b| a < b),
73 Opcode::Jle32Reg => execute_jump_register_conditional_u32(vm, inst, |a, b| a <= b),
74 Opcode::Jset32Reg => execute_jump_register_conditional_u32(vm, inst, |a, b| (a & b) != 0),
75 Opcode::Jne32Reg => execute_jump_register_conditional_u32(vm, inst, |a, b| a != b),
76 Opcode::Jsgt32Reg => execute_jump_register_conditional_i32(vm, inst, |a, b| a > b),
77 Opcode::Jsge32Reg => execute_jump_register_conditional_i32(vm, inst, |a, b| a >= b),
78 Opcode::Jslt32Reg => execute_jump_register_conditional_i32(vm, inst, |a, b| a < b),
79 Opcode::Jsle32Reg => execute_jump_register_conditional_i32(vm, inst, |a, b| a <= b),
80 _ => Err(ExecutionError::InvalidInstruction),
81 }
82}
83
84fn execute_jump_immediate_conditional(
85 vm: &mut dyn Vm,
86 inst: &Instruction,
87 condition: fn(u64, u64) -> bool,
88) -> ExecutionResult<()> {
89 let dst = get_dst(inst)?;
90 let off = get_offset(inst)?;
91 let imm = (get_imm_i64(inst)? as i32 as i64) as u64;
92
93 if condition(vm.get_register(dst), imm) {
94 vm.set_pc(((vm.get_pc() as i64) + 1 + (off as i64)) as usize);
95 } else {
96 vm.advance_pc();
97 }
98 Ok(())
99}
100
101fn execute_jump_register_conditional(
102 vm: &mut dyn Vm,
103 inst: &Instruction,
104 condition: fn(u64, u64) -> bool,
105) -> ExecutionResult<()> {
106 let dst = get_dst(inst)?;
107 let src = get_src(inst)?;
108 let off = get_offset(inst)?;
109
110 if condition(vm.get_register(dst), vm.get_register(src)) {
111 vm.set_pc(((vm.get_pc() as i64) + 1 + (off as i64)) as usize);
112 } else {
113 vm.advance_pc();
114 }
115 Ok(())
116}
117
118fn execute_jump_immediate_conditional_u32(
119 vm: &mut dyn Vm,
120 inst: &Instruction,
121 condition: fn(u32, u32) -> bool,
122) -> ExecutionResult<()> {
123 let dst = get_dst(inst)?;
124 let off = get_offset(inst)?;
125 let lhs = vm.get_register(dst) as u32;
126 let rhs = get_imm_i64(inst)? as u32;
127
128 if condition(lhs, rhs) {
129 vm.set_pc(((vm.get_pc() as i64) + 1 + (off as i64)) as usize);
130 } else {
131 vm.advance_pc();
132 }
133 Ok(())
134}
135
136fn execute_jump_immediate_conditional_i32(
137 vm: &mut dyn Vm,
138 inst: &Instruction,
139 condition: fn(i32, i32) -> bool,
140) -> ExecutionResult<()> {
141 let dst = get_dst(inst)?;
142 let off = get_offset(inst)?;
143 let lhs = vm.get_register(dst) as i32;
144 let rhs = get_imm_i64(inst)? as i32;
145
146 if condition(lhs, rhs) {
147 vm.set_pc(((vm.get_pc() as i64) + 1 + (off as i64)) as usize);
148 } else {
149 vm.advance_pc();
150 }
151 Ok(())
152}
153
154fn execute_jump_register_conditional_u32(
155 vm: &mut dyn Vm,
156 inst: &Instruction,
157 condition: fn(u32, u32) -> bool,
158) -> ExecutionResult<()> {
159 let dst = get_dst(inst)?;
160 let src = get_src(inst)?;
161 let off = get_offset(inst)?;
162 let lhs = vm.get_register(dst) as u32;
163 let rhs = vm.get_register(src) as u32;
164
165 if condition(lhs, rhs) {
166 vm.set_pc(((vm.get_pc() as i64) + 1 + (off as i64)) as usize);
167 } else {
168 vm.advance_pc();
169 }
170 Ok(())
171}
172
173fn execute_jump_register_conditional_i32(
174 vm: &mut dyn Vm,
175 inst: &Instruction,
176 condition: fn(i32, i32) -> bool,
177) -> ExecutionResult<()> {
178 let dst = get_dst(inst)?;
179 let src = get_src(inst)?;
180 let off = get_offset(inst)?;
181 let lhs = vm.get_register(dst) as i32;
182 let rhs = vm.get_register(src) as i32;
183
184 if condition(lhs, rhs) {
185 vm.set_pc(((vm.get_pc() as i64) + 1 + (off as i64)) as usize);
186 } else {
187 vm.advance_pc();
188 }
189 Ok(())
190}
191
192#[cfg(test)]
193mod tests {
194 use {
195 super::*,
196 crate::{
197 execute::{MockVm, make_test_instruction},
198 inst_param::{Number, Register},
199 },
200 either::Either,
201 };
202
203 #[test]
204 fn test_ja_forward() {
205 let inst = make_test_instruction(Opcode::Ja, None, None, Some(Either::Right(5)), None);
207 let mut vm = MockVm::new();
208
209 execute_jump(&mut vm, &inst).unwrap();
210
211 assert_eq!(vm.pc, 6);
212 }
213
214 #[test]
215 fn test_ja_backward() {
216 let inst = make_test_instruction(Opcode::Ja, None, None, Some(Either::Right(-3)), None);
218 let mut vm = MockVm::new();
219 vm.pc = 10;
220
221 execute_jump(&mut vm, &inst).unwrap();
222
223 assert_eq!(vm.pc, 8);
224 }
225
226 #[test]
227 fn test_jeq_imm() {
228 let inst = make_test_instruction(
230 Opcode::JeqImm,
231 Some(Register { n: 1 }),
232 None,
233 Some(Either::Right(10)),
234 Some(Either::Right(Number::Int(5))),
235 );
236 let mut vm = MockVm::new();
237 vm.registers[1] = 5;
238
239 execute_jump_immediate(&mut vm, &inst).unwrap();
240
241 assert_eq!(vm.pc, 11);
242 }
243
244 #[test]
245 fn test_jgt_imm() {
246 let inst = make_test_instruction(
248 Opcode::JgtImm,
249 Some(Register { n: 1 }),
250 None,
251 Some(Either::Right(3)),
252 Some(Either::Right(Number::Int(10))),
253 );
254 let mut vm = MockVm::new();
255 vm.registers[1] = 11;
256
257 execute_jump_immediate(&mut vm, &inst).unwrap();
258
259 assert_eq!(vm.pc, 4);
260 }
261
262 #[test]
263 fn test_jge_imm() {
264 let inst = make_test_instruction(
266 Opcode::JgeImm,
267 Some(Register { n: 1 }),
268 None,
269 Some(Either::Right(2)),
270 Some(Either::Right(Number::Int(10))),
271 );
272 let mut vm = MockVm::new();
273 vm.registers[1] = 10;
274
275 execute_jump_immediate(&mut vm, &inst).unwrap();
276
277 assert_eq!(vm.pc, 3);
278 }
279
280 #[test]
281 fn test_jlt_imm() {
282 let inst = make_test_instruction(
284 Opcode::JltImm,
285 Some(Register { n: 1 }),
286 None,
287 Some(Either::Right(3)),
288 Some(Either::Right(Number::Int(10))),
289 );
290 let mut vm = MockVm::new();
291 vm.registers[1] = 5;
292
293 execute_jump_immediate(&mut vm, &inst).unwrap();
294
295 assert_eq!(vm.pc, 4);
296 }
297
298 #[test]
299 fn test_jle_imm() {
300 let inst = make_test_instruction(
302 Opcode::JleImm,
303 Some(Register { n: 0 }),
304 None,
305 Some(Either::Right(4)),
306 Some(Either::Right(Number::Int(10))),
307 );
308 let mut vm = MockVm::new();
309 vm.registers[0] = 0;
310
311 execute_jump_immediate(&mut vm, &inst).unwrap();
312
313 assert_eq!(vm.pc, 5);
314 }
315
316 #[test]
317 fn test_jset_imm() {
318 let inst = make_test_instruction(
320 Opcode::JsetImm,
321 Some(Register { n: 1 }),
322 None,
323 Some(Either::Right(2)),
324 Some(Either::Right(Number::Int(0x0f))),
325 );
326 let mut vm = MockVm::new();
327 vm.registers[1] = 0xff;
328
329 execute_jump_immediate(&mut vm, &inst).unwrap();
330
331 assert_eq!(vm.pc, 3);
332 }
333
334 #[test]
335 fn test_jne_imm() {
336 let inst = make_test_instruction(
338 Opcode::JneImm,
339 Some(Register { n: 1 }),
340 None,
341 Some(Either::Right(2)),
342 Some(Either::Right(Number::Int(10))),
343 );
344 let mut vm = MockVm::new();
345 vm.registers[1] = 9;
346
347 execute_jump_immediate(&mut vm, &inst).unwrap();
348
349 assert_eq!(vm.pc, 3);
350 }
351
352 #[test]
353 fn test_jsgt_imm() {
354 let inst = make_test_instruction(
356 Opcode::JsgtImm,
357 Some(Register { n: 1 }),
358 None,
359 Some(Either::Right(4)),
360 Some(Either::Right(Number::Int(-10))),
361 );
362 let mut vm = MockVm::new();
363 vm.registers[1] = 5;
364
365 execute_jump_immediate(&mut vm, &inst).unwrap();
366
367 assert_eq!(vm.pc, 5);
368 }
369
370 #[test]
371 fn test_jsge_imm() {
372 let inst = make_test_instruction(
374 Opcode::JsgeImm,
375 Some(Register { n: 1 }),
376 None,
377 Some(Either::Right(1)),
378 Some(Either::Right(Number::Int(-5))),
379 );
380 let mut vm = MockVm::new();
381 vm.registers[1] = (-5i64) as u64;
382
383 execute_jump_immediate(&mut vm, &inst).unwrap();
384
385 assert_eq!(vm.pc, 2);
386 }
387
388 #[test]
389 fn test_jslt_imm() {
390 let inst = make_test_instruction(
392 Opcode::JsltImm,
393 Some(Register { n: 1 }),
394 None,
395 Some(Either::Right(3)),
396 Some(Either::Right(Number::Int(-4))),
397 );
398 let mut vm = MockVm::new();
399 vm.registers[1] = (-5i64) as u64;
400
401 execute_jump_immediate(&mut vm, &inst).unwrap();
402
403 assert_eq!(vm.pc, 4);
404 }
405
406 #[test]
407 fn test_jsle_imm() {
408 let inst = make_test_instruction(
410 Opcode::JsleImm,
411 Some(Register { n: 1 }),
412 None,
413 Some(Either::Right(2)),
414 Some(Either::Right(Number::Int(-5))),
415 );
416 let mut vm = MockVm::new();
417 vm.registers[1] = (-10i64) as u64;
418
419 execute_jump_immediate(&mut vm, &inst).unwrap();
420
421 assert_eq!(vm.pc, 3);
422 }
423
424 #[test]
425 fn test_jeq_reg() {
426 let inst = make_test_instruction(
428 Opcode::JeqReg,
429 Some(Register { n: 1 }),
430 Some(Register { n: 2 }),
431 Some(Either::Right(3)),
432 None,
433 );
434 let mut vm = MockVm::new();
435 vm.registers[1] = 5;
436 vm.registers[2] = 5;
437
438 execute_jump_register(&mut vm, &inst).unwrap();
439
440 assert_eq!(vm.pc, 4);
441 }
442
443 #[test]
444 fn test_jgt_reg() {
445 let inst = make_test_instruction(
447 Opcode::JgtReg,
448 Some(Register { n: 1 }),
449 Some(Register { n: 2 }),
450 Some(Either::Right(5)),
451 None,
452 );
453 let mut vm = MockVm::new();
454 vm.registers[1] = 100;
455 vm.registers[2] = 50;
456
457 execute_jump_register(&mut vm, &inst).unwrap();
458
459 assert_eq!(vm.pc, 6);
460 }
461
462 #[test]
463 fn test_jge_reg() {
464 let inst = make_test_instruction(
466 Opcode::JgeReg,
467 Some(Register { n: 1 }),
468 Some(Register { n: 2 }),
469 Some(Either::Right(2)),
470 None,
471 );
472 let mut vm = MockVm::new();
473 vm.registers[1] = 100;
474 vm.registers[2] = 100;
475
476 execute_jump_register(&mut vm, &inst).unwrap();
477
478 assert_eq!(vm.pc, 3);
479 }
480
481 #[test]
482 fn test_jlt_reg() {
483 let inst = make_test_instruction(
485 Opcode::JltReg,
486 Some(Register { n: 1 }),
487 Some(Register { n: 2 }),
488 Some(Either::Right(4)),
489 None,
490 );
491 let mut vm = MockVm::new();
492 vm.registers[1] = 50;
493 vm.registers[2] = 100;
494
495 execute_jump_register(&mut vm, &inst).unwrap();
496
497 assert_eq!(vm.pc, 5);
498 }
499
500 #[test]
501 fn test_jle_reg() {
502 let inst = make_test_instruction(
504 Opcode::JleReg,
505 Some(Register { n: 1 }),
506 Some(Register { n: 2 }),
507 Some(Either::Right(3)),
508 None,
509 );
510 let mut vm = MockVm::new();
511 vm.registers[1] = 50;
512 vm.registers[2] = 60;
513
514 execute_jump_register(&mut vm, &inst).unwrap();
515
516 assert_eq!(vm.pc, 4);
517 }
518
519 #[test]
520 fn test_jset_reg() {
521 let inst = make_test_instruction(
523 Opcode::JsetReg,
524 Some(Register { n: 1 }),
525 Some(Register { n: 2 }),
526 Some(Either::Right(2)),
527 None,
528 );
529 let mut vm = MockVm::new();
530 vm.registers[1] = 0xFF;
531 vm.registers[2] = 0x0F;
532
533 execute_jump_register(&mut vm, &inst).unwrap();
534
535 assert_eq!(vm.pc, 3);
536 }
537
538 #[test]
539 fn test_jne_reg() {
540 let inst = make_test_instruction(
542 Opcode::JneReg,
543 Some(Register { n: 1 }),
544 Some(Register { n: 2 }),
545 Some(Either::Right(1)),
546 None,
547 );
548 let mut vm = MockVm::new();
549 vm.registers[1] = 10;
550 vm.registers[2] = 20;
551
552 execute_jump_register(&mut vm, &inst).unwrap();
553
554 assert_eq!(vm.pc, 2);
555 }
556
557 #[test]
558 fn test_jsgt_reg() {
559 let inst = make_test_instruction(
561 Opcode::JsgtReg,
562 Some(Register { n: 1 }),
563 Some(Register { n: 2 }),
564 Some(Either::Right(3)),
565 None,
566 );
567 let mut vm = MockVm::new();
568 vm.registers[1] = 5;
569 vm.registers[2] = (-10i64) as u64;
570
571 execute_jump_register(&mut vm, &inst).unwrap();
572
573 assert_eq!(vm.pc, 4);
574 }
575
576 #[test]
577 fn test_jsge_reg() {
578 let inst = make_test_instruction(
580 Opcode::JsgeReg,
581 Some(Register { n: 1 }),
582 Some(Register { n: 2 }),
583 Some(Either::Right(2)),
584 None,
585 );
586 let mut vm = MockVm::new();
587 vm.registers[1] = (-5i64) as u64;
588 vm.registers[2] = (-6i64) as u64;
589
590 execute_jump_register(&mut vm, &inst).unwrap();
591
592 assert_eq!(vm.pc, 3);
593 }
594
595 #[test]
596 fn test_jslt_reg() {
597 let inst = make_test_instruction(
599 Opcode::JsltReg,
600 Some(Register { n: 1 }),
601 Some(Register { n: 2 }),
602 Some(Either::Right(2)),
603 None,
604 );
605 let mut vm = MockVm::new();
606 vm.registers[1] = (-5i64) as u64;
607 vm.registers[2] = 2;
608
609 execute_jump_register(&mut vm, &inst).unwrap();
610
611 assert_eq!(vm.pc, 3);
612 }
613
614 #[test]
615 fn test_jsle_reg() {
616 let inst = make_test_instruction(
618 Opcode::JsleReg,
619 Some(Register { n: 1 }),
620 Some(Register { n: 2 }),
621 Some(Either::Right(2)),
622 None,
623 );
624 let mut vm = MockVm::new();
625 vm.registers[1] = (-10i64) as u64;
626 vm.registers[2] = 5;
627
628 execute_jump_register(&mut vm, &inst).unwrap();
629
630 assert_eq!(vm.pc, 3);
631 }
632
633 #[test]
634 fn test_jeq32_imm() {
635 let inst = make_test_instruction(
637 Opcode::Jeq32Imm,
638 Some(Register { n: 1 }),
639 None,
640 Some(Either::Right(2)),
641 Some(Either::Right(Number::Int(5))),
642 );
643 let mut vm = MockVm::new();
644 vm.registers[1] = 0x0000_0001_0000_0005;
645
646 execute_jump_immediate(&mut vm, &inst).unwrap();
647
648 assert_eq!(vm.pc, 3);
649 }
650
651 #[test]
652 fn test_jgt32_imm() {
653 let inst = make_test_instruction(
655 Opcode::Jgt32Imm,
656 Some(Register { n: 1 }),
657 None,
658 Some(Either::Right(3)),
659 Some(Either::Right(Number::Int(-1))),
660 );
661 let mut vm = MockVm::new();
662 vm.registers[1] = 0xffff_fffe;
663
664 execute_jump_immediate(&mut vm, &inst).unwrap();
665
666 assert_eq!(vm.pc, 1);
667 }
668
669 #[test]
670 fn test_jge32_imm() {
671 let inst = make_test_instruction(
673 Opcode::Jge32Imm,
674 Some(Register { n: 1 }),
675 None,
676 Some(Either::Right(2)),
677 Some(Either::Right(Number::Int(10))),
678 );
679 let mut vm = MockVm::new();
680 vm.registers[1] = 0x0000_0002_0000_000a;
681
682 execute_jump_immediate(&mut vm, &inst).unwrap();
683
684 assert_eq!(vm.pc, 3);
685 }
686
687 #[test]
688 fn test_jlt32_imm() {
689 let inst = make_test_instruction(
691 Opcode::Jlt32Imm,
692 Some(Register { n: 1 }),
693 None,
694 Some(Either::Right(3)),
695 Some(Either::Right(Number::Int(10))),
696 );
697 let mut vm = MockVm::new();
698 vm.registers[1] = 5;
699
700 execute_jump_immediate(&mut vm, &inst).unwrap();
701
702 assert_eq!(vm.pc, 4);
703 }
704
705 #[test]
706 fn test_jle32_imm() {
707 let inst = make_test_instruction(
709 Opcode::Jle32Imm,
710 Some(Register { n: 1 }),
711 None,
712 Some(Either::Right(4)),
713 Some(Either::Right(Number::Int(10))),
714 );
715 let mut vm = MockVm::new();
716 vm.registers[1] = 10;
717
718 execute_jump_immediate(&mut vm, &inst).unwrap();
719
720 assert_eq!(vm.pc, 5);
721 }
722
723 #[test]
724 fn test_jset32_imm() {
725 let inst = make_test_instruction(
727 Opcode::Jset32Imm,
728 Some(Register { n: 1 }),
729 None,
730 Some(Either::Right(2)),
731 Some(Either::Right(Number::Int(0x0f))),
732 );
733 let mut vm = MockVm::new();
734 vm.registers[1] = 0x0000_0001_0000_000f;
735
736 execute_jump_immediate(&mut vm, &inst).unwrap();
737
738 assert_eq!(vm.pc, 3);
739 }
740
741 #[test]
742 fn test_jne32_imm() {
743 let inst = make_test_instruction(
745 Opcode::Jne32Imm,
746 Some(Register { n: 1 }),
747 None,
748 Some(Either::Right(1)),
749 Some(Either::Right(Number::Int(10))),
750 );
751 let mut vm = MockVm::new();
752 vm.registers[1] = 9;
753
754 execute_jump_immediate(&mut vm, &inst).unwrap();
755
756 assert_eq!(vm.pc, 2);
757 }
758
759 #[test]
760 fn test_jsgt32_imm() {
761 let inst = make_test_instruction(
763 Opcode::Jsgt32Imm,
764 Some(Register { n: 1 }),
765 None,
766 Some(Either::Right(1)),
767 Some(Either::Right(Number::Int(-1))),
768 );
769 let mut vm = MockVm::new();
770 vm.registers[1] = 1;
771
772 execute_jump_immediate(&mut vm, &inst).unwrap();
773
774 assert_eq!(vm.pc, 2);
775 }
776
777 #[test]
778 fn test_jsge32_imm() {
779 let inst = make_test_instruction(
781 Opcode::Jsge32Imm,
782 Some(Register { n: 1 }),
783 None,
784 Some(Either::Right(2)),
785 Some(Either::Right(Number::Int(-1))),
786 );
787 let mut vm = MockVm::new();
788 vm.registers[1] = 1;
789
790 execute_jump_immediate(&mut vm, &inst).unwrap();
791
792 assert_eq!(vm.pc, 3);
793 }
794
795 #[test]
796 fn test_jslt32_imm() {
797 let inst = make_test_instruction(
799 Opcode::Jslt32Imm,
800 Some(Register { n: 1 }),
801 None,
802 Some(Either::Right(3)),
803 Some(Either::Right(Number::Int(1))),
804 );
805 let mut vm = MockVm::new();
806 vm.registers[1] = 0xffff_ffff;
807
808 execute_jump_immediate(&mut vm, &inst).unwrap();
809
810 assert_eq!(vm.pc, 4);
811 }
812
813 #[test]
814 fn test_jsle32_imm() {
815 let inst = make_test_instruction(
817 Opcode::Jsle32Imm,
818 Some(Register { n: 1 }),
819 None,
820 Some(Either::Right(2)),
821 Some(Either::Right(Number::Int(5))),
822 );
823 let mut vm = MockVm::new();
824 vm.registers[1] = 0xffff_fff6;
825
826 execute_jump_immediate(&mut vm, &inst).unwrap();
827
828 assert_eq!(vm.pc, 3);
829 }
830
831 #[test]
832 fn test_jeq32_reg() {
833 let inst = make_test_instruction(
835 Opcode::Jeq32Reg,
836 Some(Register { n: 1 }),
837 Some(Register { n: 2 }),
838 Some(Either::Right(2)),
839 None,
840 );
841 let mut vm = MockVm::new();
842 vm.registers[1] = 0x0000_0001_0000_0005;
843 vm.registers[2] = 0x0000_0002_0000_0005;
844
845 execute_jump_register(&mut vm, &inst).unwrap();
846
847 assert_eq!(vm.pc, 3);
848 }
849
850 #[test]
851 fn test_jgt32_reg() {
852 let inst = make_test_instruction(
854 Opcode::Jgt32Reg,
855 Some(Register { n: 1 }),
856 Some(Register { n: 2 }),
857 Some(Either::Right(3)),
858 None,
859 );
860 let mut vm = MockVm::new();
861 vm.registers[1] = 11;
862 vm.registers[2] = 10;
863
864 execute_jump_register(&mut vm, &inst).unwrap();
865
866 assert_eq!(vm.pc, 4);
867 }
868
869 #[test]
870 fn test_jge32_reg() {
871 let inst = make_test_instruction(
873 Opcode::Jge32Reg,
874 Some(Register { n: 1 }),
875 Some(Register { n: 2 }),
876 Some(Either::Right(2)),
877 None,
878 );
879 let mut vm = MockVm::new();
880 vm.registers[1] = 10;
881 vm.registers[2] = 10;
882
883 execute_jump_register(&mut vm, &inst).unwrap();
884
885 assert_eq!(vm.pc, 3);
886 }
887
888 #[test]
889 fn test_jlt32_reg() {
890 let inst = make_test_instruction(
892 Opcode::Jlt32Reg,
893 Some(Register { n: 1 }),
894 Some(Register { n: 2 }),
895 Some(Either::Right(3)),
896 None,
897 );
898 let mut vm = MockVm::new();
899 vm.registers[1] = 5;
900 vm.registers[2] = 10;
901
902 execute_jump_register(&mut vm, &inst).unwrap();
903
904 assert_eq!(vm.pc, 4);
905 }
906
907 #[test]
908 fn test_jle32_reg() {
909 let inst = make_test_instruction(
911 Opcode::Jle32Reg,
912 Some(Register { n: 1 }),
913 Some(Register { n: 2 }),
914 Some(Either::Right(2)),
915 None,
916 );
917 let mut vm = MockVm::new();
918 vm.registers[1] = 5;
919 vm.registers[2] = 5;
920
921 execute_jump_register(&mut vm, &inst).unwrap();
922
923 assert_eq!(vm.pc, 3);
924 }
925
926 #[test]
927 fn test_jset32_reg() {
928 let inst = make_test_instruction(
930 Opcode::Jset32Reg,
931 Some(Register { n: 1 }),
932 Some(Register { n: 2 }),
933 Some(Either::Right(4)),
934 None,
935 );
936 let mut vm = MockVm::new();
937 vm.registers[1] = 0x0000_0001_0000_0000;
938 vm.registers[2] = 0x0000_0002_0000_0000;
939
940 execute_jump_register(&mut vm, &inst).unwrap();
941
942 assert_eq!(vm.pc, 1);
943 }
944
945 #[test]
946 fn test_jne32_reg() {
947 let inst = make_test_instruction(
949 Opcode::Jne32Reg,
950 Some(Register { n: 1 }),
951 Some(Register { n: 2 }),
952 Some(Either::Right(1)),
953 None,
954 );
955 let mut vm = MockVm::new();
956 vm.registers[1] = 9;
957 vm.registers[2] = 10;
958
959 execute_jump_register(&mut vm, &inst).unwrap();
960
961 assert_eq!(vm.pc, 2);
962 }
963
964 #[test]
965 fn test_jsgt32_reg() {
966 let inst = make_test_instruction(
968 Opcode::Jsgt32Reg,
969 Some(Register { n: 1 }),
970 Some(Register { n: 2 }),
971 Some(Either::Right(2)),
972 None,
973 );
974 let mut vm = MockVm::new();
975 vm.registers[1] = 1;
976 vm.registers[2] = 0xffff_ffff;
977
978 execute_jump_register(&mut vm, &inst).unwrap();
979
980 assert_eq!(vm.pc, 3);
981 }
982
983 #[test]
984 fn test_jsge32_reg() {
985 let inst = make_test_instruction(
987 Opcode::Jsge32Reg,
988 Some(Register { n: 1 }),
989 Some(Register { n: 2 }),
990 Some(Either::Right(2)),
991 None,
992 );
993 let mut vm = MockVm::new();
994 vm.registers[1] = 1;
995 vm.registers[2] = 0xffff_ffff;
996
997 execute_jump_register(&mut vm, &inst).unwrap();
998
999 assert_eq!(vm.pc, 3);
1000 }
1001
1002 #[test]
1003 fn test_jslt32_reg() {
1004 let inst = make_test_instruction(
1006 Opcode::Jslt32Reg,
1007 Some(Register { n: 1 }),
1008 Some(Register { n: 2 }),
1009 Some(Either::Right(2)),
1010 None,
1011 );
1012 let mut vm = MockVm::new();
1013 vm.registers[1] = 0x0000_0000_8000_0000;
1014 vm.registers[2] = 0x0000_0000_7fff_ffff;
1015
1016 execute_jump_register(&mut vm, &inst).unwrap();
1017
1018 assert_eq!(vm.pc, 3);
1019 }
1020
1021 #[test]
1022 fn test_jsle32_reg() {
1023 let inst = make_test_instruction(
1025 Opcode::Jsle32Reg,
1026 Some(Register { n: 1 }),
1027 Some(Register { n: 2 }),
1028 Some(Either::Right(2)),
1029 None,
1030 );
1031 let mut vm = MockVm::new();
1032 vm.registers[1] = 0xffff_fff6;
1033 vm.registers[2] = 5;
1034
1035 execute_jump_register(&mut vm, &inst).unwrap();
1036
1037 assert_eq!(vm.pc, 3);
1038 }
1039}