1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
(* Reduction of native operators *)
open Names
open CPrimitives
open Retroknowledge
open Environ
open CErrors
let add_retroknowledge env action =
match action with
| Register_type(PT_int63,c) ->
let retro = env.retroknowledge in
let retro =
match retro.retro_int63 with
| None -> { retro with retro_int63 = Some c }
| Some c' -> assert (Constant.equal c c'); retro in
set_retroknowledge env retro
| Register_ind(pit,ind) ->
let retro = env.retroknowledge in
let retro =
match pit with
| PIT_bool ->
let r =
match retro.retro_bool with
| None -> ((ind,1), (ind,2))
| Some (((ind',_),_) as t) -> assert (eq_ind ind ind'); t in
{ retro with retro_bool = Some r }
| PIT_carry ->
let r =
match retro.retro_carry with
| None -> ((ind,1), (ind,2))
| Some (((ind',_),_) as t) -> assert (eq_ind ind ind'); t in
{ retro with retro_carry = Some r }
| PIT_pair ->
let r =
match retro.retro_pair with
| None -> (ind,1)
| Some ((ind',_) as t) -> assert (eq_ind ind ind'); t in
{ retro with retro_pair = Some r }
| PIT_cmp ->
let r =
match retro.retro_cmp with
| None -> ((ind,1), (ind,2), (ind,3))
| Some (((ind',_),_,_) as t) -> assert (eq_ind ind ind'); t in
{ retro with retro_cmp = Some r }
in
set_retroknowledge env retro
let get_int_type env =
match env.retroknowledge.retro_int63 with
| Some c -> c
| None -> anomaly Pp.(str"Reduction of primitive: int63 not registered")
let get_bool_constructors env =
match env.retroknowledge.retro_bool with
| Some r -> r
| None -> anomaly Pp.(str"Reduction of primitive: bool not registered")
let get_carry_constructors env =
match env.retroknowledge.retro_carry with
| Some r -> r
| None -> anomaly Pp.(str"Reduction of primitive: carry not registered")
let get_pair_constructor env =
match env.retroknowledge.retro_pair with
| Some c -> c
| None -> anomaly Pp.(str"Reduction of primitive: pair not registered")
let get_cmp_constructors env =
match env.retroknowledge.retro_cmp with
| Some r -> r
| None -> anomaly Pp.(str"Reduction of primitive: cmp not registered")
exception NativeDestKO
module type RedNativeEntries =
sig
type elem
type args
type evd (* will be unit in kernel, evar_map outside *)
val get : args -> int -> elem
val get_int : evd -> elem -> Uint63.t
val mkInt : env -> Uint63.t -> elem
val mkBool : env -> bool -> elem
val mkCarry : env -> bool -> elem -> elem (* true if carry *)
val mkIntPair : env -> elem -> elem -> elem
val mkLt : env -> elem
val mkEq : env -> elem
val mkGt : env -> elem
end
module type RedNative =
sig
type elem
type args
type evd
val red_prim : env -> evd -> CPrimitives.t -> args -> elem option
end
module RedNative (E:RedNativeEntries) :
RedNative with type elem = E.elem
with type args = E.args
with type evd = E.evd =
struct
type elem = E.elem
type args = E.args
type evd = E.evd
let get_int evd args i = E.get_int evd (E.get args i)
let get_int1 evd args = get_int evd args 0
let get_int2 evd args = get_int evd args 0, get_int evd args 1
let get_int3 evd args =
get_int evd args 0, get_int evd args 1, get_int evd args 2
let red_prim_aux env evd op args =
let open CPrimitives in
match op with
| Int63head0 ->
let i = get_int1 evd args in E.mkInt env (Uint63.head0 i)
| Int63tail0 ->
let i = get_int1 evd args in E.mkInt env (Uint63.tail0 i)
| Int63add ->
let i1, i2 = get_int2 evd args in E.mkInt env (Uint63.add i1 i2)
| Int63sub ->
let i1, i2 = get_int2 evd args in E.mkInt env (Uint63.sub i1 i2)
| Int63mul ->
let i1, i2 = get_int2 evd args in E.mkInt env (Uint63.mul i1 i2)
| Int63div ->
let i1, i2 = get_int2 evd args in E.mkInt env (Uint63.div i1 i2)
| Int63mod ->
let i1, i2 = get_int2 evd args in E.mkInt env (Uint63.rem i1 i2)
| Int63lsr ->
let i1, i2 = get_int2 evd args in E.mkInt env (Uint63.l_sr i1 i2)
| Int63lsl ->
let i1, i2 = get_int2 evd args in E.mkInt env (Uint63.l_sl i1 i2)
| Int63land ->
let i1, i2 = get_int2 evd args in E.mkInt env (Uint63.l_and i1 i2)
| Int63lor ->
let i1, i2 = get_int2 evd args in E.mkInt env (Uint63.l_or i1 i2)
| Int63lxor ->
let i1, i2 = get_int2 evd args in E.mkInt env (Uint63.l_xor i1 i2)
| Int63addc ->
let i1, i2 = get_int2 evd args in
let s = Uint63.add i1 i2 in
E.mkCarry env (Uint63.lt s i1) (E.mkInt env s)
| Int63subc ->
let i1, i2 = get_int2 evd args in
let s = Uint63.sub i1 i2 in
E.mkCarry env (Uint63.lt i1 i2) (E.mkInt env s)
| Int63addCarryC ->
let i1, i2 = get_int2 evd args in
let s = Uint63.add (Uint63.add i1 i2) (Uint63.of_int 1) in
E.mkCarry env (Uint63.le s i1) (E.mkInt env s)
| Int63subCarryC ->
let i1, i2 = get_int2 evd args in
let s = Uint63.sub (Uint63.sub i1 i2) (Uint63.of_int 1) in
E.mkCarry env (Uint63.le i1 i2) (E.mkInt env s)
| Int63mulc ->
let i1, i2 = get_int2 evd args in
let (h, l) = Uint63.mulc i1 i2 in
E.mkIntPair env (E.mkInt env h) (E.mkInt env l)
| Int63diveucl ->
let i1, i2 = get_int2 evd args in
let q,r = Uint63.div i1 i2, Uint63.rem i1 i2 in
E.mkIntPair env (E.mkInt env q) (E.mkInt env r)
| Int63div21 ->
let i1, i2, i3 = get_int3 evd args in
let q,r = Uint63.div21 i1 i2 i3 in
E.mkIntPair env (E.mkInt env q) (E.mkInt env r)
| Int63addMulDiv ->
let p, i, j = get_int3 evd args in
E.mkInt env
(Uint63.l_or
(Uint63.l_sl i p)
(Uint63.l_sr j (Uint63.sub (Uint63.of_int Uint63.uint_size) p)))
| Int63eq ->
let i1, i2 = get_int2 evd args in
E.mkBool env (Uint63.equal i1 i2)
| Int63lt ->
let i1, i2 = get_int2 evd args in
E.mkBool env (Uint63.lt i1 i2)
| Int63le ->
let i1, i2 = get_int2 evd args in
E.mkBool env (Uint63.le i1 i2)
| Int63compare ->
let i1, i2 = get_int2 evd args in
begin match Uint63.compare i1 i2 with
| x when x < 0 -> E.mkLt env
| 0 -> E.mkEq env
| _ -> E.mkGt env
end
let red_prim env evd p args =
try
let r =
red_prim_aux env evd p args
in Some r
with NativeDestKO -> None
end
|