source: src/RTLabs/RTLabsToRTL.ma @ 2674

Last change on this file since 2674 was 2674, checked in by tranquil, 7 years ago
  • another change in block definition
  • RTLabs -> RTL and ERTL -> ERTLptr passes fixed, others stil broken
File size: 36.7 KB
Line 
1include "RTLabs/RTLabs_syntax.ma".
2include "RTL/RTL.ma".
3include "common/AssocList.ma".
4include "common/FrontEndOps.ma".
5include "common/Graphs.ma".
6include "joint/TranslateUtils.ma".
7include alias "ASM/BitVector.ma".
8include alias "arithmetics/nat.ma".
9
10definition size_of_sig_type ≝
11  λsig.
12  match sig with
13  [ ASTint isize sign ⇒
14    match isize with [ I8 ⇒ 1 | I16 ⇒ 2 | I32 ⇒ 4 ]
15  | ASTptr ⇒ 2 (* rgn ⇒ nat_of_bitvector ? ptr_size *)
16  ].
17
18inductive register_type: Type[0] ≝
19  | register_int: register → register_type
20  | register_ptr: register → register → register_type.
21
22definition local_env ≝ identifier_map RegisterTag (list register).
23
24definition local_env_typed :
25  list (register × typ) → local_env → Prop ≝
26  λl,env.All ?
27    (λp.let 〈r, ty〉 ≝ p in ∃regs.lookup … env r = Some ? regs ∧
28                                 |regs| = size_of_sig_type ty) l.
29
30definition find_local_env ≝ λr.λlenv : local_env.
31  λprf : r ∈ lenv.opt_safe … (lookup … lenv r) ?.
32lapply (in_map_domain … lenv r)
33>prf * #x #lookup_eq >lookup_eq % #ABS destruct(ABS)
34qed.
35
36lemma find_local_env_elim : ∀P : list register → Prop.∀r. ∀lenv: local_env.∀prf.
37  (∀x.lookup … lenv r = Some ? x → P x) → P (find_local_env r lenv prf).
38#P#r#lenv#prf #H
39change with (P (opt_safe ???))
40@opt_safe_elim assumption
41qed.
42
43definition find_local_env_arg : register → local_env → ? → list psd_argument ≝
44  λr,lenv,prf. map … (Reg ?) (find_local_env r lenv prf).
45
46(* move *)
47let rec m_iter (M : Monad) X (f : X → M X) (n : ℕ) (m : M X) on n : M X ≝
48match n with
49[ O ⇒ m
50| S k ⇒
51  ! v ← m ;
52  m_iter … f k (f v)
53].
54
55definition fresh_registers : ∀p,g.ℕ → state_monad (joint_internal_function p g) (list register) ≝
56λp,g,n.
57  let f ≝ λacc.! m ← fresh_register … ; return (m :: acc) in
58  m_iter … f n (return [ ]).
59
60include alias "common/Identifiers.ma".
61let rec map_list_local_env
62  lenv (regs : list (register×typ)) on regs :
63  All ? (λpr.bool_to_Prop (\fst pr ∈ lenv)) regs → list register ≝
64  match regs return λx.All ?? x → ? with
65  [ nil ⇒ λ_.[ ]
66  | cons hd tl ⇒ λprf.find_local_env (\fst hd) lenv ? @ map_list_local_env lenv tl ?
67  ].cases prf #A #B assumption qed.
68
69definition initialize_local_env :
70  ∀globals.
71  list (register×typ) →
72  state_monad (joint_internal_function RTL globals) local_env ≝
73  λglobals,registers.
74  let f ≝
75    λr_sig,lenv.
76    let 〈r, sig〉 ≝ r_sig in
77    let size ≝ size_of_sig_type sig in
78    ! regs ← fresh_registers … size ;
79    return add … lenv r regs in
80  m_fold … f registers (empty_map …).
81
82lemma initialize_local_env_in : ∀globals,l,def,r.
83  Exists ? (λx.\fst x = r) l → r ∈ \snd (initialize_local_env globals l def).
84whd in match initialize_local_env; normalize nodelta #globals
85cut (∀l,init,def,r.(Exists  ? (λx.\fst x = r) l ∨ bool_to_Prop (r ∈ init)) →
86     r ∈ \snd (m_fold (state_monad ?) ??? l init def))
87[7: #aux #l #def #r #H @aux %1{H} |*:]
88#l elim l -l
89[ #init #def #r * [*] #H @H ]
90* #hd #sig #tl #IH #init #def #r #H
91whd in ⊢ (?(???(???%)?)); normalize nodelta
92whd in ⊢ (?(???(???(match % with [ _ ⇒ ?]))?));
93inversion (fresh_registers ????) #def' #regs #EQfresh normalize nodelta
94@IH cases H -H [*] #H
95[ destruct %2 @mem_set_add_id
96| %1{H}
97| %2 >mem_set_add @orb_Prop_r @H
98]
99qed.
100
101example proj1_rewrite : ∀A,B,a,b.∀pr : A×B.〈a,b〉 = pr → a = \fst pr.
102// qed-.
103example proj2_rewrite : ∀A,B,a,b.∀pr : A×B.〈a,b〉 = pr → b = \snd pr.
104// qed-.
105
106definition initialize_locals_params_ret :
107  ∀globals.
108  (* locals *) list (register×typ) →
109  (* params *) list (register×typ) →
110  (* return *) option (register×typ) →
111  state_monad (joint_internal_function RTL globals) local_env ≝
112  λglobals,locals,params,ret,def.
113  let 〈def',lenv〉 as EQ ≝
114    initialize_local_env globals
115    ((match ret with
116     [ Some r_sig ⇒ [r_sig]
117     | None ⇒ [ ]
118     ]) @ locals @ params) def in
119  let params' ≝ map_list_local_env lenv params ? in
120  let ret' ≝ match ret return λx.ret = x → ? with
121    [ Some r_sig ⇒ λprf.find_local_env (\fst r_sig) lenv ?
122    | None ⇒ λ_.[ ]
123    ] (refl …) in
124  let def'' ≝
125    mk_joint_internal_function RTL globals
126      (joint_if_luniverse … def') (joint_if_runiverse … def') ret'
127      params' (joint_if_stacksize … def')
128      (joint_if_code … def') (joint_if_entry … def') in
129   〈def'', lenv〉. @hide_prf
130[ >(proj2_rewrite ????? EQ)
131  @initialize_local_env_in >prf %1 %
132|*: >(proj2_rewrite ????? EQ)
133  @(All_mp ??? (λpr.initialize_local_env_in ??? (\fst pr)))
134  @(All_mp … (λpr.Exists ? (λx.\fst x = \fst pr) params))
135  [ #a #H @Exists_append_r @Exists_append_r @H
136  | elim params [%] #hd #tl #IH % [ %1 % ] @(All_mp … IH) #x #G %2{G}
137  ]
138]
139qed.
140
141definition make_addr ≝
142  λA.
143  λlst: list A.
144  λprf: 2 = length A lst.〈nth_safe … 0 lst ?, nth_safe … 1 lst ?〉. <prf [%2] %1
145  qed.
146
147definition find_and_addr ≝
148  λr,lenv,prf. make_addr ? (find_local_env r lenv prf).
149
150definition find_and_addr_arg ≝
151  λr,lenv,prf. make_addr ? (find_local_env_arg r lenv prf).
152
153(*include alias "common/Identifiers.ma".*)
154let rec rtl_args (args : list register) (env : local_env) on args :
155  All ? (λr.bool_to_Prop (r∈env)) args → list psd_argument ≝
156  match args return λx.All ?? x → ? with
157  [ nil ⇒ λ_.[ ]
158  | cons hd tl ⇒ λprf.find_local_env_arg hd env ? @ rtl_args tl env ?
159  ].
160  cases prf #H #G assumption
161  qed.
162
163include alias "basics/lists/list.ma".
164let rec vrsplit A (m,n : nat)
165  on m : Vector A (m*n) → Σs : list (Vector A n).|s| = m ≝
166  match m return λx.Vector A (x*n) → Sig (list ?) ? with
167  [ O ⇒ λv.[ ]
168  | S k ⇒ λv.let spl ≝ vsplit ? n … v in \fst spl :: vrsplit ? k n (\snd spl)
169  ].
170  [ %
171  | cases (vrsplit ????) #lst #EQ normalize >EQ %
172  ] qed.
173
174definition split_into_bytes:
175  ∀size. ∀int: bvint size. Σbytes: list Byte. |bytes| = size_intsize size ≝
176λsize.vrsplit ? (size_intsize size) 8.
177
178let rec list_inject_All_aux A P (l : list A) on l : All A P l → list (Σx.P x) ≝
179match l return λx.All A P x → list (Σx.P x) with
180[ nil ⇒ λ_.[ ]
181| cons hd tl ⇒ λprf.«hd, proj1 … prf» :: list_inject_All_aux A P tl (proj2 … prf)
182].
183
184definition translate_op:
185  ∀globals. Op2 →
186  ∀dests : list register.
187  ∀srcrs1 : list psd_argument.
188  ∀srcrs2 : list psd_argument.
189  |dests| = |srcrs1| → |srcrs1| = |srcrs2| →
190  bind_new register (list (joint_seq RTL globals))
191  ≝
192  λglobals: list ident.
193  λop.
194  λdestrs.
195  λsrcrs1.
196  λsrcrs2.
197  λprf1,prf2.
198  (* first, clear carry if op relies on it *)
199  match op with
200  [ Addc ⇒ [CLEAR_CARRY ??]
201  | Sub ⇒ [CLEAR_CARRY ??]
202  | _ ⇒ [ ]
203  ] @ map3 ???? (OP2 RTL globals op) destrs srcrs1 srcrs2 prf1 prf2.
204
205definition cast_list : ∀A.A → ℕ → list A → list A ≝
206λA,deflt,new_length,l.
207  if leb (|l|) new_length then
208    l @ make_list ? deflt (new_length - |l|)
209  else
210    lhd … l new_length.
211
212lemma length_make_list:
213  ∀A: Type[0].
214  ∀elt: A.
215  ∀n: nat.
216    length ? (make_list A elt n) = n.
217  #A #ELT #N
218  elim N normalize // qed.
219
220lemma length_lhd : ∀A,l,n.|lhd A l n| = min (|l|) n.
221#A #l elim l -l
222[ * //
223| #hd #tl #IH * normalize [%]
224  #n >IH normalize elim (leb ??) %
225]
226qed.
227
228lemma length_cast_list : ∀A,dflt,n,l.|cast_list A dflt n l| = n.
229#A #dflt #n #l
230normalize @leb_elim #H normalize
231[ >length_append >length_make_list
232  @sym_eq @minus_to_plus //
233| >length_lhd normalize @leb_elim
234  [ #abs elim (absurd ? abs H) ]
235  #_ %
236]
237qed.
238
239definition translate_op_asym_unsigned :
240  ∀globals.Op2 → list register → list psd_argument → list psd_argument →
241  bind_new register (list (joint_seq RTL globals)) ≝
242  λglobals,op,destrs,srcrs1,srcrs2.
243  let l ≝ |destrs| in
244  let srcrs1' ≝ cast_list ? (zero_byte : psd_argument) l srcrs1 in
245  let srcrs2' ≝ cast_list ? (zero_byte : psd_argument) l srcrs2 in
246  translate_op globals op destrs srcrs1' srcrs2' ??.
247  @hide_prf
248  normalize nodelta
249  >length_cast_list [2: >length_cast_list ] %
250qed.
251
252let rec nat_to_args (size : nat) (k : nat) on size : Σl : list psd_argument.|l| = size ≝
253match size with
254[ O ⇒ [ ]
255| S size' ⇒
256  (byte_of_nat k : psd_argument) :: nat_to_args size' (k ÷ 8)
257]. @hide_prf [ % | cases (nat_to_args ??) #res #EQ  normalize >EQ % ] qed.
258
259definition size_of_cst ≝ λtyp.λcst : constant typ.match cst with
260  [ Ointconst size _ _ ⇒ size_intsize size
261  | _ ⇒ 2
262  ].
263
264definition cst_well_defd : ∀ty.list ident → constant ty → Prop ≝ λty,globals,cst.
265  match cst with
266  [ Oaddrsymbol id _ ⇒ bool_to_Prop (id ∈ globals)
267  | _ ⇒ True
268  ].
269 
270definition translate_cst :
271  ∀ty.
272  ∀globals: list ident.
273  ∀cst_sig: Σcst : constant ty.cst_well_defd ty globals cst.
274  ∀destrs: list register.
275  |destrs| = size_of_cst ? cst_sig →
276  bind_new register (list (joint_seq RTL globals))
277 ≝
278  λty,globals,cst_sig,destrs.
279  match pi1 … cst_sig in constant return λty'.λx : constant ty'.
280      cst_well_defd ty' ? x → |destrs| = size_of_cst ty' x → ?
281  with
282  [ Ointconst size sign const ⇒ λcst_prf,prf.
283      map2 … (λr.λb : Byte.r ← b) destrs
284        (split_into_bytes size const) ?
285  | Oaddrsymbol id offset ⇒ λcst_prf,prf.
286    let 〈r1, r2〉 ≝ make_addr … destrs ? in
287    [ADDRESS RTL globals id ? r1 r2]
288  | Oaddrstack offset ⇒ λcst_prf,prf.
289    let 〈r1, r2〉 ≝ make_addr … destrs ? in
290    [(rtl_stack_address r1 r2 : joint_seq RTL globals)]
291  ] (pi2 … cst_sig).
292  @hide_prf
293  [ cases (split_into_bytes ??) #lst
294    #EQ >EQ >prf whd in ⊢ (??%?); cases size %
295  | @cst_prf
296  |*: >prf %
297  ]
298qed.
299 
300definition translate_move :
301  ∀globals.
302  ∀destrs: list register.
303  ∀srcrs: list psd_argument.
304  |destrs| = |srcrs| → list (joint_seq RTL globals) ≝
305  λglobals,destrs,srcrs,length_eq.
306  map2 … (λdst,src.dst ← src) destrs srcrs length_eq.
307
308definition sign_mask : ∀globals.register → psd_argument →
309  list (joint_seq RTL globals) ≝
310    (* this sets destr to 0xFF if s is neg, 0x00 o.w. Done like that:
311       byte in destr if srcr is: neg   |  pos
312       destr ← srcr | 127       11...1 | 01...1
313       destr ← destr <rot< 1    1...11 | 1...10
314       destr ← INC destr        0....0 | 1....1
315       destr ← CPL destr        1....1 | 0....0
316     *)
317  λglobals,destr,srca.
318  match srca with
319  [ Reg srcr ⇒
320    let byte_127 : Byte ≝ false ::: maximum ? in
321    [destr ← srcr .Or. byte_127 ;
322     destr ← .Rl. destr ;
323     destr ← .Inc. destr ;
324     destr ← .Cmpl. destr ]
325  | Imm b ⇒
326    if sign_bit … b then
327      [ destr ← (maximum … : Byte) ]
328    else
329      [ destr ← zero_byte ]
330  ].
331
332definition translate_cast_signed :
333  ∀globals : list ident.
334  list register → psd_argument →
335  bind_new register (list (joint_seq RTL globals)) ≝
336  λglobals,destrs,srca.
337  ν tmp in
338  (sign_mask ? tmp srca @
339  translate_move ? destrs (make_list ? (Reg ? tmp) (|destrs|)) ?).
340 >length_make_list % qed.
341
342definition translate_fill_with_zero :
343  ∀globals : list ident.
344  list register → list (joint_seq RTL globals) ≝
345  λglobals,destrs.
346  match nat_to_args (|destrs|) 0 with
347  [ mk_Sig res prf ⇒ translate_move ? destrs res ?].
348  // qed.
349
350let rec last A (l : list A) on l : option A ≝
351match l with
352[ nil ⇒ None ?
353| cons hd tl ⇒
354  match tl with
355  [ nil ⇒ Some ? hd
356  | _ ⇒ last A tl
357  ]
358].
359
360lemma last_def : ∀A,hd,tl.last A (hd @ [tl]) = Some ? tl.
361#A #hd elim hd -hd [ #tl % ] #hd * [ #_ #last % ] #hd' #tl #IH #last
362@IH qed.
363
364lemma last_not_empty : ∀A,l.not_empty A l →
365  match last A l with
366  [ None ⇒ False
367  | _ ⇒ True ].
368#A @list_elim_left [*] #pref #last #_ #_ >last_def % qed.
369
370definition translate_op_asym_signed :
371  ∀globals.Op2 → list register → list psd_argument → list psd_argument →
372  bind_new register (list (joint_seq RTL globals)) ≝
373  λglobals,op,destrs,srcrs1,srcrs2.
374  νtmp1,tmp2 in
375  let l ≝ |destrs| in
376  let cast_srcrs ≝ λsrcrs,tmp.
377    let srcrs_l ≝ |srcrs| in
378    if leb srcrs_l l then
379      match last ? srcrs with
380      [ Some last ⇒
381        〈srcrs @ make_list … (Reg ? tmp) (l - srcrs_l),
382         sign_mask … tmp last〉
383      | None ⇒
384        〈make_list … (zero_byte : psd_argument) l, [ ]〉
385      ]
386    else
387      〈lhd … srcrs l, [ ]〉 in
388  let prf : ∀srcrs,tmp.|destrs| = |\fst (cast_srcrs srcrs tmp)| ≝ ? in
389  let srcrs1init ≝ cast_srcrs srcrs1 tmp1 in
390  let srcrs2init ≝ cast_srcrs srcrs2 tmp2 in
391  \snd srcrs1init @@ \snd srcrs2init @@
392  translate_op globals op destrs (\fst srcrs1init) (\fst srcrs2init) ??.
393  @hide_prf
394  [ @prf | <prf @prf ]
395  #srcrs #tmp normalize nodelta
396  @leb_elim #H normalize nodelta
397  [ cases (last ??) normalize nodelta
398    [ >length_make_list %
399    | #_ >length_append >length_make_list
400      @minus_to_plus //
401    ]
402  | >length_lhd normalize >(not_le_to_leb_false … H) %
403  ]
404qed.
405
406(* using size of lists as size of ints *)
407definition translate_cast :
408  ∀globals: list ident.
409  signedness → list register → list register →
410    bind_new register (list (joint_seq RTL globals)) ≝
411  λglobals,src_sign,destrs,srcrs.
412  match reduce_strong ?? destrs srcrs with
413  [ mk_Sig t prf ⇒
414    let src_common ≝ \fst (\fst t) in
415    let src_rest   ≝ \snd (\fst t) in
416    let dst_common ≝ \fst (\snd t) in
417    let dst_rest   ≝ \snd (\snd t) in
418    (* first, move the common part *)
419    translate_move ? src_common (map … (Reg ?) dst_common) ? @@
420    match src_rest return λ_.bind_new ?? with
421    [ nil ⇒ (* upcast *)
422      match src_sign return λ_.bind_new ?? with
423      [ Unsigned ⇒ translate_fill_with_zero ? dst_rest
424      | Signed ⇒
425        match last … srcrs (* = src_common *) with
426        [ Some src_last ⇒ translate_cast_signed ? dst_rest src_last
427        | None ⇒ (* srcrs is empty *) translate_fill_with_zero ? dst_rest
428        ]
429      ]
430    | _ ⇒ (* downcast, nothing else to do *) [ ]
431    ]
432  ].
433  >length_map @prf qed.
434 
435definition translate_notint :
436  ∀globals : list ident.
437  ∀destrs : list register.
438  ∀srcrs_arg : list register.
439  |destrs| = |srcrs_arg| → list (joint_seq RTL globals) ≝
440  λglobals, destrs, srcrs, prf.
441  map2 ??? (OP1 RTL globals Cmpl) destrs srcrs prf.
442
443definition translate_negint : ∀globals.? → ? → ? → bind_new register (list (joint_seq RTL globals)) ≝
444  λglobals: list ident.
445  λdestrs: list register.
446  λsrcrs: list register.
447  λprf: |destrs| = |srcrs|. (* assert in caml code *)
448  translate_notint … destrs srcrs prf @@
449  translate_op ? Add destrs (map … (Reg ?) destrs) (nat_to_args (|destrs|) 1) ??.
450@hide_prf >length_map [ cases (nat_to_args ??) ] // qed.
451
452definition translate_notbool:
453  ∀globals : list ident.
454  list register → list register →
455    bind_new register (list (joint_seq RTL globals)) ≝
456  λglobals,destrs,srcrs.
457  match destrs with
458  [ nil ⇒ [ ]
459  | cons destr destrs' ⇒
460    translate_fill_with_zero ? destrs' @@
461    match srcrs return λ_.bind_new ?? with
462    [ nil ⇒ [destr ← zero_byte]
463    | cons srcr srcrs' ⇒
464      (destr ← srcr) :::
465      map register (joint_seq RTL globals) (λr. destr ← destr .Or. r) srcrs' @@
466      (* now destr is non-null iff srcrs was non-null *)
467      CLEAR_CARRY ?? :::
468      (* many uses of 0, better not use immediates *)
469      ν tmp in
470      [tmp ← zero_byte ;
471       destr ← tmp .Sub. tmp ;
472       (* now carry bit is set iff destr was non-null *)
473       destr ← tmp .Addc. tmp]
474     ]
475   ].
476
477definition translate_op1 : ∀globals.? → ? → ? → ? → ? → ? → ? →
478  bind_new register (list (joint_seq RTL globals)) ≝
479  λglobals.
480  λty, ty'.
481  λop1: unary_operation ty ty'.
482  λdestrs: list register.
483  λsrcrs: list register.
484  λprf1: |destrs| = size_of_sig_type ty'.
485  λprf2: |srcrs| = size_of_sig_type ty.
486  match op1
487  return λty'',ty'''.λx : unary_operation ty'' ty'''.ty'' = ty → ty''' = ty' →
488    bind_new register (list (joint_seq RTL globals)) with
489  [ Ocastint _ src_sign _ _ ⇒ λeq1,eq2.
490    translate_cast globals src_sign destrs srcrs
491  | Onegint sz sg ⇒ λeq1,eq2.
492    translate_negint globals destrs srcrs ?
493  | Onotbool _ _ _ _ ⇒ λeq1,eq2.
494    translate_notbool globals destrs srcrs
495  | Onotint sz sg ⇒ λeq1,eq2.
496    translate_notint globals destrs srcrs ?
497  | Optrofint sz sg ⇒ λeq1,eq2.
498    translate_cast globals Unsigned destrs srcrs
499  | Ointofptr sz sg ⇒ λeq1,eq2.
500    translate_cast globals Unsigned destrs srcrs
501  | Oid t ⇒ λeq1,eq2.
502      translate_move globals destrs (map … (Reg ?) srcrs) ?
503  | _ ⇒ λeq1,eq2.? (* float operations implemented in runtime *)
504  ] (refl …) (refl …).
505  @hide_prf
506  destruct >prf1 >prf2 [3: >length_map ] //
507qed.
508
509include alias "arithmetics/nat.ma".
510
511definition translate_mul_i :
512  ∀globals.
513  register → register →
514  (* size of destination and sources *)
515  ∀n : ℕ.
516  (* the temporary destination, with a dummy register at the end *)
517  ∀tmp_destrs_dummy : list register.
518  ∀srcrs1,srcrs2 : list psd_argument.
519  |tmp_destrs_dummy| = S n →
520  n = |srcrs1| →
521  |srcrs1| = |srcrs2| →
522  (* the position of the least significant byte of the result we compute at
523     this stage (goes from 0 to n in the main function) *)
524  ∀k : ℕ.
525  lt k n →
526  (* the position of the byte in the first source we will use in this stage.
527     the position in the other source will be k - i *)
528  (Σi.i<S k) →
529  (* the accumulator *)
530  bind_new register (list (joint_seq RTL globals)) →
531    bind_new register (list (joint_seq RTL globals)) ≝
532  λglobals,a,b,n,tmp_destrs_dummy,srcrs1,srcrs2,
533    tmp_destrs_dummy_prf,srcrs1_prf,srcrs2_prf,k,k_prf,i_sig,acc.
534  (* the following will expand to
535     a, b ← srcrs1[i] * srcrs2[k-i]
536     tmp_destrs_dummy[k]   ← tmp_destrs_dummy[k] + a
537     tmp_destrs_dummy[k+1] ← tmp_destrs_dummy[k+1] + b + C
538     tmp_destrs_dummy[k+2] ← tmp_destrs_dummy[k+2] + 0 + C
539     ...
540     tmp_destrs_dummy[n]   ← tmp_destrs_dummy[n] + 0 + C
541     ( all calculations on tmp_destrs_dummy[n] will be eliminated with
542     liveness analysis) *)
543  match i_sig with
544    [ mk_Sig i i_prf ⇒
545      (* we pad the result of a byte multiplication with zeros in order
546         for the bit to be carried. Redundant calculations will be eliminated
547         by constant propagation. *)
548      let args : list psd_argument ≝
549        [Reg ? a;Reg ? b] @ make_list ? (zero_byte : psd_argument) (n - 1 - k) in
550      let tmp_destrs_view : list register ≝
551        ltl ? tmp_destrs_dummy k in
552      [❮a, b❯ ← (nth_safe ? i srcrs1 ?) .Mul. (nth_safe ? (k - i) srcrs2 ?)] @@
553      translate_op … Add tmp_destrs_view (map … (Reg ?) tmp_destrs_view) args ?? @@
554      acc
555    ].
556@hide_prf
557[ <srcrs1_prf
558  @(transitive_le … i_prf k_prf)
559| @lt_plus_to_minus [ @le_S_S_to_le assumption | <srcrs2_prf <srcrs1_prf
560  whd >(plus_n_O (S k)) @le_plus // ]
561| >length_map %
562| >length_map
563  >length_ltl
564  >tmp_destrs_dummy_prf >length_append
565  >length_make_list
566  normalize in ⊢ (???(?%?));
567  cases n in k_prf; [ #ABS cases (absurd ? ABS ?) /2 by le_to_not_lt/ ]
568  #n' #k_prf >minus_S_S <minus_n_O
569  >plus_minus_commutative [%] @le_S_S_to_le assumption
570] qed.
571
572definition translate_mul : ∀globals.?→?→?→?→?→bind_new register (list (joint_seq RTL globals)) ≝
573λglobals : list ident.
574λdestrs : list register.
575λsrcrs1 : list psd_argument.
576λsrcrs2 : list psd_argument.
577λsrcrs1_prf : |destrs| = |srcrs1|.
578λsrcrs2_prf : |srcrs1| = |srcrs2|.
579(* needed fresh registers *)
580νa in
581νb in
582(* temporary registers for the result are created, so to avoid overwriting
583   sources *)
584νν |destrs| as tmp_destrs with tmp_destrs_prf in
585νdummy in
586(* the step calculating all products with least significant byte going in the
587   k-th position of the result *)
588let translate_mul_k : (Σk.k<|destrs|) → bind_new register (list (joint_seq RTL globals)) →
589  bind_new register (list (joint_seq RTL globals)) ≝
590  λk_sig,acc.match k_sig with
591  [ mk_Sig k k_prf ⇒
592    foldr … (translate_mul_i ? a b (|destrs|)
593      (tmp_destrs @ [dummy]) srcrs1 srcrs2
594      ? srcrs1_prf srcrs2_prf k k_prf) acc (range_strong (S k))
595  ] in
596(* initializing tmp_destrs to zero
597   dummy is intentionally uninitialized *)
598translate_fill_with_zero … tmp_destrs @@
599(* the main body, roughly:
600   for k in 0 ... n-1 do
601     for i in 0 ... k do
602       translate_mul_i … k … i *)
603foldr … translate_mul_k [ ] (range_strong (|destrs|)) @@
604(* epilogue: saving the result *)
605translate_move … destrs (map … (Reg ?) tmp_destrs) ?.
606@hide_prf
607[ >length_map >tmp_destrs_prf //
608| >length_append <plus_n_Sm <plus_n_O //
609]
610qed.
611
612definition translate_divumodu8 : ∀globals.?→?→?→?→?→?→
613    bind_new register (list (joint_seq RTL globals)) ≝
614  λglobals: list ident.
615  λdiv_not_mod: bool.
616  λdestrs: list register.
617  λsrcrs1: list psd_argument.
618  λsrcrs2: list psd_argument.
619  λsrcrs1_prf : |destrs| = |srcrs1|.
620  λsrcrs2_prf : |srcrs1| = |srcrs2|.
621  match destrs return λx.x = destrs → bind_new ?? with
622  [ nil ⇒ λ_.[ ]
623  | cons destr destrs' ⇒ λeq_destrs.
624    match destrs' with
625    [ nil ⇒
626      match srcrs1 return λx.x = srcrs1 → bind_new ??  with
627      [ nil ⇒ λeq_srcrs1.⊥
628      | cons srcr1 srcrs1' ⇒ λeq_srcrs1.
629        match srcrs2 return λx.x = srcrs2 → bind_new ??  with
630        [ nil ⇒ λeq_srcrs2.⊥
631        | cons srcr2 srcrs2' ⇒ λeq_srcrs2.
632          νdummy in
633          let 〈destr1, destr2〉 ≝
634            if div_not_mod then 〈destr, dummy〉 else 〈dummy, destr〉 in
635          [❮destr1, destr2❯ ← srcr1 .DivuModu. srcr2]
636        ] (refl …)
637      ] (refl …)
638    | _ ⇒ ? (* not implemented *)
639    ]
640  ] (refl …).
641[3: elim not_implemented]
642@hide_prf
643destruct normalize in srcrs1_prf srcrs2_prf; destruct qed.
644
645(* Paolo: to be moved elsewhere *)
646let rec foldr2 (A : Type[0]) (B : Type[0]) (C : Type[0]) (f : A→B→C→C) (init : C) (l1 : list A) (l2 : list B)
647  (prf : |l1| = |l2|) on l1 : C ≝
648  match l1 return λx.x = l1 → C with 
649  [ nil ⇒ λ_.init
650  | cons a l1' ⇒ λeq_l1.
651    match l2 return λy.y = l2 → C with
652    [ nil ⇒ λeq_l2.⊥
653    | cons b l2' ⇒ λeq_l2.
654      f a b (foldr2 A B C f init l1' l2' ?)
655    ] (refl …)
656  ] (refl …).
657@hide_prf
658destruct normalize in prf;  [destruct|//]
659qed.
660
661definition translate_ne: ∀globals: list ident.?→?→?→?→
662  bind_new register (list (joint_seq RTL globals)) ≝
663  λglobals: list ident.
664  λdestrs: list register.
665  λsrcrs1: list psd_argument.
666  λsrcrs2: list psd_argument.
667  match destrs return λ_.|srcrs1| = |srcrs2| → bind_new ?? with
668  [ nil ⇒ λ_.[ ]
669  | cons destr destrs' ⇒ λEQ.
670    translate_fill_with_zero … destrs' @@
671    match srcrs1 return λx.|x| = |srcrs2| → bind_new ?? with
672    [ nil ⇒ λ_.[destr ← zero_byte]
673    | cons srcr1 srcrs1' ⇒
674      match srcrs2 return λx.S (|srcrs1'|) = |x| → bind_new ?? with
675      [ nil ⇒ λEQ.⊥
676      | cons srcr2 srcrs2' ⇒ λEQ.
677        νtmpr in
678        let f : psd_argument → psd_argument → list (joint_seq RTL globals) → list (joint_seq RTL globals) ≝
679          λs1,s2,acc.
680          tmpr  ← s1 .Xor. s2 ::
681          destr ← destr .Or. tmpr ::
682          acc in
683        let epilogue : list (joint_seq RTL globals) ≝
684          [ CLEAR_CARRY ?? ;
685            tmpr ← zero_byte .Sub. destr ;
686            (* now carry bit is 1 iff destrs != 0 *)
687            destr ← zero_byte .Addc. zero_byte ] in
688         destr ← srcr1 .Xor. srcr2 ::
689         foldr2 ??? f epilogue srcrs1' srcrs2' ?
690       ]
691     ] EQ
692   ].
693@hide_prf normalize in EQ; destruct(EQ) assumption qed.
694
695(* if destrs is 0 or 1, it inverses it. To be used after operations that
696   ensure this. *)
697definition translate_toggle_bool : ∀globals.?→bind_new register (list (joint_seq RTL globals)) ≝
698  λglobals: list ident.
699  λdestrs: list register.
700  match destrs with
701  [ nil ⇒ [ ]
702  | cons destr _ ⇒ [destr ← .Cmpl. destr]
703  ].
704 
705definition translate_lt_unsigned :
706  ∀globals.
707  ∀destrs: list register.
708  ∀srcrs1: list psd_argument.
709  ∀srcrs2: list psd_argument.
710  |srcrs1| = |srcrs2| →
711  bind_new register (list (joint_seq RTL globals)) ≝
712  λglobals,destrs,srcrs1,srcrs2,srcrs_prf.
713  match destrs with
714  [ nil ⇒ [ ]
715  | cons destr destrs' ⇒
716    ν tmpr in
717    (translate_fill_with_zero … destrs' @@
718    (* I perform a subtraction, but the only interest is in the carry bit *)
719    translate_op ? Sub (make_list … tmpr (|srcrs1|)) srcrs1 srcrs2 ? srcrs_prf @@
720    [ destr ← zero_byte .Addc. zero_byte ])
721  ].
722@hide_prf
723>length_make_list % qed.
724
725(* shifts signed integers by adding 128 to the most significant byte
726   it replaces it with a fresh register which must be provided *)
727let rec shift_signed globals
728  (tmp : register)
729  (srcrs : list psd_argument) on srcrs :
730  Σt : (list psd_argument) × (list (joint_seq RTL globals)).|\fst t| = |srcrs| ≝
731  let byte_128 : Byte ≝ true ::: bv_zero ? in
732  match srcrs with
733  [ nil ⇒ 〈[ ],[ ]〉
734  | cons srcr srcrs' ⇒
735    match srcrs' with
736    [ nil ⇒ 〈[ Reg ? tmp ], [ tmp ← srcr .Add. byte_128 ]〉
737    | _ ⇒
738      let re ≝ shift_signed globals tmp srcrs' in
739      〈srcr :: \fst re, \snd re〉
740    ]
741  ].
742@hide_prf
743[1,2: %
744|*: cases re * #a #b >p1 normalize #EQ >EQ %
745] qed.
746
747definition translate_lt_signed :
748  ∀globals.
749  ∀destrs: list register.
750  ∀srcrs1: list psd_argument.
751  ∀srcrs2: list psd_argument.
752  |srcrs1| = |srcrs2| →
753  bind_new register (list (joint_seq RTL globals)) ≝
754  λglobals,destrs,srcrs1,srcrs2,srcrs_prf.
755  νtmp_last_s1 in
756  νtmp_last_s2 in
757  let p1 ≝ shift_signed globals tmp_last_s1 srcrs1 in
758  let new_srcrs1 ≝ \fst p1 in
759  let shift_srcrs1 ≝ \snd p1 in
760  let p2 ≝ shift_signed globals tmp_last_s2 srcrs2 in
761  let new_srcrs2 ≝ \fst p2 in
762  let shift_srcrs2 ≝ \snd p2 in
763  shift_srcrs1 @@ shift_srcrs2 @@
764  translate_lt_unsigned globals destrs new_srcrs1 new_srcrs2 ?.
765@hide_prf
766whd in match new_srcrs1; whd in match new_srcrs2;
767cases p1
768cases p2
769//
770qed.
771
772definition translate_lt : bool→∀globals.?→?→?→?→bind_new register (list (joint_seq RTL globals)) ≝
773  λis_unsigned,globals,destrs,srcrs1,srcrs2,srcrs_prf.
774  if is_unsigned then
775    translate_lt_unsigned globals destrs srcrs1 srcrs2 srcrs_prf
776  else
777    translate_lt_signed globals destrs srcrs1 srcrs2 srcrs_prf.
778
779definition translate_cmp ≝
780  λis_unsigned,globals,cmp,destrs,srcrs1,srcrs2,srcrs_prf.
781  match cmp with
782  [ Ceq ⇒
783    translate_ne globals destrs srcrs1 srcrs2 srcrs_prf @@
784    translate_toggle_bool globals destrs
785  | Cne ⇒
786    translate_ne globals destrs srcrs1 srcrs2 srcrs_prf
787  | Clt ⇒
788    translate_lt is_unsigned globals destrs srcrs1 srcrs2 srcrs_prf
789  | Cgt ⇒
790    translate_lt is_unsigned globals destrs srcrs2 srcrs1 ?
791  | Cle ⇒
792    translate_lt is_unsigned globals destrs srcrs2 srcrs1 ? @@
793    translate_toggle_bool globals destrs
794  | Cge ⇒
795    translate_lt is_unsigned globals destrs srcrs1 srcrs2 srcrs_prf @@
796    translate_toggle_bool globals destrs
797  ]. @sym_eq assumption qed.
798
799definition translate_op2 :
800  ∀globals.∀ty1,ty2,ty3.∀op : binary_operation ty1 ty2 ty3.
801  ∀destrs : list register.
802  ∀srcrs1,srcrs2 : list psd_argument.
803  |destrs| = size_of_sig_type ty3 →
804  |srcrs1| = size_of_sig_type ty1 →
805  |srcrs2| = size_of_sig_type ty2 →
806  bind_new register (list (joint_seq RTL globals)) ≝
807  λglobals,ty1,ty2,ty3,op2,destrs,srcrs1,srcrs2.
808  match op2 return λty1,ty2,ty3.λx : binary_operation ty1 ty2 ty3.
809    ? = size_of_sig_type ty3 → ? = size_of_sig_type ty1 → ? = size_of_sig_type ty2 →
810    bind_new ?? with
811  [ Oadd sz sg ⇒ λprf1,prf2,prf3.
812    translate_op globals Add destrs srcrs1 srcrs2 ??
813  | Oaddpi sz ⇒ λprf1,prf2,prf3.
814    translate_op_asym_signed globals Add destrs srcrs1 srcrs2
815  | Oaddip sz ⇒ λprf1,prf2,prf3.
816    translate_op_asym_signed globals Add destrs srcrs2 srcrs1
817  | Osub sz sg ⇒ λprf1,prf2,prf2.
818    translate_op globals Sub destrs srcrs1 srcrs2 ??
819  | Osubpi sz ⇒ λprf1,prf2,prf3.
820    translate_op_asym_signed globals Add destrs srcrs1 srcrs2
821  | Osubpp sz ⇒ λprf1,prf2,prf3.
822    translate_op_asym_unsigned globals Sub destrs srcrs1 srcrs2
823  | Omul sz sg ⇒ λprf1,prf2,prf3.
824    translate_mul globals destrs srcrs1 srcrs2 ??
825  | Odivu sz ⇒ λprf1,prf2,prf3.
826    translate_divumodu8 globals true destrs srcrs1 srcrs2 ??
827  | Omodu sz ⇒ λprf1,prf2,prf3.
828    translate_divumodu8 globals false destrs srcrs1 srcrs2 ??
829  | Oand sz sg ⇒ λprf1,prf2,prf3.
830    translate_op globals And destrs srcrs1 srcrs2 ??
831  | Oor sz sg ⇒ λprf1,prf2,prf3.
832    translate_op globals Or destrs srcrs1 srcrs2 ??
833  | Oxor sz sg ⇒ λprf1,prf2,prf3.
834    translate_op globals Xor destrs srcrs1 srcrs2 ??
835  | Ocmp sz sg1 sg2 c ⇒ λprf1,prf2,prf3.
836    translate_cmp false globals c destrs srcrs1 srcrs2 ?
837  | Ocmpu sz sg c ⇒ λprf1,prf2,prf3.
838    translate_cmp true globals c destrs srcrs1 srcrs2 ?
839  | Ocmpp sg c ⇒ λprf1,prf2,prf3.
840    let is_Ocmpp ≝ 0 in
841    translate_cmp true globals c destrs srcrs1 srcrs2 ?
842  | _ ⇒ ⊥ (* assert false, implemented in run time or float op *)
843  ]. try @not_implemented @hide_prf //
844  qed.
845
846definition translate_cond: ∀globals: list ident. list register → label →
847  bind_step_block RTL globals ≝
848  λglobals: list ident.
849  λsrcrs: list register.
850  λlbl_true: label.
851  match srcrs return λ_.bind_step_block RTL ? with
852  [ nil ⇒ bret … [ ]
853  | cons srcr srcrs' ⇒
854    ν tmpr in
855    let f : register → label → joint_seq RTL globals ≝
856      λr.λ_. tmpr ← tmpr .Or. r in
857    bret …
858    〈(λ_.MOVE RTL globals 〈tmpr,srcr〉) ::
859     map ?? f srcrs',
860     λ_.COND … tmpr lbl_true, [ ]〉
861  ].
862
863(* Paolo: to be controlled (original seemed overly complex) *)
864definition translate_load : ∀globals.?→?→?→bind_new register ? ≝
865  λglobals: list ident.
866  λaddr : list psd_argument.
867  λaddr_prf: 2 = |addr|.
868  λdestrs: list register.
869  ν tmp_addr_l in
870  ν tmp_addr_h in
871  (translate_move … [tmp_addr_l ; tmp_addr_h] addr ? @@
872  let f ≝ λdestr : register.λacc : bind_new register (list (joint_seq RTL globals)).
873    [LOAD RTL globals destr (Reg ? tmp_addr_l) (Reg ? tmp_addr_h)] @@
874    translate_op ? Add
875      [tmp_addr_l ; tmp_addr_h]
876      [tmp_addr_l ; tmp_addr_h]
877      [zero_byte ; (int_size : Byte)] ? ? @@ acc in
878  foldr … f [ ] destrs).
879@hide_prf
880[ <addr_prf ] % qed.
881 
882definition translate_store : ∀globals.?→?→?→bind_new register ? ≝
883  λglobals: list ident.
884  λaddr : list psd_argument.
885  λaddr_prf: 2 = |addr|.
886  λsrcrs: list psd_argument.
887  ν tmp_addr_l in
888  ν tmp_addr_h in
889  (translate_move … [tmp_addr_l ; tmp_addr_h] addr ? @@
890  let f ≝ λsrcr : psd_argument.λacc : bind_new register (list (joint_seq RTL globals)).
891    [STORE RTL globals (Reg ? tmp_addr_l) (Reg ? tmp_addr_h) srcr] @@
892    translate_op … Add
893      [tmp_addr_l ; tmp_addr_h]
894      [tmp_addr_l ; tmp_addr_h]
895      [zero_byte ; (int_size : Byte)] ? ? @@ acc in
896  foldr … f [ ] srcrs).
897@hide_prf [ <addr_prf ] % qed.
898
899lemma lenv_typed_reg_typed_ok1 :
900  ∀locals,env,r,ty.
901  local_env_typed locals env →
902  Exists ? (λx:register×typ.〈r,ty〉=x) locals →
903  ∀prf.
904  |find_local_env r env prf| = size_of_sig_type ty.
905#locals #env #r #ty #env_typed #r_ok
906elim (Exists_All … r_ok env_typed)
907* #r' #ty' * #EQ destruct(EQ) * #rs * #EQ1 #EQ2 #prf
908whd in match find_local_env; normalize nodelta
909@opt_safe_elim #rs' >EQ1 #EQ' destruct assumption
910qed.
911
912lemma lenv_typed_arg_typed_ok1 :
913  ∀locals,env,r,ty.
914  local_env_typed locals env →
915  Exists ? (λx:register×typ.〈r,ty〉=x) locals →
916  ∀prf.
917  |find_local_env_arg r env prf| = size_of_sig_type ty.
918#locals #env #r #ty #env_typed #r_ok #prf
919whd in match find_local_env_arg; normalize nodelta
920>length_map @lenv_typed_reg_typed_ok1 assumption
921qed.
922
923lemma lenv_typed_reg_typed_ok2 :
924  ∀locals,env,r,ty.
925  local_env_typed locals env →
926  Exists ? (λx:register×typ.〈r,ty〉=x) locals →
927  r ∈ env.
928#locals #env #r #ty #env_typed #r_ok
929elim (Exists_All … r_ok env_typed)
930* #r' #ty' * #EQ destruct(EQ) * #rs * #EQ1 #EQ2
931whd in ⊢ (?%);
932>EQ1 %
933qed.
934
935lemma cst_size_ok : ∀ty,cst.size_of_sig_type ty=size_of_cst ty cst.
936#ty * -ty [*] //
937qed.
938
939(* TODO: move it *)
940definition ensure_bind_step_block : ∀p : params.∀g.
941  bind_new register (list (joint_seq p g)) → bind_step_block p g ≝
942  λp,g,b.! l ← b; bret ? (step_block p g) l.
943
944coercion bind_step_block_from_bind_list nocomposites :
945  ∀p : params.∀g.
946  ∀b : bind_new register (list (joint_seq p g)).bind_step_block p g ≝
947  ensure_bind_step_block on _b : bind_new register (list (joint_seq ??)) to
948  bind_step_block ??.
949
950definition translate_statement : ∀globals, locals.∀env.
951  local_env_typed locals env →
952  ∀stmt : statement.statement_typed locals stmt →
953  𝚺b :
954  bind_step_block RTL globals +
955  bind_fin_block RTL globals.
956  match b with [ inl _ ⇒ label | _ ⇒ unit] ≝
957  λglobals,locals,lenv,lenv_typed,stmt.
958  match stmt return λstmt.statement_typed locals stmt → 𝚺b: bind_step_block RTL globals ⊎ bind_fin_block RTL globals.match b with [ inl _ ⇒ label | _ ⇒ unit ] with
959  [ St_skip lbl' ⇒ λstmt_typed.
960    ❬inl … (bret … [ ]), lbl'❭
961  | St_cost cost_lbl lbl' ⇒ λstmt_typed.
962    ❬inl … (bret … [COST_LABEL … cost_lbl]), lbl'❭
963  | St_const ty destr cst lbl' ⇒ λstmt_typed.
964    ❬inl … (translate_cst ty globals cst (find_local_env destr lenv ?) ?), lbl'❭
965  | St_op1 ty ty' op1 destr srcr lbl' ⇒ λstmt_typed.
966    ❬inl … (translate_op1 globals ty' ty op1
967      (find_local_env destr lenv ?)
968      (find_local_env srcr lenv ?) ??), lbl'❭
969  | St_op2 ty1 ty2 ty3 op2 destr srcr1 srcr2 lbl' ⇒ λstmt_typed.
970    ❬inl … (translate_op2 globals … op2
971      (find_local_env destr lenv ?)
972      (find_local_env_arg srcr1 lenv ?)
973      (find_local_env_arg srcr2 lenv ?) ???), lbl'❭
974    (* XXX: should we be ignoring this? *)
975  | St_load ignore addr destr lbl' ⇒ λstmt_typed.
976    ❬inl … (translate_load globals
977      (find_local_env_arg addr lenv ?) ? (find_local_env destr lenv ?)), lbl'❭
978    (* XXX: should we be ignoring this? *)
979  | St_store ignore addr srcr lbl' ⇒ λstmt_typed.
980    ❬inl … (translate_store globals (find_local_env_arg addr lenv ?) ?
981      (find_local_env_arg srcr lenv ?)), lbl'❭
982  | St_call_id f args retr lbl' ⇒ λstmt_typed.
983    ❬inl … (bret …
984      〈[ ],λ_.CALL RTL ? (inl ?? f) (rtl_args args lenv ?)
985        (match retr with
986         [ Some retr ⇒
987           find_local_env retr lenv ?
988         | None ⇒ [ ]
989         ]), [ ]〉), lbl'❭
990  | St_call_ptr f args retr lbl' ⇒ λstmt_typed.
991    let fs ≝ find_and_addr_arg f lenv ?? in
992    ❬inl … (bret …
993      〈[ ],λ_.CALL RTL ? (inr ?? fs) (rtl_args args lenv ?)
994        (match retr with
995         [ Some retr ⇒
996           find_local_env retr lenv ?
997         | None ⇒ [ ]
998         ]), [ ]〉), lbl'❭
999  | St_cond r lbl_true lbl_false ⇒ λstmt_typed.
1000    ❬inl … (translate_cond globals (find_local_env r lenv ?) lbl_true), lbl_false❭
1001  | St_return ⇒ λ_. ❬inr … (bret … 〈[ ], RETURN ?〉),it❭
1002  ].
1003  @hide_prf
1004  [ cases daemon (* needs more hypotheses *)
1005  | @(lenv_typed_reg_typed_ok2 … lenv_typed stmt_typed)
1006  | >(lenv_typed_reg_typed_ok1 … lenv_typed stmt_typed)
1007    @cst_size_ok
1008  |4,5,6,7: cases stmt_typed #dstr_typed #srcr_typed
1009    [3,4: @(lenv_typed_reg_typed_ok1 … lenv_typed) assumption
1010    |2: @(lenv_typed_reg_typed_ok2 … lenv_typed srcr_typed)
1011    |1: @(lenv_typed_reg_typed_ok2 … lenv_typed dstr_typed)
1012    ]
1013  |8,9,10,11,12,13:
1014    cases stmt_typed * #srcrs1_prf #srcrs2_prf #dstr_prf
1015    [5,6: @(lenv_typed_arg_typed_ok1 … lenv_typed) assumption
1016    |4: @(lenv_typed_reg_typed_ok1 … lenv_typed) assumption
1017    |3: @(lenv_typed_reg_typed_ok2 … lenv_typed srcrs2_prf)
1018    |2: @(lenv_typed_reg_typed_ok2 … lenv_typed srcrs1_prf)
1019    |1: @(lenv_typed_reg_typed_ok2 … lenv_typed dstr_prf)
1020    ]
1021  |*: cases daemon (* TODO  *)
1022  ]
1023qed.
1024
1025definition translate_internal :
1026  ∀globals.internal_function → (* insert here more properties *)
1027  joint_closed_internal_function RTL globals ≝
1028  λglobals: list ident.
1029  λdef.
1030  let runiverse' ≝ f_reggen def in
1031  let luniverse' ≝ f_labgen def in
1032  let stack_size' ≝ f_stacksize def in
1033  let entry' ≝ f_entry def in
1034  let init ≝ mk_joint_internal_function RTL globals
1035    luniverse' runiverse' [ ] [ ] stack_size'
1036    (add … (empty_map ? (joint_statement ??)) entry' (RETURN …)) (pi1 … entry') in
1037  let 〈init',lenv〉 as pr_eq ≝ initialize_locals_params_ret globals
1038    (f_locals def) (f_params def) (f_result def) init in
1039  let vars ≝ (f_locals def) @ (f_params def) @
1040    match f_result def with [ Some x ⇒ [x] | _ ⇒ [ ] ] in
1041  let f_trans ≝ λlbl,stmt,def.
1042    let pr ≝ translate_statement … vars lenv ? stmt ? in
1043    match dpi1 … pr return λx.match x with [ inl _ ⇒ label | _ ⇒ unit ] → ? with
1044    [ inl instrs ⇒ λlbl'.b_adds_graph … instrs lbl lbl' def
1045    | inr instrs ⇒ λ_.b_fin_adds_graph … instrs lbl def
1046    ] (dpi2 … pr) in
1047  foldi … f_trans (f_graph def) init'.
1048[4: >graph_code_has_point @mem_set_add_id ] 
1049(* TODO *) cases daemon
1050qed.
1051
1052(*CSC: here we are not doing any alignment on variables, like it is done in OCaml
1053  because of CompCert heritage *)
1054definition rtlabs_to_rtl: RTLabs_program → rtl_program ≝
1055 λp. transform_program … p (λvarnames. transf_fundef … (translate_internal varnames)).
Note: See TracBrowser for help on using the repository browser.