summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKathy Gray2015-11-03 10:54:36 +0000
committerKathy Gray2015-11-03 10:54:36 +0000
commit7ae09fc36e8dcd6af767f1d5ffe7786d01870ab6 (patch)
treee4c09e9299d9bfb573a7e7e2f97cb0738bce8c53 /src
parent623a962bfb9a9e1595459053e8be6748ca2277b3 (diff)
Support int and bigint library functions
Diffstat (limited to 'src')
-rw-r--r--src/gen_lib/sail_values.ml549
1 files changed, 438 insertions, 111 deletions
diff --git a/src/gen_lib/sail_values.ml b/src/gen_lib/sail_values.ml
index 8a1a27c6..dc44ab5d 100644
--- a/src/gen_lib/sail_values.ml
+++ b/src/gen_lib/sail_values.ml
@@ -15,11 +15,14 @@ let to_bool = function
| Vone -> true
| Vundef -> assert false
-let is_one i =
+let is_one_big i =
if eq_big_int i unit_big_int
then Vone
else Vzero
+let is_one i =
+ if i = 1 then Vone else Vzero
+
let get_barray = function
| Vvector(a,_,_) -> a
| Vregister(a,_,_,_) -> !a
@@ -38,11 +41,13 @@ let get_start = function
| _ -> assert false
let length = function
- | Vvector(array,_,_) -> big_int_of_int (Array.length array)
- | Vregister(array,_,_,_) -> big_int_of_int (Array.length !array)
- | VvectorR(array,_,_) -> big_int_of_int (Array.length array)
+ | Vvector(array,_,_) -> Array.length array
+ | Vregister(array,_,_,_) -> Array.length !array
+ | VvectorR(array,_,_) -> Array.length array
| _ -> assert false
+let length_big v = big_int_of_int (length v)
+
let read_register = function
| Vregister(a,start,inc,_) -> Vvector(!a,start,inc)
| v -> v
@@ -53,6 +58,8 @@ let vector_access v n = match v with
then (array.(n-start))
else (array.(start-n))
| _ -> assert false
+
+let vector_access_big v n = vector_access v (int_of_big_int n)
let bit_vector_access v n = match v with
| Vvector(array,start,is_inc) ->
@@ -65,6 +72,8 @@ let bit_vector_access v n = match v with
else !array.(start-n)
| _ -> assert false
+let bit_vector_access_big v n = bit_vector_access v (int_of_big_int n)
+
let vector_subrange v n m =
let builder array length offset default =
let new_array = Array.make length default in
@@ -87,6 +96,8 @@ let vector_subrange v n m =
Vvector(builder !array length offset Vzero,n,is_inc)
| _ -> v
+let vector_subrange_big v n m = vector_subrange v (int_of_big_int n) (int_of_big_int m)
+
let get_register_field_vec reg field =
match reg with
| Vregister(_,_,_,fields) ->
@@ -128,6 +139,9 @@ let set_vector_subrange_vec v n m new_v =
walker array length offset new_v
| _ -> ()
+let set_vector_subrange_vec_big v n m new_v =
+ set_vector_subrange_vec v (int_of_big_int n) (int_of_big_int m) new_v
+
let set_vector_subrange_bit v n m new_v =
let walker array length offset new_values =
begin
@@ -145,6 +159,9 @@ let set_vector_subrange_bit v n m new_v =
walker !array length offset new_v
| _ -> ()
+let set_vector_subrange_bit_big v n m new_v =
+ set_vector_subrange_bit v (int_of_big_int n) (int_of_big_int m) new_v
+
let set_register_field_v reg field new_v =
match reg with
| Vregister(array,start,dir,fields) ->
@@ -166,10 +183,10 @@ let set_register_field_bit reg field new_v =
| _ -> ()
let set_two_reg r1 r2 vec =
- let size = int_of_big_int (length r1) in
+ let size = length r1 in
let dir = get_ord r1 in
let start = get_start vec in
- let vsize = int_of_big_int (length vec) in
+ let vsize = length vec in
let r1_v = vector_subrange vec start ((if dir then size - start else start - size) - 1) in
let r2_v = vector_subrange vec (if dir then size - start else start - size)
(if dir then vsize - start else start - vsize) in
@@ -186,6 +203,9 @@ let make_indexed_v entries default start size dir =
VvectorR(array, start, dir)
end
+let make_indexed_v_big entries default start size dir =
+ make_indexed_v entries default (int_of_big_int start) (int_of_big_int size) dir
+
let make_indexed_bitv entries default start size dir =
let default_value = match default with
| None -> Vundef
@@ -196,6 +216,9 @@ let make_indexed_bitv entries default start size dir =
Vvector(array, start, dir)
end
+let make_indexed_bitv_big entries default start size dir =
+ make_indexed_bitv entries default (int_of_big_int start) (int_of_big_int size) dir
+
let vector_concat l r =
match l,r with
| Vvector(arrayl,start,ord), Vvector(arrayr,_,_) ->
@@ -283,11 +306,44 @@ let bitwise_and = bitwise_binop (&&)
let bitwise_or = bitwise_binop (||)
let bitwise_xor = bitwise_binop (fun x y -> (1 = (if x then 1 else 0) lxor (if y then 0 else 1)))
+let rec power_int base raiseto =
+ if raiseto = 0
+ then 1
+ else base * (power_int base (raiseto - 1))
+
let unsigned = function
| (Vvector(array,_,_) as v) ->
if has_undef v
then assert false
else
+ let acc = ref 0 in
+ begin for i = (Array.length array) - 1 downto 0 do
+ match array.(i) with
+ | Vone -> acc := !acc + (power_int 2 i)
+ | _ -> ()
+ done;
+ !acc
+ end
+ | (Vregister(array,_,_,_) as v)->
+ let array = !array in
+ if has_undef v
+ then assert false
+ else
+ let acc = ref 0 in
+ begin for i = (Array.length array) - 1 downto 0 do
+ match array.(i) with
+ | Vone -> acc := !acc + (power_int 2 i)
+ | _ -> ()
+ done;
+ !acc
+ end
+ | _ -> assert false
+
+let unsigned_big = function
+ | (Vvector(array,_,_) as v) ->
+ if has_undef v
+ then assert false
+ else
let acc = ref zero_big_int in
begin for i = (Array.length array) - 1 downto 0 do
match array.(i) with
@@ -313,12 +369,19 @@ let unsigned = function
let signed v =
match most_significant v with
- | Vone -> minus_big_int(add_int_big_int 1 (unsigned (bitwise_not v)))
+ | Vone -> -(1 + (unsigned (bitwise_not v)))
| Vzero -> unsigned v
| _ -> assert false
+let signed_big v =
+ match most_significant v with
+ | Vone -> minus_big_int(add_int_big_int 1 (unsigned_big (bitwise_not v)))
+ | Vzero -> unsigned_big v
+ | _ -> assert false
+
let to_num sign = if sign then signed else unsigned
-
+let to_num_big sign = if sign then signed_big else unsigned_big
+
let two_big_int = big_int_of_int 2
let max_64u = pred_big_int (power_big two_big_int (big_int_of_int 64))
let max_64 = pred_big_int (power_big two_big_int (big_int_of_int 63))
@@ -347,12 +410,19 @@ let get_min_representable_in _ n =
else minus_big_int (power_big two_big_int (big_int_of_int n))
-
-let rec divide_by_2 array i n =
+let rec divide_by_2_big array i n =
if i < 0 || eq_big_int n zero_big_int
then array
else let (quo,modu) = quomod_big_int n two_big_int in
if eq_big_int modu unit_big_int
+ then begin array.(i) <- Vone; divide_by_2_big array (i-1) quo end
+ else divide_by_2_big array (i-1) quo
+
+let rec divide_by_2 array i n =
+ if i < 0 || n = 0
+ then array
+ else let (quo,modu) = n/2, n mod 2 in
+ if modu = 0
then begin array.(i) <- Vone; divide_by_2 array (i-1) quo end
else divide_by_2 array (i-1) quo
@@ -367,16 +437,31 @@ let rec add_one_bit array co i =
| Vundef,_ -> assert false
let to_vec ord len n =
+ let array = Array.make len Vzero in
+ let start = if ord then 0 else len-1 in
+ if n = 0
+ then Vvector(array, start, ord)
+ else if n >= 0
+ then Vvector(divide_by_2 array (len -1) n, start, ord)
+ else
+ let abs_n = abs n in
+ let abs_array = divide_by_2 array (len-1) abs_n in
+ let v_abs = bitwise_not (Vvector(abs_array,start,ord)) in
+ match v_abs with
+ | Vvector(array,start,ord) -> Vvector(add_one_bit array false (len-1),start,ord)
+ | _ -> assert false
+
+let to_vec_big ord len n =
let len = int_of_big_int len in
let array = Array.make len Vzero in
let start = if ord then 0 else len-1 in
if eq_big_int n zero_big_int
then Vvector(array, start, ord)
else if gt_big_int n zero_big_int
- then Vvector(divide_by_2 array (len -1) n, start, ord)
+ then Vvector(divide_by_2_big array (len -1) n, start, ord)
else
let abs_n = abs_big_int n in
- let abs_array = divide_by_2 array (len-1) abs_n in
+ let abs_array = divide_by_2_big array (len-1) abs_n in
let v_abs = bitwise_not (Vvector(abs_array,start,ord)) in
match v_abs with
| Vvector(array,start,ord) -> Vvector(add_one_bit array false (len-1),start,ord)
@@ -385,7 +470,15 @@ let to_vec ord len n =
let to_vec_inc (len,n) = to_vec true len n
let to_vec_dec (len,n) = to_vec false len n
+let to_vec_inc_big (len,n) = to_vec_big true len n
+let to_vec_dec_big (len,n) = to_vec_big false len n
+
let to_vec_undef ord len =
+ let array = Array.make len Vundef in
+ let start = if ord then 0 else len-1 in
+ Vvector(array, start, ord)
+
+let to_vec_undef_big ord len =
let len = int_of_big_int len in
let array = Array.make len Vundef in
let start = if ord then 0 else len-1 in
@@ -394,86 +487,184 @@ let to_vec_undef ord len =
let to_vec_inc_undef len = to_vec_undef true len
let to_vec_dec_undef len = to_vec_undef false len
+let to_vec_inc_undef_big len = to_vec_undef_big true len
+let to_vec_dec_undef_big len = to_vec_undef_big false len
+
let arith_op op (l,r) = op l r
-let add = arith_op add_big_int
-let add_signed = arith_op add_big_int
-let minus = arith_op sub_big_int
-let multiply = arith_op mult_big_int
-let modulo = arith_op mod_big_int
-let quot = arith_op div_big_int
-let power = arith_op power_big
+let add_big = arith_op add_big_int
+let add_signed_big = arith_op add_big_int
+let minus_big = arith_op sub_big_int
+let multiply_big = arith_op mult_big_int
+let modulo_big = arith_op mod_big_int
+let quot_big = arith_op div_big_int
+let power_big = arith_op power_big
+
+let add = arith_op (+)
+let add_signed = arith_op (+)
+let minus = arith_op (-)
+let multiply = arith_op ( * )
+let modulo = arith_op (mod)
+let quot = arith_op (/)
+let power = arith_op power_int
+
+let arith_op_vec_big op sign size (l,r) =
+ let ord = get_ord l in
+ let (l',r') = to_num_big sign l, to_num_big sign r in
+ let n = arith_op op (l',r') in
+ to_vec_big ord (mult_big_int size (length_big l)) n
+
+let add_vec_big = arith_op_vec_big add_big_int false unit_big_int
+let add_vec_signed_big = arith_op_vec_big add_big_int true unit_big_int
+let minus_vec_big = arith_op_vec_big sub_big_int false unit_big_int
+let multiply_vec_big = arith_op_vec_big mult_big_int false two_big_int
+let multiply_vec_signed_big = arith_op_vec_big mult_big_int true two_big_int
let arith_op_vec op sign size (l,r) =
let ord = get_ord l in
let (l',r') = to_num sign l, to_num sign r in
let n = arith_op op (l',r') in
- to_vec ord (mult_big_int size (length l)) n
+ to_vec ord (size * (length l)) n
-let add_vec = arith_op_vec add_big_int false unit_big_int
-let add_vec_signed = arith_op_vec add_big_int true unit_big_int
-let minus_vec = arith_op_vec sub_big_int false unit_big_int
-let multiply_vec = arith_op_vec mult_big_int false two_big_int
-let multiply_vec_signed = arith_op_vec mult_big_int true two_big_int
+let add_vec = arith_op_vec (+) false 1
+let add_vec_signed = arith_op_vec (+) true 1
+let minus_vec = arith_op_vec (-) false 1
+let multiply_vec = arith_op_vec ( * ) false 2
+let multiply_vec_signed = arith_op_vec ( * ) true 2
let arith_op_vec_range op sign size (l,r) =
let ord = get_ord l in
arith_op_vec op sign size (l, to_vec ord (length l) r)
-let add_vec_range = arith_op_vec_range add_big_int false unit_big_int
-let add_vec_range_signed = arith_op_vec_range add_big_int true unit_big_int
-let minus_vec_range = arith_op_vec_range sub_big_int false unit_big_int
-let mult_vec_range = arith_op_vec_range mult_big_int false two_big_int
-let mult_vec_range_signed = arith_op_vec_range mult_big_int true two_big_int
+let add_vec_range = arith_op_vec_range (+) false 1
+let add_vec_range_signed = arith_op_vec_range (+) true 1
+let minus_vec_range = arith_op_vec_range (-) false 1
+let mult_vec_range = arith_op_vec_range ( * ) false 2
+let mult_vec_range_signed = arith_op_vec_range ( * ) true 2
+
+let arith_op_vec_range_big op sign size (l,r) =
+ let ord = get_ord l in
+ arith_op_vec_big op sign size (l, to_vec_big ord (length_big l) r)
+
+let add_vec_range_big = arith_op_vec_range_big add_big_int false unit_big_int
+let add_vec_range_signed_big = arith_op_vec_range_big add_big_int true unit_big_int
+let minus_vec_range_big = arith_op_vec_range_big sub_big_int false unit_big_int
+let mult_vec_range_big = arith_op_vec_range_big mult_big_int false two_big_int
+let mult_vec_range_signed_big = arith_op_vec_range_big mult_big_int true two_big_int
+
let arith_op_range_vec op sign size (l,r) =
let ord = get_ord r in
arith_op_vec op sign size ((to_vec ord (length r) l), r)
-let add_range_vec = arith_op_range_vec add_big_int false unit_big_int
-let add_range_vec_signed = arith_op_range_vec add_big_int true unit_big_int
-let minus_range_vec = arith_op_range_vec sub_big_int false unit_big_int
-let mult_range_vec = arith_op_range_vec mult_big_int false two_big_int
-let mult_range_vec_signed = arith_op_range_vec mult_big_int true two_big_int
+let add_range_vec = arith_op_range_vec (+) false 1
+let add_range_vec_signed = arith_op_range_vec (+) true 1
+let minus_range_vec = arith_op_range_vec (-) false 1
+let mult_range_vec = arith_op_range_vec ( * ) false 2
+let mult_range_vec_signed = arith_op_range_vec ( * ) true 2
+
+let arith_op_range_vec_big op sign size (l,r) =
+ let ord = get_ord r in
+ arith_op_vec_big op sign size ((to_vec_big ord (length_big r) l), r)
+
+let add_range_vec_big = arith_op_range_vec_big add_big_int false unit_big_int
+let add_range_vec_signed_big = arith_op_range_vec_big add_big_int true unit_big_int
+let minus_range_vec_big = arith_op_range_vec_big sub_big_int false unit_big_int
+let mult_range_vec_big = arith_op_range_vec_big mult_big_int false two_big_int
+let mult_range_vec_signed_big = arith_op_range_vec_big mult_big_int true two_big_int
+
let arith_op_range_vec_range op sign (l,r) = arith_op op (l, to_num sign r)
-let add_range_vec_range = arith_op_range_vec_range add_big_int false
-let add_range_vec_range_signed = arith_op_range_vec_range add_big_int true
-let minus_range_vec_range = arith_op_range_vec_range sub_big_int false
+let add_range_vec_range = arith_op_range_vec_range (+) false
+let add_range_vec_range_signed = arith_op_range_vec_range (+) true
+let minus_range_vec_range = arith_op_range_vec_range (-) false
+
+let arith_op_range_vec_range_big op sign (l,r) = arith_op op (l, to_num_big sign r)
+
+let add_range_vec_range_big = arith_op_range_vec_range_big add_big_int false
+let add_range_vec_range_signed_big = arith_op_range_vec_range_big add_big_int true
+let minus_range_vec_range_big = arith_op_range_vec_range_big sub_big_int false
let arith_op_vec_range_range op sign (l,r) = arith_op op (to_num sign l,r)
-let add_vec_range_range = arith_op_vec_range_range add_big_int false
-let add_vec_range_range_signed = arith_op_vec_range_range add_big_int true
-let minus_vec_range_range = arith_op_vec_range_range sub_big_int false
+let add_vec_range_range = arith_op_vec_range_range (+) false
+let add_vec_range_range_signed = arith_op_vec_range_range (+) true
+let minus_vec_range_range = arith_op_vec_range_range (-) false
+
+let arith_op_vec_range_range_big op sign (l,r) = arith_op op (to_num_big sign l,r)
+
+let add_vec_range_range_big = arith_op_vec_range_range_big add_big_int false
+let add_vec_range_range_signed_big = arith_op_vec_range_range_big add_big_int true
+let minus_vec_range_range_big = arith_op_vec_range_range_big sub_big_int false
let arith_op_vec_vec_range op sign (l,r) =
let (l',r') = (to_num sign l,to_num sign r) in
arith_op op (l',r')
-let add_vec_vec_range = arith_op_vec_vec_range add_big_int false
-let add_vec_vec_range_signed = arith_op_vec_vec_range add_big_int true
+let add_vec_vec_range = arith_op_vec_vec_range (+) false
+let add_vec_vec_range_signed = arith_op_vec_vec_range (+) true
+
+let arith_op_vec_vec_range_big op sign (l,r) =
+ let (l',r') = (to_num_big sign l,to_num_big sign r) in
+ arith_op op (l',r')
-let arith_op_vec_bit op sign size (l,r) =
+let add_vec_vec_range_big = arith_op_vec_vec_range_big add_big_int false
+let add_vec_vec_range_signed_big = arith_op_vec_vec_range_big add_big_int true
+
+let arith_op_vec_bit op sign (l,r) =
let ord = get_ord l in
let l' = to_num sign l in
+ let n = arith_op op (l', match r with | Vone -> 1 | _ -> 0) in
+ to_vec ord (length l) n
+
+let add_vec_bit = arith_op_vec_bit (+) false
+let add_vec_bit_signed = arith_op_vec_bit (+) true
+let minus_vec_bit = arith_op_vec_bit (-) true
+
+let arith_op_vec_bit_big op sign (l,r) =
+ let ord = get_ord l in
+ let l' = to_num_big sign l in
let n = arith_op op (l', match r with | Vone -> unit_big_int | _ -> zero_big_int) in
- to_vec ord (mult_big_int (length l) size) n
+ to_vec_big ord (length_big l) n
-let add_vec_bit = arith_op_vec_bit add_big_int false unit_big_int
-let add_vec_bit_signed = arith_op_vec_bit add_big_int true unit_big_int
-let minus_vec_bit = arith_op_vec_bit sub_big_int true unit_big_int
+let add_vec_bit_big = arith_op_vec_bit_big add_big_int false
+let add_vec_bit_signed_big = arith_op_vec_bit_big add_big_int true
+let minus_vec_bit_big = arith_op_vec_bit_big sub_big_int true
let rec arith_op_overflow_vec op sign size (l,r) =
let ord = get_ord l in
let len = length l in
- let act_size = mult_big_int len size in
+ let act_size = len * size in
let (l_sign,r_sign) = (to_num sign l,to_num sign r) in
let (l_unsign,r_unsign) = (to_num false l,to_num false r) in
let n = arith_op op (l_sign,r_sign) in
let n_unsign = arith_op op (l_unsign,r_unsign) in
let correct_size_num = to_vec ord act_size n in
- let one_more_size_u = to_vec ord (succ_big_int act_size) n_unsign in
+ let one_more_size_u = to_vec ord (act_size +1) n_unsign in
+ let overflow = if (n <= (int_of_big_int (get_max_representable_in sign len))) &&
+ (n >= (int_of_big_int (get_min_representable_in sign len)))
+ then Vzero
+ else Vone in
+ let c_out = most_significant one_more_size_u in
+ (correct_size_num,overflow,c_out)
+
+let add_overflow_vec = arith_op_overflow_vec (+) false 1
+let add_overflow_vec_signed = arith_op_overflow_vec (+) true 1
+let minus_overflow_vec = arith_op_overflow_vec (-) false 1
+let minus_overflow_vec_signed = arith_op_overflow_vec (-) true 1
+let mult_overflow_vec = arith_op_overflow_vec ( * ) false 2
+let mult_overflow_vec_signed = arith_op_overflow_vec ( * ) true 2
+
+let rec arith_op_overflow_vec_big op sign size (l,r) =
+ let ord = get_ord l in
+ let len = length_big l in
+ let act_size = mult_big_int len size in
+ let (l_sign,r_sign) = (to_num_big sign l,to_num_big sign r) in
+ let (l_unsign,r_unsign) = (to_num_big false l,to_num_big false r) in
+ let n = arith_op op (l_sign,r_sign) in
+ let n_unsign = arith_op op (l_unsign,r_unsign) in
+ let correct_size_num = to_vec_big ord act_size n in
+ let one_more_size_u = to_vec_big ord (succ_big_int act_size) n_unsign in
let overflow = if (le_big_int n (get_max_representable_in sign (int_of_big_int len))) &&
(ge_big_int n (get_min_representable_in sign (int_of_big_int len)))
then Vzero
@@ -481,25 +672,50 @@ let rec arith_op_overflow_vec op sign size (l,r) =
let c_out = most_significant one_more_size_u in
(correct_size_num,overflow,c_out)
-let add_overflow_vec = arith_op_overflow_vec add_big_int false unit_big_int
-let add_overflow_vec_signed = arith_op_overflow_vec add_big_int true unit_big_int
-let minus_overflow_vec = arith_op_overflow_vec sub_big_int false unit_big_int
-let minus_overflow_vec_signed = arith_op_overflow_vec sub_big_int true unit_big_int
-let mult_overflow_vec = arith_op_overflow_vec mult_big_int false two_big_int
-let mult_overflow_vec_signed = arith_op_overflow_vec mult_big_int true two_big_int
-
-let rec arith_op_overflow_vec_bit op sign size (l,r_bit) =
+let add_overflow_vec_big = arith_op_overflow_vec_big add_big_int false unit_big_int
+let add_overflow_vec_signed_big = arith_op_overflow_vec_big add_big_int true unit_big_int
+let minus_overflow_vec_big = arith_op_overflow_vec_big sub_big_int false unit_big_int
+let minus_overflow_vec_signed_big = arith_op_overflow_vec_big sub_big_int true unit_big_int
+let mult_overflow_vec_big = arith_op_overflow_vec_big mult_big_int false two_big_int
+let mult_overflow_vec_signed_big = arith_op_overflow_vec_big mult_big_int true two_big_int
+
+let rec arith_op_overflow_vec_bit op sign (l,r_bit) =
let ord = get_ord l in
- let act_size = mult_big_int (length l) size in
+ let act_size = length l in
let l' = to_num sign l in
let l_u = to_num false l in
let (n,nu,changed) = match r_bit with
- | Vone -> (arith_op op (l',unit_big_int), arith_op op (l_u,unit_big_int), true)
+ | Vone -> (arith_op op (l',1), arith_op op (l_u,1), true)
| Vzero -> (l',l_u,false)
| _ -> assert false
in
let correct_size_num = to_vec ord act_size n in
- let one_larger = to_vec ord (succ_big_int act_size) nu in
+ let one_larger = to_vec ord (1+ act_size) nu in
+ let overflow =
+ if changed
+ then if (n <= (int_of_big_int (get_max_representable_in sign act_size))) &&
+ (n >= (int_of_big_int (get_min_representable_in sign act_size)))
+ then Vzero
+ else Vone
+ else Vone in
+ (correct_size_num,overflow,most_significant one_larger)
+
+let add_overflow_vec_bit_signed = arith_op_overflow_vec_bit (+) true
+let minus_overflow_vec_bit = arith_op_overflow_vec_bit (-) false
+let minus_overflow_vec_bit_signed = arith_op_overflow_vec_bit (-) true
+
+let rec arith_op_overflow_vec_bit_big op sign (l,r_bit) =
+ let ord = get_ord l in
+ let act_size = length_big l in
+ let l' = to_num_big sign l in
+ let l_u = to_num_big false l in
+ let (n,nu,changed) = match r_bit with
+ | Vone -> (arith_op op (l',unit_big_int), arith_op op (l_u,unit_big_int), true)
+ | Vzero -> (l',l_u,false)
+ | _ -> assert false
+ in
+ let correct_size_num = to_vec_big ord act_size n in
+ let one_larger = to_vec_big ord (succ_big_int act_size) nu in
let overflow =
if changed
then if (le_big_int n (get_max_representable_in sign (int_of_big_int act_size))) &&
@@ -509,28 +725,28 @@ let rec arith_op_overflow_vec_bit op sign size (l,r_bit) =
else Vone in
(correct_size_num,overflow,most_significant one_larger)
-let add_overflow_vec_bit_signed = arith_op_overflow_vec_bit add_big_int true unit_big_int
-let minus_overflow_vec_bit = arith_op_overflow_vec_bit sub_big_int false unit_big_int
-let minus_overflow_vec_bit_signed = arith_op_overflow_vec_bit sub_big_int true unit_big_int
-
+let add_overflow_vec_bit_signed_big = arith_op_overflow_vec_bit_big add_big_int true
+let minus_overflow_vec_bit_big = arith_op_overflow_vec_bit_big sub_big_int false
+let minus_overflow_vec_bit_signed_big = arith_op_overflow_vec_bit_big sub_big_int true
+
+
let shift_op_vec op (l,r) =
match l with
| Vvector(_,start,ord) | Vregister(_,start,ord,_) ->
let array = match l with | Vvector(array,_,_) -> array | Vregister(array,_,_,_) -> !array | _ -> assert false in
let len = Array.length array in
- let n = int_of_big_int r in
(match op with
| "<<" ->
- let right_vec = Vvector(Array.make n Vzero,0,true) in
- let left_vec = vector_subrange l n (if ord then len + start else start - len) in
+ let right_vec = Vvector(Array.make r Vzero,0,true) in
+ let left_vec = vector_subrange l r (if ord then len + start else start - len) in
vector_concat left_vec right_vec
| ">>" ->
- let right_vec = vector_subrange l start n in
- let left_vec = Vvector(Array.make n Vzero,0,true) in
+ let right_vec = vector_subrange l start r in
+ let left_vec = Vvector(Array.make r Vzero,0,true) in
vector_concat left_vec right_vec
| "<<<" ->
- let left_vec = vector_subrange l n (if ord then len + start else start - len) in
- let right_vec = vector_subrange l start n in
+ let left_vec = vector_subrange l r (if ord then len + start else start - len) in
+ let right_vec = vector_subrange l start r in
vector_concat left_vec right_vec
| _ -> assert false)
| _ -> assert false
@@ -539,41 +755,77 @@ let bitwise_leftshift = shift_op_vec "<<"
let bitwise_rightshift = shift_op_vec ">>"
let bitwise_rotate = shift_op_vec "<<<"
-let rec arith_op_no0 op (l,r) =
+let shift_op_vec_big op (l,r) = shift_op_vec op (l, int_of_big_int r)
+let bitwise_leftshift_big = shift_op_vec_big "<<"
+let bitwise_rightshift_big = shift_op_vec_big ">>"
+let bitwise_rotate_big = shift_op_vec_big "<<<"
+
+let rec arith_op_no0_big op (l,r) =
if eq_big_int r zero_big_int
then None
else Some (op l r)
-let modulo = arith_op_no0 mod_big_int
-let quot = arith_op_no0 div_big_int
+let modulo_big = arith_op_no0_big mod_big_int
+let quot_big = arith_op_no0_big div_big_int
+
+let rec arith_op_no0 op (l,r) =
+ if r = 0
+ then None
+ else Some (op l r)
+
+let modulo = arith_op_no0 (mod)
+let quot = arith_op_no0 (/)
let rec arith_op_vec_no0 op sign size (l,r) =
let ord = get_ord l in
- let act_size = int_of_big_int (mult_big_int (length l) size) in
+ let act_size = ((length l) * size) in
let (l',r') = (to_num sign l,to_num sign r) in
let n = arith_op_no0 op (l',r') in
let representable,n' =
match n with
| Some n' ->
+ ((n' <= (int_of_big_int (get_max_representable_in sign act_size))) &&
+ (n' >= (int_of_big_int (get_min_representable_in sign act_size)))), n'
+ | _ -> false,0 in
+ if representable
+ then to_vec ord act_size n'
+ else
+ match l with
+ | Vvector(_, start, _) | Vregister(_, start, _, _) ->
+ Vvector((Array.make act_size Vundef), start, ord)
+ | _ -> assert false
+
+let mod_vec = arith_op_vec_no0 (mod) false 1
+let quot_vec = arith_op_vec_no0 (/) false 1
+let quot_vec_signed = arith_op_vec_no0 (/) true 1
+
+let rec arith_op_vec_no0_big op sign size (l,r) =
+ let ord = get_ord l in
+ let act_size = int_of_big_int (mult_int_big_int (length l) size) in
+ let (l',r') = (to_num_big sign l,to_num_big sign r) in
+ let n = arith_op_no0_big op (l',r') in
+ let representable,n' =
+ match n with
+ | Some n' ->
((le_big_int n' (get_max_representable_in sign act_size)) &&
(ge_big_int n' (get_min_representable_in sign act_size))), n'
| _ -> false,zero_big_int in
if representable
- then to_vec ord (big_int_of_int act_size) n'
+ then to_vec_big ord (big_int_of_int act_size) n'
else
match l with
| Vvector(_, start, _) | Vregister(_, start, _, _) ->
Vvector((Array.make act_size Vundef), start, ord)
| _ -> assert false
-let mod_vec = arith_op_vec_no0 mod_big_int false unit_big_int
-let quot_vec = arith_op_vec_no0 div_big_int false unit_big_int
-let quot_vec_signed = arith_op_vec_no0 div_big_int true unit_big_int
+let mod_vec_big = arith_op_vec_no0_big mod_big_int false unit_big_int
+let quot_vec_big = arith_op_vec_no0_big div_big_int false unit_big_int
+let quot_vec_signed_big = arith_op_vec_no0_big div_big_int true unit_big_int
let arith_op_overflow_no0_vec op sign size (l,r) =
let ord = get_ord l in
- let rep_size = mult_big_int (length r) size in
- let act_size = mult_big_int (length l) size in
+ let rep_size = (length r) * size in
+ let act_size = (length l) * size in
let (l',r') = ((to_num sign l),(to_num sign r)) in
let (l_u,r_u) = (to_num false l,to_num false r) in
let n = arith_op_no0 op (l',r') in
@@ -581,12 +833,40 @@ let arith_op_overflow_no0_vec op sign size (l,r) =
let representable,n',n_u' =
match n, n_u with
| Some n',Some n_u' ->
+ ((n' <= (int_of_big_int (get_max_representable_in sign rep_size))) &&
+ (n' >= (int_of_big_int (get_min_representable_in sign rep_size))), n', n_u')
+ | _ -> true,0,0 in
+ let (correct_size_num,one_more) =
+ if representable then
+ (to_vec ord act_size n',to_vec ord (1+act_size) n_u')
+ else match l with
+ | Vvector(_, start, _) | Vregister(_, start, _, _) ->
+ Vvector((Array.make act_size Vundef), start, ord),
+ Vvector((Array.make (act_size + 1) Vundef), start, ord)
+ | _ -> assert false in
+ let overflow = if representable then Vzero else Vone in
+ (correct_size_num,overflow,most_significant one_more)
+
+let quot_overflow_vec = arith_op_overflow_no0_vec (/) false 1
+let quot_overflow_vec_signed = arith_op_overflow_no0_vec (/) true 1
+
+let arith_op_overflow_no0_vec_big op sign size (l,r) =
+ let ord = get_ord l in
+ let rep_size = mult_big_int (length_big r) size in
+ let act_size = mult_big_int (length_big l) size in
+ let (l',r') = ((to_num_big sign l),(to_num_big sign r)) in
+ let (l_u,r_u) = (to_num_big false l,to_num_big false r) in
+ let n = arith_op_no0_big op (l',r') in
+ let n_u = arith_op_no0_big op (l_u,r_u) in
+ let representable,n',n_u' =
+ match n, n_u with
+ | Some n',Some n_u' ->
((le_big_int n' (get_max_representable_in sign (int_of_big_int rep_size))) &&
(ge_big_int n' (get_min_representable_in sign (int_of_big_int rep_size))), n', n_u')
| _ -> true,zero_big_int,zero_big_int in
let (correct_size_num,one_more) =
if representable then
- (to_vec ord act_size n',to_vec ord (succ_big_int act_size) n_u')
+ (to_vec_big ord act_size n',to_vec_big ord (succ_big_int act_size) n_u')
else match l with
| Vvector(_, start, _) | Vregister(_, start, _, _) ->
Vvector((Array.make (int_of_big_int act_size) Vundef), start, ord),
@@ -595,62 +875,109 @@ let arith_op_overflow_no0_vec op sign size (l,r) =
let overflow = if representable then Vzero else Vone in
(correct_size_num,overflow,most_significant one_more)
-let quot_overflow_vec = arith_op_overflow_no0_vec div_big_int false unit_big_int
-let quot_overflow_vec_signed = arith_op_overflow_no0_vec div_big_int true unit_big_int
+let quot_overflow_vec_big = arith_op_overflow_no0_vec_big div_big_int false unit_big_int
+let quot_overflow_vec_signed_big = arith_op_overflow_no0_vec_big div_big_int true unit_big_int
let arith_op_vec_range_no0 op sign size (l,r) =
let ord = get_ord l in
arith_op_vec_no0 op sign size (l,(to_vec ord (length l) r))
-let mod_vec_range = arith_op_vec_range_no0 mod_big_int false unit_big_int
+let mod_vec_range = arith_op_vec_range_no0 (mod) false 1
+
+let arith_op_vec_range_no0_big op sign size (l,r) =
+ let ord = get_ord l in
+ arith_op_vec_no0_big op sign size (l,(to_vec_big ord (length_big l) r))
+
+let mod_vec_range_big = arith_op_vec_range_no0_big mod_big_int false unit_big_int
(*Need to have a default top level direction reference I think*)
let duplicate (bit,length) =
- Vvector((Array.make (int_of_big_int length) bit), 0, true)
+ Vvector((Array.make length bit), 0, true)
+let duplicate_big (bit,length) =
+ Vvector((Array.make (int_of_big_int length) bit), 0, true)
let compare_op op (l,r) =
if (op l r)
then Vone
else Vzero
-let lt = compare_op lt_big_int
-let gt = compare_op gt_big_int
-let lteq = compare_op le_big_int
-let gteq = compare_op ge_big_int
+let lt_big = compare_op lt_big_int
+let gt_big = compare_op gt_big_int
+let lteq_big = compare_op le_big_int
+let gteq_big = compare_op ge_big_int
+let lt : (int* int) -> vbit = compare_op (<)
+let gt : (int * int) -> vbit = compare_op (>)
+let lteq : (int * int) -> vbit = compare_op (<=)
+let gteq : (int*int) -> vbit = compare_op (>=)
let compare_op_vec op sign (l,r) =
let (l',r') = (to_num sign l, to_num sign r) in
compare_op op (l',r')
-let lt_vec = compare_op_vec lt_big_int true
-let gt_vec = compare_op_vec gt_big_int true
-let lteq_vec = compare_op_vec le_big_int true
-let gteq_vec = compare_op_vec ge_big_int true
-let lt_vec_signed = compare_op_vec lt_big_int true
-let gt_vec_signed = compare_op_vec gt_big_int true
-let lteq_vec_signed = compare_op_vec le_big_int true
-let gteq_vec_signed = compare_op_vec ge_big_int true
-let lt_vec_unsigned = compare_op_vec lt_big_int false
-let gt_vec_unsigned = compare_op_vec gt_big_int false
-let lteq_vec_unsigned = compare_op_vec le_big_int false
-let gteq_vec_unsigned = compare_op_vec ge_big_int false
+let lt_vec = compare_op_vec (<) true
+let gt_vec = compare_op_vec (>) true
+let lteq_vec = compare_op_vec (<=) true
+let gteq_vec = compare_op_vec (>=) true
+let lt_vec_signed = compare_op_vec (<) true
+let gt_vec_signed = compare_op_vec (>) true
+let lteq_vec_signed = compare_op_vec (<=) true
+let gteq_vec_signed = compare_op_vec (>=) true
+let lt_vec_unsigned = compare_op_vec (<) false
+let gt_vec_unsigned = compare_op_vec (>) false
+let lteq_vec_unsigned = compare_op_vec (<=) false
+let gteq_vec_unsigned = compare_op_vec (>=) false
+
+let compare_op_vec_big op sign (l,r) =
+ let (l',r') = (to_num_big sign l, to_num_big sign r) in
+ compare_op op (l',r')
+
+let lt_vec_big = compare_op_vec_big lt_big_int true
+let gt_vec_big = compare_op_vec_big gt_big_int true
+let lteq_vec_big = compare_op_vec_big le_big_int true
+let gteq_vec_big = compare_op_vec_big ge_big_int true
+let lt_vec_signed_big = compare_op_vec_big lt_big_int true
+let gt_vec_signed_big = compare_op_vec_big gt_big_int true
+let lteq_vec_signed_big = compare_op_vec_big le_big_int true
+let gteq_vec_signed_big = compare_op_vec_big ge_big_int true
+let lt_vec_unsigned_big = compare_op_vec_big lt_big_int false
+let gt_vec_unsigned_big = compare_op_vec_big gt_big_int false
+let lteq_vec_unsigned_big = compare_op_vec_big le_big_int false
+let gteq_vec_unsigned_big = compare_op_vec_big ge_big_int false
+
let compare_op_vec_range op sign (l,r) =
compare_op op ((to_num sign l),r)
-let lt_vec_range = compare_op_vec_range lt_big_int true
-let gt_vec_range = compare_op_vec_range gt_big_int true
-let lteq_vec_range = compare_op_vec_range le_big_int true
-let gteq_vec_range = compare_op_vec_range ge_big_int true
+let lt_vec_range = compare_op_vec_range (<) true
+let gt_vec_range = compare_op_vec_range (>) true
+let lteq_vec_range = compare_op_vec_range (<=) true
+let gteq_vec_range = compare_op_vec_range (>=) true
+
+let compare_op_vec_range_big op sign (l,r) =
+ compare_op op ((to_num_big sign l),r)
+
+let lt_vec_range_big = compare_op_vec_range_big lt_big_int true
+let gt_vec_range_big = compare_op_vec_range_big gt_big_int true
+let lteq_vec_range_big = compare_op_vec_range_big le_big_int true
+let gteq_vec_range_big = compare_op_vec_range_big ge_big_int true
let compare_op_range_vec op sign (l,r) =
compare_op op (l, (to_num sign r))
-let lt_range_vec = compare_op_range_vec lt_big_int true
-let gt_range_vec = compare_op_range_vec gt_big_int true
-let lteq_range_vec = compare_op_range_vec le_big_int true
-let gteq_range_vec = compare_op_range_vec ge_big_int true
+let lt_range_vec = compare_op_range_vec (<) true
+let gt_range_vec = compare_op_range_vec (>) true
+let lteq_range_vec = compare_op_range_vec (<=) true
+let gteq_range_vec = compare_op_range_vec (>=) true
+
+let compare_op_range_vec_big op sign (l,r) =
+ compare_op op (l, (to_num_big sign r))
+
+let lt_range_vec_big = compare_op_range_vec_big lt_big_int true
+let gt_range_vec_big = compare_op_range_vec_big gt_big_int true
+let lteq_range_vec_big = compare_op_range_vec_big le_big_int true
+let gteq_range_vec_big = compare_op_range_vec_big ge_big_int true
+
let eq (l,r) = if l == r then Vone else Vzero
let eq_vec_range (l,r) = eq (to_num false l,r)