let cond_binop mem binop tr e1 t1 e2 t2 =
    match binop with
      | IndexPI | PlusPI ->
          let te = 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
          boolean_of_loc (M.shift loc te idx)

      | MinusPI ->
          let te = 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
          boolean_of_loc (M.shift loc te idx)

      | MinusPP ->
          boolean_of_integer
            (M.minus_loc
               (loc_of_value (!expr_rec mem e1))
               (loc_of_value (!expr_rec mem e2)))

      | (Eq | Ne | Ge | Le | Gt | Lt->
          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 ->
                  boolean_of_int (expr_int_operator mem ir binop i1 e1 i2 e2)
              | C_float fr, C_float f1, C_float f2 ->
                  boolean_of_float
                    (expr_float_operator mem fr binop f1 e1 f2 e2)
              | _ -> WpLog.fatal "non arithmetics arguments"
          end

      | LAnd -> F.e_and (!cond_rec mem e1) (!cond_rec mem e2)
      | LOr ->  F.e_or  (!cond_rec mem e1) (!cond_rec mem e2)