@@ -424,8 +424,38 @@ bool ConcolicInterpreter::i_instr_math_u64(Module *m, uint8_t opcode) {
424
424
}
425
425
426
426
bool ConcolicInterpreter::i_instr_math_f32 (Module *m, uint8_t opcode) {
427
- // TODO: Symbolic semantics
428
- assert (false );
427
+ int original_sp = m->sp ;
428
+ Interpreter::i_instr_math_f32 (m, opcode);
429
+ m->sp = original_sp;
430
+
431
+ z3::expr a = m->symbolic_stack [m->sp - 1 ].value ();
432
+ z3::expr b = m->symbolic_stack [m->sp ].value ();
433
+ std::optional<z3::expr> c;
434
+ m->sp -= 1 ;
435
+ switch (opcode) {
436
+ case 0x5b :
437
+ c = z3::ite (z3::fp_eq (a, b), m->ctx .bv_val (1 , 32 ), m->ctx .bv_val (0 , 32 ));
438
+ break ; // f32.eq
439
+ case 0x5c :
440
+ c = z3::ite (!z3::fp_eq (a, b), m->ctx .bv_val (1 , 32 ), m->ctx .bv_val (0 , 32 ));
441
+ break ; // f32.ne
442
+ case 0x5d :
443
+ c = z3::ite (a < b, m->ctx .bv_val (1 , 32 ), m->ctx .bv_val (0 , 32 ));
444
+ break ; // f32.lt
445
+ case 0x5e :
446
+ c = z3::ite (a > b, m->ctx .bv_val (1 , 32 ), m->ctx .bv_val (0 , 32 ));
447
+ break ; // f32.gt
448
+ case 0x5f :
449
+ c = z3::ite (a <= b, m->ctx .bv_val (1 , 32 ), m->ctx .bv_val (0 , 32 ));
450
+ break ; // f32.le
451
+ case 0x60 :
452
+ c = z3::ite (a >= b, m->ctx .bv_val (1 , 32 ), m->ctx .bv_val (0 , 32 ));
453
+ break ; // f32.ge
454
+ default :
455
+ return false ;
456
+ }
457
+ m->symbolic_stack [m->sp ] = c;
458
+ return true ;
429
459
}
430
460
431
461
bool ConcolicInterpreter::i_instr_math_f64 (Module *m, uint8_t opcode) {
@@ -786,8 +816,8 @@ bool ConcolicInterpreter::i_instr_conversion(Module *m, uint8_t opcode) {
786
816
assert (false );
787
817
break ; // i64.trunc_u/f64
788
818
case 0xb2 :
789
- // TODO: Symbolic semantics
790
- assert ( false );
819
+ // TODO: fpa_sort values
820
+ m-> symbolic_stack [m-> sp ] = sbv_to_fpa (m-> symbolic_stack [m-> sp ]. value (), m-> ctx . fpa_sort ( 8 , 24 ) );
791
821
break ; // f32.convert_s/i32
792
822
case 0xb3 :
793
823
// TODO: Symbolic semantics
0 commit comments