aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Maxime Dénès <mail@maximedenes.fr>2014-04-07 15:45:33 -0400
committerGravatar Maxime Dénès <mail@maximedenes.fr>2014-04-09 01:05:48 -0400
commit2e8c02d5644e8e8e446ab6dfd832322276e44f89 (patch)
tree9f7564ac88d210611cbd5fa5cf2de8efad038e36
parenta91518d0b07b9a2cd7d9381044c20365771ec382 (diff)
Machine arithmetic operations for native compiler.
This completes the port of the native compiler to retroknowledge. However, some testing and optimizations are still to be done.
-rw-r--r--dev/printers.mllib1
-rw-r--r--kernel/environ.ml35
-rw-r--r--kernel/kernel.mllib1
-rw-r--r--kernel/nativecode.ml217
-rw-r--r--kernel/nativeinstr.mli1
-rw-r--r--kernel/nativelambda.ml18
-rw-r--r--kernel/nativelambda.mli2
-rw-r--r--kernel/nativevalues.ml222
-rw-r--r--kernel/nativevalues.mli71
-rw-r--r--kernel/primitives.ml91
-rw-r--r--kernel/primitives.mli39
-rw-r--r--kernel/retroknowledge.ml26
-rw-r--r--kernel/retroknowledge.mli16
13 files changed, 669 insertions, 71 deletions
diff --git a/dev/printers.mllib b/dev/printers.mllib
index c56982d99..1e2764997 100644
--- a/dev/printers.mllib
+++ b/dev/printers.mllib
@@ -62,6 +62,7 @@ Cbytecodes
Copcodes
Cemitcodes
Nativevalues
+Primitives
Nativeinstr
Future
Opaqueproof
diff --git a/kernel/environ.ml b/kernel/environ.ml
index 5a40b1c2a..be0b65d91 100644
--- a/kernel/environ.ml
+++ b/kernel/environ.ml
@@ -477,8 +477,11 @@ let register =
(* subfunction which adds the compiling information of an
int31 operation which has a specific vm instruction (associates
it to the name of the coq definition in the reactive retroknowledge) *)
- let add_int31_op retroknowledge v n op kn =
- add_vm_compiling_info retroknowledge v (Cbytegen.op_compilation n op kn)
+ let add_int31_op retroknowledge v n op prim kn =
+ let rk =
+ add_vm_compiling_info retroknowledge v (Cbytegen.op_compilation n op kn)
+ in
+ add_native_compiling_info rk v (Nativelambda.compile_prim prim kn)
in
let add_int31_before_match rk v =
@@ -490,16 +493,16 @@ let register =
fun env field value ->
(* subfunction which shortens the (very often use) registration of binary
operators to the reactive retroknowledge. *)
- let add_int31_binop_from_const op =
+ let add_int31_binop_from_const op prim =
match kind_of_term value with
| Const kn -> retroknowledge add_int31_op env value 2
- op kn
+ op prim kn
| _ -> anomaly ~label:"Environ.register" (Pp.str "should be a constant")
in
- let add_int31_unop_from_const op =
+ let add_int31_unop_from_const op prim =
match kind_of_term value with
| Const kn -> retroknowledge add_int31_op env value 1
- op kn
+ op prim kn
| _ -> anomaly ~label:"Environ.register" (Pp.str "should be a constant")
in
(* subfunction which completes the function constr_of_int31 above
@@ -531,33 +534,47 @@ fun env field value ->
(add_int31_before_match
(retroknowledge add_int31c env i31c) value)
| KInt31 (_, Int31Plus) -> add_int31_binop_from_const Cbytecodes.Kaddint31
+ Primitives.Int31add
| KInt31 (_, Int31PlusC) -> add_int31_binop_from_const Cbytecodes.Kaddcint31
+ Primitives.Int31addc
| KInt31 (_, Int31PlusCarryC) -> add_int31_binop_from_const Cbytecodes.Kaddcarrycint31
+ Primitives.Int31addcarryc
| KInt31 (_, Int31Minus) -> add_int31_binop_from_const Cbytecodes.Ksubint31
+ Primitives.Int31sub
| KInt31 (_, Int31MinusC) -> add_int31_binop_from_const Cbytecodes.Ksubcint31
+ Primitives.Int31subc
| KInt31 (_, Int31MinusCarryC) -> add_int31_binop_from_const
- Cbytecodes.Ksubcarrycint31
+ Cbytecodes.Ksubcarrycint31 Primitives.Int31subcarryc
| KInt31 (_, Int31Times) -> add_int31_binop_from_const Cbytecodes.Kmulint31
+ Primitives.Int31mul
| KInt31 (_, Int31TimesC) -> add_int31_binop_from_const Cbytecodes.Kmulcint31
+ Primitives.Int31mulc
| KInt31 (_, Int31Div21) -> (* this is a ternary operation *)
(match kind_of_term value with
| Const kn ->
retroknowledge add_int31_op env value 3
- Cbytecodes.Kdiv21int31 kn
+ Cbytecodes.Kdiv21int31 Primitives.Int31div21 kn
| _ -> anomaly ~label:"Environ.register" (Pp.str "should be a constant"))
| KInt31 (_, Int31Div) -> add_int31_binop_from_const Cbytecodes.Kdivint31
+ Primitives.Int31div
| KInt31 (_, Int31AddMulDiv) -> (* this is a ternary operation *)
(match kind_of_term value with
| Const kn ->
retroknowledge add_int31_op env value 3
- Cbytecodes.Kaddmuldivint31 kn
+ Cbytecodes.Kaddmuldivint31 Primitives.Int31addmuldiv kn
| _ -> anomaly ~label:"Environ.register" (Pp.str "should be a constant"))
| KInt31 (_, Int31Compare) -> add_int31_binop_from_const Cbytecodes.Kcompareint31
+ Primitives.Int31compare
| KInt31 (_, Int31Head0) -> add_int31_unop_from_const Cbytecodes.Khead0int31
+ Primitives.Int31head0
| KInt31 (_, Int31Tail0) -> add_int31_unop_from_const Cbytecodes.Ktail0int31
+ Primitives.Int31tail0
| KInt31 (_, Int31Lor) -> add_int31_binop_from_const Cbytecodes.Klorint31
+ Primitives.Int31lor
| KInt31 (_, Int31Land) -> add_int31_binop_from_const Cbytecodes.Klandint31
+ Primitives.Int31land
| KInt31 (_, Int31Lxor) -> add_int31_binop_from_const Cbytecodes.Klxorint31
+ Primitives.Int31lxor
| _ -> env.retroknowledge
in
Retroknowledge.add_field retroknowledge_with_reactive_info field value
diff --git a/kernel/kernel.mllib b/kernel/kernel.mllib
index 3267b7e75..0d0adf9a7 100644
--- a/kernel/kernel.mllib
+++ b/kernel/kernel.mllib
@@ -13,6 +13,7 @@ Cbytecodes
Copcodes
Cemitcodes
Nativevalues
+Primitives
Nativeinstr
Opaqueproof
Declareops
diff --git a/kernel/nativecode.ml b/kernel/nativecode.ml
index c4ede775e..c8572eec3 100644
--- a/kernel/nativecode.ml
+++ b/kernel/nativecode.ml
@@ -12,6 +12,7 @@ open Context
open Declarations
open Util
open Nativevalues
+open Primitives
open Nativeinstr
open Nativelambda
open Pre_env
@@ -255,14 +256,32 @@ type primitive =
| Mk_rel of int
| Mk_var of identifier
| Is_accu
+ | Is_int
| Cast_accu
| Upd_cofix
| Force_cofix
| Mk_uint
+ | Mk_int
+ | Mk_bool
+ | Val_to_int
| Mk_I31_accu
| Decomp_uint
| Mk_meta
| Mk_evar
+ | MLand
+ | MLle
+ | MLlt
+ | MLinteq
+ | MLlsl
+ | MLlsr
+ | MLland
+ | MLlor
+ | MLlxor
+ | MLadd
+ | MLsub
+ | MLmul
+ | MLmagic
+ | Coq_primitive of Primitives.t * (prefix * constant) option
let eq_primitive p1 p2 =
match p1, p2 with
@@ -284,29 +303,49 @@ let eq_primitive p1 p2 =
| _ -> false
let primitive_hash = function
-| Mk_prod -> 1
-| Mk_sort -> 2
-| Mk_ind -> 3
-| Mk_const -> 4
-| Mk_sw -> 5
-| Mk_fix (r, i) ->
- let h = Array.fold_left (fun h i -> combine h (Int.hash i)) 0 r in
- combinesmall 6 (combine h (Int.hash i))
-| Mk_cofix i ->
- combinesmall 7 (Int.hash i)
-| Mk_rel i ->
- combinesmall 8 (Int.hash i)
-| Mk_var id ->
- combinesmall 9 (Id.hash id)
-| Is_accu -> 10
-| Cast_accu -> 11
-| Upd_cofix -> 12
-| Force_cofix -> 13
-| Mk_uint -> 14
-| Mk_I31_accu -> 15
-| Decomp_uint -> 16
-| Mk_meta -> 17
-| Mk_evar -> 18
+ | Mk_prod -> 1
+ | Mk_sort -> 2
+ | Mk_ind -> 3
+ | Mk_const -> 4
+ | Mk_sw -> 5
+ | Mk_fix (r, i) ->
+ let h = Array.fold_left (fun h i -> combine h (Int.hash i)) 0 r in
+ combinesmall 6 (combine h (Int.hash i))
+ | Mk_cofix i ->
+ combinesmall 7 (Int.hash i)
+ | Mk_rel i ->
+ combinesmall 8 (Int.hash i)
+ | Mk_var id ->
+ combinesmall 9 (Id.hash id)
+ | Is_accu -> 10
+ | Is_int -> 11
+ | Cast_accu -> 12
+ | Upd_cofix -> 13
+ | Force_cofix -> 14
+ | Mk_uint -> 15
+ | Mk_int -> 16
+ | Mk_bool -> 17
+ | Val_to_int -> 18
+ | Mk_I31_accu -> 19
+ | Decomp_uint -> 20
+ | Mk_meta -> 21
+ | Mk_evar -> 22
+ | MLand -> 23
+ | MLle -> 24
+ | MLlt -> 25
+ | MLinteq -> 26
+ | MLlsl -> 27
+ | MLlsr -> 28
+ | MLland -> 29
+ | MLlor -> 30
+ | MLlxor -> 31
+ | MLadd -> 32
+ | MLsub -> 33
+ | MLmul -> 34
+ | MLmagic -> 35
+ | Coq_primitive (prim, None) -> combinesmall 36 (Primitives.hash prim)
+ | Coq_primitive (prim, Some (prefix,kn)) ->
+ combinesmall 37 (combine3 (String.hash prefix) (Constant.hash kn) (Primitives.hash prim))
type mllambda =
| MLlocal of lname
@@ -828,6 +867,113 @@ let merge_branches t =
Array.iter (fun (c,args,body) -> insert (c,args) body newt) t;
Array.of_list (to_list newt)
+
+type prim_aux =
+ | PAprim of string * constant * Primitives.t * prim_aux array
+ | PAml of mllambda
+
+let add_check cond args =
+ let aux cond a =
+ match a with
+ | PAml(MLint _) -> cond
+ | PAml ml ->
+ (* FIXME: use explicit equality function *)
+ if List.mem ml cond then cond else ml::cond
+ | _ -> cond
+ in
+ Array.fold_left aux cond args
+
+let extract_prim ml_of l =
+ let decl = ref [] in
+ let cond = ref [] in
+ let rec aux l =
+ match l with
+ | Lprim(prefix,kn,p,args) ->
+ let args = Array.map aux args in
+ cond := add_check !cond args;
+ PAprim(prefix,kn,p,args)
+ | Lrel _ | Lvar _ | Luint _ | Lval _ | Lconst _ -> PAml (ml_of l)
+ | _ ->
+ let x = fresh_lname Anonymous in
+ decl := (x,ml_of l)::!decl;
+ PAml (MLlocal x) in
+ let res = aux l in
+ (!decl, !cond, res)
+
+let app_prim p args = MLapp(MLprimitive p, args)
+
+let to_int v =
+ match v with
+ | MLapp(MLprimitive Mk_uint, t) ->
+ begin match t.(0) with
+ | MLuint i -> MLint (Uint31.to_int i)
+ | _ -> MLapp(MLprimitive Val_to_int, [|v|])
+ end
+ | MLapp(MLprimitive Mk_int, t) -> t.(0)
+ | _ -> MLapp(MLprimitive Val_to_int, [|v|])
+
+let of_int v =
+ match v with
+ | MLapp(MLprimitive Val_to_int, t) -> t.(0)
+ | _ -> MLapp(MLprimitive Mk_int,[|v|])
+
+let compile_prim decl cond paux =
+(*
+ let args_to_int args =
+ for i = 0 to Array.length args - 1 do
+ args.(i) <- to_int args.(i)
+ done;
+ args in
+ *)
+ let rec opt_prim_aux paux =
+ match paux with
+ | PAprim(prefix, kn, op, args) ->
+ let args = Array.map opt_prim_aux args in
+ app_prim (Coq_primitive(op,None)) args
+(*
+ TODO: check if this inling was useful
+ begin match op with
+ | Int31lt ->
+ if Sys.word_size = 64 then
+ app_prim Mk_bool [|(app_prim MLlt (args_to_int args))|]
+ else app_prim (Coq_primitive (Primitives.Int31lt,None)) args
+ | Int31le ->
+ if Sys.word_size = 64 then
+ app_prim Mk_bool [|(app_prim MLle (args_to_int args))|]
+ else app_prim (Coq_primitive (Primitives.Int31le, None)) args
+ | Int31lsl -> of_int (mk_lsl (args_to_int args))
+ | Int31lsr -> of_int (mk_lsr (args_to_int args))
+ | Int31land -> of_int (mk_land (args_to_int args))
+ | Int31lor -> of_int (mk_lor (args_to_int args))
+ | Int31lxor -> of_int (mk_lxor (args_to_int args))
+ | Int31add -> of_int (mk_add (args_to_int args))
+ | Int31sub -> of_int (mk_sub (args_to_int args))
+ | Int31mul -> of_int (mk_mul (args_to_int args))
+ | _ -> app_prim (Coq_primitive(op,None)) args
+ end *)
+ | PAml ml -> ml
+ and naive_prim_aux paux =
+ match paux with
+ | PAprim(prefix, kn, op, args) ->
+ app_prim (Coq_primitive(op, Some (prefix, kn))) (Array.map naive_prim_aux args)
+ | PAml ml -> ml in
+
+ let compile_cond cond paux =
+ match cond with
+ | [] -> opt_prim_aux paux
+ | [c1] ->
+ MLif(app_prim Is_int [|c1|], opt_prim_aux paux, naive_prim_aux paux)
+ | c1::cond ->
+ let cond =
+ List.fold_left
+ (fun ml c -> app_prim MLland [| ml; to_int c|])
+ (app_prim MLland [|to_int c1; MLint 0 |]) cond in
+ let cond = app_prim MLmagic [|cond|] in
+ MLif(cond, naive_prim_aux paux, opt_prim_aux paux) in
+ let add_decl decl body =
+ List.fold_left (fun body (x,d) -> MLlet(x,d,body)) body decl in
+ add_decl decl (compile_cond cond paux)
+
let rec ml_of_lam env l t =
match t with
| Lrel(id ,i) -> get_rel env id i
@@ -858,6 +1004,9 @@ let merge_branches t =
| Lapp(f,args) ->
MLapp(ml_of_lam env l f, Array.map (ml_of_lam env l) args)
| Lconst (prefix,c) -> MLglobal(Gconstant (prefix,c))
+ | Lprim _ ->
+ let decl,cond,paux = extract_prim (ml_of_lam env l) t in
+ compile_prim decl cond paux
| Lcase (annot,p,a,bs) ->
(* let predicate_uid fv_pred = compilation of p
let rec case_uid fv a_uid =
@@ -1482,14 +1631,36 @@ let pp_mllam fmt l =
| Mk_var id ->
Format.fprintf fmt "mk_var_accu (Names.id_of_string \"%s\")" (string_of_id id)
| Is_accu -> Format.fprintf fmt "is_accu"
+ | Is_int -> Format.fprintf fmt "is_int"
| Cast_accu -> Format.fprintf fmt "cast_accu"
| Upd_cofix -> Format.fprintf fmt "upd_cofix"
| Force_cofix -> Format.fprintf fmt "force_cofix"
| Mk_uint -> Format.fprintf fmt "mk_uint"
+ | Mk_int -> Format.fprintf fmt "mk_int"
+ | Mk_bool -> Format.fprintf fmt "mk_bool"
+ | Val_to_int -> Format.fprintf fmt "val_to_int"
| Mk_I31_accu -> Format.fprintf fmt "mk_I31_accu"
| Decomp_uint -> Format.fprintf fmt "decomp_uint"
| Mk_meta -> Format.fprintf fmt "mk_meta_accu"
| Mk_evar -> Format.fprintf fmt "mk_evar_accu"
+ | MLand -> Format.fprintf fmt "(&&)"
+ | MLle -> Format.fprintf fmt "(<=)"
+ | MLlt -> Format.fprintf fmt "(<)"
+ | MLinteq -> Format.fprintf fmt "(==)"
+ | MLlsl -> Format.fprintf fmt "(lsl)"
+ | MLlsr -> Format.fprintf fmt "(lsr)"
+ | MLland -> Format.fprintf fmt "(land)"
+ | MLlor -> Format.fprintf fmt "(lor)"
+ | MLlxor -> Format.fprintf fmt "(lxor)"
+ | MLadd -> Format.fprintf fmt "(+)"
+ | MLsub -> Format.fprintf fmt "(-)"
+ | MLmul -> Format.fprintf fmt "( * )"
+ | MLmagic -> Format.fprintf fmt "Obj.magic"
+ | Coq_primitive (op,None) ->
+ Format.fprintf fmt "no_check_%s" (Primitives.to_string op)
+ | Coq_primitive (op, Some (prefix,kn)) ->
+ Format.fprintf fmt "%s %a" (Primitives.to_string op)
+ pp_mllam (MLglobal (Gconstant (prefix,kn)))
in
Format.fprintf fmt "@[%a@]" pp_mllam l
diff --git a/kernel/nativeinstr.mli b/kernel/nativeinstr.mli
index bba011475..13d61841f 100644
--- a/kernel/nativeinstr.mli
+++ b/kernel/nativeinstr.mli
@@ -29,6 +29,7 @@ and lambda =
| Llet of name * lambda * lambda
| Lapp of lambda * lambda array
| Lconst of prefix * constant
+ | Lprim of prefix * constant * Primitives.t * lambda array
| Lcase of annot_sw * lambda * lambda * lam_branches
(* annotations, term being matched, accu, branches *)
| Lif of lambda * lambda * lambda
diff --git a/kernel/nativelambda.ml b/kernel/nativelambda.ml
index f6fb25ab0..631349c07 100644
--- a/kernel/nativelambda.ml
+++ b/kernel/nativelambda.ml
@@ -101,6 +101,9 @@ let map_lam_with_binders g f n lam =
let fct' = f n fct in
let args' = Array.smartmap (f n) args in
if fct == fct' && args == args' then lam else mkLapp fct' args'
+ | Lprim(prefix,kn,op,args) ->
+ let args' = Array.smartmap (f n) args in
+ if args == args' then lam else Lprim(prefix,kn,op,args')
| Lcase(annot,t,a,br) ->
let t' = f n t in
let a' = f n a in
@@ -297,7 +300,7 @@ let rec occurence k kind lam =
occurence (k+1) (occurence k kind def) body
| Lapp(f, args) ->
occurence_args k (occurence k kind f) args
- | Lmakeblock(_,_,_,args) ->
+ | Lprim(_,_,_,args) | Lmakeblock(_,_,_,args) ->
occurence_args k kind args
| Lcase(_,t,a,br) ->
let kind = occurence k (occurence k kind t) a in
@@ -626,6 +629,12 @@ and lambda_of_app env sigma f args =
| Const kn ->
let kn = get_allias !global_env kn in
let cb = lookup_constant kn !global_env in
+ (try
+ let prefix = get_const_prefix !global_env kn in
+ let args = lambda_of_args env sigma 0 args in
+ Retroknowledge.get_native_compiling_info
+ (!global_env).retroknowledge (mkConst kn) prefix args
+ with Not_found ->
begin match cb.const_body with
| Def csubst ->
if cb.const_inline_code then
@@ -641,7 +650,7 @@ and lambda_of_app env sigma f args =
| OpaqueDef _ | Undef _ ->
let prefix = get_const_prefix !global_env kn in
mkLapp (Lconst (prefix, kn)) (lambda_of_args env sigma 0 args)
- end
+ end)
| Construct c ->
let tag, nparams, arity = Renv.get_construct_info env c in
let expected = nparams + arity in
@@ -726,3 +735,8 @@ let before_match_int31 fc prefix c t =
| Luint (UintVal i) -> assert false
| Luint (UintDigits (prefix,c,args)) -> assert false
| _ -> Luint (UintDecomp (prefix,c,t))
+
+let compile_prim prim kn fc prefix args =
+ if not fc then raise Not_found
+ else
+ Lprim(prefix, kn, prim, args)
diff --git a/kernel/nativelambda.mli b/kernel/nativelambda.mli
index 8ff0d727c..afebf8087 100644
--- a/kernel/nativelambda.mli
+++ b/kernel/nativelambda.mli
@@ -37,3 +37,5 @@ val compile_dynamic_int31 : bool -> prefix -> constructor -> lambda array ->
val before_match_int31 : bool -> prefix -> constructor -> lambda -> lambda
+val compile_prim : Primitives.t -> constant -> bool -> prefix -> lambda array ->
+ lambda
diff --git a/kernel/nativevalues.ml b/kernel/nativevalues.ml
index 7f2785cf9..ab56c4be0 100644
--- a/kernel/nativevalues.ml
+++ b/kernel/nativevalues.ml
@@ -222,6 +222,8 @@ let dummy_value : unit -> t =
let cast_accu v = (Obj.magic v:accumulator)
let mk_int (x : int) = (Obj.magic x : t)
+(* Coq's booleans are reversed... *)
+let mk_bool (b : bool) = (Obj.magic (not b) : t)
let mk_uint (x : Uint31.t) = (Obj.magic x : t)
type block
@@ -260,7 +262,223 @@ let is_int (x:t) =
let o = Obj.repr x in
Obj.is_int o
-let to_int (x:t) = (Obj.magic x : int)
+let val_to_int (x:t) = (Obj.magic x : int)
+
+let to_uint (x:t) = (Obj.magic x : Uint31.t)
+let of_uint (x: Uint31.t) = (Obj.magic x : t)
+
+let no_check_head0 x =
+ of_uint (Uint31.head0 (to_uint x))
+
+let head0 accu x =
+ if is_int x then no_check_head0 x
+ else accu x
+
+let no_check_tail0 x =
+ of_uint (Uint31.tail0 (to_uint x))
+
+let tail0 accu x =
+ if is_int x then no_check_tail0 x
+ else accu x
+
+let no_check_add x y =
+ of_uint (Uint31.add (to_uint x) (to_uint y))
+
+let add accu x y =
+ if is_int x && is_int y then no_check_add x y
+ else accu x y
+
+let no_check_sub x y =
+ of_uint (Uint31.sub (to_uint x) (to_uint y))
+
+let sub accu x y =
+ if is_int x && is_int y then no_check_sub x y
+ else accu x y
+
+let no_check_mul x y =
+ of_uint (Uint31.mul (to_uint x) (to_uint y))
+
+let mul accu x y =
+ if is_int x && is_int y then no_check_mul x y
+ else accu x y
+
+let no_check_div x y =
+ of_uint (Uint31.div (to_uint x) (to_uint y))
+
+let div accu x y =
+ if is_int x && is_int y then no_check_div x y
+ else accu x y
+
+let no_check_rem x y =
+ of_uint (Uint31.rem (to_uint x) (to_uint y))
+
+let rem accu x y =
+ if is_int x && is_int y then no_check_rem x y
+ else accu x y
+
+let no_check_l_sr x y =
+ of_uint (Uint31.l_sr (to_uint x) (to_uint y))
+
+let l_sr accu x y =
+ if is_int x && is_int y then no_check_l_sr x y
+ else accu x y
+
+let no_check_l_sl x y =
+ of_uint (Uint31.l_sl (to_uint x) (to_uint y))
+
+let l_sl accu x y =
+ if is_int x && is_int y then no_check_l_sl x y
+ else accu x y
+
+let no_check_l_and x y =
+ of_uint (Uint31.l_and (to_uint x) (to_uint y))
+
+let l_and accu x y =
+ if is_int x && is_int y then no_check_l_and x y
+ else accu x y
+
+let no_check_l_xor x y =
+ of_uint (Uint31.l_xor (to_uint x) (to_uint y))
+
+let l_xor accu x y =
+ if is_int x && is_int y then no_check_l_xor x y
+ else accu x y
+
+let no_check_l_or x y =
+ of_uint (Uint31.l_or (to_uint x) (to_uint y))
+
+let l_or accu x y =
+ if is_int x && is_int y then no_check_l_or x y
+ else accu x y
+
+type coq_carry =
+ | Caccu of t
+ | C0 of t
+ | C1 of t
+
+type coq_pair =
+ | Paccu of t
+ | PPair of t * t
+
+let mkCarry b i =
+ if b then (Obj.magic (C1(of_uint i)):t)
+ else (Obj.magic (C0(of_uint i)):t)
+
+let no_check_addc x y =
+ let s = Uint31.add (to_uint x) (to_uint y) in
+ mkCarry (Uint31.lt s (to_uint x)) s
+
+let addc accu x y =
+ if is_int x && is_int y then no_check_addc x y
+ else accu x y
+
+let no_check_subc x y =
+ let s = Uint31.sub (to_uint x) (to_uint y) in
+ mkCarry (Uint31.lt (to_uint x) (to_uint y)) s
+
+let subc accu x y =
+ if is_int x && is_int y then no_check_subc x y
+ else accu x y
+
+let no_check_addCarryC x y =
+ let s =
+ Uint31.add (Uint31.add (to_uint x) (to_uint y))
+ (Uint31.of_int 1) in
+ mkCarry (Uint31.le s (to_uint x)) s
+
+let addCarryC accu x y =
+ if is_int x && is_int y then no_check_addCarryC x y
+ else accu x y
+
+let no_check_subCarryC x y =
+ let s =
+ Uint31.sub (Uint31.sub (to_uint x) (to_uint y))
+ (Uint31.of_int 1) in
+ mkCarry (Uint31.le (to_uint x) (to_uint y)) s
+
+let subCarryC accu x y =
+ if is_int x && is_int y then no_check_subCarryC x y
+ else accu x y
+
+let of_pair (x, y) =
+ (Obj.magic (PPair(of_uint x, of_uint y)):t)
+
+let no_check_mulc x y =
+ of_pair(Uint31.mulc (to_uint x) (to_uint y))
+
+let mulc accu x y =
+ if is_int x && is_int y then no_check_mulc x y
+ else accu x y
+
+let no_check_diveucl x y =
+ let i1, i2 = to_uint x, to_uint y in
+ of_pair(Uint31.div i1 i2, Uint31.rem i1 i2)
+
+let diveucl accu x y =
+ if is_int x && is_int y then no_check_diveucl x y
+ else accu x y
+
+let no_check_div21 x y z =
+ let i1, i2, i3 = to_uint x, to_uint y, to_uint z in
+ of_pair (Uint31.div21 i1 i2 i3)
+
+let div21 accu x y z =
+ if is_int x && is_int y && is_int z then no_check_div21 x y z
+ else accu x y z
+
+let no_check_addMulDiv x y z =
+ let p, i, j = to_uint x, to_uint y, to_uint z in
+ let p' = Uint31.to_int p in
+ of_uint (Uint31.l_or
+ (Uint31.l_sl i p)
+ (Uint31.l_sr j (Uint31.of_int (31 - p'))))
+
+let addMulDiv accu x y z =
+ if is_int x && is_int y && is_int z then no_check_addMulDiv x y z
+ else accu x y z
+
+
+type coq_bool =
+ | Baccu of t
+ | Btrue
+ | Bfalse
+
+type coq_cmp =
+ | CmpAccu of t
+ | CmpEq
+ | CmpLt
+ | CmpGt
+
+let no_check_eq x y =
+ mk_bool (Uint31.equal (to_uint x) (to_uint y))
+
+let eq accu x y =
+ if is_int x && is_int y then no_check_eq x y
+ else accu x y
+
+let no_check_lt x y =
+ mk_bool (Uint31.lt (to_uint x) (to_uint y))
+
+let lt accu x y =
+ if is_int x && is_int y then no_check_lt x y
+ else accu x y
+
+let no_check_le x y =
+ mk_bool (Uint31.le (to_uint x) (to_uint y))
+
+let le accu x y =
+ if is_int x && is_int y then no_check_le x y
+ else accu x y
+
+let no_check_compare x y =
+ match Uint31.compare (to_uint x) (to_uint y) with
+ | x when x < 0 -> (Obj.magic CmpLt:t)
+ | 0 -> (Obj.magic CmpEq:t)
+ | _ -> (Obj.magic CmpGt:t)
+
+let compare accu x y =
+ if is_int x && is_int y then no_check_compare x y
+ else accu x y
let hobcnv = Array.init 256 (fun i -> Printf.sprintf "%.2x" i)
let bohcnv = Array.init 256 (fun i -> i -
@@ -340,7 +558,7 @@ let mk_I31_accu c x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 x16 x17
let decomp_uint c v =
if is_int v then
let r = ref c in
- let v = to_int v in
+ let v = val_to_int v in
for i = 30 downto 0 do
r := (!r) (mk_int ((v lsr i) land 1));
done;
diff --git a/kernel/nativevalues.mli b/kernel/nativevalues.mli
index 821b23168..9b0ce8e82 100644
--- a/kernel/nativevalues.mli
+++ b/kernel/nativevalues.mli
@@ -73,7 +73,7 @@ val force_cofix : t -> t
val mk_const : tag -> t
val mk_block : tag -> t array -> t
-
+val mk_bool : bool -> t
val mk_int : int -> t
val mk_uint : Uint31.t -> t
@@ -112,5 +112,74 @@ val is_accu : t -> bool
val str_encode : 'a -> string
val str_decode : string -> 'a
+(** Support for machine integers *)
+
+val val_to_int : t -> int
+val is_int : t -> bool
+
+(* function with check *)
+val head0 : t -> t -> t
+val tail0 : t -> t -> t
+
+val add : t -> t -> t -> t
+val sub : t -> t -> t -> t
+val mul : t -> t -> t -> t
+val div : t -> t -> t -> t
+val rem : t -> t -> t -> t
+
+val l_sr : t -> t -> t -> t
+val l_sl : t -> t -> t -> t
+val l_and : t -> t -> t -> t
+val l_xor : t -> t -> t -> t
+val l_or : t -> t -> t -> t
+
+val addc : t -> t -> t -> t
+val subc : t -> t -> t -> t
+val addCarryC : t -> t -> t -> t
+val subCarryC : t -> t -> t -> t
+
+val mulc : t -> t -> t -> t
+val diveucl : t -> t -> t -> t
+
+val div21 : t -> t -> t -> t -> t
+val addMulDiv : t -> t -> t -> t -> t
+
+val eq : t -> t -> t -> t
+val lt : t -> t -> t -> t
+val le : t -> t -> t -> t
+val compare : t -> t -> t -> t
+
+(* Function without check *)
+val no_check_head0 : t -> t
+val no_check_tail0 : t -> t
+
+val no_check_add : t -> t -> t
+val no_check_sub : t -> t -> t
+val no_check_mul : t -> t -> t
+val no_check_div : t -> t -> t
+val no_check_rem : t -> t -> t
+
+val no_check_l_sr : t -> t -> t
+val no_check_l_sl : t -> t -> t
+val no_check_l_and : t -> t -> t
+val no_check_l_xor : t -> t -> t
+val no_check_l_or : t -> t -> t
+
+val no_check_addc : t -> t -> t
+val no_check_subc : t -> t -> t
+val no_check_addCarryC : t -> t -> t
+val no_check_subCarryC : t -> t -> t
+
+val no_check_mulc : t -> t -> t
+val no_check_diveucl : t -> t -> t
+
+val no_check_div21 : t -> t -> t -> t
+val no_check_addMulDiv : t -> t -> t -> t
+
+val no_check_eq : t -> t -> t
+val no_check_lt : t -> t -> t
+val no_check_le : t -> t -> t
+val no_check_compare : t -> t -> t
+
val mk_I31_accu : t
val decomp_uint : t -> t -> t
diff --git a/kernel/primitives.ml b/kernel/primitives.ml
new file mode 100644
index 000000000..64c486220
--- /dev/null
+++ b/kernel/primitives.ml
@@ -0,0 +1,91 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2014 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+type t =
+ | Int31head0
+ | Int31tail0
+ | Int31add
+ | Int31sub
+ | Int31mul
+ | Int31div
+ | Int31mod
+(*
+ | Int31lsr
+ | Int31lsl
+ *)
+ | Int31land
+ | Int31lor
+ | Int31lxor
+ | Int31addc
+ | Int31subc
+ | Int31addcarryc
+ | Int31subcarryc
+ | Int31mulc
+ | Int31diveucl
+ | Int31div21
+ | Int31addmuldiv
+ | Int31eq
+ | Int31lt
+ | Int31le
+ | Int31compare
+
+let hash = function
+ | Int31head0 -> 1
+ | Int31tail0 -> 2
+ | Int31add -> 3
+ | Int31sub -> 4
+ | Int31mul -> 5
+ | Int31div -> 6
+ | Int31mod -> 7
+(*
+ | Int31lsr -> 8
+ | Int31lsl -> 9
+ *)
+ | Int31land -> 10
+ | Int31lor -> 11
+ | Int31lxor -> 12
+ | Int31addc -> 13
+ | Int31subc -> 14
+ | Int31addcarryc -> 15
+ | Int31subcarryc -> 16
+ | Int31mulc -> 17
+ | Int31diveucl -> 18
+ | Int31div21 -> 19
+ | Int31addmuldiv -> 20
+ | Int31eq -> 21
+ | Int31lt -> 22
+ | Int31le -> 23
+ | Int31compare -> 24
+
+let to_string = function
+ | Int31head0 -> "head0"
+ | Int31tail0 -> "tail0"
+ | Int31add -> "add"
+ | Int31sub -> "sub"
+ | Int31mul -> "mul"
+ | Int31div -> "div"
+ | Int31mod -> "mod"
+(*
+ | Int31lsr -> "l_sr"
+ | Int31lsl -> "l_sl"
+ *)
+ | Int31land -> "l_and"
+ | Int31lor -> "l_or"
+ | Int31lxor -> "l_xor"
+ | Int31addc -> "addc"
+ | Int31subc -> "subc"
+ | Int31addcarryc -> "addcarryc"
+ | Int31subcarryc -> "subcarryc"
+ | Int31mulc -> "mulc"
+ | Int31diveucl -> "diveucl"
+ | Int31div21 -> "div21"
+ | Int31addmuldiv -> "addmuldiv"
+ | Int31eq -> "eq"
+ | Int31lt -> "lt"
+ | Int31le -> "le"
+ | Int31compare -> "compare"
diff --git a/kernel/primitives.mli b/kernel/primitives.mli
new file mode 100644
index 000000000..1b70a9be8
--- /dev/null
+++ b/kernel/primitives.mli
@@ -0,0 +1,39 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA - CNRS - LIX - LRI - PPS - Copyright 1999-2014 *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+type t =
+ | Int31head0
+ | Int31tail0
+ | Int31add
+ | Int31sub
+ | Int31mul
+ | Int31div
+ | Int31mod
+(*
+ | Int31lsr
+ | Int31lsl
+ *)
+ | Int31land
+ | Int31lor
+ | Int31lxor
+ | Int31addc
+ | Int31subc
+ | Int31addcarryc
+ | Int31subcarryc
+ | Int31mulc
+ | Int31diveucl
+ | Int31div21
+ | Int31addmuldiv
+ | Int31eq
+ | Int31lt
+ | Int31le
+ | Int31compare
+
+val hash : t -> int
+
+val to_string : t -> string
diff --git a/kernel/retroknowledge.ml b/kernel/retroknowledge.ml
index f4b57d085..466380f2d 100644
--- a/kernel/retroknowledge.ml
+++ b/kernel/retroknowledge.ml
@@ -130,9 +130,8 @@ type reactive_end = {(*information required by the compiler of the VM *)
vm_decompile_const : (int -> Term.constr) option;
native_compiling :
- (bool->Cbytecodes.comp_env->constr array ->
- int->Cbytecodes.bytecodes->Cbytecodes.bytecodes)
- option;
+ (bool -> Nativeinstr.prefix -> Nativeinstr.lambda array ->
+ Nativeinstr.lambda) option;
native_constant_static :
(bool -> constr array -> Nativeinstr.lambda) option;
@@ -142,9 +141,8 @@ type reactive_end = {(*information required by the compiler of the VM *)
Nativeinstr.lambda array -> Nativeinstr.lambda) option;
native_before_match : (bool -> Nativeinstr.prefix -> constructor ->
- Nativeinstr.lambda -> Nativeinstr.lambda) option;
+ Nativeinstr.lambda -> Nativeinstr.lambda) option
- native_decompile_const : (int -> Term.constr) option
}
@@ -186,7 +184,6 @@ let empty_reactive_end =
native_constant_static = None;
native_constant_dynamic = None;
native_before_match = None;
- native_decompile_const = None
}
@@ -270,12 +267,6 @@ let get_native_before_match_info knowledge key =
| None -> raise Not_found
| Some f -> f knowledge.flags.fastcomputation
-let get_native_decompile_constant_info knowledge key =
- match (Reactive.find key knowledge.reactive).native_decompile_const
- with
- | None -> raise Not_found
- | Some f -> f
-
(* functions manipulating reactive knowledge *)
let add_vm_compiling_info knowledge value nfo =
{knowledge with reactive =
@@ -376,16 +367,5 @@ let add_native_before_match_info knowledge value nfo =
knowledge.reactive
}
-let add_native_decompile_constant_info knowledge value nfo =
- {knowledge with reactive =
- try
- Reactive.add value
- {(Reactive.find value (knowledge.reactive)) with native_decompile_const = Some nfo}
- knowledge.reactive
- with Not_found ->
- Reactive.add value {empty_reactive_end with native_decompile_const = Some nfo}
- knowledge.reactive
- }
-
let clear_info knowledge value =
{knowledge with reactive = Reactive.remove value knowledge.reactive}
diff --git a/kernel/retroknowledge.mli b/kernel/retroknowledge.mli
index 644fb7074..30d824a9b 100644
--- a/kernel/retroknowledge.mli
+++ b/kernel/retroknowledge.mli
@@ -118,9 +118,8 @@ val get_vm_before_match_info : retroknowledge -> entry -> Cbytecodes.bytecodes
val get_vm_decompile_constant_info : retroknowledge -> entry -> int -> Term.constr
-val get_native_compiling_info : retroknowledge -> entry -> Cbytecodes.comp_env ->
- constr array ->
- int -> Cbytecodes.bytecodes-> Cbytecodes.bytecodes
+val get_native_compiling_info : retroknowledge -> entry -> Nativeinstr.prefix ->
+ Nativeinstr.lambda array -> Nativeinstr.lambda
val get_native_constant_static_info : retroknowledge -> entry ->
constr array -> Nativeinstr.lambda
@@ -134,8 +133,6 @@ val get_native_before_match_info : retroknowledge -> entry ->
Nativeinstr.prefix -> constructor ->
Nativeinstr.lambda -> Nativeinstr.lambda
-val get_native_decompile_constant_info : retroknowledge -> entry -> int -> Term.constr
-
(** the following functions are solely used in Pre_env and Environ to implement
the functions register and unregister (and mem) of Environ *)
val add_field : retroknowledge -> field -> entry -> retroknowledge
@@ -167,9 +164,9 @@ val add_vm_decompile_constant_info : retroknowledge -> entry ->
(int -> constr) -> retroknowledge
val add_native_compiling_info : retroknowledge-> entry ->
- (bool -> Cbytecodes.comp_env -> constr array -> int ->
- Cbytecodes.bytecodes -> Cbytecodes.bytecodes) ->
- retroknowledge
+ (bool -> Nativeinstr.prefix ->
+ Nativeinstr.lambda array -> Nativeinstr.lambda) ->
+ retroknowledge
val add_native_constant_static_info : retroknowledge -> entry ->
(bool -> constr array ->
@@ -187,9 +184,6 @@ val add_native_before_match_info : retroknowledge -> entry ->
Nativeinstr.lambda -> Nativeinstr.lambda) ->
retroknowledge
-val add_native_decompile_constant_info : retroknowledge -> entry ->
- (int -> constr) -> retroknowledge
-
val clear_info : retroknowledge-> entry -> retroknowledge