@@ -605,53 +605,52 @@ bool ConcolicInterpreter::i_instr_binary_i64(Module *m, uint8_t opcode) {
605
605
Interpreter::i_instr_binary_i64 (m, opcode);
606
606
m->sp = original_sp;
607
607
608
- z3::expr d = m->symbolic_stack [m->sp - 1 ].value ();
609
- z3::expr e = m->symbolic_stack [m->sp ].value ();
610
- std::optional<z3::expr> f ;
608
+ z3::expr a = m->symbolic_stack [m->sp - 1 ].value ();
609
+ z3::expr b = m->symbolic_stack [m->sp ].value ();
610
+ std::optional<z3::expr> c ;
611
611
m->sp -= 1 ;
612
612
switch (opcode) {
613
613
case 0x7c :
614
- f = d + e ;
614
+ c = a + b ;
615
615
break ; // i64.add
616
616
case 0x7d :
617
- f = d - e ;
617
+ c = a - b ;
618
618
break ; // i64.sub
619
619
case 0x7e :
620
- f = d * e ;
620
+ c = a * b ;
621
621
break ; // i64.mul
622
622
case 0x7f :
623
- f = d / e ;
623
+ c = a / b ;
624
624
break ; // i64.div_s
625
625
case 0x80 :
626
- f = z3::udiv (d, e );
626
+ c = z3::udiv (a, b );
627
627
break ; // i64.div_u
628
628
case 0x81 :
629
- f = z3::srem (d, e );
629
+ c = z3::srem (a, b );
630
630
break ; // i64.rem_s
631
631
case 0x82 :
632
- f = z3::urem (d, e );
632
+ c = z3::urem (a, b );
633
633
break ; // i64.rem_u
634
634
case 0x83 :
635
- f = d & e ;
635
+ c = a & b ;
636
636
break ; // i64.and
637
637
case 0x84 :
638
- f = d | e ;
638
+ c = a | b ;
639
639
break ; // i64.or
640
640
case 0x85 :
641
- f = d ^ e ;
641
+ c = a ^ b ;
642
642
break ; // i64.xor
643
643
case 0x86 :
644
- f = z3::shl (d, e );
644
+ c = z3::shl (a, b );
645
645
break ; // i64.shl
646
646
case 0x87 :
647
- f = z3::ashr (d, e );
647
+ c = z3::ashr (a, b );
648
648
break ; // i64.shr_s
649
649
case 0x88 :
650
- f = z3::lshr (d, e );
650
+ c = z3::lshr (a, b );
651
651
break ; // i64.shr_u
652
652
case 0x89 :
653
- // TODO: Symbolic semantics
654
- assert (false );
653
+ c = z3::shl (b, a) | z3::lshr (b, 64 - a);
655
654
break ; // i64.rotl
656
655
case 0x8a :
657
656
// TODO: Symbolic semantics
@@ -660,15 +659,75 @@ bool ConcolicInterpreter::i_instr_binary_i64(Module *m, uint8_t opcode) {
660
659
default :
661
660
return false ;
662
661
}
663
- m->symbolic_stack [m->sp ] = f ;
662
+ m->symbolic_stack [m->sp ] = c ;
664
663
665
664
return true ;
666
665
}
667
666
668
667
bool ConcolicInterpreter::i_instr_binary_f32 (Module *m, uint8_t opcode) {
669
- // TODO: Symbolic semantics
670
- assert (false );
671
- return false ;
668
+ // TODO: Maybe reduce duplication since this is the same as i32?
669
+ int original_sp = m->sp ;
670
+ Interpreter::i_instr_binary_i64 (m, opcode);
671
+ m->sp = original_sp;
672
+
673
+ z3::expr a = m->symbolic_stack [m->sp - 1 ].value ();
674
+ z3::expr b = m->symbolic_stack [m->sp ].value ();
675
+ std::optional<z3::expr> c;
676
+ m->sp -= 1 ;
677
+ switch (opcode) {
678
+ case 0x7c :
679
+ c = a + b;
680
+ break ; // f32.add
681
+ case 0x7d :
682
+ c = a - b;
683
+ break ; // f32.sub
684
+ case 0x7e :
685
+ c = a * b;
686
+ break ; // f32.mul
687
+ case 0x7f :
688
+ c = a / b;
689
+ break ; // f32.div_s
690
+ case 0x80 :
691
+ c = z3::udiv (a, b);
692
+ break ; // f32.div_u
693
+ case 0x81 :
694
+ c = z3::srem (a, b);
695
+ break ; // f32.rem_s
696
+ case 0x82 :
697
+ c = z3::urem (a, b);
698
+ break ; // f32.rem_u
699
+ case 0x83 :
700
+ c = a & b;
701
+ break ; // f32.and
702
+ case 0x84 :
703
+ c = a | b;
704
+ break ; // f32.or
705
+ case 0x85 :
706
+ c = a ^ b;
707
+ break ; // f32.xor
708
+ case 0x86 :
709
+ c = z3::shl (a, b);
710
+ break ; // f32.shl
711
+ case 0x87 :
712
+ c = z3::ashr (a, b);
713
+ break ; // f32.shr_s
714
+ case 0x88 :
715
+ c = z3::lshr (a, b);
716
+ break ; // f32.shr_u
717
+ case 0x89 :
718
+ // TODO: Symbolic semantics
719
+ c = z3::shl (a, b) | z3::lshr (a, 32 - b);
720
+ break ; // f32.rotl
721
+ case 0x8a :
722
+ // TODO: Symbolic semantics
723
+ assert (false );
724
+ break ; // f32.rotr
725
+ default :
726
+ return false ;
727
+ }
728
+ m->symbolic_stack [m->sp ] = c;
729
+
730
+ return true ;
672
731
}
673
732
674
733
bool ConcolicInterpreter::i_instr_binary_f64 (Module *m, uint8_t opcode) {
0 commit comments