let expr_binop mem binop tr e1 t1 e2 t2 =
match binop with
| IndexPI | PlusPI ->
let ty = Ctypes.object_of_pointed (Ctypes.object_of t1) in
let loc = loc_of_value (!expr_rec mem e1) in
let idx = int_of_value (!expr_rec mem e2) in
M.V_pointer(ty,M.shift loc ty idx)
| MinusPI ->
let ty = Ctypes.object_of_pointed (Ctypes.object_of t1) in
let loc = loc_of_value (!expr_rec mem e1) in
let neg_idx = int_of_value (!expr_rec mem e2) in
let idx = F.e_ineg neg_idx in
M.V_pointer(ty,M.shift loc ty idx)
| MinusPP ->
let iota = c_int_of_typ tr in
value_of_integer iota
(M.minus_loc
(loc_of_value (!expr_rec mem e1))
(loc_of_value (!expr_rec mem e2)))
| (Eq | Ne | Ge | Le | Gt | Lt) ->
value_of_boolean (expr_cond_cmp mem binop t1 e1 t2 e2)
| PlusA | MinusA | Mult | Div | Mod
| BAnd | BXor | BOr | Shiftlt | Shiftrt ->
let ct1 = Ctypes.object_of t1 in
let ct2 = Ctypes.object_of t2 in
let ctr = Ctypes.object_of tr in
begin
match ctr , ct1 , ct2 with
| C_int ir , C_int i1 , C_int i2 ->
M.V_int(ir,expr_int_operator mem ir binop i1 e1 i2 e2)
| C_float fr, C_float f1, C_float f2 ->
M.V_float(fr,expr_float_operator mem fr binop f1 e1 f2 e2)
| _ -> WpLog.fatal "non arithmetics arguments"
end
| LAnd ->
value_of_boolean (F.e_and (!cond_rec mem e1) (!cond_rec mem e2))
| LOr ->
value_of_boolean (F.e_or (!cond_rec mem e1) (!cond_rec mem e2))